@flowengage/react-chatbot 1.1.9 → 1.2.0
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/flowengage-embed.js
CHANGED
|
@@ -492,7 +492,7 @@ registerProcessor("scribeAudioProcessor", ScribeAudioProcessor);
|
|
|
492
492
|
`)}i(e);let a=n.join(` `).replace(/[ \t]+/g,` `).replace(/\n /g,`
|
|
493
493
|
`).replace(/\n{3,}/g,`
|
|
494
494
|
|
|
495
|
-
`).trim();return a.length>t&&(a=a.slice(0,t).replace(/\s\S*$/,``)+`…`),a}function Ig(){if(typeof document>`u`)return null;for(let e of[`main`,`article`,`[role="main"]`,`#content`,`#main-content`,`#main`,`.main-content`,`.content`,`.post-content`,`.article-content`,`.entry-content`]){let t=document.querySelector(e);if(t&&!Ng(t))return t}return document.body}function Lg(e){if(!e||typeof e.querySelector!=`function`)return e;let t=e.querySelector([`.post-content`,`.entry-content`,`.article-body`,`[itemprop='articleBody']`,`.article__body`,`.field-item`,`.field--name-body`,`.field--body`,`.node__content`].join(`, `));return t&&!Ng(t)?t:e}function Rg(e){if(!e)return null;try{return e.closest(`form`)}catch{let t=e.parentElement;for(;t;){if(t.tagName===`FORM`)return t;t=t.parentElement}return null}}function zg(e){if(!e)return null;let t=e.querySelector(`h1, h2, h3, h4, h5, legend`);if(t)return t.textContent.replace(/\s+/g,` `).trim().slice(0,60);let n=e.getAttribute(`aria-label`);if(n)return n.trim().slice(0,60);let r=e.getAttribute(`title`);if(r)return r.trim().slice(0,60);let i=e.previousElementSibling;for(let e=0;e<3&&i;e++){if(/^H[1-5]$/.test(i.tagName))return i.textContent.replace(/\s+/g,` `).trim().slice(0,60);i=i.previousElementSibling}return null}function Bg(e){try{let t=e.ownerDocument?.defaultView;if(t)return t.getComputedStyle(e)}catch{}return window.getComputedStyle(e)}function Vg(e){let t=new Set;function n(r){if(!r||t.has(r))return;t.add(r),e(r);let i=r.querySelectorAll(`iframe`);for(let e of i)if(!Ng(e))try{let t=e.contentDocument;t&&n(t)}catch{}}typeof document<`u`&&n(document)}function Hg(e){return e==null?null:String(e).replace(/\u00a0/g,` `).replace(/\s*\*+\s*$/u,``).replace(/\s+/g,` `).trim()}function Ug(e){let t=e.ownerDocument||document,n=e.getAttribute(`aria-labelledby`);if(n){let e=n.trim().split(/\s+/).filter(Boolean),r=[];for(let n of e)try{let e=t.getElementById(n);e?.textContent&&r.push(e.textContent.trim())}catch{}if(r.length)return Hg(r.join(` `))}if(e.labels&&e.labels.length)return Hg(e.labels[0].textContent);let r=e.id;if(r)try{let e=t.querySelector(`label[for="${CSS.escape(r)}"]`);if(e)return Hg(e.textContent)}catch{let e=t.querySelector(`label[for="${r.replace(/"/g,`\\"`)}"]`);if(e)return Hg(e.textContent)}let i=e.previousElementSibling;for(let e=0;e<6&&i;e+=1){if(i.tagName===`LABEL`)return Hg(i.textContent);let e=(i.className||``).toString().toLowerCase();if(/chakra-form__label|formlabel|field-label|form-label|mui-form-label/.test(e)){let e=Hg(i.textContent);if(e)return e}i=i.previousElementSibling}let a=e.parentElement;for(let e=0;e<5&&a;e+=1){if(a.tagName===`LABEL`)return Hg(a.textContent);let e=a.querySelector?.(`:scope > label, :scope > [class*='FormLabel'], :scope > [class*='form__label']`);if(e?.textContent)return Hg(e.textContent);a=a.parentElement}let o=e.getAttribute(`aria-label`);return o?Hg(o):null}function Wg(){let e=[];return Vg(t=>{e.push(...Array.from(t.querySelectorAll(`input, select, textarea`)).filter(e=>{if(Ng(e))return!1;let t=(e.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`image`].includes(t)||e.disabled||e.readOnly)return!1;try{let t=Bg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}try{if(e.offsetWidth===0&&e.offsetHeight===0)return!1}catch{}return!0}))}),e}function Gg(e){if(!e||typeof e.closest!=`function`)return!1;try{return!!e.closest(`footer, [role="contentinfo"], #footer, .site-footer, [class*="footer"], [id*="footer"]`)}catch{return!1}}function Kg(){let e=Wg();for(let t of e){if((t.type||``).toLowerCase()!==`email`||Gg(t))continue;let e=Rg(t);if(e)return e}return null}function qg(){let e=Wg(),t=new Map,n=0;return e.map((e,r)=>{let i=Rg(e),a=i||`__orphan__`;t.has(a)||t.set(a,n++);let o=t.get(a);return{formIndex:o,formName:(i?zg(i):null)||`Form ${o}`,fieldIndex:r,tag:e.tagName,type:e.type||`text`,name:e.name||null,id:e.id||null,label:Ug(e),placeholder:e.placeholder||null}})}function Jg(e){if(Ng(e)||e.disabled)return!1;try{let t=Bg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}return!0}function Yg(){let e=[];return Vg(t=>{e.push(...Array.from(t.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Jg)),e.push(...Array.from(t.querySelectorAll(`a[href]`)).filter(e=>{if(!Jg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))}),e.slice(0,60).map((e,t)=>({index:t,text:(e.textContent||e.value||``).replace(/\s+/g,` `).trim().slice(0,120)||null,ariaLabel:e.getAttribute(`aria-label`),type:e.type||e.tagName}))}function Xg(e){return String(e||``).toLowerCase().replace(/\u00a0/g,` `).replace(/\*/g,``).replace(/\s+/g,` `).trim()}function Zg(e){let t=Xg(e);return t=t.replace(/\s+field\s*$/i,``).trim(),t}function Qg(e,t){let n=Zg(t);if(!n)return 0;let r=(e.name||``).toLowerCase(),i=(e.id||``).toLowerCase();if(r===`url`&&/url|website|domain|audit|conduct|site(\s|$)|page(\s|$)/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n)||(i===`url-input`||i.endsWith(`-url-input`))&&/url|website|domain|audit|conduct/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n))return 100;let a=(e.type||``).toLowerCase();if(a===`email`&&/email|e-mail|mail/.test(n))return 100;if(a===`tel`&&/phone|mobile|tel|cell/.test(n))return 95;if(a===`url`&&/url|website|domain|link/.test(n))return 100;let o=[e.name,e.id,e.placeholder,Ug(e),e.getAttribute(`aria-label`),e.getAttribute(`title`),e.getAttribute(`data-testid`),e.getAttribute(`autocomplete`)].filter(Boolean).map(e=>Xg(e)),s=0;for(let e of o){if(!e)continue;if(e===n){s=100;break}if(e.includes(n)||n.includes(e)){s=Math.max(s,96);continue}let t=n.split(/\s+/).filter(e=>e.length>1);if(!t.length)continue;let r=0;for(let n of t)e.includes(n)&&(r+=1);let i=r/t.length;i>0&&(s=Math.max(s,i*88))}return s}var $g=22;function e_(e,t){let n=null,r=0;for(let i of e){let e=Qg(i,t);e>r&&(r=e,n=i)}return!n||r<$g?null:n}function t_(e,t,n){let r=String(t||``).toLowerCase().trim(),i=String(n||``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i)||!(/^https?:\/\//i.test(i)||/\.\w{2,}(\/|\s|$)/.test(i)||r.includes(`url`)||r.includes(`website`)||r.includes(`domain`)||r.includes(`site`)))return null;let a=null,o=0;for(let t of e){if(t.tagName!==`INPUT`&&t.tagName!==`TEXTAREA`)continue;let e=(t.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`checkbox`,`radio`].includes(e))continue;let n=0;(e===`url`||e===`text`||e===`search`)&&(n+=45);let r=[t.name,t.id,t.placeholder,Ug(t),t.getAttribute(`aria-label`),t.getAttribute(`autocomplete`)].filter(Boolean).join(` `).toLowerCase();/(website|url|domain|site\s*url)/.test(r)&&(n+=55),n>o&&(o=n,a=t)}return!a||o<42?null:a}function n_(e){let t=String(e??``).trim();return!t||/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!1:/^https?:\/\//i.test(t)?!0:/\.\w{2,}(\/|\s|$)/.test(t)}function r_(e){let t=String(e??``).toLowerCase().trim();return t?!!(t===`url`||t===`website`||t===`website url`||t===`website_url`||t===`enter website url`||t.includes(`website`)||t.includes(`domain`)||/(enter\s+website|site\s*url|page\s*url)/.test(t)):!1}function i_(e){if(!e||e.tagName!==`INPUT`&&e.tagName!==`TEXTAREA`)return!1;let t=(e.type||``).toLowerCase();return![`hidden`,`submit`,`button`,`checkbox`,`radio`,`file`].includes(t)}function a_(e){if(!i_(e))return!1;let t=(e.name||``).toLowerCase(),n=(e.id||``).toLowerCase(),r=[e.name,e.id,e.placeholder,Ug(e),e.getAttribute(`aria-label`)].filter(Boolean).join(` `).toLowerCase();return t===`url`||n===`url-input`||n.endsWith(`-url-input`)||/(website\s*url|enter\s+website|site\s*url)/.test(r)||/(website|domain)/.test(r)&&/(url|site)/.test(r)}function o_(e,t,n){let r=String(t??``),i=String(n??``),a=l_(e,r)||e_(e,r)||t_(e,r,i);if(!a)return[];let o=new Set([a]);if(n_(i)&&r_(r))for(let t of e)t!==a&&a_(t)&&o.add(t);let s=Array.from(o);return s.sort((e,t)=>{if(e===t)return 0;let n=e.compareDocumentPosition(t);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0}),s}function s_(e,t){try{if(!e?.getBoundingClientRect||!t?.getBoundingClientRect)return 1/0;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i={x:n.left+n.width/2,y:n.top+n.height/2},a={x:r.left+r.width/2,y:r.top+r.height/2};return Math.hypot(i.x-a.x,i.y-a.y)}catch{return 1/0}}function c_(e){if(!e||typeof e!=`string`)return null;let t=null;return Vg(n=>{try{let r=n.getElementById(e);r&&!Ng(r)&&r.matches?.(`input, select, textarea`)&&(t=r)}catch{}}),t}function l_(e,t){let n=String(t??``).trim();if(!n)return null;let r=n.match(/^name:\s*([\w.-]+)$/i);if(r){let t=r[1];for(let n of e)if(n.name===t)return n}let i=n.match(/^id:\s*([\w.-]+)$/i);if(i){let e=c_(i[1]);if(e)return e}let a=n.startsWith(`#`)?n.slice(1):n;if(/^[\w-]+$/.test(a)){let e=c_(a);if(e)return e}let o=n.toLowerCase().replace(/\s+/g,` `);if(o===`url`||o===`website`||o===`website url`||o===`website_url`||o===`enter website url`)for(let t of e){let e=(t.name||``).toLowerCase(),n=(t.id||``).toLowerCase();if(e===`url`||n===`url-input`||n.endsWith(`-url-input`))return t}return null}function u_(e,t){let n=String(t||``).toLowerCase().trim();if(!n)return 0;let r=[e.textContent,e.value,e.getAttribute(`aria-label`),e.getAttribute(`title`)].filter(Boolean).join(` `).toLowerCase().replace(/\s+/g,` `);if(r===n)return 100;if(r.includes(n))return 98;let i=n.split(/\s+/).filter(e=>e.length>1);if(!i.length)return 0;let a=0;for(let e of i)r.includes(e)&&(a+=1);return a/i.length*92}function d_(e,t){let n=[];Vg(e=>{n.push(...Array.from(e.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Jg)),n.push(...Array.from(e.querySelectorAll(`a[href]`)).filter(e=>{if(!Jg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))});let r=0,i=n.map(t=>({el:t,s:u_(t,e)}));for(let{s:e}of i)e>r&&(r=e);let a=e.split(/\s+/).filter(e=>e.length>1).length>=3?28:36;if(r<a)return null;let o=i.filter(({s:e})=>e===r).map(({el:e})=>e);if(o.length===1)return o[0];let s=Array.isArray(t)?t.filter(e=>e&&e.isConnected):[];if(s.length){let e=o[0],t=1/0;for(let n of o)for(let r of s){let i=s_(n,r);i<t&&(t=i,e=n)}return e}return o[0]}function f_(e){if(e==null)return{};if(typeof e==`string`){let t=e.trim();if(!t)return{};try{return JSON.parse(t)}catch{return{url:t}}}return e}function p_(e){let t=f_(e);if(Array.isArray(t)&&t.length>0){let e=t[0];if(e?.field_key!=null||e?.fieldKey!=null)return t.map(e=>({field_key:e.field_key??e.fieldKey,value:e.value}))}if(!t||typeof t!=`object`)return[];let n=t.fields??t.Fields??t.field_list??t.fieldList??t.data?.fields;if(typeof n==`string`)try{n=JSON.parse(n)}catch{n=null}n&&!Array.isArray(n)&&typeof n==`object`&&(n=Object.values(n)),(!n||n.length===0)&&(t.field_key!=null||t.fieldKey!=null)&&t.value!=null&&(n=[{field_key:t.field_key??t.fieldKey,value:t.value}]);let r=t.website_url??t.websiteUrl??t.url??t.website??t.domain??t.site_url??t.siteUrl;return(!n||n.length===0)&&r!=null&&String(r).trim()&&(n=[{field_key:t.field_key??t.fieldKey??`url`,value:String(r).trim()}]),Array.isArray(n)?n.map(e=>({field_key:e?.field_key??e?.fieldKey,value:e?.value??e?.Value})):[]}function m_(e){if(!e||typeof e!=`string`)return e;let t=e.trim();return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?t:(t=t.replace(/\s+at\s+the\s+rate\s*(of)?\s+/gi,`@`),t=t.replace(/\s+at\s+/gi,`@`),t=t.replace(/\s+dot\s+/gi,`.`),t=t.replace(/\s+/g,``),t=t.replace(/\.{2,}/g,`.`).replace(/\.$/,``),t)}function h_(e){if(!e||typeof e!=`string`)return e;let t={zero:`0`,one:`1`,two:`2`,three:`3`,four:`4`,five:`5`,six:`6`,seven:`7`,eight:`8`,nine:`9`,oh:`0`,o:`0`},n=e.toLowerCase().trim();for(let[e,r]of Object.entries(t))n=n.replace(RegExp(`\\b${e}\\b`,`g`),r);return n=n.replace(/[^\d+]/g,``),n}function g_(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t||/\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}\b/i.test(t))return[];let n=t.match(/https?:\/\/[^\s<>"']+/i);if(n)return[{field_key:`url`,value:n[0].replace(/[.,;:)]+$/,``)}];let r=t.match(/\b(?:[\w-]+\.)+[a-z]{2,}\b/i);if(r){let e=r[0].replace(/[.,;:)]+$/,``);return/^https?:/i.test(e)||(e=`https://${e}`),[{field_key:`url`,value:e}]}return[]}function __(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t)return[];let n=[],r=new Set,i=/\b([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\b/i,a=(e,t)=>{let i=String(t??``).trim().replace(/^["']|["']$/g,``);if(!i||i.length>800)return;let a=`${e}\0${i}`;r.has(a)||(r.add(a),n.push({field_key:e,value:i}))},o=m_(t),s=i.test(o),c=o.match(/^\s*([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\s*$/i);if(c)return a(`Email Address`,c[1]),n;if(!i.test(t)&&s){let e=o.match(i);if(e)return a(`Email Address`,e[1]),n}let l=t.match(/\b(?:please\s+)?(?:enter|type|put)\s+(.+?)\s+in(?:to)?\s+(?:the\s+)?(?:full\s*name|full\s*name\s*field|name\s*field)\b/i);if(l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name,?\s*(?:please\s+)?(?:enter|type|put)\s+(.+?)(?:\.|$|!|\?)/i),l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name\s*(?:is|:|please\s+enter|-)\s*(.+?)(?:\.|$|(?=\s+(?:and|my\s+email|email|message))\b)/i),l&&a(`Full Name`,l[1]),l=t.match(/\b(.+?)\s+for\s+(?:the\s+)?full\s*name\b/i),l){let e=l[1].trim();e.length>1&&e.length<120&&!/@/.test(e)&&a(`Full Name`,e)}if(l=t.match(/\b(?:email|e-mail)(?:\s*address)?\s*(?:is|:|please\s+use|enter|-)\s*([^\s@]+@[^\s@]+\.[^\s,]+)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:enter|type|put)\s+([^\s@]+@[^\s@]+\.[^\s,]+)\s+in(?:to)?\s+(?:the\s+)?(?:email|e-mail)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:message|comment)\s*(?:is|:|please\s+enter|-)\s*(.+)$/is),l){let e=l[1].trim();e.length>0&&a(`Message`,e)}if(!n.some(e=>/email/i.test(String(e.field_key)))){let e=t.match(i);if(e){let r=t.replace(e[0],``).trim().replace(/^(please|it's|it is|use|is|my email is|e-?mail is)\s*/i,``).replace(/[.,;:!?]+$/,``).trim();if(t.length<=96&&r.length<=36)return a(`Email Address`,e[1]),n}}if(n.length===0){let e=t.split(/\s+/).filter(Boolean).length,n=/[.!?]/.test(t)||e>=6||t.length>=24&&e>=5||t.length>=42,r=/^[A-Z][a-z]+\s+[A-Z][a-z]+$/.test(t.trim());n&&t.length>=16&&!i.test(t)&&!r&&a(`Message`,t)}return n}function v_(e){if(!e||typeof e!=`object`)return null;let t=e.url??e.target_url??e.page_url??e.pageUrl??e.link??e.href??e.path;return t==null?null:String(t).trim()||null}function y_(e){if(!e||typeof e!=`object`)return null;let t=e.query??e.q??e.search??e.text??e.keywords??e.search_query??e.searchQuery??e.question??e.prompt??e.topic??e.intent;return t==null?null:String(t).trim()||null}function b_(e){let t=e.ownerDocument?.defaultView||window,n=e.tagName===`TEXTAREA`?t.HTMLTextAreaElement.prototype:t.HTMLInputElement.prototype,r=Object.getOwnPropertyDescriptor(n,`value`);return(e,t)=>{try{e._valueTracker&&e._valueTracker.setValue(``)}catch{}r?.set?r.set.call(e,t):e.value=t}}async function x_(e,t,n){if(!n?.skipScroll)try{e.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{try{e.scrollIntoView(!0)}catch{}}try{await Og(e)}catch{}try{Tg(e)}catch{}await new Promise(e=>setTimeout(e,180));try{e.focus({preventScroll:!0})}catch{try{e.focus()}catch{}}let r=e.tagName,i=(e.type||``).toLowerCase(),a={bubbles:!0,cancelable:!0,composed:!0};if(r===`SELECT`)return e.value=String(t),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a)),Eg(e),!0;if(i===`checkbox`||i===`radio`)return e.checked=[`1`,`true`,`yes`,`on`].includes(String(t).toLowerCase().trim()),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),Eg(e),!0;let o=String(t);if(r===`INPUT`||r===`TEXTAREA`){let t=b_(e);try{await vg(e,o,t)}catch{t(e,o)}e.value!==o&&t(e,o)}else e.value=o;try{e.dispatchEvent(new InputEvent(`input`,{...a,inputType:`insertText`,data:o}))}catch{e.dispatchEvent(new Event(`input`,a))}e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a));try{e.focus({preventScroll:!0})}catch{}try{queueMicrotask(()=>{try{e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a))}catch{}})}catch{}return Eg(e),!0}function S_(e){let t=e.siteId||null,n=(e.apiBaseUrl||``).replace(/\/$/,``),r=!!e.preferLiveSpeechHighlight,i=typeof e.getLastUserVoiceText==`function`?e.getLastUserVoiceText:null,a=[],o=null,s={navigate_to_page:async n=>{$(`navigate_to_page ▶ raw parameters:`,n);let r=f_(n),i=v_(r),a=r.section_text??r.sectionText??r.section;if($(`navigate_to_page · coerced:`,{url:i,sectionText:a}),!i){let e=`Missing url: pass a string url, path like /pricing, or JSON with a url field.`;return $(`navigate_to_page ✖`,e),e}let o=typeof window<`u`?xn(i):i;if(xg(`Navigating to ${String(o).replace(/^https?:\/\/[^/]+/,``)||`/`}…`),Cg(),!await Cn(o,{siteId:t,apiBaseUrl:e.apiBaseUrl})){wg(),Sg(200);let e=`That page is not available in the site index; answer without navigating.`;return $(`navigate_to_page ✖ blocked`,e),e}try{if($(`navigate_to_page → shadowNavigate`,o),await Tn(o,{sectionText:a||void 0}),await new Promise(e=>setTimeout(e,600)),wg(),Sg(300),a&&typeof a==`string`){let e=un(null,a);e&&yn(e),$(`navigate_to_page · highlight`,{sectionText:a,found:!!e})}let e=``;try{let t=qg(),n=Yg();if(t.length>0){let r=t.map(e=>e.label||e.placeholder||e.name||e.id).filter(Boolean).join(`, `),i=n.map(e=>e.text).filter(Boolean).join(`, `);e=` This page has a form with fields: [${r}]`+(i?` and buttons: [${i}].`:`.`)+` Call list_page_forms then start filling.`}}catch{}let t=`OK_NAVIGATION ${o}${e}`;return $(`navigate_to_page ✓`,t),t}catch(e){wg(),Sg(200);let t=`Navigation error: ${e?.message||String(e)}`;return $(`navigate_to_page ✖`,t),t}},highlight_on_page:async e=>{if($(`highlight_on_page ▶`,e),r)return $(`highlight_on_page · skipped (live speech highlight owns the page)`),`OK_HIGHLIGHT The page already follows your speech automatically; do not call highlight_on_page again for this turn.`;let t=f_(e),n=t?.section_id||t?.sectionId,i=t?.section_text||t?.sectionText,a=un(n||null,i||null);return a?(yn(a,{speaking:!0}),$(`highlight_on_page ✓ (speaking)`),`OK_HIGHLIGHT section is now highlighted and scrolled into view.`):($(`highlight_on_page ✖ no element`),`Could not find that section on the page.`)},search_site_content:async e=>{$(`search_site_content ▶`,e);let r=y_(f_(e));if($(`search_site_content · query:`,r,`siteId:`,t,`apiBase:`,n||`(empty)`),xg(`Searching site content…`,{spinner:!0}),!r)return Sg(),$(`search_site_content ✖ missing query`),`Missing query parameter.`;if(!t)return Sg(),$(`search_site_content ✖ no siteId`),`Site is not configured for search.`;if(!n)return Sg(),$(`search_site_content ✖ no api base`),`API base URL is missing; cannot search.`;try{let e=`${n}/api/site-tools/search`;$(`search_site_content → POST`,e);let i=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({siteId:t,query:r,currentUrl:typeof window<`u`?window.location.href:``})}),a=await i.json();if($(`search_site_content · HTTP`,i.status,`success:`,a.success),Sg(200),!a.success){let e=a.error||`Search failed.`;return $(`search_site_content ✖`,e),e}let o=a.results||[];return $(`search_site_content ✓`,`${o.length} result(s)`,o.slice(0,3).map(e=>e?.url||e)),JSON.stringify(o)}catch(e){Sg();let t=`Search error: ${e.message||`network`}`;return $(`search_site_content ✖`,t),t}},read_page_content:async e=>{$(`read_page_content ▶`,e);let t=f_(e),n=t?.section_text||t?.sectionText,r=3e3;try{if(n){let e=un(null,n);if(!e){let t=String(n).trim().split(/\s+/).filter(e=>e.length>2);for(let n=Math.min(t.length,5);n>=2&&!e;n--)e=un(null,t.slice(0,n).join(` `))}if(!e)return`Could not find a section matching "${n}" on this page. Try navigate_to_page or click_page_button with the article title, then read_page_content again.`;yn(e,{speaking:!0});let t=Fg(e,r);return t?($(`read_page_content ✓ section:`,t.length,`chars`),`OK_READ: ${t}`):`Found the section but it appears to be empty.`}let e=Lg(Ig());if(!e)return`Could not determine the main content area of this page.`;let t=Fg(e,r);return t?($(`read_page_content ✓ page:`,t.length,`chars`),`OK_READ: ${t}`):`The page appears to have no readable text content.`}catch(e){return $(`read_page_content ✖`,e?.message),`Error reading page content: ${e?.message||`unknown error`}`}},end_voice_session:async()=>($(`end_voice_session ▶`),xg(`Ending voice session…`,{icon:`👋`,spinner:!1,duration:2e3}),kg(!0),Dg(),typeof e.requestEndSession==`function`&&e.requestEndSession(),`Voice session is ending.`),list_page_forms:async()=>{let e=qg(),t=Yg();return $(`list_page_forms ✓`,`${e.length} field(s)`,`${t.length} button(s)`),o=Kg(),$(`list_page_forms · activeFormAncestor`,o?`contact-preferring`:`none`),JSON.stringify({fields:e,buttons:t,hint:`Fields are grouped by formIndex/formName. Work with ONE form at a time — only fill fields from the same formIndex. Do not jump to fields in a different form. On pages with a contact form AND a footer or secondary website-URL field: only use the contact form unless the visitor explicitly asks to use the URL or promo flow. Contact forms: fill in order Full Name → Email Address → Message. Message must be a short note the visitor wants to send (one or two sentences), never a recap of the whole chat or assistant replies. field_key: use placeholder, label, name, or id from this list. click_page_button picks the button nearest the filled fields (e.g. Send Message on the same form).`})},fill_form_fields:async e=>{try{$(`fill_form_fields ▶ raw:`,e);let t=p_(e);if(!t.length&&i){let e=i(),n=g_(e);n.length?$(`fill_form_fields · inferred URL from last user utterance (model omitted usable fields):`,n):(n=__(e),n.length&&$(`fill_form_fields · inferred contact fields from last user utterance (empty tool params):`,n)),n.length&&(t=n)}if($(`fill_form_fields · normalized fields:`,t),!t.length)return`No fields provided. Call list_page_forms for field_key strings, then fill_form_fields with { "fields": [ { "field_key": "<label or placeholder from list>", "value": "<user value>" } ] }. Never use empty {}. Pass the value the user just said (email, message, name, URL) in fields.`;t.length>1&&xg(`Filling ${t.length} fields…`);let n=[];for(let e of t){let t=e?.field_key??e?.fieldKey,r=e?.value;if(t==null||r==null)continue;let i=String(t).toLowerCase();if(/email|e-mail|mail/.test(i))r=m_(r);else if(/phone|mobile|tel|cell/.test(i))r=h_(r);else if(r_(t)||i===`url`){let e=String(r??``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)||/\bat\b/i.test(e)&&/\bdot\b/i.test(e)){let n=m_(e);/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n.trim())&&($(`fill_form_fields · remapping url/website intent to Email Address (value is an email)`),t=`Email Address`,i=`email address`,r=n.trim())}}xg(`Filling ${t}…`),$(`fill_form_fields · processing field:`,t,`=`,r);let s=Wg(),c=s;if(o){let e=s.filter(e=>Rg(e)===o);e.length>0&&(c=e,$(`fill_form_fields · scoped to active form, inputs:`,e.length))}$(`fill_form_fields · visible inputs count:`,s.length,`scoped:`,c.length);let l=!1;for(let e of[c,...c===s?[]:[s]]){let i=o_(e,String(t),r);if(i.length){for(let e=0;e<i.length;e++)await x_(i[e],r,{skipScroll:e>0}),await new Promise(e=>setTimeout(e,80));a=i,o=Rg(i[0])||o,n.push(String(t)),l=!0;break}let s=l_(e,String(t));if(s||=e_(e,String(t)),s||=t_(e,String(t),r),s){await x_(s,r),a=[s],o=Rg(s)||o,n.push(String(t)),l=!0;break}}l||$(`fill_form_fields · no match for field:`,t)}Sg(400);try{kg()}catch{}if(!n.length)return $(`fill_form_fields ✖ no matches`),`Could not match any fields. Call list_page_forms and use field_key values that match placeholder, label, name, or id (e.g. Enter Website URL). Ensure the form is on the page, not the chat panel.`;let r=`OK_FILLED: ${n.join(`, `)}`;return $(`fill_form_fields ✓`,r),r}catch(e){Sg(),Dg(),kg(!0);let t=`fill_form_fields error: ${e?.message||String(e)}`;return $(`fill_form_fields ✖`,t),t}},click_page_button:async e=>{let t=f_(e),n=(t.button_text??t.buttonText??t.text??``).trim();if($(`click_page_button ▶`,n),!n)return`Missing button_text: pass the visible label, e.g. Submit or Read more.`;xg(`Clicking "${n}"…`);let r=d_(n,a);if(!r)return Sg(200),$(`click_page_button ✖ no match`),`Could not find a button matching "${n}". Call list_page_forms to see button texts.`;try{try{r.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{r.scrollIntoView(!0)}try{await Og(r)}catch{}try{jg(r)}catch{}try{await Ag(r)}catch{}let e=Rg(r)||o,t=[];if(e){let n=Array.from(e.querySelectorAll(`input[required], textarea[required], select[required]`)).filter(e=>!Ng(e));for(let e of n)if(!(e.value||``).trim()){let n=Ug(e)||e.placeholder||e.name||e.type;t.push(n)}}if(t.length>0){Sg(200);try{kg()}catch{}let e=`Cannot submit — these required fields are still empty: ${t.join(`, `)}. Fill them first with fill_form_fields, then click again.`;return $(`click_page_button ✖ empty required fields:`,t),e}r.focus?.(),r.click();let n=(r.textContent||r.value||r.getAttribute(`aria-label`)||``).trim().slice(0,80)||`button`;Sg(600);try{kg()}catch{}Dg(),o=null,a=[];let i=`OK_CLICK ${n}`;return $(`click_page_button ✓`,i),i}catch(e){Sg(200),kg(!0);let t=`Click failed: ${e?.message||String(e)}`;return $(`click_page_button ✖`,t),t}}};return{...s,navigateToPage:s.navigate_to_page,highlightOnPage:s.highlight_on_page,searchSiteContent:s.search_site_content,endVoiceSession:s.end_voice_session,listPageForms:s.list_page_forms,fillFormFields:s.fill_form_fields,clickPageButton:s.click_page_button}}function C_(e){return!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,async n=>{let r=nn();r?console.log(`[FlowEngage:voice-tool] ▶`,e,n):console.info(`[FlowEngage] voice tool » ${e}`);let i;try{i=await t(n)}catch(t){let n=`Tool error: ${t?.message||String(t)}`;return console.error(`[FlowEngage] voice tool ${e} threw:`,t),n}let a=typeof i==`string`?i.length>220?`${i.slice(0,220)}…`:i:String(i);return r?console.log(`[FlowEngage:voice-tool] ◀`,e,a):console.info(`[FlowEngage] voice tool « ${e}:`,a),i}]))}var w_={idle:`rgba(99,102,241,0.18)`,listening:`rgba(16,185,129,0.25)`,speaking:`rgba(245,158,11,0.25)`,error:`rgba(239,68,68,0.2)`},T_={idle:`#6366f1`,listening:`#10b981`,speaking:`#f59e0b`,error:`#ef4444`},E_=17,D_=6;function O_(e,t){let n=(t||``).trim();return n?!!(/\b(let'?s|let us)\s+(end|stop|finish|wrap up|close)\s+(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\bend\s+(this\s+)?(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\b(hang\s+up|disconnect)\b/i.test(n)||/\b(that'?s all|we'?re done)\b/i.test(n)||e===`bot`&&(/\b(I'?ll|I will|Let me|I can|I'?m going to)\s+(end|close)\s+(the\s+)?(voice\s+)?(session|call)\b/i.test(n)||/\b(ending|closing)\s+(the\s+)?(voice\s+)?session\b|\bvoice\s+session\s+(is\s+)?(now\s+)?(ended|over|closing)\b/i.test(n)||/\b(session|call)\s+(is\s+)?(now\s+)?(ended|over)\b/i.test(n)||/\bwe\s+can\s+end\s+(the\s+)?(session|call)?\s*(here|now)\b/i.test(n)||/\b(wrapping\s+up|signing\s+off)\b/i.test(n))||/^(goodbye|bye|that'?s all|we'?re done|hang up|disconnect)\b/i.test(n)):!1}function k_({agentId:e,chatId:t,siteId:n,apiBaseUrl:r,onEnd:i,historyRef:a,hasSyncedRef:o,onMessageSync:s,onStartSync:c}){let[l,u]=(0,v.useState)(`idle`),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)(!1),h=(0,v.useRef)(null),g=(0,v.useRef)(null),_=(0,v.useRef)(``),y=(0,v.useRef)(async()=>{}),b=(0,v.useRef)(!1),x=(0,v.useRef)(``),ee=(0,v.useRef)(null),te=(0,v.useRef)(null),S=(0,v.useRef)(null),ne=(0,v.useRef)(null),re=(0,v.useRef)(null),ie=(0,v.useCallback)(()=>{S.current&&=(clearTimeout(S.current),null),ne.current&&=(clearInterval(ne.current),null),x.current=``,ee.current=null,te.current=null,re.current!=null&&(cancelAnimationFrame(re.current),re.current=null);try{bn()}catch{}},[]),ae=(0,v.useCallback)(async()=>{ie();try{await h.current?.endSession?.()}catch{}h.current=null,m(!1),u(`idle`),b.current=!1,typeof s==`function`&&await s(a.current),typeof i==`function`&&i()},[ie,a,s,i]);y.current=ae,(0,v.useEffect)(()=>{let t=!1,i=null;return(async()=>{try{if(await navigator.mediaDevices.getUserMedia({audio:!0}),t)return;a.current=[],_.current=``,b.current=!1;let o=C_(S_({siteId:n||null,apiBaseUrl:r||null,getLastUserVoiceText:()=>_.current,preferLiveSpeechHighlight:!0,requestEndSession:()=>{queueMicrotask(()=>{b.current||(b.current=!0,y.current?.())})}})),s=()=>{try{let e=x.current,t=ee.current;if(!e?.trim()||t==null)return;let n=te.current,r=Date.now(),i;if(n!=null){let t=Math.max(0,(r-n)/1e3);i=Math.min(e.length,Math.floor(t*E_))}else{let n=Math.max(0,(r-t)/1e3);if(n>2.1&&e.length>36)i=Math.min(e.length,Math.floor(Math.max(0,n-.4)*E_));else{let t=Math.min(96,Math.floor(n*D_));i=Math.min(e.length,t)}}let a=e.slice(0,i);if(a.trim().length<8)return;ln();let o=vn(a);o&&yn(o,{speaking:!0})}catch(e){console.warn(`[VoiceInterface] speech highlight failed`,e?.message)}},l=()=>{re.current??=requestAnimationFrame(()=>{re.current=null,s()})},d=()=>{S.current&&clearTimeout(S.current),S.current=setTimeout(()=>{S.current=null,s()},120)},p=()=>{ne.current||=setInterval(()=>{s()},160)},g=await Yh.startSession({agentId:e,clientTools:o,onUnhandledClientToolCall:e=>{console.error(`[VoiceInterface] ElevenLabs requested a client tool that is not registered in the widget:`,e?.tool_name,e?.parameters,`Add a matching handler in voiceClientTools (snake_case and camelCase are both supported).`)},onModeChange:({mode:e})=>{t||u(e===`speaking`?`speaking`:`listening`)},onAudio:()=>{t||(te.current??=Date.now(),p(),l())},onAgentChatResponsePart:e=>{if(t)return;let n=e?.text_response_part??e,r=n?.type,i=n?.text??``;r===`start`?(S.current&&=(clearTimeout(S.current),null),ne.current&&=(clearInterval(ne.current),null),re.current!=null&&(cancelAnimationFrame(re.current),re.current=null),te.current=null,x.current=i,ee.current=Date.now(),p()):r===`delta`?(x.current+=i,ee.current??=Date.now(),p()):r===`stop`?(x.current+=i,p()):(x.current+=i,ee.current==null&&i&&(ee.current=Date.now()),p()),x.current.trim().length>=10&&(d(),l())},onInterruption:()=>{ie()},onMessage:e=>{if(t)return;let n=e.role===`user`?`user`:`bot`,r=e.message||e.text||e.content||``;if(!r)return;let i={sender:n,message:r,timestamp:new Date().toISOString()};n===`user`&&(_.current=r,ie()),a.current=[...a.current,i],O_(n,r)&&queueMicrotask(()=>{b.current||(b.current=!0,y.current?.())})},onError:e=>{t||(console.error(`[VoiceInterface] ElevenLabs error`,e),ie(),u(`error`),f(`Voice session encountered an error.`))},onDisconnect:()=>{t||(console.log(`[VoiceInterface] session disconnected`),ie(),m(!1),u(`idle`))}});if(t){g.endSession().catch(()=>{});return}i=g,h.current=g,m(!0),u(`listening`);try{let e=typeof window<`u`?window.location.href:``,t=``;try{t=await o.list_page_forms()}catch{t=`[]`}g.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${n||`unknown`}. Page fields/buttons JSON: ${t}. Navigation: when the user wants to go to any page (contact, pricing, about, services, etc.), call search_site_content then navigate_to_page immediately — never ask permission. After navigating to a page with a form, call list_page_forms and proactively start helping the user fill it. Contact / lead forms: use only the main contact form (Full Name, Email, Message). Ignore footer or secondary marketing URL fields unless the user explicitly asks to use them. Fill in order: name → email → message. Message must be a short visitor note (what they want from the team), not a transcript of the conversation. Forms: use fill_form_fields then click_page_button (e.g. Send Message) when appropriate. Fill each field right after the user gives that value — do not click submit until required fields are filled. Voice: if the user wants to end the voice session, call end_voice_session or confirm and end.`)}catch{}typeof c==`function`&&c()}catch(e){t||(console.error(`[VoiceInterface] startSession failed`,e),u(`error`),f(`Could not start voice session. Please try again.`))}})(),()=>{t=!0,ie(),i?i.endSession().catch(()=>{}):h.current&&h.current.endSession().catch(()=>{})}},[e,n,r,a,c,ie]);let oe=l===`listening`||l===`speaking`,se=T_[l]||T_.idle,ce=w_[l]||w_.idle;return(0,k.jsxs)(`div`,{ref:g,style:{display:`flex`,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,flex:1,gap:`24px`,padding:`24px 20px`,background:`transparent`},children:[(0,k.jsxs)(`div`,{style:{position:`relative`,width:`140px`,height:`140px`,display:`flex`,alignItems:`center`,justifyContent:`center`},children:[oe&&(0,k.jsx)(`div`,{style:{position:`absolute`,inset:`-16px`,borderRadius:`50%`,border:`2px solid ${se}`,animation:`fe-orb-pulse 1.4s ease-in-out infinite`,opacity:.6}}),oe&&(0,k.jsx)(`div`,{style:{position:`absolute`,inset:`-8px`,borderRadius:`50%`,border:`2px solid ${se}`,animation:`fe-orb-pulse 1.4s ease-in-out 0.35s infinite`,opacity:.4}}),(0,k.jsx)(`div`,{style:{width:`140px`,height:`140px`,borderRadius:`50%`,background:ce,border:`3px solid ${se}`,display:`flex`,alignItems:`center`,justifyContent:`center`,transition:`all 0.35s ease`,transform:l===`speaking`?`scale(1.08)`:`scale(1)`,boxShadow:`0 0 40px ${ce}, 0 8px 32px rgba(0,0,0,0.08)`},children:(0,k.jsx)(In,{size:44,color:se})})]}),(0,k.jsxs)(`div`,{style:{fontSize:`15px`,fontWeight:600,color:l===`error`?`#ef4444`:`#374151`,letterSpacing:`0.01em`,textAlign:`center`},children:[l===`idle`&&`Starting voice session…`,l===`listening`&&`Listening…`,l===`speaking`&&`AI is speaking…`,l===`error`&&(d||`Error`)]}),(0,k.jsxs)(`button`,{onClick:ae,style:{display:`flex`,alignItems:`center`,gap:`8px`,padding:`12px 24px`,borderRadius:`999px`,background:`#fee2e2`,color:`#dc2626`,border:`1px solid #fca5a5`,fontWeight:600,fontSize:`14px`,cursor:`pointer`,transition:`all 0.2s ease`},onMouseEnter:e=>{e.currentTarget.style.background=`#fecaca`},onMouseLeave:e=>{e.currentTarget.style.background=`#fee2e2`},children:[(0,k.jsx)(Ln,{size:18}),`End Voice Session`]}),(0,k.jsx)(`style`,{children:`
|
|
495
|
+
`).trim();return a.length>t&&(a=a.slice(0,t).replace(/\s\S*$/,``)+`…`),a}function Ig(){if(typeof document>`u`)return null;for(let e of[`main`,`article`,`[role="main"]`,`#content`,`#main-content`,`#main`,`.main-content`,`.content`,`.post-content`,`.article-content`,`.entry-content`]){let t=document.querySelector(e);if(t&&!Ng(t))return t}return document.body}function Lg(e){if(!e||typeof e.querySelector!=`function`)return e;let t=e.querySelector([`.post-content`,`.entry-content`,`.article-body`,`[itemprop='articleBody']`,`.article__body`,`.field-item`,`.field--name-body`,`.field--body`,`.node__content`].join(`, `));return t&&!Ng(t)?t:e}function Rg(e){if(!e)return null;try{return e.closest(`form`)}catch{let t=e.parentElement;for(;t;){if(t.tagName===`FORM`)return t;t=t.parentElement}return null}}function zg(e){if(!e)return null;let t=e.querySelector(`h1, h2, h3, h4, h5, legend`);if(t)return t.textContent.replace(/\s+/g,` `).trim().slice(0,60);let n=e.getAttribute(`aria-label`);if(n)return n.trim().slice(0,60);let r=e.getAttribute(`title`);if(r)return r.trim().slice(0,60);let i=e.previousElementSibling;for(let e=0;e<3&&i;e++){if(/^H[1-5]$/.test(i.tagName))return i.textContent.replace(/\s+/g,` `).trim().slice(0,60);i=i.previousElementSibling}return null}function Bg(e){try{let t=e.ownerDocument?.defaultView;if(t)return t.getComputedStyle(e)}catch{}return window.getComputedStyle(e)}function Vg(e){let t=new Set;function n(r){if(!r||t.has(r))return;t.add(r),e(r);let i=r.querySelectorAll(`iframe`);for(let e of i)if(!Ng(e))try{let t=e.contentDocument;t&&n(t)}catch{}}typeof document<`u`&&n(document)}function Hg(e){return e==null?null:String(e).replace(/\u00a0/g,` `).replace(/\s*\*+\s*$/u,``).replace(/\s+/g,` `).trim()}function Ug(e){let t=e.ownerDocument||document,n=e.getAttribute(`aria-labelledby`);if(n){let e=n.trim().split(/\s+/).filter(Boolean),r=[];for(let n of e)try{let e=t.getElementById(n);e?.textContent&&r.push(e.textContent.trim())}catch{}if(r.length)return Hg(r.join(` `))}if(e.labels&&e.labels.length)return Hg(e.labels[0].textContent);let r=e.id;if(r)try{let e=t.querySelector(`label[for="${CSS.escape(r)}"]`);if(e)return Hg(e.textContent)}catch{let e=t.querySelector(`label[for="${r.replace(/"/g,`\\"`)}"]`);if(e)return Hg(e.textContent)}let i=e.previousElementSibling;for(let e=0;e<6&&i;e+=1){if(i.tagName===`LABEL`)return Hg(i.textContent);let e=(i.className||``).toString().toLowerCase();if(/chakra-form__label|formlabel|field-label|form-label|mui-form-label/.test(e)){let e=Hg(i.textContent);if(e)return e}i=i.previousElementSibling}let a=e.parentElement;for(let e=0;e<5&&a;e+=1){if(a.tagName===`LABEL`)return Hg(a.textContent);let e=a.querySelector?.(`:scope > label, :scope > [class*='FormLabel'], :scope > [class*='form__label']`);if(e?.textContent)return Hg(e.textContent);a=a.parentElement}let o=e.getAttribute(`aria-label`);return o?Hg(o):null}function Wg(){let e=[];return Vg(t=>{e.push(...Array.from(t.querySelectorAll(`input, select, textarea`)).filter(e=>{if(Ng(e))return!1;let t=(e.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`image`].includes(t)||e.disabled||e.readOnly)return!1;try{let t=Bg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}try{if(e.offsetWidth===0&&e.offsetHeight===0)return!1}catch{}return!0}))}),e}function Gg(e){if(!e||typeof e.closest!=`function`)return!1;try{return!!e.closest(`footer, [role="contentinfo"], #footer, .site-footer, [class*="footer"], [id*="footer"]`)}catch{return!1}}function Kg(){let e=Wg();for(let t of e){if((t.type||``).toLowerCase()!==`email`||Gg(t))continue;let e=Rg(t);if(e)return e}return null}function qg(){let e=Wg(),t=new Map,n=0;return e.map((e,r)=>{let i=Rg(e),a=i||`__orphan__`;t.has(a)||t.set(a,n++);let o=t.get(a);return{formIndex:o,formName:(i?zg(i):null)||`Form ${o}`,fieldIndex:r,tag:e.tagName,type:e.type||`text`,name:e.name||null,id:e.id||null,label:Ug(e),placeholder:e.placeholder||null}})}function Jg(e){if(Ng(e)||e.disabled)return!1;try{let t=Bg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}return!0}function Yg(){let e=[];return Vg(t=>{e.push(...Array.from(t.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Jg)),e.push(...Array.from(t.querySelectorAll(`a[href]`)).filter(e=>{if(!Jg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))}),e.slice(0,60).map((e,t)=>({index:t,text:(e.textContent||e.value||``).replace(/\s+/g,` `).trim().slice(0,120)||null,ariaLabel:e.getAttribute(`aria-label`),type:e.type||e.tagName}))}function Xg(e){return String(e||``).toLowerCase().replace(/\u00a0/g,` `).replace(/\*/g,``).replace(/\s+/g,` `).trim()}function Zg(e){let t=Xg(e);return t=t.replace(/\s+field\s*$/i,``).trim(),t}function Qg(e,t){let n=Zg(t);if(!n)return 0;let r=(e.name||``).toLowerCase(),i=(e.id||``).toLowerCase();if(r===`url`&&/url|website|domain|audit|conduct|site(\s|$)|page(\s|$)/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n)||(i===`url-input`||i.endsWith(`-url-input`))&&/url|website|domain|audit|conduct/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n))return 100;let a=(e.type||``).toLowerCase();if(a===`email`&&/email|e-mail|mail/.test(n))return 100;if(a===`tel`&&/phone|mobile|tel|cell/.test(n))return 95;if(a===`url`&&/url|website|domain|link/.test(n))return 100;let o=[e.name,e.id,e.placeholder,Ug(e),e.getAttribute(`aria-label`),e.getAttribute(`title`),e.getAttribute(`data-testid`),e.getAttribute(`autocomplete`)].filter(Boolean).map(e=>Xg(e)),s=0;for(let e of o){if(!e)continue;if(e===n){s=100;break}if(e.includes(n)||n.includes(e)){s=Math.max(s,96);continue}let t=n.split(/\s+/).filter(e=>e.length>1);if(!t.length)continue;let r=0;for(let n of t)e.includes(n)&&(r+=1);let i=r/t.length;i>0&&(s=Math.max(s,i*88))}return s}var $g=22;function e_(e,t){let n=null,r=0;for(let i of e){let e=Qg(i,t);e>r&&(r=e,n=i)}return!n||r<$g?null:n}function t_(e,t,n){let r=String(t||``).toLowerCase().trim(),i=String(n||``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i)||!(/^https?:\/\//i.test(i)||/\.\w{2,}(\/|\s|$)/.test(i)||r.includes(`url`)||r.includes(`website`)||r.includes(`domain`)||r.includes(`site`)))return null;let a=null,o=0;for(let t of e){if(t.tagName!==`INPUT`&&t.tagName!==`TEXTAREA`)continue;let e=(t.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`checkbox`,`radio`].includes(e))continue;let n=0;(e===`url`||e===`text`||e===`search`)&&(n+=45);let r=[t.name,t.id,t.placeholder,Ug(t),t.getAttribute(`aria-label`),t.getAttribute(`autocomplete`)].filter(Boolean).join(` `).toLowerCase();/(website|url|domain|site\s*url)/.test(r)&&(n+=55),n>o&&(o=n,a=t)}return!a||o<42?null:a}function n_(e){let t=String(e??``).trim();return!t||/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!1:/^https?:\/\//i.test(t)?!0:/\.\w{2,}(\/|\s|$)/.test(t)}function r_(e){let t=String(e??``).toLowerCase().trim();return t?!!(t===`url`||t===`website`||t===`website url`||t===`website_url`||t===`enter website url`||t.includes(`website`)||t.includes(`domain`)||/(enter\s+website|site\s*url|page\s*url)/.test(t)):!1}function i_(e){if(!e||e.tagName!==`INPUT`&&e.tagName!==`TEXTAREA`)return!1;let t=(e.type||``).toLowerCase();return![`hidden`,`submit`,`button`,`checkbox`,`radio`,`file`].includes(t)}function a_(e){if(!i_(e))return!1;let t=(e.name||``).toLowerCase(),n=(e.id||``).toLowerCase(),r=[e.name,e.id,e.placeholder,Ug(e),e.getAttribute(`aria-label`)].filter(Boolean).join(` `).toLowerCase();return t===`url`||n===`url-input`||n.endsWith(`-url-input`)||/(website\s*url|enter\s+website|site\s*url)/.test(r)||/(website|domain)/.test(r)&&/(url|site)/.test(r)}function o_(e,t,n){let r=String(t??``),i=String(n??``),a=l_(e,r)||e_(e,r)||t_(e,r,i);if(!a)return[];let o=new Set([a]);if(n_(i)&&r_(r))for(let t of e)t!==a&&a_(t)&&o.add(t);let s=Array.from(o);return s.sort((e,t)=>{if(e===t)return 0;let n=e.compareDocumentPosition(t);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0}),s}function s_(e,t){try{if(!e?.getBoundingClientRect||!t?.getBoundingClientRect)return 1/0;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i={x:n.left+n.width/2,y:n.top+n.height/2},a={x:r.left+r.width/2,y:r.top+r.height/2};return Math.hypot(i.x-a.x,i.y-a.y)}catch{return 1/0}}function c_(e){if(!e||typeof e!=`string`)return null;let t=null;return Vg(n=>{try{let r=n.getElementById(e);r&&!Ng(r)&&r.matches?.(`input, select, textarea`)&&(t=r)}catch{}}),t}function l_(e,t){let n=String(t??``).trim();if(!n)return null;let r=n.match(/^name:\s*([\w.-]+)$/i);if(r){let t=r[1];for(let n of e)if(n.name===t)return n}let i=n.match(/^id:\s*([\w.-]+)$/i);if(i){let e=c_(i[1]);if(e)return e}let a=n.startsWith(`#`)?n.slice(1):n;if(/^[\w-]+$/.test(a)){let e=c_(a);if(e)return e}let o=n.toLowerCase().replace(/\s+/g,` `);if(o===`url`||o===`website`||o===`website url`||o===`website_url`||o===`enter website url`)for(let t of e){let e=(t.name||``).toLowerCase(),n=(t.id||``).toLowerCase();if(e===`url`||n===`url-input`||n.endsWith(`-url-input`))return t}return null}function u_(e,t){let n=String(t||``).toLowerCase().trim();if(!n)return 0;let r=[e.textContent,e.value,e.getAttribute(`aria-label`),e.getAttribute(`title`)].filter(Boolean).join(` `).toLowerCase().replace(/\s+/g,` `);if(r===n)return 100;if(r.includes(n))return 98;let i=n.split(/\s+/).filter(e=>e.length>1);if(!i.length)return 0;let a=0;for(let e of i)r.includes(e)&&(a+=1);return a/i.length*92}function d_(e,t){let n=[];Vg(e=>{n.push(...Array.from(e.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Jg)),n.push(...Array.from(e.querySelectorAll(`a[href]`)).filter(e=>{if(!Jg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))});let r=0,i=n.map(t=>({el:t,s:u_(t,e)}));for(let{s:e}of i)e>r&&(r=e);let a=e.split(/\s+/).filter(e=>e.length>1).length>=3?28:36;if(r<a)return null;let o=i.filter(({s:e})=>e===r).map(({el:e})=>e);if(o.length===1)return o[0];let s=Array.isArray(t)?t.filter(e=>e&&e.isConnected):[];if(s.length){let e=o[0],t=1/0;for(let n of o)for(let r of s){let i=s_(n,r);i<t&&(t=i,e=n)}return e}return o[0]}function f_(e){if(e==null)return{};if(typeof e==`string`){let t=e.trim();if(!t)return{};try{return JSON.parse(t)}catch{return{url:t}}}return e}function p_(e){let t=f_(e);if(Array.isArray(t)&&t.length>0){let e=t[0];if(e?.field_key!=null||e?.fieldKey!=null)return t.map(e=>({field_key:e.field_key??e.fieldKey,value:e.value}))}if(!t||typeof t!=`object`)return[];let n=t.fields??t.Fields??t.field_list??t.fieldList??t.data?.fields;if(typeof n==`string`)try{n=JSON.parse(n)}catch{n=null}n&&!Array.isArray(n)&&typeof n==`object`&&(n=Object.values(n)),(!n||n.length===0)&&(t.field_key!=null||t.fieldKey!=null)&&t.value!=null&&(n=[{field_key:t.field_key??t.fieldKey,value:t.value}]);let r=t.website_url??t.websiteUrl??t.url??t.website??t.domain??t.site_url??t.siteUrl;return(!n||n.length===0)&&r!=null&&String(r).trim()&&(n=[{field_key:t.field_key??t.fieldKey??`url`,value:String(r).trim()}]),Array.isArray(n)?n.map(e=>({field_key:e?.field_key??e?.fieldKey,value:e?.value??e?.Value})):[]}function m_(e){if(!e||typeof e!=`string`)return e;let t=e.trim();return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?t:(t=t.replace(/\s+at\s+the\s+rate\s*(of)?\s+/gi,`@`),t=t.replace(/\s+at\s+/gi,`@`),t=t.replace(/\s+dot\s+/gi,`.`),t=t.replace(/\s+/g,``),t=t.replace(/\.{2,}/g,`.`).replace(/\.$/,``),t)}function h_(e){if(!e||typeof e!=`string`)return e;let t={zero:`0`,one:`1`,two:`2`,three:`3`,four:`4`,five:`5`,six:`6`,seven:`7`,eight:`8`,nine:`9`,oh:`0`,o:`0`},n=e.toLowerCase().trim();for(let[e,r]of Object.entries(t))n=n.replace(RegExp(`\\b${e}\\b`,`g`),r);return n=n.replace(/[^\d+]/g,``),n}function g_(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t||/\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}\b/i.test(t))return[];let n=t.match(/https?:\/\/[^\s<>"']+/i);if(n)return[{field_key:`url`,value:n[0].replace(/[.,;:)]+$/,``)}];let r=t.match(/\b(?:[\w-]+\.)+[a-z]{2,}\b/i);if(r){let e=r[0].replace(/[.,;:)]+$/,``);return/^https?:/i.test(e)||(e=`https://${e}`),[{field_key:`url`,value:e}]}return[]}function __(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t)return[];let n=[],r=new Set,i=/\b([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\b/i,a=(e,t)=>{let i=String(t??``).trim().replace(/^["']|["']$/g,``);if(!i||i.length>800)return;let a=`${e}\0${i}`;r.has(a)||(r.add(a),n.push({field_key:e,value:i}))},o=m_(t),s=i.test(o),c=o.match(/^\s*([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\s*$/i);if(c)return a(`Email Address`,c[1]),n;if(!i.test(t)&&s){let e=o.match(i);if(e)return a(`Email Address`,e[1]),n}let l=t.match(/\b(?:please\s+)?(?:enter|type|put)\s+(.+?)\s+in(?:to)?\s+(?:the\s+)?(?:full\s*name|full\s*name\s*field|name\s*field)\b/i);if(l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name,?\s*(?:please\s+)?(?:enter|type|put)\s+(.+?)(?:\.|$|!|\?)/i),l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name\s*(?:is|:|please\s+enter|-)\s*(.+?)(?:\.|$|(?=\s+(?:and|my\s+email|email|message))\b)/i),l&&a(`Full Name`,l[1]),l=t.match(/\b(.+?)\s+for\s+(?:the\s+)?full\s*name\b/i),l){let e=l[1].trim();e.length>1&&e.length<120&&!/@/.test(e)&&a(`Full Name`,e)}if(l=t.match(/\b(?:email|e-mail)(?:\s*address)?\s*(?:is|:|please\s+use|enter|-)\s*([^\s@]+@[^\s@]+\.[^\s,]+)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:enter|type|put)\s+([^\s@]+@[^\s@]+\.[^\s,]+)\s+in(?:to)?\s+(?:the\s+)?(?:email|e-mail)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:message|comment)\s*(?:is|:|please\s+enter|-)\s*(.+)$/is),l){let e=l[1].trim();e.length>0&&a(`Message`,e)}if(!n.some(e=>/email/i.test(String(e.field_key)))){let e=t.match(i);if(e){let r=t.replace(e[0],``).trim().replace(/^(please|it's|it is|use|is|my email is|e-?mail is)\s*/i,``).replace(/[.,;:!?]+$/,``).trim();if(t.length<=96&&r.length<=36)return a(`Email Address`,e[1]),n}}if(n.length===0){let e=t.split(/\s+/).filter(Boolean).length,n=/[.!?]/.test(t)||e>=6||t.length>=24&&e>=5||t.length>=42,r=/^[A-Z][a-z]+\s+[A-Z][a-z]+$/.test(t.trim());n&&t.length>=16&&!i.test(t)&&!r&&a(`Message`,t)}return n}function v_(e){if(!e||typeof e!=`object`)return null;let t=e.url??e.target_url??e.page_url??e.pageUrl??e.link??e.href??e.path;return t==null?null:String(t).trim()||null}function y_(e){if(!e||typeof e!=`object`)return null;let t=e.query??e.q??e.search??e.text??e.keywords??e.search_query??e.searchQuery??e.question??e.prompt??e.topic??e.intent;return t==null?null:String(t).trim()||null}function b_(e){let t=e.ownerDocument?.defaultView||window,n=e.tagName===`TEXTAREA`?t.HTMLTextAreaElement.prototype:t.HTMLInputElement.prototype,r=Object.getOwnPropertyDescriptor(n,`value`);return(e,t)=>{try{e._valueTracker&&e._valueTracker.setValue(``)}catch{}r?.set?r.set.call(e,t):e.value=t}}async function x_(e,t,n){if(!n?.skipScroll)try{e.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{try{e.scrollIntoView(!0)}catch{}}try{await Og(e)}catch{}try{Tg(e)}catch{}await new Promise(e=>setTimeout(e,180));try{e.focus({preventScroll:!0})}catch{try{e.focus()}catch{}}let r=e.tagName,i=(e.type||``).toLowerCase(),a={bubbles:!0,cancelable:!0,composed:!0};if(r===`SELECT`)return e.value=String(t),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a)),Eg(e),!0;if(i===`checkbox`||i===`radio`)return e.checked=[`1`,`true`,`yes`,`on`].includes(String(t).toLowerCase().trim()),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),Eg(e),!0;let o=String(t);if(r===`INPUT`||r===`TEXTAREA`){let t=b_(e);try{await vg(e,o,t)}catch{t(e,o)}e.value!==o&&t(e,o)}else e.value=o;try{e.dispatchEvent(new InputEvent(`input`,{...a,inputType:`insertText`,data:o}))}catch{e.dispatchEvent(new Event(`input`,a))}e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a));try{e.focus({preventScroll:!0})}catch{}try{queueMicrotask(()=>{try{e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a))}catch{}})}catch{}return Eg(e),!0}function S_(e){let t=e.siteId||null,n=(e.apiBaseUrl||``).replace(/\/$/,``),r=!!e.preferLiveSpeechHighlight,i=typeof e.getLastUserVoiceText==`function`?e.getLastUserVoiceText:null,a=[],o=null,s={navigate_to_page:async n=>{$(`navigate_to_page ▶ raw parameters:`,n);let r=f_(n),i=v_(r),a=r.section_text??r.sectionText??r.section;if($(`navigate_to_page · coerced:`,{url:i,sectionText:a}),!i){let e=`Missing url: pass a string url, path like /pricing, or JSON with a url field.`;return $(`navigate_to_page ✖`,e),e}let o=typeof window<`u`?xn(i):i;if(xg(`Navigating to ${String(o).replace(/^https?:\/\/[^/]+/,``)||`/`}…`),Cg(),!await Cn(o,{siteId:t,apiBaseUrl:e.apiBaseUrl})){wg(),Sg(200);let e=`That page is not available in the site index; answer without navigating.`;return $(`navigate_to_page ✖ blocked`,e),e}try{if($(`navigate_to_page → shadowNavigate`,o),await Tn(o,{sectionText:a||void 0}),await new Promise(e=>setTimeout(e,600)),wg(),Sg(300),a&&typeof a==`string`){let e=un(null,a);e&&yn(e),$(`navigate_to_page · highlight`,{sectionText:a,found:!!e})}let e=``;try{let t=qg(),n=Yg();if(t.length>0){let r=t.map(e=>e.label||e.placeholder||e.name||e.id).filter(Boolean).join(`, `),i=n.map(e=>e.text).filter(Boolean).join(`, `);e=` This page has a form with fields: [${r}]`+(i?` and buttons: [${i}].`:`.`)+` Call list_page_forms then start filling.`}}catch{}let t=`OK_NAVIGATION ${o}${e}`;return $(`navigate_to_page ✓`,t),t}catch(e){wg(),Sg(200);let t=`Navigation error: ${e?.message||String(e)}`;return $(`navigate_to_page ✖`,t),t}},highlight_on_page:async e=>{if($(`highlight_on_page ▶`,e),r)return $(`highlight_on_page · skipped (live speech highlight owns the page)`),`OK_HIGHLIGHT The page already follows your speech automatically; do not call highlight_on_page again for this turn.`;let t=f_(e),n=t?.section_id||t?.sectionId,i=t?.section_text||t?.sectionText,a=un(n||null,i||null);return a?(yn(a,{speaking:!0}),$(`highlight_on_page ✓ (speaking)`),`OK_HIGHLIGHT section is now highlighted and scrolled into view.`):($(`highlight_on_page ✖ no element`),`Could not find that section on the page.`)},search_site_content:async e=>{$(`search_site_content ▶`,e);let r=y_(f_(e));if($(`search_site_content · query:`,r,`siteId:`,t,`apiBase:`,n||`(empty)`),xg(`Searching site content…`,{spinner:!0}),!r)return Sg(),$(`search_site_content ✖ missing query`),`Missing query parameter.`;if(!t)return Sg(),$(`search_site_content ✖ no siteId`),`Site is not configured for search.`;if(!n)return Sg(),$(`search_site_content ✖ no api base`),`API base URL is missing; cannot search.`;try{let e=`${n}/api/site-tools/search`;$(`search_site_content → POST`,e);let i=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({siteId:t,query:r,currentUrl:typeof window<`u`?window.location.href:``})}),a=await i.json();if($(`search_site_content · HTTP`,i.status,`success:`,a.success),Sg(200),!a.success){let e=a.error||`Search failed.`;return $(`search_site_content ✖`,e),e}let o=a.results||[];return $(`search_site_content ✓`,`${o.length} result(s)`,o.slice(0,3).map(e=>e?.url||e)),JSON.stringify(o)}catch(e){Sg();let t=`Search error: ${e.message||`network`}`;return $(`search_site_content ✖`,t),t}},read_page_content:async e=>{$(`read_page_content ▶`,e);let t=f_(e),n=t?.section_text||t?.sectionText,r=3e3;try{if(n){let e=un(null,n);if(!e){let t=String(n).trim().split(/\s+/).filter(e=>e.length>2);for(let n=Math.min(t.length,5);n>=2&&!e;n--)e=un(null,t.slice(0,n).join(` `))}if(!e)return`Could not find a section matching "${n}" on this page. Try navigate_to_page or click_page_button with the article title, then read_page_content again.`;yn(e,{speaking:!0});let t=Fg(e,r);return t?($(`read_page_content ✓ section:`,t.length,`chars`),`OK_READ: ${t}`):`Found the section but it appears to be empty.`}let e=Lg(Ig());if(!e)return`Could not determine the main content area of this page.`;let t=Fg(e,r);return t?($(`read_page_content ✓ page:`,t.length,`chars`),`OK_READ: ${t}`):`The page appears to have no readable text content.`}catch(e){return $(`read_page_content ✖`,e?.message),`Error reading page content: ${e?.message||`unknown error`}`}},end_voice_session:async()=>($(`end_voice_session ▶`),xg(`Ending voice session…`,{icon:`👋`,spinner:!1,duration:2e3}),kg(!0),Dg(),typeof e.requestEndSession==`function`&&e.requestEndSession(),`Voice session is ending.`),list_page_forms:async()=>{let e=qg(),t=Yg();return $(`list_page_forms ✓`,`${e.length} field(s)`,`${t.length} button(s)`),o=Kg(),$(`list_page_forms · activeFormAncestor`,o?`contact-preferring`:`none`),JSON.stringify({fields:e,buttons:t,hint:`Fields are grouped by formIndex/formName. Work with ONE form at a time — only fill fields from the same formIndex. Do not jump to fields in a different form. On pages with a contact form AND a footer or secondary website-URL field: only use the contact form unless the visitor explicitly asks to use the URL or promo flow. Contact forms: fill in order Full Name → Email Address → Message. Message must be a short note the visitor wants to send (one or two sentences), never a recap of the whole chat or assistant replies. field_key: use placeholder, label, name, or id from this list. click_page_button picks the button nearest the filled fields (e.g. Send Message on the same form).`})},fill_form_fields:async e=>{try{$(`fill_form_fields ▶ raw:`,e);let t=p_(e);if(!t.length&&i){let e=i(),n=g_(e);n.length?$(`fill_form_fields · inferred URL from last user utterance (model omitted usable fields):`,n):(n=__(e),n.length&&$(`fill_form_fields · inferred contact fields from last user utterance (empty tool params):`,n)),n.length&&(t=n)}if($(`fill_form_fields · normalized fields:`,t),!t.length)return`No fields provided. Call list_page_forms for field_key strings, then fill_form_fields with { "fields": [ { "field_key": "<label or placeholder from list>", "value": "<user value>" } ] }. Never use empty {}. Pass the value the user just said (email, message, name, URL) in fields.`;t.length>1&&xg(`Filling ${t.length} fields…`);let n=[];for(let e of t){let t=e?.field_key??e?.fieldKey,r=e?.value;if(t==null||r==null)continue;let i=String(t).toLowerCase();if(/email|e-mail|mail/.test(i))r=m_(r);else if(/phone|mobile|tel|cell/.test(i))r=h_(r);else if(r_(t)||i===`url`){let e=String(r??``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)||/\bat\b/i.test(e)&&/\bdot\b/i.test(e)){let n=m_(e);/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n.trim())&&($(`fill_form_fields · remapping url/website intent to Email Address (value is an email)`),t=`Email Address`,i=`email address`,r=n.trim())}}xg(`Filling ${t}…`),$(`fill_form_fields · processing field:`,t,`=`,r);let s=Wg(),c=s;if(o){let e=s.filter(e=>Rg(e)===o);e.length>0&&(c=e,$(`fill_form_fields · scoped to active form, inputs:`,e.length))}$(`fill_form_fields · visible inputs count:`,s.length,`scoped:`,c.length);let l=!1;for(let e of[c,...c===s?[]:[s]]){let i=o_(e,String(t),r);if(i.length){for(let e=0;e<i.length;e++)await x_(i[e],r,{skipScroll:e>0}),await new Promise(e=>setTimeout(e,80));a=i,o=Rg(i[0])||o,n.push(String(t)),l=!0;break}let s=l_(e,String(t));if(s||=e_(e,String(t)),s||=t_(e,String(t),r),s){await x_(s,r),a=[s],o=Rg(s)||o,n.push(String(t)),l=!0;break}}l||$(`fill_form_fields · no match for field:`,t)}Sg(400);try{kg()}catch{}if(!n.length)return $(`fill_form_fields ✖ no matches`),`Could not match any fields. Call list_page_forms and use field_key values that match placeholder, label, name, or id (e.g. Enter Website URL). Ensure the form is on the page, not the chat panel.`;let r=`OK_FILLED: ${n.join(`, `)}`;return $(`fill_form_fields ✓`,r),r}catch(e){Sg(),Dg(),kg(!0);let t=`fill_form_fields error: ${e?.message||String(e)}`;return $(`fill_form_fields ✖`,t),t}},click_page_button:async e=>{let t=f_(e),n=(t.button_text??t.buttonText??t.text??``).trim();if($(`click_page_button ▶`,n),!n)return`Missing button_text: pass the visible label, e.g. Submit or Read more.`;xg(`Clicking "${n}"…`);let r=d_(n,a);if(!r)return Sg(200),$(`click_page_button ✖ no match`),`Could not find a button matching "${n}". Call list_page_forms to see button texts.`;try{try{r.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{r.scrollIntoView(!0)}try{await Og(r)}catch{}try{jg(r)}catch{}try{await Ag(r)}catch{}let e=Rg(r)||o,t=[];if(e){let n=Array.from(e.querySelectorAll(`input[required], textarea[required], select[required]`)).filter(e=>!Ng(e));for(let e of n)if(!(e.value||``).trim()){let n=Ug(e)||e.placeholder||e.name||e.type;t.push(n)}}if(t.length>0){Sg(200);try{kg()}catch{}let e=`Cannot submit — these required fields are still empty: ${t.join(`, `)}. Fill them first with fill_form_fields, then click again.`;return $(`click_page_button ✖ empty required fields:`,t),e}r.focus?.(),r.click();let n=(r.textContent||r.value||r.getAttribute(`aria-label`)||``).trim().slice(0,80)||`button`;Sg(600);try{kg()}catch{}Dg(),o=null,a=[];let i=`OK_CLICK ${n}`;return $(`click_page_button ✓`,i),i}catch(e){Sg(200),kg(!0);let t=`Click failed: ${e?.message||String(e)}`;return $(`click_page_button ✖`,t),t}}};return{...s,navigateToPage:s.navigate_to_page,highlightOnPage:s.highlight_on_page,searchSiteContent:s.search_site_content,endVoiceSession:s.end_voice_session,listPageForms:s.list_page_forms,fillFormFields:s.fill_form_fields,clickPageButton:s.click_page_button}}function C_(e){return!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,async n=>{let r=nn();r?console.log(`[FlowEngage:voice-tool] ▶`,e,n):console.info(`[FlowEngage] voice tool » ${e}`);let i;try{i=await t(n)}catch(t){let n=`Tool error: ${t?.message||String(t)}`;return console.error(`[FlowEngage] voice tool ${e} threw:`,t),n}let a=typeof i==`string`?i.length>220?`${i.slice(0,220)}…`:i:String(i);return r?console.log(`[FlowEngage:voice-tool] ◀`,e,a):console.info(`[FlowEngage] voice tool « ${e}:`,a),i}]))}var w_={idle:`rgba(99,102,241,0.18)`,listening:`rgba(16,185,129,0.25)`,speaking:`rgba(245,158,11,0.25)`,error:`rgba(239,68,68,0.2)`},T_={idle:`#6366f1`,listening:`#10b981`,speaking:`#f59e0b`,error:`#ef4444`},E_=17,D_=6;function O_(e,t){let n=(t||``).trim();return n?!!(/\b(let'?s|let us)\s+(end|stop|finish|wrap up|close)\s+(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\bend\s+(this\s+)?(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\b(hang\s+up|disconnect)\b/i.test(n)||/\b(that'?s all|we'?re done)\b/i.test(n)||e===`bot`&&(/\b(I'?ll|I will|Let me|I can|I'?m going to)\s+(end|close)\s+(the\s+)?(voice\s+)?(session|call)\b/i.test(n)||/\b(ending|closing)\s+(the\s+)?(voice\s+)?session\b|\bvoice\s+session\s+(is\s+)?(now\s+)?(ended|over|closing)\b/i.test(n)||/\b(session|call)\s+(is\s+)?(now\s+)?(ended|over)\b/i.test(n)||/\bwe\s+can\s+end\s+(the\s+)?(session|call)?\s*(here|now)\b/i.test(n)||/\b(wrapping\s+up|signing\s+off)\b/i.test(n))||/^(goodbye|bye|that'?s all|we'?re done|hang up|disconnect)\b/i.test(n)):!1}function k_({agentId:e,chatId:t,siteId:n,apiBaseUrl:r,onEnd:i,historyRef:a,hasSyncedRef:o,onMessageSync:s,onStartSync:c}){let[l,u]=(0,v.useState)(`idle`),[d,f]=(0,v.useState)(null),[p,m]=(0,v.useState)(!1),h=(0,v.useRef)(null),g=(0,v.useRef)(null),_=(0,v.useRef)(``),y=(0,v.useRef)(async()=>{}),b=(0,v.useRef)(!1),x=(0,v.useRef)(``),ee=(0,v.useRef)(null),te=(0,v.useRef)(null),S=(0,v.useRef)(null),ne=(0,v.useRef)(null),re=(0,v.useRef)(null),ie=(0,v.useCallback)(()=>{S.current&&=(clearTimeout(S.current),null),ne.current&&=(clearInterval(ne.current),null),x.current=``,ee.current=null,te.current=null,re.current!=null&&(cancelAnimationFrame(re.current),re.current=null);try{bn()}catch{}},[]),ae=(0,v.useCallback)(async()=>{ie();try{await h.current?.endSession?.()}catch{}h.current=null,m(!1),u(`idle`),b.current=!1,typeof s==`function`&&await s(a.current),typeof i==`function`&&i()},[ie,a,s,i]);y.current=ae,(0,v.useEffect)(()=>{let t=!1,i=null;return(async()=>{try{if(await navigator.mediaDevices.getUserMedia({audio:!0}),t)return;a.current=[],_.current=``,b.current=!1;let o=C_(S_({siteId:n||null,apiBaseUrl:r||null,getLastUserVoiceText:()=>_.current,preferLiveSpeechHighlight:!0,requestEndSession:()=>{queueMicrotask(()=>{b.current||(b.current=!0,y.current?.())})}})),s=()=>{try{let e=x.current,t=ee.current;if(!e?.trim()||t==null)return;let n=te.current,r=Date.now(),i;if(n!=null){let t=Math.max(0,(r-n)/1e3),a=Math.min(e.length,Math.floor(t*E_));t>.06&&e.length>=14&&(a=Math.max(a,Math.min(40,e.length))),i=a}else{let n=Math.max(0,(r-t)/1e3);if(n>2.1&&e.length>36)i=Math.min(e.length,Math.floor(Math.max(0,n-.4)*E_));else{let t=Math.min(96,Math.floor(n*D_));i=Math.min(e.length,t)}}let a=e.slice(0,i);if(a.trim().length<6)return;ln();let o=vn(a);o&&yn(o,{speaking:!0})}catch(e){console.warn(`[VoiceInterface] speech highlight failed`,e?.message)}},l=()=>{re.current??=requestAnimationFrame(()=>{re.current=null,s()})},d=()=>{S.current&&clearTimeout(S.current),S.current=setTimeout(()=>{S.current=null,s()},120)},p=()=>{ne.current||=setInterval(()=>{s()},160)},g=await Yh.startSession({agentId:e,clientTools:o,onUnhandledClientToolCall:e=>{console.error(`[VoiceInterface] ElevenLabs requested a client tool that is not registered in the widget:`,e?.tool_name,e?.parameters,`Add a matching handler in voiceClientTools (snake_case and camelCase are both supported).`)},onModeChange:({mode:e})=>{t||u(e===`speaking`?`speaking`:`listening`)},onAudio:()=>{t||(te.current??=Date.now(),p(),l())},onAgentChatResponsePart:e=>{if(t)return;let n=e?.text_response_part??e,r=n?.type,i=n?.text??``;r===`start`?(S.current&&=(clearTimeout(S.current),null),ne.current&&=(clearInterval(ne.current),null),re.current!=null&&(cancelAnimationFrame(re.current),re.current=null),te.current=null,x.current=i,ee.current=Date.now(),p()):r===`delta`?(x.current+=i,ee.current??=Date.now(),p()):r===`stop`?(x.current+=i,p()):(x.current+=i,ee.current==null&&i&&(ee.current=Date.now()),p()),x.current.trim().length>=10&&(d(),l())},onInterruption:()=>{ie()},onMessage:e=>{if(t)return;let n=e.role===`user`?`user`:`bot`,r=e.message||e.text||e.content||``;if(!r)return;let i={sender:n,message:r,timestamp:new Date().toISOString()};if(n===`user`)_.current=r;else if(n===`bot`&&r.trim()){let e=r.trim();e.length>(x.current?.length||0)&&(x.current=e,ee.current??=Date.now(),p(),e.length>=10&&(d(),l()))}a.current=[...a.current,i],O_(n,r)&&queueMicrotask(()=>{b.current||(b.current=!0,y.current?.())})},onError:e=>{t||(console.error(`[VoiceInterface] ElevenLabs error`,e),ie(),u(`error`),f(`Voice session encountered an error.`))},onDisconnect:()=>{t||(console.log(`[VoiceInterface] session disconnected`),ie(),m(!1),u(`idle`))}});if(t){g.endSession().catch(()=>{});return}i=g,h.current=g,m(!0),u(`listening`);try{let e=typeof window<`u`?window.location.href:``,t=``;try{t=await o.list_page_forms()}catch{t=`[]`}g.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${n||`unknown`}. Page fields/buttons JSON: ${t}. Navigation: when the user wants to go to any page (contact, pricing, about, services, etc.), call search_site_content then navigate_to_page immediately — never ask permission. After navigating to a page with a form, call list_page_forms and proactively start helping the user fill it. Contact / lead forms: use only the main contact form (Full Name, Email, Message). Ignore footer or secondary marketing URL fields unless the user explicitly asks to use them. Fill in order: name → email → message. Message must be a short visitor note (what they want from the team), not a transcript of the conversation. Forms: use fill_form_fields then click_page_button (e.g. Send Message) when appropriate. Fill each field right after the user gives that value — do not click submit until required fields are filled. Voice: if the user wants to end the voice session, call end_voice_session or confirm and end.`)}catch{}typeof c==`function`&&c()}catch(e){t||(console.error(`[VoiceInterface] startSession failed`,e),u(`error`),f(`Could not start voice session. Please try again.`))}})(),()=>{t=!0,ie(),i?i.endSession().catch(()=>{}):h.current&&h.current.endSession().catch(()=>{})}},[e,n,r,a,c,ie]);let oe=l===`listening`||l===`speaking`,se=T_[l]||T_.idle,ce=w_[l]||w_.idle;return(0,k.jsxs)(`div`,{ref:g,style:{display:`flex`,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,flex:1,gap:`24px`,padding:`24px 20px`,background:`transparent`},children:[(0,k.jsxs)(`div`,{style:{position:`relative`,width:`140px`,height:`140px`,display:`flex`,alignItems:`center`,justifyContent:`center`},children:[oe&&(0,k.jsx)(`div`,{style:{position:`absolute`,inset:`-16px`,borderRadius:`50%`,border:`2px solid ${se}`,animation:`fe-orb-pulse 1.4s ease-in-out infinite`,opacity:.6}}),oe&&(0,k.jsx)(`div`,{style:{position:`absolute`,inset:`-8px`,borderRadius:`50%`,border:`2px solid ${se}`,animation:`fe-orb-pulse 1.4s ease-in-out 0.35s infinite`,opacity:.4}}),(0,k.jsx)(`div`,{style:{width:`140px`,height:`140px`,borderRadius:`50%`,background:ce,border:`3px solid ${se}`,display:`flex`,alignItems:`center`,justifyContent:`center`,transition:`all 0.35s ease`,transform:l===`speaking`?`scale(1.08)`:`scale(1)`,boxShadow:`0 0 40px ${ce}, 0 8px 32px rgba(0,0,0,0.08)`},children:(0,k.jsx)(In,{size:44,color:se})})]}),(0,k.jsxs)(`div`,{style:{fontSize:`15px`,fontWeight:600,color:l===`error`?`#ef4444`:`#374151`,letterSpacing:`0.01em`,textAlign:`center`},children:[l===`idle`&&`Starting voice session…`,l===`listening`&&`Listening…`,l===`speaking`&&`AI is speaking…`,l===`error`&&(d||`Error`)]}),(0,k.jsxs)(`button`,{onClick:ae,style:{display:`flex`,alignItems:`center`,gap:`8px`,padding:`12px 24px`,borderRadius:`999px`,background:`#fee2e2`,color:`#dc2626`,border:`1px solid #fca5a5`,fontWeight:600,fontSize:`14px`,cursor:`pointer`,transition:`all 0.2s ease`},onMouseEnter:e=>{e.currentTarget.style.background=`#fecaca`},onMouseLeave:e=>{e.currentTarget.style.background=`#fee2e2`},children:[(0,k.jsx)(Ln,{size:18}),`End Voice Session`]}),(0,k.jsx)(`style`,{children:`
|
|
496
496
|
@keyframes fe-orb-pulse {
|
|
497
497
|
0% { transform: scale(1); opacity: 0.6; }
|
|
498
498
|
50% { transform: scale(1.18); opacity: 0.15; }
|
|
@@ -484,7 +484,7 @@ registerProcessor("scribeAudioProcessor", ScribeAudioProcessor);
|
|
|
484
484
|
`)}i(e);let a=n.join(` `).replace(/[ \t]+/g,` `).replace(/\n /g,`
|
|
485
485
|
`).replace(/\n{3,}/g,`
|
|
486
486
|
|
|
487
|
-
`).trim();return a.length>t&&(a=a.slice(0,t).replace(/\s\S*$/,``)+`…`),a}function Tg(){if(typeof document>`u`)return null;for(let e of[`main`,`article`,`[role="main"]`,`#content`,`#main-content`,`#main`,`.main-content`,`.content`,`.post-content`,`.article-content`,`.entry-content`]){let t=document.querySelector(e);if(t&&!Sg(t))return t}return document.body}function Eg(e){if(!e||typeof e.querySelector!=`function`)return e;let t=e.querySelector([`.post-content`,`.entry-content`,`.article-body`,`[itemprop='articleBody']`,`.article__body`,`.field-item`,`.field--name-body`,`.field--body`,`.node__content`].join(`, `));return t&&!Sg(t)?t:e}function Dg(e){if(!e)return null;try{return e.closest(`form`)}catch{let t=e.parentElement;for(;t;){if(t.tagName===`FORM`)return t;t=t.parentElement}return null}}function Og(e){if(!e)return null;let t=e.querySelector(`h1, h2, h3, h4, h5, legend`);if(t)return t.textContent.replace(/\s+/g,` `).trim().slice(0,60);let n=e.getAttribute(`aria-label`);if(n)return n.trim().slice(0,60);let r=e.getAttribute(`title`);if(r)return r.trim().slice(0,60);let i=e.previousElementSibling;for(let e=0;e<3&&i;e++){if(/^H[1-5]$/.test(i.tagName))return i.textContent.replace(/\s+/g,` `).trim().slice(0,60);i=i.previousElementSibling}return null}function kg(e){try{let t=e.ownerDocument?.defaultView;if(t)return t.getComputedStyle(e)}catch{}return window.getComputedStyle(e)}function Ag(e){let t=new Set;function n(r){if(!r||t.has(r))return;t.add(r),e(r);let i=r.querySelectorAll(`iframe`);for(let e of i)if(!Sg(e))try{let t=e.contentDocument;t&&n(t)}catch{}}typeof document<`u`&&n(document)}function jg(e){return e==null?null:String(e).replace(/\u00a0/g,` `).replace(/\s*\*+\s*$/u,``).replace(/\s+/g,` `).trim()}function Mg(e){let t=e.ownerDocument||document,n=e.getAttribute(`aria-labelledby`);if(n){let e=n.trim().split(/\s+/).filter(Boolean),r=[];for(let n of e)try{let e=t.getElementById(n);e?.textContent&&r.push(e.textContent.trim())}catch{}if(r.length)return jg(r.join(` `))}if(e.labels&&e.labels.length)return jg(e.labels[0].textContent);let r=e.id;if(r)try{let e=t.querySelector(`label[for="${CSS.escape(r)}"]`);if(e)return jg(e.textContent)}catch{let e=t.querySelector(`label[for="${r.replace(/"/g,`\\"`)}"]`);if(e)return jg(e.textContent)}let i=e.previousElementSibling;for(let e=0;e<6&&i;e+=1){if(i.tagName===`LABEL`)return jg(i.textContent);let e=(i.className||``).toString().toLowerCase();if(/chakra-form__label|formlabel|field-label|form-label|mui-form-label/.test(e)){let e=jg(i.textContent);if(e)return e}i=i.previousElementSibling}let a=e.parentElement;for(let e=0;e<5&&a;e+=1){if(a.tagName===`LABEL`)return jg(a.textContent);let e=a.querySelector?.(`:scope > label, :scope > [class*='FormLabel'], :scope > [class*='form__label']`);if(e?.textContent)return jg(e.textContent);a=a.parentElement}let o=e.getAttribute(`aria-label`);return o?jg(o):null}function Ng(){let e=[];return Ag(t=>{e.push(...Array.from(t.querySelectorAll(`input, select, textarea`)).filter(e=>{if(Sg(e))return!1;let t=(e.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`image`].includes(t)||e.disabled||e.readOnly)return!1;try{let t=kg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}try{if(e.offsetWidth===0&&e.offsetHeight===0)return!1}catch{}return!0}))}),e}function Pg(e){if(!e||typeof e.closest!=`function`)return!1;try{return!!e.closest(`footer, [role="contentinfo"], #footer, .site-footer, [class*="footer"], [id*="footer"]`)}catch{return!1}}function Fg(){let e=Ng();for(let t of e){if((t.type||``).toLowerCase()!==`email`||Pg(t))continue;let e=Dg(t);if(e)return e}return null}function Ig(){let e=Ng(),t=new Map,n=0;return e.map((e,r)=>{let i=Dg(e),a=i||`__orphan__`;t.has(a)||t.set(a,n++);let o=t.get(a);return{formIndex:o,formName:(i?Og(i):null)||`Form ${o}`,fieldIndex:r,tag:e.tagName,type:e.type||`text`,name:e.name||null,id:e.id||null,label:Mg(e),placeholder:e.placeholder||null}})}function Lg(e){if(Sg(e)||e.disabled)return!1;try{let t=kg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}return!0}function Rg(){let e=[];return Ag(t=>{e.push(...Array.from(t.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Lg)),e.push(...Array.from(t.querySelectorAll(`a[href]`)).filter(e=>{if(!Lg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))}),e.slice(0,60).map((e,t)=>({index:t,text:(e.textContent||e.value||``).replace(/\s+/g,` `).trim().slice(0,120)||null,ariaLabel:e.getAttribute(`aria-label`),type:e.type||e.tagName}))}function zg(e){return String(e||``).toLowerCase().replace(/\u00a0/g,` `).replace(/\*/g,``).replace(/\s+/g,` `).trim()}function Bg(e){let t=zg(e);return t=t.replace(/\s+field\s*$/i,``).trim(),t}function Vg(e,t){let n=Bg(t);if(!n)return 0;let r=(e.name||``).toLowerCase(),i=(e.id||``).toLowerCase();if(r===`url`&&/url|website|domain|audit|conduct|site(\s|$)|page(\s|$)/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n)||(i===`url-input`||i.endsWith(`-url-input`))&&/url|website|domain|audit|conduct/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n))return 100;let a=(e.type||``).toLowerCase();if(a===`email`&&/email|e-mail|mail/.test(n))return 100;if(a===`tel`&&/phone|mobile|tel|cell/.test(n))return 95;if(a===`url`&&/url|website|domain|link/.test(n))return 100;let o=[e.name,e.id,e.placeholder,Mg(e),e.getAttribute(`aria-label`),e.getAttribute(`title`),e.getAttribute(`data-testid`),e.getAttribute(`autocomplete`)].filter(Boolean).map(e=>zg(e)),s=0;for(let e of o){if(!e)continue;if(e===n){s=100;break}if(e.includes(n)||n.includes(e)){s=Math.max(s,96);continue}let t=n.split(/\s+/).filter(e=>e.length>1);if(!t.length)continue;let r=0;for(let n of t)e.includes(n)&&(r+=1);let i=r/t.length;i>0&&(s=Math.max(s,i*88))}return s}var Hg=22;function Ug(e,t){let n=null,r=0;for(let i of e){let e=Vg(i,t);e>r&&(r=e,n=i)}return!n||r<Hg?null:n}function Wg(e,t,n){let r=String(t||``).toLowerCase().trim(),i=String(n||``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i)||!(/^https?:\/\//i.test(i)||/\.\w{2,}(\/|\s|$)/.test(i)||r.includes(`url`)||r.includes(`website`)||r.includes(`domain`)||r.includes(`site`)))return null;let a=null,o=0;for(let t of e){if(t.tagName!==`INPUT`&&t.tagName!==`TEXTAREA`)continue;let e=(t.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`checkbox`,`radio`].includes(e))continue;let n=0;(e===`url`||e===`text`||e===`search`)&&(n+=45);let r=[t.name,t.id,t.placeholder,Mg(t),t.getAttribute(`aria-label`),t.getAttribute(`autocomplete`)].filter(Boolean).join(` `).toLowerCase();/(website|url|domain|site\s*url)/.test(r)&&(n+=55),n>o&&(o=n,a=t)}return!a||o<42?null:a}function Gg(e){let t=String(e??``).trim();return!t||/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!1:/^https?:\/\//i.test(t)?!0:/\.\w{2,}(\/|\s|$)/.test(t)}function Kg(e){let t=String(e??``).toLowerCase().trim();return t?!!(t===`url`||t===`website`||t===`website url`||t===`website_url`||t===`enter website url`||t.includes(`website`)||t.includes(`domain`)||/(enter\s+website|site\s*url|page\s*url)/.test(t)):!1}function qg(e){if(!e||e.tagName!==`INPUT`&&e.tagName!==`TEXTAREA`)return!1;let t=(e.type||``).toLowerCase();return![`hidden`,`submit`,`button`,`checkbox`,`radio`,`file`].includes(t)}function Jg(e){if(!qg(e))return!1;let t=(e.name||``).toLowerCase(),n=(e.id||``).toLowerCase(),r=[e.name,e.id,e.placeholder,Mg(e),e.getAttribute(`aria-label`)].filter(Boolean).join(` `).toLowerCase();return t===`url`||n===`url-input`||n.endsWith(`-url-input`)||/(website\s*url|enter\s+website|site\s*url)/.test(r)||/(website|domain)/.test(r)&&/(url|site)/.test(r)}function Yg(e,t,n){let r=String(t??``),i=String(n??``),a=Qg(e,r)||Ug(e,r)||Wg(e,r,i);if(!a)return[];let o=new Set([a]);if(Gg(i)&&Kg(r))for(let t of e)t!==a&&Jg(t)&&o.add(t);let s=Array.from(o);return s.sort((e,t)=>{if(e===t)return 0;let n=e.compareDocumentPosition(t);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0}),s}function Xg(e,t){try{if(!e?.getBoundingClientRect||!t?.getBoundingClientRect)return 1/0;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i={x:n.left+n.width/2,y:n.top+n.height/2},a={x:r.left+r.width/2,y:r.top+r.height/2};return Math.hypot(i.x-a.x,i.y-a.y)}catch{return 1/0}}function Zg(e){if(!e||typeof e!=`string`)return null;let t=null;return Ag(n=>{try{let r=n.getElementById(e);r&&!Sg(r)&&r.matches?.(`input, select, textarea`)&&(t=r)}catch{}}),t}function Qg(e,t){let n=String(t??``).trim();if(!n)return null;let r=n.match(/^name:\s*([\w.-]+)$/i);if(r){let t=r[1];for(let n of e)if(n.name===t)return n}let i=n.match(/^id:\s*([\w.-]+)$/i);if(i){let e=Zg(i[1]);if(e)return e}let a=n.startsWith(`#`)?n.slice(1):n;if(/^[\w-]+$/.test(a)){let e=Zg(a);if(e)return e}let o=n.toLowerCase().replace(/\s+/g,` `);if(o===`url`||o===`website`||o===`website url`||o===`website_url`||o===`enter website url`)for(let t of e){let e=(t.name||``).toLowerCase(),n=(t.id||``).toLowerCase();if(e===`url`||n===`url-input`||n.endsWith(`-url-input`))return t}return null}function $g(e,t){let n=String(t||``).toLowerCase().trim();if(!n)return 0;let r=[e.textContent,e.value,e.getAttribute(`aria-label`),e.getAttribute(`title`)].filter(Boolean).join(` `).toLowerCase().replace(/\s+/g,` `);if(r===n)return 100;if(r.includes(n))return 98;let i=n.split(/\s+/).filter(e=>e.length>1);if(!i.length)return 0;let a=0;for(let e of i)r.includes(e)&&(a+=1);return a/i.length*92}function e_(e,t){let n=[];Ag(e=>{n.push(...Array.from(e.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Lg)),n.push(...Array.from(e.querySelectorAll(`a[href]`)).filter(e=>{if(!Lg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))});let r=0,i=n.map(t=>({el:t,s:$g(t,e)}));for(let{s:e}of i)e>r&&(r=e);let a=e.split(/\s+/).filter(e=>e.length>1).length>=3?28:36;if(r<a)return null;let o=i.filter(({s:e})=>e===r).map(({el:e})=>e);if(o.length===1)return o[0];let s=Array.isArray(t)?t.filter(e=>e&&e.isConnected):[];if(s.length){let e=o[0],t=1/0;for(let n of o)for(let r of s){let i=Xg(n,r);i<t&&(t=i,e=n)}return e}return o[0]}function t_(e){if(e==null)return{};if(typeof e==`string`){let t=e.trim();if(!t)return{};try{return JSON.parse(t)}catch{return{url:t}}}return e}function n_(e){let t=t_(e);if(Array.isArray(t)&&t.length>0){let e=t[0];if(e?.field_key!=null||e?.fieldKey!=null)return t.map(e=>({field_key:e.field_key??e.fieldKey,value:e.value}))}if(!t||typeof t!=`object`)return[];let n=t.fields??t.Fields??t.field_list??t.fieldList??t.data?.fields;if(typeof n==`string`)try{n=JSON.parse(n)}catch{n=null}n&&!Array.isArray(n)&&typeof n==`object`&&(n=Object.values(n)),(!n||n.length===0)&&(t.field_key!=null||t.fieldKey!=null)&&t.value!=null&&(n=[{field_key:t.field_key??t.fieldKey,value:t.value}]);let r=t.website_url??t.websiteUrl??t.url??t.website??t.domain??t.site_url??t.siteUrl;return(!n||n.length===0)&&r!=null&&String(r).trim()&&(n=[{field_key:t.field_key??t.fieldKey??`url`,value:String(r).trim()}]),Array.isArray(n)?n.map(e=>({field_key:e?.field_key??e?.fieldKey,value:e?.value??e?.Value})):[]}function r_(e){if(!e||typeof e!=`string`)return e;let t=e.trim();return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?t:(t=t.replace(/\s+at\s+the\s+rate\s*(of)?\s+/gi,`@`),t=t.replace(/\s+at\s+/gi,`@`),t=t.replace(/\s+dot\s+/gi,`.`),t=t.replace(/\s+/g,``),t=t.replace(/\.{2,}/g,`.`).replace(/\.$/,``),t)}function i_(e){if(!e||typeof e!=`string`)return e;let t={zero:`0`,one:`1`,two:`2`,three:`3`,four:`4`,five:`5`,six:`6`,seven:`7`,eight:`8`,nine:`9`,oh:`0`,o:`0`},n=e.toLowerCase().trim();for(let[e,r]of Object.entries(t))n=n.replace(RegExp(`\\b${e}\\b`,`g`),r);return n=n.replace(/[^\d+]/g,``),n}function a_(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t||/\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}\b/i.test(t))return[];let n=t.match(/https?:\/\/[^\s<>"']+/i);if(n)return[{field_key:`url`,value:n[0].replace(/[.,;:)]+$/,``)}];let r=t.match(/\b(?:[\w-]+\.)+[a-z]{2,}\b/i);if(r){let e=r[0].replace(/[.,;:)]+$/,``);return/^https?:/i.test(e)||(e=`https://${e}`),[{field_key:`url`,value:e}]}return[]}function o_(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t)return[];let n=[],r=new Set,i=/\b([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\b/i,a=(e,t)=>{let i=String(t??``).trim().replace(/^["']|["']$/g,``);if(!i||i.length>800)return;let a=`${e}\0${i}`;r.has(a)||(r.add(a),n.push({field_key:e,value:i}))},o=r_(t),s=i.test(o),c=o.match(/^\s*([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\s*$/i);if(c)return a(`Email Address`,c[1]),n;if(!i.test(t)&&s){let e=o.match(i);if(e)return a(`Email Address`,e[1]),n}let l=t.match(/\b(?:please\s+)?(?:enter|type|put)\s+(.+?)\s+in(?:to)?\s+(?:the\s+)?(?:full\s*name|full\s*name\s*field|name\s*field)\b/i);if(l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name,?\s*(?:please\s+)?(?:enter|type|put)\s+(.+?)(?:\.|$|!|\?)/i),l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name\s*(?:is|:|please\s+enter|-)\s*(.+?)(?:\.|$|(?=\s+(?:and|my\s+email|email|message))\b)/i),l&&a(`Full Name`,l[1]),l=t.match(/\b(.+?)\s+for\s+(?:the\s+)?full\s*name\b/i),l){let e=l[1].trim();e.length>1&&e.length<120&&!/@/.test(e)&&a(`Full Name`,e)}if(l=t.match(/\b(?:email|e-mail)(?:\s*address)?\s*(?:is|:|please\s+use|enter|-)\s*([^\s@]+@[^\s@]+\.[^\s,]+)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:enter|type|put)\s+([^\s@]+@[^\s@]+\.[^\s,]+)\s+in(?:to)?\s+(?:the\s+)?(?:email|e-mail)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:message|comment)\s*(?:is|:|please\s+enter|-)\s*(.+)$/is),l){let e=l[1].trim();e.length>0&&a(`Message`,e)}if(!n.some(e=>/email/i.test(String(e.field_key)))){let e=t.match(i);if(e){let r=t.replace(e[0],``).trim().replace(/^(please|it's|it is|use|is|my email is|e-?mail is)\s*/i,``).replace(/[.,;:!?]+$/,``).trim();if(t.length<=96&&r.length<=36)return a(`Email Address`,e[1]),n}}if(n.length===0){let e=t.split(/\s+/).filter(Boolean).length,n=/[.!?]/.test(t)||e>=6||t.length>=24&&e>=5||t.length>=42,r=/^[A-Z][a-z]+\s+[A-Z][a-z]+$/.test(t.trim());n&&t.length>=16&&!i.test(t)&&!r&&a(`Message`,t)}return n}function s_(e){if(!e||typeof e!=`object`)return null;let t=e.url??e.target_url??e.page_url??e.pageUrl??e.link??e.href??e.path;return t==null?null:String(t).trim()||null}function c_(e){if(!e||typeof e!=`object`)return null;let t=e.query??e.q??e.search??e.text??e.keywords??e.search_query??e.searchQuery??e.question??e.prompt??e.topic??e.intent;return t==null?null:String(t).trim()||null}function l_(e){let t=e.ownerDocument?.defaultView||window,n=e.tagName===`TEXTAREA`?t.HTMLTextAreaElement.prototype:t.HTMLInputElement.prototype,r=Object.getOwnPropertyDescriptor(n,`value`);return(e,t)=>{try{e._valueTracker&&e._valueTracker.setValue(``)}catch{}r?.set?r.set.call(e,t):e.value=t}}async function u_(e,t,n){if(!n?.skipScroll)try{e.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{try{e.scrollIntoView(!0)}catch{}}try{await _g(e)}catch{}try{mg(e)}catch{}await new Promise(e=>setTimeout(e,180));try{e.focus({preventScroll:!0})}catch{try{e.focus()}catch{}}let r=e.tagName,i=(e.type||``).toLowerCase(),a={bubbles:!0,cancelable:!0,composed:!0};if(r===`SELECT`)return e.value=String(t),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a)),hg(e),!0;if(i===`checkbox`||i===`radio`)return e.checked=[`1`,`true`,`yes`,`on`].includes(String(t).toLowerCase().trim()),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),hg(e),!0;let o=String(t);if(r===`INPUT`||r===`TEXTAREA`){let t=l_(e);try{await sg(e,o,t)}catch{t(e,o)}e.value!==o&&t(e,o)}else e.value=o;try{e.dispatchEvent(new InputEvent(`input`,{...a,inputType:`insertText`,data:o}))}catch{e.dispatchEvent(new Event(`input`,a))}e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a));try{e.focus({preventScroll:!0})}catch{}try{queueMicrotask(()=>{try{e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a))}catch{}})}catch{}return hg(e),!0}function d_(e){let t=e.siteId||null,n=(e.apiBaseUrl||``).replace(/\/$/,``),r=!!e.preferLiveSpeechHighlight,i=typeof e.getLastUserVoiceText==`function`?e.getLastUserVoiceText:null,a=[],o=null,s={navigate_to_page:async n=>{$(`navigate_to_page ▶ raw parameters:`,n);let r=t_(n),i=s_(r),a=r.section_text??r.sectionText??r.section;if($(`navigate_to_page · coerced:`,{url:i,sectionText:a}),!i){let e=`Missing url: pass a string url, path like /pricing, or JSON with a url field.`;return $(`navigate_to_page ✖`,e),e}let o=typeof window<`u`?hn(i):i;if(ug(`Navigating to ${String(o).replace(/^https?:\/\/[^/]+/,``)||`/`}…`),fg(),!await _n(o,{siteId:t,apiBaseUrl:e.apiBaseUrl})){pg(),dg(200);let e=`That page is not available in the site index; answer without navigating.`;return $(`navigate_to_page ✖ blocked`,e),e}try{if($(`navigate_to_page → shadowNavigate`,o),await yn(o,{sectionText:a||void 0}),await new Promise(e=>setTimeout(e,600)),pg(),dg(300),a&&typeof a==`string`){let e=rn(null,a);e&&pn(e),$(`navigate_to_page · highlight`,{sectionText:a,found:!!e})}let e=``;try{let t=Ig(),n=Rg();if(t.length>0){let r=t.map(e=>e.label||e.placeholder||e.name||e.id).filter(Boolean).join(`, `),i=n.map(e=>e.text).filter(Boolean).join(`, `);e=` This page has a form with fields: [${r}]`+(i?` and buttons: [${i}].`:`.`)+` Call list_page_forms then start filling.`}}catch{}let t=`OK_NAVIGATION ${o}${e}`;return $(`navigate_to_page ✓`,t),t}catch(e){pg(),dg(200);let t=`Navigation error: ${e?.message||String(e)}`;return $(`navigate_to_page ✖`,t),t}},highlight_on_page:async e=>{if($(`highlight_on_page ▶`,e),r)return $(`highlight_on_page · skipped (live speech highlight owns the page)`),`OK_HIGHLIGHT The page already follows your speech automatically; do not call highlight_on_page again for this turn.`;let t=t_(e),n=t?.section_id||t?.sectionId,i=t?.section_text||t?.sectionText,a=rn(n||null,i||null);return a?(pn(a,{speaking:!0}),$(`highlight_on_page ✓ (speaking)`),`OK_HIGHLIGHT section is now highlighted and scrolled into view.`):($(`highlight_on_page ✖ no element`),`Could not find that section on the page.`)},search_site_content:async e=>{$(`search_site_content ▶`,e);let r=c_(t_(e));if($(`search_site_content · query:`,r,`siteId:`,t,`apiBase:`,n||`(empty)`),ug(`Searching site content…`,{spinner:!0}),!r)return dg(),$(`search_site_content ✖ missing query`),`Missing query parameter.`;if(!t)return dg(),$(`search_site_content ✖ no siteId`),`Site is not configured for search.`;if(!n)return dg(),$(`search_site_content ✖ no api base`),`API base URL is missing; cannot search.`;try{let e=`${n}/api/site-tools/search`;$(`search_site_content → POST`,e);let i=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({siteId:t,query:r,currentUrl:typeof window<`u`?window.location.href:``})}),a=await i.json();if($(`search_site_content · HTTP`,i.status,`success:`,a.success),dg(200),!a.success){let e=a.error||`Search failed.`;return $(`search_site_content ✖`,e),e}let o=a.results||[];return $(`search_site_content ✓`,`${o.length} result(s)`,o.slice(0,3).map(e=>e?.url||e)),JSON.stringify(o)}catch(e){dg();let t=`Search error: ${e.message||`network`}`;return $(`search_site_content ✖`,t),t}},read_page_content:async e=>{$(`read_page_content ▶`,e);let t=t_(e),n=t?.section_text||t?.sectionText,r=3e3;try{if(n){let e=rn(null,n);if(!e){let t=String(n).trim().split(/\s+/).filter(e=>e.length>2);for(let n=Math.min(t.length,5);n>=2&&!e;n--)e=rn(null,t.slice(0,n).join(` `))}if(!e)return`Could not find a section matching "${n}" on this page. Try navigate_to_page or click_page_button with the article title, then read_page_content again.`;pn(e,{speaking:!0});let t=wg(e,r);return t?($(`read_page_content ✓ section:`,t.length,`chars`),`OK_READ: ${t}`):`Found the section but it appears to be empty.`}let e=Eg(Tg());if(!e)return`Could not determine the main content area of this page.`;let t=wg(e,r);return t?($(`read_page_content ✓ page:`,t.length,`chars`),`OK_READ: ${t}`):`The page appears to have no readable text content.`}catch(e){return $(`read_page_content ✖`,e?.message),`Error reading page content: ${e?.message||`unknown error`}`}},end_voice_session:async()=>($(`end_voice_session ▶`),ug(`Ending voice session…`,{icon:`👋`,spinner:!1,duration:2e3}),vg(!0),gg(),typeof e.requestEndSession==`function`&&e.requestEndSession(),`Voice session is ending.`),list_page_forms:async()=>{let e=Ig(),t=Rg();return $(`list_page_forms ✓`,`${e.length} field(s)`,`${t.length} button(s)`),o=Fg(),$(`list_page_forms · activeFormAncestor`,o?`contact-preferring`:`none`),JSON.stringify({fields:e,buttons:t,hint:`Fields are grouped by formIndex/formName. Work with ONE form at a time — only fill fields from the same formIndex. Do not jump to fields in a different form. On pages with a contact form AND a footer or secondary website-URL field: only use the contact form unless the visitor explicitly asks to use the URL or promo flow. Contact forms: fill in order Full Name → Email Address → Message. Message must be a short note the visitor wants to send (one or two sentences), never a recap of the whole chat or assistant replies. field_key: use placeholder, label, name, or id from this list. click_page_button picks the button nearest the filled fields (e.g. Send Message on the same form).`})},fill_form_fields:async e=>{try{$(`fill_form_fields ▶ raw:`,e);let t=n_(e);if(!t.length&&i){let e=i(),n=a_(e);n.length?$(`fill_form_fields · inferred URL from last user utterance (model omitted usable fields):`,n):(n=o_(e),n.length&&$(`fill_form_fields · inferred contact fields from last user utterance (empty tool params):`,n)),n.length&&(t=n)}if($(`fill_form_fields · normalized fields:`,t),!t.length)return`No fields provided. Call list_page_forms for field_key strings, then fill_form_fields with { "fields": [ { "field_key": "<label or placeholder from list>", "value": "<user value>" } ] }. Never use empty {}. Pass the value the user just said (email, message, name, URL) in fields.`;t.length>1&&ug(`Filling ${t.length} fields…`);let n=[];for(let e of t){let t=e?.field_key??e?.fieldKey,r=e?.value;if(t==null||r==null)continue;let i=String(t).toLowerCase();if(/email|e-mail|mail/.test(i))r=r_(r);else if(/phone|mobile|tel|cell/.test(i))r=i_(r);else if(Kg(t)||i===`url`){let e=String(r??``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)||/\bat\b/i.test(e)&&/\bdot\b/i.test(e)){let n=r_(e);/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n.trim())&&($(`fill_form_fields · remapping url/website intent to Email Address (value is an email)`),t=`Email Address`,i=`email address`,r=n.trim())}}ug(`Filling ${t}…`),$(`fill_form_fields · processing field:`,t,`=`,r);let s=Ng(),c=s;if(o){let e=s.filter(e=>Dg(e)===o);e.length>0&&(c=e,$(`fill_form_fields · scoped to active form, inputs:`,e.length))}$(`fill_form_fields · visible inputs count:`,s.length,`scoped:`,c.length);let l=!1;for(let e of[c,...c===s?[]:[s]]){let i=Yg(e,String(t),r);if(i.length){for(let e=0;e<i.length;e++)await u_(i[e],r,{skipScroll:e>0}),await new Promise(e=>setTimeout(e,80));a=i,o=Dg(i[0])||o,n.push(String(t)),l=!0;break}let s=Qg(e,String(t));if(s||=Ug(e,String(t)),s||=Wg(e,String(t),r),s){await u_(s,r),a=[s],o=Dg(s)||o,n.push(String(t)),l=!0;break}}l||$(`fill_form_fields · no match for field:`,t)}dg(400);try{vg()}catch{}if(!n.length)return $(`fill_form_fields ✖ no matches`),`Could not match any fields. Call list_page_forms and use field_key values that match placeholder, label, name, or id (e.g. Enter Website URL). Ensure the form is on the page, not the chat panel.`;let r=`OK_FILLED: ${n.join(`, `)}`;return $(`fill_form_fields ✓`,r),r}catch(e){dg(),gg(),vg(!0);let t=`fill_form_fields error: ${e?.message||String(e)}`;return $(`fill_form_fields ✖`,t),t}},click_page_button:async e=>{let t=t_(e),n=(t.button_text??t.buttonText??t.text??``).trim();if($(`click_page_button ▶`,n),!n)return`Missing button_text: pass the visible label, e.g. Submit or Read more.`;ug(`Clicking "${n}"…`);let r=e_(n,a);if(!r)return dg(200),$(`click_page_button ✖ no match`),`Could not find a button matching "${n}". Call list_page_forms to see button texts.`;try{try{r.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{r.scrollIntoView(!0)}try{await _g(r)}catch{}try{bg(r)}catch{}try{await yg(r)}catch{}let e=Dg(r)||o,t=[];if(e){let n=Array.from(e.querySelectorAll(`input[required], textarea[required], select[required]`)).filter(e=>!Sg(e));for(let e of n)if(!(e.value||``).trim()){let n=Mg(e)||e.placeholder||e.name||e.type;t.push(n)}}if(t.length>0){dg(200);try{vg()}catch{}let e=`Cannot submit — these required fields are still empty: ${t.join(`, `)}. Fill them first with fill_form_fields, then click again.`;return $(`click_page_button ✖ empty required fields:`,t),e}r.focus?.(),r.click();let n=(r.textContent||r.value||r.getAttribute(`aria-label`)||``).trim().slice(0,80)||`button`;dg(600);try{vg()}catch{}gg(),o=null,a=[];let i=`OK_CLICK ${n}`;return $(`click_page_button ✓`,i),i}catch(e){dg(200),vg(!0);let t=`Click failed: ${e?.message||String(e)}`;return $(`click_page_button ✖`,t),t}}};return{...s,navigateToPage:s.navigate_to_page,highlightOnPage:s.highlight_on_page,searchSiteContent:s.search_site_content,endVoiceSession:s.end_voice_session,listPageForms:s.list_page_forms,fillFormFields:s.fill_form_fields,clickPageButton:s.click_page_button}}function f_(e){return!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,async n=>{let r=Xt();r?console.log(`[FlowEngage:voice-tool] ▶`,e,n):console.info(`[FlowEngage] voice tool » ${e}`);let i;try{i=await t(n)}catch(t){let n=`Tool error: ${t?.message||String(t)}`;return console.error(`[FlowEngage] voice tool ${e} threw:`,t),n}let a=typeof i==`string`?i.length>220?`${i.slice(0,220)}…`:i:String(i);return r?console.log(`[FlowEngage:voice-tool] ◀`,e,a):console.info(`[FlowEngage] voice tool « ${e}:`,a),i}]))}var p_={idle:`rgba(99,102,241,0.18)`,listening:`rgba(16,185,129,0.25)`,speaking:`rgba(245,158,11,0.25)`,error:`rgba(239,68,68,0.2)`},m_={idle:`#6366f1`,listening:`#10b981`,speaking:`#f59e0b`,error:`#ef4444`},h_=17,g_=6;function __(e,t){let n=(t||``).trim();return n?!!(/\b(let'?s|let us)\s+(end|stop|finish|wrap up|close)\s+(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\bend\s+(this\s+)?(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\b(hang\s+up|disconnect)\b/i.test(n)||/\b(that'?s all|we'?re done)\b/i.test(n)||e===`bot`&&(/\b(I'?ll|I will|Let me|I can|I'?m going to)\s+(end|close)\s+(the\s+)?(voice\s+)?(session|call)\b/i.test(n)||/\b(ending|closing)\s+(the\s+)?(voice\s+)?session\b|\bvoice\s+session\s+(is\s+)?(now\s+)?(ended|over|closing)\b/i.test(n)||/\b(session|call)\s+(is\s+)?(now\s+)?(ended|over)\b/i.test(n)||/\bwe\s+can\s+end\s+(the\s+)?(session|call)?\s*(here|now)\b/i.test(n)||/\b(wrapping\s+up|signing\s+off)\b/i.test(n))||/^(goodbye|bye|that'?s all|we'?re done|hang up|disconnect)\b/i.test(n)):!1}function v_({agentId:e,chatId:t,siteId:n,apiBaseUrl:r,onEnd:i,historyRef:a,hasSyncedRef:o,onMessageSync:s,onStartSync:c}){let[d,f]=(0,l.useState)(`idle`),[p,m]=(0,l.useState)(null),[ee,h]=(0,l.useState)(!1),g=(0,l.useRef)(null),_=(0,l.useRef)(null),te=(0,l.useRef)(``),ne=(0,l.useRef)(async()=>{}),re=(0,l.useRef)(!1),ie=(0,l.useRef)(``),ae=(0,l.useRef)(null),oe=(0,l.useRef)(null),v=(0,l.useRef)(null),se=(0,l.useRef)(null),ce=(0,l.useRef)(null),y=(0,l.useCallback)(()=>{v.current&&=(clearTimeout(v.current),null),se.current&&=(clearInterval(se.current),null),ie.current=``,ae.current=null,oe.current=null,ce.current!=null&&(cancelAnimationFrame(ce.current),ce.current=null);try{mn()}catch{}},[]),le=(0,l.useCallback)(async()=>{y();try{await g.current?.endSession?.()}catch{}g.current=null,h(!1),f(`idle`),re.current=!1,typeof s==`function`&&await s(a.current),typeof i==`function`&&i()},[y,a,s,i]);ne.current=le,(0,l.useEffect)(()=>{let t=!1,i=null;return(async()=>{try{if(await navigator.mediaDevices.getUserMedia({audio:!0}),t)return;a.current=[],te.current=``,re.current=!1;let o=f_(d_({siteId:n||null,apiBaseUrl:r||null,getLastUserVoiceText:()=>te.current,preferLiveSpeechHighlight:!0,requestEndSession:()=>{queueMicrotask(()=>{re.current||(re.current=!0,ne.current?.())})}})),s=()=>{try{let e=ie.current,t=ae.current;if(!e?.trim()||t==null)return;let n=oe.current,r=Date.now(),i;if(n!=null){let t=Math.max(0,(r-n)/1e3);i=Math.min(e.length,Math.floor(t*h_))}else{let n=Math.max(0,(r-t)/1e3);if(n>2.1&&e.length>36)i=Math.min(e.length,Math.floor(Math.max(0,n-.4)*h_));else{let t=Math.min(96,Math.floor(n*g_));i=Math.min(e.length,t)}}let a=e.slice(0,i);if(a.trim().length<8)return;nn();let o=fn(a);o&&pn(o,{speaking:!0})}catch(e){console.warn(`[VoiceInterface] speech highlight failed`,e?.message)}},l=()=>{ce.current??=requestAnimationFrame(()=>{ce.current=null,s()})},u=()=>{v.current&&clearTimeout(v.current),v.current=setTimeout(()=>{v.current=null,s()},120)},d=()=>{se.current||=setInterval(()=>{s()},160)},p=await Rh.startSession({agentId:e,clientTools:o,onUnhandledClientToolCall:e=>{console.error(`[VoiceInterface] ElevenLabs requested a client tool that is not registered in the widget:`,e?.tool_name,e?.parameters,`Add a matching handler in voiceClientTools (snake_case and camelCase are both supported).`)},onModeChange:({mode:e})=>{t||f(e===`speaking`?`speaking`:`listening`)},onAudio:()=>{t||(oe.current??=Date.now(),d(),l())},onAgentChatResponsePart:e=>{if(t)return;let n=e?.text_response_part??e,r=n?.type,i=n?.text??``;r===`start`?(v.current&&=(clearTimeout(v.current),null),se.current&&=(clearInterval(se.current),null),ce.current!=null&&(cancelAnimationFrame(ce.current),ce.current=null),oe.current=null,ie.current=i,ae.current=Date.now(),d()):r===`delta`?(ie.current+=i,ae.current??=Date.now(),d()):r===`stop`?(ie.current+=i,d()):(ie.current+=i,ae.current==null&&i&&(ae.current=Date.now()),d()),ie.current.trim().length>=10&&(u(),l())},onInterruption:()=>{y()},onMessage:e=>{if(t)return;let n=e.role===`user`?`user`:`bot`,r=e.message||e.text||e.content||``;if(!r)return;let i={sender:n,message:r,timestamp:new Date().toISOString()};n===`user`&&(te.current=r,y()),a.current=[...a.current,i],__(n,r)&&queueMicrotask(()=>{re.current||(re.current=!0,ne.current?.())})},onError:e=>{t||(console.error(`[VoiceInterface] ElevenLabs error`,e),y(),f(`error`),m(`Voice session encountered an error.`))},onDisconnect:()=>{t||(console.log(`[VoiceInterface] session disconnected`),y(),h(!1),f(`idle`))}});if(t){p.endSession().catch(()=>{});return}i=p,g.current=p,h(!0),f(`listening`);try{let e=typeof window<`u`?window.location.href:``,t=``;try{t=await o.list_page_forms()}catch{t=`[]`}p.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${n||`unknown`}. Page fields/buttons JSON: ${t}. Navigation: when the user wants to go to any page (contact, pricing, about, services, etc.), call search_site_content then navigate_to_page immediately — never ask permission. After navigating to a page with a form, call list_page_forms and proactively start helping the user fill it. Contact / lead forms: use only the main contact form (Full Name, Email, Message). Ignore footer or secondary marketing URL fields unless the user explicitly asks to use them. Fill in order: name → email → message. Message must be a short visitor note (what they want from the team), not a transcript of the conversation. Forms: use fill_form_fields then click_page_button (e.g. Send Message) when appropriate. Fill each field right after the user gives that value — do not click submit until required fields are filled. Voice: if the user wants to end the voice session, call end_voice_session or confirm and end.`)}catch{}typeof c==`function`&&c()}catch(e){t||(console.error(`[VoiceInterface] startSession failed`,e),f(`error`),m(`Could not start voice session. Please try again.`))}})(),()=>{t=!0,y(),i?i.endSession().catch(()=>{}):g.current&&g.current.endSession().catch(()=>{})}},[e,n,r,a,c,y]);let ue=d===`listening`||d===`speaking`,de=m_[d]||m_.idle,fe=p_[d]||p_.idle;return(0,u.jsxs)(`div`,{ref:_,style:{display:`flex`,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,flex:1,gap:`24px`,padding:`24px 20px`,background:`transparent`},children:[(0,u.jsxs)(`div`,{style:{position:`relative`,width:`140px`,height:`140px`,display:`flex`,alignItems:`center`,justifyContent:`center`},children:[ue&&(0,u.jsx)(`div`,{style:{position:`absolute`,inset:`-16px`,borderRadius:`50%`,border:`2px solid ${de}`,animation:`fe-orb-pulse 1.4s ease-in-out infinite`,opacity:.6}}),ue&&(0,u.jsx)(`div`,{style:{position:`absolute`,inset:`-8px`,borderRadius:`50%`,border:`2px solid ${de}`,animation:`fe-orb-pulse 1.4s ease-in-out 0.35s infinite`,opacity:.4}}),(0,u.jsx)(`div`,{style:{width:`140px`,height:`140px`,borderRadius:`50%`,background:fe,border:`3px solid ${de}`,display:`flex`,alignItems:`center`,justifyContent:`center`,transition:`all 0.35s ease`,transform:d===`speaking`?`scale(1.08)`:`scale(1)`,boxShadow:`0 0 40px ${fe}, 0 8px 32px rgba(0,0,0,0.08)`},children:(0,u.jsx)(kn,{size:44,color:de})})]}),(0,u.jsxs)(`div`,{style:{fontSize:`15px`,fontWeight:600,color:d===`error`?`#ef4444`:`#374151`,letterSpacing:`0.01em`,textAlign:`center`},children:[d===`idle`&&`Starting voice session…`,d===`listening`&&`Listening…`,d===`speaking`&&`AI is speaking…`,d===`error`&&(p||`Error`)]}),(0,u.jsxs)(`button`,{onClick:le,style:{display:`flex`,alignItems:`center`,gap:`8px`,padding:`12px 24px`,borderRadius:`999px`,background:`#fee2e2`,color:`#dc2626`,border:`1px solid #fca5a5`,fontWeight:600,fontSize:`14px`,cursor:`pointer`,transition:`all 0.2s ease`},onMouseEnter:e=>{e.currentTarget.style.background=`#fecaca`},onMouseLeave:e=>{e.currentTarget.style.background=`#fee2e2`},children:[(0,u.jsx)(An,{size:18}),`End Voice Session`]}),(0,u.jsx)(`style`,{children:`
|
|
487
|
+
`).trim();return a.length>t&&(a=a.slice(0,t).replace(/\s\S*$/,``)+`…`),a}function Tg(){if(typeof document>`u`)return null;for(let e of[`main`,`article`,`[role="main"]`,`#content`,`#main-content`,`#main`,`.main-content`,`.content`,`.post-content`,`.article-content`,`.entry-content`]){let t=document.querySelector(e);if(t&&!Sg(t))return t}return document.body}function Eg(e){if(!e||typeof e.querySelector!=`function`)return e;let t=e.querySelector([`.post-content`,`.entry-content`,`.article-body`,`[itemprop='articleBody']`,`.article__body`,`.field-item`,`.field--name-body`,`.field--body`,`.node__content`].join(`, `));return t&&!Sg(t)?t:e}function Dg(e){if(!e)return null;try{return e.closest(`form`)}catch{let t=e.parentElement;for(;t;){if(t.tagName===`FORM`)return t;t=t.parentElement}return null}}function Og(e){if(!e)return null;let t=e.querySelector(`h1, h2, h3, h4, h5, legend`);if(t)return t.textContent.replace(/\s+/g,` `).trim().slice(0,60);let n=e.getAttribute(`aria-label`);if(n)return n.trim().slice(0,60);let r=e.getAttribute(`title`);if(r)return r.trim().slice(0,60);let i=e.previousElementSibling;for(let e=0;e<3&&i;e++){if(/^H[1-5]$/.test(i.tagName))return i.textContent.replace(/\s+/g,` `).trim().slice(0,60);i=i.previousElementSibling}return null}function kg(e){try{let t=e.ownerDocument?.defaultView;if(t)return t.getComputedStyle(e)}catch{}return window.getComputedStyle(e)}function Ag(e){let t=new Set;function n(r){if(!r||t.has(r))return;t.add(r),e(r);let i=r.querySelectorAll(`iframe`);for(let e of i)if(!Sg(e))try{let t=e.contentDocument;t&&n(t)}catch{}}typeof document<`u`&&n(document)}function jg(e){return e==null?null:String(e).replace(/\u00a0/g,` `).replace(/\s*\*+\s*$/u,``).replace(/\s+/g,` `).trim()}function Mg(e){let t=e.ownerDocument||document,n=e.getAttribute(`aria-labelledby`);if(n){let e=n.trim().split(/\s+/).filter(Boolean),r=[];for(let n of e)try{let e=t.getElementById(n);e?.textContent&&r.push(e.textContent.trim())}catch{}if(r.length)return jg(r.join(` `))}if(e.labels&&e.labels.length)return jg(e.labels[0].textContent);let r=e.id;if(r)try{let e=t.querySelector(`label[for="${CSS.escape(r)}"]`);if(e)return jg(e.textContent)}catch{let e=t.querySelector(`label[for="${r.replace(/"/g,`\\"`)}"]`);if(e)return jg(e.textContent)}let i=e.previousElementSibling;for(let e=0;e<6&&i;e+=1){if(i.tagName===`LABEL`)return jg(i.textContent);let e=(i.className||``).toString().toLowerCase();if(/chakra-form__label|formlabel|field-label|form-label|mui-form-label/.test(e)){let e=jg(i.textContent);if(e)return e}i=i.previousElementSibling}let a=e.parentElement;for(let e=0;e<5&&a;e+=1){if(a.tagName===`LABEL`)return jg(a.textContent);let e=a.querySelector?.(`:scope > label, :scope > [class*='FormLabel'], :scope > [class*='form__label']`);if(e?.textContent)return jg(e.textContent);a=a.parentElement}let o=e.getAttribute(`aria-label`);return o?jg(o):null}function Ng(){let e=[];return Ag(t=>{e.push(...Array.from(t.querySelectorAll(`input, select, textarea`)).filter(e=>{if(Sg(e))return!1;let t=(e.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`image`].includes(t)||e.disabled||e.readOnly)return!1;try{let t=kg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}try{if(e.offsetWidth===0&&e.offsetHeight===0)return!1}catch{}return!0}))}),e}function Pg(e){if(!e||typeof e.closest!=`function`)return!1;try{return!!e.closest(`footer, [role="contentinfo"], #footer, .site-footer, [class*="footer"], [id*="footer"]`)}catch{return!1}}function Fg(){let e=Ng();for(let t of e){if((t.type||``).toLowerCase()!==`email`||Pg(t))continue;let e=Dg(t);if(e)return e}return null}function Ig(){let e=Ng(),t=new Map,n=0;return e.map((e,r)=>{let i=Dg(e),a=i||`__orphan__`;t.has(a)||t.set(a,n++);let o=t.get(a);return{formIndex:o,formName:(i?Og(i):null)||`Form ${o}`,fieldIndex:r,tag:e.tagName,type:e.type||`text`,name:e.name||null,id:e.id||null,label:Mg(e),placeholder:e.placeholder||null}})}function Lg(e){if(Sg(e)||e.disabled)return!1;try{let t=kg(e);if(t.display===`none`||t.visibility===`hidden`||parseFloat(t.opacity)===0)return!1}catch{}return!0}function Rg(){let e=[];return Ag(t=>{e.push(...Array.from(t.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Lg)),e.push(...Array.from(t.querySelectorAll(`a[href]`)).filter(e=>{if(!Lg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))}),e.slice(0,60).map((e,t)=>({index:t,text:(e.textContent||e.value||``).replace(/\s+/g,` `).trim().slice(0,120)||null,ariaLabel:e.getAttribute(`aria-label`),type:e.type||e.tagName}))}function zg(e){return String(e||``).toLowerCase().replace(/\u00a0/g,` `).replace(/\*/g,``).replace(/\s+/g,` `).trim()}function Bg(e){let t=zg(e);return t=t.replace(/\s+field\s*$/i,``).trim(),t}function Vg(e,t){let n=Bg(t);if(!n)return 0;let r=(e.name||``).toLowerCase(),i=(e.id||``).toLowerCase();if(r===`url`&&/url|website|domain|audit|conduct|site(\s|$)|page(\s|$)/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n)||(i===`url-input`||i.endsWith(`-url-input`))&&/url|website|domain|audit|conduct/.test(n)&&!/email|e-mail|mail|name|message|phone/.test(n))return 100;let a=(e.type||``).toLowerCase();if(a===`email`&&/email|e-mail|mail/.test(n))return 100;if(a===`tel`&&/phone|mobile|tel|cell/.test(n))return 95;if(a===`url`&&/url|website|domain|link/.test(n))return 100;let o=[e.name,e.id,e.placeholder,Mg(e),e.getAttribute(`aria-label`),e.getAttribute(`title`),e.getAttribute(`data-testid`),e.getAttribute(`autocomplete`)].filter(Boolean).map(e=>zg(e)),s=0;for(let e of o){if(!e)continue;if(e===n){s=100;break}if(e.includes(n)||n.includes(e)){s=Math.max(s,96);continue}let t=n.split(/\s+/).filter(e=>e.length>1);if(!t.length)continue;let r=0;for(let n of t)e.includes(n)&&(r+=1);let i=r/t.length;i>0&&(s=Math.max(s,i*88))}return s}var Hg=22;function Ug(e,t){let n=null,r=0;for(let i of e){let e=Vg(i,t);e>r&&(r=e,n=i)}return!n||r<Hg?null:n}function Wg(e,t,n){let r=String(t||``).toLowerCase().trim(),i=String(n||``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i)||!(/^https?:\/\//i.test(i)||/\.\w{2,}(\/|\s|$)/.test(i)||r.includes(`url`)||r.includes(`website`)||r.includes(`domain`)||r.includes(`site`)))return null;let a=null,o=0;for(let t of e){if(t.tagName!==`INPUT`&&t.tagName!==`TEXTAREA`)continue;let e=(t.type||``).toLowerCase();if([`hidden`,`submit`,`button`,`checkbox`,`radio`].includes(e))continue;let n=0;(e===`url`||e===`text`||e===`search`)&&(n+=45);let r=[t.name,t.id,t.placeholder,Mg(t),t.getAttribute(`aria-label`),t.getAttribute(`autocomplete`)].filter(Boolean).join(` `).toLowerCase();/(website|url|domain|site\s*url)/.test(r)&&(n+=55),n>o&&(o=n,a=t)}return!a||o<42?null:a}function Gg(e){let t=String(e??``).trim();return!t||/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?!1:/^https?:\/\//i.test(t)?!0:/\.\w{2,}(\/|\s|$)/.test(t)}function Kg(e){let t=String(e??``).toLowerCase().trim();return t?!!(t===`url`||t===`website`||t===`website url`||t===`website_url`||t===`enter website url`||t.includes(`website`)||t.includes(`domain`)||/(enter\s+website|site\s*url|page\s*url)/.test(t)):!1}function qg(e){if(!e||e.tagName!==`INPUT`&&e.tagName!==`TEXTAREA`)return!1;let t=(e.type||``).toLowerCase();return![`hidden`,`submit`,`button`,`checkbox`,`radio`,`file`].includes(t)}function Jg(e){if(!qg(e))return!1;let t=(e.name||``).toLowerCase(),n=(e.id||``).toLowerCase(),r=[e.name,e.id,e.placeholder,Mg(e),e.getAttribute(`aria-label`)].filter(Boolean).join(` `).toLowerCase();return t===`url`||n===`url-input`||n.endsWith(`-url-input`)||/(website\s*url|enter\s+website|site\s*url)/.test(r)||/(website|domain)/.test(r)&&/(url|site)/.test(r)}function Yg(e,t,n){let r=String(t??``),i=String(n??``),a=Qg(e,r)||Ug(e,r)||Wg(e,r,i);if(!a)return[];let o=new Set([a]);if(Gg(i)&&Kg(r))for(let t of e)t!==a&&Jg(t)&&o.add(t);let s=Array.from(o);return s.sort((e,t)=>{if(e===t)return 0;let n=e.compareDocumentPosition(t);return n&Node.DOCUMENT_POSITION_FOLLOWING?-1:n&Node.DOCUMENT_POSITION_PRECEDING?1:0}),s}function Xg(e,t){try{if(!e?.getBoundingClientRect||!t?.getBoundingClientRect)return 1/0;let n=e.getBoundingClientRect(),r=t.getBoundingClientRect(),i={x:n.left+n.width/2,y:n.top+n.height/2},a={x:r.left+r.width/2,y:r.top+r.height/2};return Math.hypot(i.x-a.x,i.y-a.y)}catch{return 1/0}}function Zg(e){if(!e||typeof e!=`string`)return null;let t=null;return Ag(n=>{try{let r=n.getElementById(e);r&&!Sg(r)&&r.matches?.(`input, select, textarea`)&&(t=r)}catch{}}),t}function Qg(e,t){let n=String(t??``).trim();if(!n)return null;let r=n.match(/^name:\s*([\w.-]+)$/i);if(r){let t=r[1];for(let n of e)if(n.name===t)return n}let i=n.match(/^id:\s*([\w.-]+)$/i);if(i){let e=Zg(i[1]);if(e)return e}let a=n.startsWith(`#`)?n.slice(1):n;if(/^[\w-]+$/.test(a)){let e=Zg(a);if(e)return e}let o=n.toLowerCase().replace(/\s+/g,` `);if(o===`url`||o===`website`||o===`website url`||o===`website_url`||o===`enter website url`)for(let t of e){let e=(t.name||``).toLowerCase(),n=(t.id||``).toLowerCase();if(e===`url`||n===`url-input`||n.endsWith(`-url-input`))return t}return null}function $g(e,t){let n=String(t||``).toLowerCase().trim();if(!n)return 0;let r=[e.textContent,e.value,e.getAttribute(`aria-label`),e.getAttribute(`title`)].filter(Boolean).join(` `).toLowerCase().replace(/\s+/g,` `);if(r===n)return 100;if(r.includes(n))return 98;let i=n.split(/\s+/).filter(e=>e.length>1);if(!i.length)return 0;let a=0;for(let e of i)r.includes(e)&&(a+=1);return a/i.length*92}function e_(e,t){let n=[];Ag(e=>{n.push(...Array.from(e.querySelectorAll(`button, [role="button"], input[type="submit"], input[type="button"]`)).filter(Lg)),n.push(...Array.from(e.querySelectorAll(`a[href]`)).filter(e=>{if(!Lg(e))return!1;let t=(e.textContent||``).replace(/\s+/g,` `).trim();return!(!t||t.length<2||t.length>150)}))});let r=0,i=n.map(t=>({el:t,s:$g(t,e)}));for(let{s:e}of i)e>r&&(r=e);let a=e.split(/\s+/).filter(e=>e.length>1).length>=3?28:36;if(r<a)return null;let o=i.filter(({s:e})=>e===r).map(({el:e})=>e);if(o.length===1)return o[0];let s=Array.isArray(t)?t.filter(e=>e&&e.isConnected):[];if(s.length){let e=o[0],t=1/0;for(let n of o)for(let r of s){let i=Xg(n,r);i<t&&(t=i,e=n)}return e}return o[0]}function t_(e){if(e==null)return{};if(typeof e==`string`){let t=e.trim();if(!t)return{};try{return JSON.parse(t)}catch{return{url:t}}}return e}function n_(e){let t=t_(e);if(Array.isArray(t)&&t.length>0){let e=t[0];if(e?.field_key!=null||e?.fieldKey!=null)return t.map(e=>({field_key:e.field_key??e.fieldKey,value:e.value}))}if(!t||typeof t!=`object`)return[];let n=t.fields??t.Fields??t.field_list??t.fieldList??t.data?.fields;if(typeof n==`string`)try{n=JSON.parse(n)}catch{n=null}n&&!Array.isArray(n)&&typeof n==`object`&&(n=Object.values(n)),(!n||n.length===0)&&(t.field_key!=null||t.fieldKey!=null)&&t.value!=null&&(n=[{field_key:t.field_key??t.fieldKey,value:t.value}]);let r=t.website_url??t.websiteUrl??t.url??t.website??t.domain??t.site_url??t.siteUrl;return(!n||n.length===0)&&r!=null&&String(r).trim()&&(n=[{field_key:t.field_key??t.fieldKey??`url`,value:String(r).trim()}]),Array.isArray(n)?n.map(e=>({field_key:e?.field_key??e?.fieldKey,value:e?.value??e?.Value})):[]}function r_(e){if(!e||typeof e!=`string`)return e;let t=e.trim();return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)?t:(t=t.replace(/\s+at\s+the\s+rate\s*(of)?\s+/gi,`@`),t=t.replace(/\s+at\s+/gi,`@`),t=t.replace(/\s+dot\s+/gi,`.`),t=t.replace(/\s+/g,``),t=t.replace(/\.{2,}/g,`.`).replace(/\.$/,``),t)}function i_(e){if(!e||typeof e!=`string`)return e;let t={zero:`0`,one:`1`,two:`2`,three:`3`,four:`4`,five:`5`,six:`6`,seven:`7`,eight:`8`,nine:`9`,oh:`0`,o:`0`},n=e.toLowerCase().trim();for(let[e,r]of Object.entries(t))n=n.replace(RegExp(`\\b${e}\\b`,`g`),r);return n=n.replace(/[^\d+]/g,``),n}function a_(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t||/\b[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}\b/i.test(t))return[];let n=t.match(/https?:\/\/[^\s<>"']+/i);if(n)return[{field_key:`url`,value:n[0].replace(/[.,;:)]+$/,``)}];let r=t.match(/\b(?:[\w-]+\.)+[a-z]{2,}\b/i);if(r){let e=r[0].replace(/[.,;:)]+$/,``);return/^https?:/i.test(e)||(e=`https://${e}`),[{field_key:`url`,value:e}]}return[]}function o_(e){if(!e||typeof e!=`string`)return[];let t=e.trim();if(!t)return[];let n=[],r=new Set,i=/\b([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\b/i,a=(e,t)=>{let i=String(t??``).trim().replace(/^["']|["']$/g,``);if(!i||i.length>800)return;let a=`${e}\0${i}`;r.has(a)||(r.add(a),n.push({field_key:e,value:i}))},o=r_(t),s=i.test(o),c=o.match(/^\s*([a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,})\s*$/i);if(c)return a(`Email Address`,c[1]),n;if(!i.test(t)&&s){let e=o.match(i);if(e)return a(`Email Address`,e[1]),n}let l=t.match(/\b(?:please\s+)?(?:enter|type|put)\s+(.+?)\s+in(?:to)?\s+(?:the\s+)?(?:full\s*name|full\s*name\s*field|name\s*field)\b/i);if(l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name,?\s*(?:please\s+)?(?:enter|type|put)\s+(.+?)(?:\.|$|!|\?)/i),l&&a(`Full Name`,l[1]),l=t.match(/\bfull\s*name\s*(?:is|:|please\s+enter|-)\s*(.+?)(?:\.|$|(?=\s+(?:and|my\s+email|email|message))\b)/i),l&&a(`Full Name`,l[1]),l=t.match(/\b(.+?)\s+for\s+(?:the\s+)?full\s*name\b/i),l){let e=l[1].trim();e.length>1&&e.length<120&&!/@/.test(e)&&a(`Full Name`,e)}if(l=t.match(/\b(?:email|e-mail)(?:\s*address)?\s*(?:is|:|please\s+use|enter|-)\s*([^\s@]+@[^\s@]+\.[^\s,]+)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:enter|type|put)\s+([^\s@]+@[^\s@]+\.[^\s,]+)\s+in(?:to)?\s+(?:the\s+)?(?:email|e-mail)/i),l&&a(`Email Address`,l[1]),l=t.match(/\b(?:message|comment)\s*(?:is|:|please\s+enter|-)\s*(.+)$/is),l){let e=l[1].trim();e.length>0&&a(`Message`,e)}if(!n.some(e=>/email/i.test(String(e.field_key)))){let e=t.match(i);if(e){let r=t.replace(e[0],``).trim().replace(/^(please|it's|it is|use|is|my email is|e-?mail is)\s*/i,``).replace(/[.,;:!?]+$/,``).trim();if(t.length<=96&&r.length<=36)return a(`Email Address`,e[1]),n}}if(n.length===0){let e=t.split(/\s+/).filter(Boolean).length,n=/[.!?]/.test(t)||e>=6||t.length>=24&&e>=5||t.length>=42,r=/^[A-Z][a-z]+\s+[A-Z][a-z]+$/.test(t.trim());n&&t.length>=16&&!i.test(t)&&!r&&a(`Message`,t)}return n}function s_(e){if(!e||typeof e!=`object`)return null;let t=e.url??e.target_url??e.page_url??e.pageUrl??e.link??e.href??e.path;return t==null?null:String(t).trim()||null}function c_(e){if(!e||typeof e!=`object`)return null;let t=e.query??e.q??e.search??e.text??e.keywords??e.search_query??e.searchQuery??e.question??e.prompt??e.topic??e.intent;return t==null?null:String(t).trim()||null}function l_(e){let t=e.ownerDocument?.defaultView||window,n=e.tagName===`TEXTAREA`?t.HTMLTextAreaElement.prototype:t.HTMLInputElement.prototype,r=Object.getOwnPropertyDescriptor(n,`value`);return(e,t)=>{try{e._valueTracker&&e._valueTracker.setValue(``)}catch{}r?.set?r.set.call(e,t):e.value=t}}async function u_(e,t,n){if(!n?.skipScroll)try{e.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{try{e.scrollIntoView(!0)}catch{}}try{await _g(e)}catch{}try{mg(e)}catch{}await new Promise(e=>setTimeout(e,180));try{e.focus({preventScroll:!0})}catch{try{e.focus()}catch{}}let r=e.tagName,i=(e.type||``).toLowerCase(),a={bubbles:!0,cancelable:!0,composed:!0};if(r===`SELECT`)return e.value=String(t),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a)),hg(e),!0;if(i===`checkbox`||i===`radio`)return e.checked=[`1`,`true`,`yes`,`on`].includes(String(t).toLowerCase().trim()),e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a)),hg(e),!0;let o=String(t);if(r===`INPUT`||r===`TEXTAREA`){let t=l_(e);try{await sg(e,o,t)}catch{t(e,o)}e.value!==o&&t(e,o)}else e.value=o;try{e.dispatchEvent(new InputEvent(`input`,{...a,inputType:`insertText`,data:o}))}catch{e.dispatchEvent(new Event(`input`,a))}e.dispatchEvent(new Event(`change`,a)),e.dispatchEvent(new Event(`blur`,a));try{e.focus({preventScroll:!0})}catch{}try{queueMicrotask(()=>{try{e.dispatchEvent(new Event(`input`,a)),e.dispatchEvent(new Event(`change`,a))}catch{}})}catch{}return hg(e),!0}function d_(e){let t=e.siteId||null,n=(e.apiBaseUrl||``).replace(/\/$/,``),r=!!e.preferLiveSpeechHighlight,i=typeof e.getLastUserVoiceText==`function`?e.getLastUserVoiceText:null,a=[],o=null,s={navigate_to_page:async n=>{$(`navigate_to_page ▶ raw parameters:`,n);let r=t_(n),i=s_(r),a=r.section_text??r.sectionText??r.section;if($(`navigate_to_page · coerced:`,{url:i,sectionText:a}),!i){let e=`Missing url: pass a string url, path like /pricing, or JSON with a url field.`;return $(`navigate_to_page ✖`,e),e}let o=typeof window<`u`?hn(i):i;if(ug(`Navigating to ${String(o).replace(/^https?:\/\/[^/]+/,``)||`/`}…`),fg(),!await _n(o,{siteId:t,apiBaseUrl:e.apiBaseUrl})){pg(),dg(200);let e=`That page is not available in the site index; answer without navigating.`;return $(`navigate_to_page ✖ blocked`,e),e}try{if($(`navigate_to_page → shadowNavigate`,o),await yn(o,{sectionText:a||void 0}),await new Promise(e=>setTimeout(e,600)),pg(),dg(300),a&&typeof a==`string`){let e=rn(null,a);e&&pn(e),$(`navigate_to_page · highlight`,{sectionText:a,found:!!e})}let e=``;try{let t=Ig(),n=Rg();if(t.length>0){let r=t.map(e=>e.label||e.placeholder||e.name||e.id).filter(Boolean).join(`, `),i=n.map(e=>e.text).filter(Boolean).join(`, `);e=` This page has a form with fields: [${r}]`+(i?` and buttons: [${i}].`:`.`)+` Call list_page_forms then start filling.`}}catch{}let t=`OK_NAVIGATION ${o}${e}`;return $(`navigate_to_page ✓`,t),t}catch(e){pg(),dg(200);let t=`Navigation error: ${e?.message||String(e)}`;return $(`navigate_to_page ✖`,t),t}},highlight_on_page:async e=>{if($(`highlight_on_page ▶`,e),r)return $(`highlight_on_page · skipped (live speech highlight owns the page)`),`OK_HIGHLIGHT The page already follows your speech automatically; do not call highlight_on_page again for this turn.`;let t=t_(e),n=t?.section_id||t?.sectionId,i=t?.section_text||t?.sectionText,a=rn(n||null,i||null);return a?(pn(a,{speaking:!0}),$(`highlight_on_page ✓ (speaking)`),`OK_HIGHLIGHT section is now highlighted and scrolled into view.`):($(`highlight_on_page ✖ no element`),`Could not find that section on the page.`)},search_site_content:async e=>{$(`search_site_content ▶`,e);let r=c_(t_(e));if($(`search_site_content · query:`,r,`siteId:`,t,`apiBase:`,n||`(empty)`),ug(`Searching site content…`,{spinner:!0}),!r)return dg(),$(`search_site_content ✖ missing query`),`Missing query parameter.`;if(!t)return dg(),$(`search_site_content ✖ no siteId`),`Site is not configured for search.`;if(!n)return dg(),$(`search_site_content ✖ no api base`),`API base URL is missing; cannot search.`;try{let e=`${n}/api/site-tools/search`;$(`search_site_content → POST`,e);let i=await fetch(e,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({siteId:t,query:r,currentUrl:typeof window<`u`?window.location.href:``})}),a=await i.json();if($(`search_site_content · HTTP`,i.status,`success:`,a.success),dg(200),!a.success){let e=a.error||`Search failed.`;return $(`search_site_content ✖`,e),e}let o=a.results||[];return $(`search_site_content ✓`,`${o.length} result(s)`,o.slice(0,3).map(e=>e?.url||e)),JSON.stringify(o)}catch(e){dg();let t=`Search error: ${e.message||`network`}`;return $(`search_site_content ✖`,t),t}},read_page_content:async e=>{$(`read_page_content ▶`,e);let t=t_(e),n=t?.section_text||t?.sectionText,r=3e3;try{if(n){let e=rn(null,n);if(!e){let t=String(n).trim().split(/\s+/).filter(e=>e.length>2);for(let n=Math.min(t.length,5);n>=2&&!e;n--)e=rn(null,t.slice(0,n).join(` `))}if(!e)return`Could not find a section matching "${n}" on this page. Try navigate_to_page or click_page_button with the article title, then read_page_content again.`;pn(e,{speaking:!0});let t=wg(e,r);return t?($(`read_page_content ✓ section:`,t.length,`chars`),`OK_READ: ${t}`):`Found the section but it appears to be empty.`}let e=Eg(Tg());if(!e)return`Could not determine the main content area of this page.`;let t=wg(e,r);return t?($(`read_page_content ✓ page:`,t.length,`chars`),`OK_READ: ${t}`):`The page appears to have no readable text content.`}catch(e){return $(`read_page_content ✖`,e?.message),`Error reading page content: ${e?.message||`unknown error`}`}},end_voice_session:async()=>($(`end_voice_session ▶`),ug(`Ending voice session…`,{icon:`👋`,spinner:!1,duration:2e3}),vg(!0),gg(),typeof e.requestEndSession==`function`&&e.requestEndSession(),`Voice session is ending.`),list_page_forms:async()=>{let e=Ig(),t=Rg();return $(`list_page_forms ✓`,`${e.length} field(s)`,`${t.length} button(s)`),o=Fg(),$(`list_page_forms · activeFormAncestor`,o?`contact-preferring`:`none`),JSON.stringify({fields:e,buttons:t,hint:`Fields are grouped by formIndex/formName. Work with ONE form at a time — only fill fields from the same formIndex. Do not jump to fields in a different form. On pages with a contact form AND a footer or secondary website-URL field: only use the contact form unless the visitor explicitly asks to use the URL or promo flow. Contact forms: fill in order Full Name → Email Address → Message. Message must be a short note the visitor wants to send (one or two sentences), never a recap of the whole chat or assistant replies. field_key: use placeholder, label, name, or id from this list. click_page_button picks the button nearest the filled fields (e.g. Send Message on the same form).`})},fill_form_fields:async e=>{try{$(`fill_form_fields ▶ raw:`,e);let t=n_(e);if(!t.length&&i){let e=i(),n=a_(e);n.length?$(`fill_form_fields · inferred URL from last user utterance (model omitted usable fields):`,n):(n=o_(e),n.length&&$(`fill_form_fields · inferred contact fields from last user utterance (empty tool params):`,n)),n.length&&(t=n)}if($(`fill_form_fields · normalized fields:`,t),!t.length)return`No fields provided. Call list_page_forms for field_key strings, then fill_form_fields with { "fields": [ { "field_key": "<label or placeholder from list>", "value": "<user value>" } ] }. Never use empty {}. Pass the value the user just said (email, message, name, URL) in fields.`;t.length>1&&ug(`Filling ${t.length} fields…`);let n=[];for(let e of t){let t=e?.field_key??e?.fieldKey,r=e?.value;if(t==null||r==null)continue;let i=String(t).toLowerCase();if(/email|e-mail|mail/.test(i))r=r_(r);else if(/phone|mobile|tel|cell/.test(i))r=i_(r);else if(Kg(t)||i===`url`){let e=String(r??``).trim();if(/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)||/\bat\b/i.test(e)&&/\bdot\b/i.test(e)){let n=r_(e);/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(n.trim())&&($(`fill_form_fields · remapping url/website intent to Email Address (value is an email)`),t=`Email Address`,i=`email address`,r=n.trim())}}ug(`Filling ${t}…`),$(`fill_form_fields · processing field:`,t,`=`,r);let s=Ng(),c=s;if(o){let e=s.filter(e=>Dg(e)===o);e.length>0&&(c=e,$(`fill_form_fields · scoped to active form, inputs:`,e.length))}$(`fill_form_fields · visible inputs count:`,s.length,`scoped:`,c.length);let l=!1;for(let e of[c,...c===s?[]:[s]]){let i=Yg(e,String(t),r);if(i.length){for(let e=0;e<i.length;e++)await u_(i[e],r,{skipScroll:e>0}),await new Promise(e=>setTimeout(e,80));a=i,o=Dg(i[0])||o,n.push(String(t)),l=!0;break}let s=Qg(e,String(t));if(s||=Ug(e,String(t)),s||=Wg(e,String(t),r),s){await u_(s,r),a=[s],o=Dg(s)||o,n.push(String(t)),l=!0;break}}l||$(`fill_form_fields · no match for field:`,t)}dg(400);try{vg()}catch{}if(!n.length)return $(`fill_form_fields ✖ no matches`),`Could not match any fields. Call list_page_forms and use field_key values that match placeholder, label, name, or id (e.g. Enter Website URL). Ensure the form is on the page, not the chat panel.`;let r=`OK_FILLED: ${n.join(`, `)}`;return $(`fill_form_fields ✓`,r),r}catch(e){dg(),gg(),vg(!0);let t=`fill_form_fields error: ${e?.message||String(e)}`;return $(`fill_form_fields ✖`,t),t}},click_page_button:async e=>{let t=t_(e),n=(t.button_text??t.buttonText??t.text??``).trim();if($(`click_page_button ▶`,n),!n)return`Missing button_text: pass the visible label, e.g. Submit or Read more.`;ug(`Clicking "${n}"…`);let r=e_(n,a);if(!r)return dg(200),$(`click_page_button ✖ no match`),`Could not find a button matching "${n}". Call list_page_forms to see button texts.`;try{try{r.scrollIntoView({behavior:`smooth`,block:`center`,inline:`nearest`})}catch{r.scrollIntoView(!0)}try{await _g(r)}catch{}try{bg(r)}catch{}try{await yg(r)}catch{}let e=Dg(r)||o,t=[];if(e){let n=Array.from(e.querySelectorAll(`input[required], textarea[required], select[required]`)).filter(e=>!Sg(e));for(let e of n)if(!(e.value||``).trim()){let n=Mg(e)||e.placeholder||e.name||e.type;t.push(n)}}if(t.length>0){dg(200);try{vg()}catch{}let e=`Cannot submit — these required fields are still empty: ${t.join(`, `)}. Fill them first with fill_form_fields, then click again.`;return $(`click_page_button ✖ empty required fields:`,t),e}r.focus?.(),r.click();let n=(r.textContent||r.value||r.getAttribute(`aria-label`)||``).trim().slice(0,80)||`button`;dg(600);try{vg()}catch{}gg(),o=null,a=[];let i=`OK_CLICK ${n}`;return $(`click_page_button ✓`,i),i}catch(e){dg(200),vg(!0);let t=`Click failed: ${e?.message||String(e)}`;return $(`click_page_button ✖`,t),t}}};return{...s,navigateToPage:s.navigate_to_page,highlightOnPage:s.highlight_on_page,searchSiteContent:s.search_site_content,endVoiceSession:s.end_voice_session,listPageForms:s.list_page_forms,fillFormFields:s.fill_form_fields,clickPageButton:s.click_page_button}}function f_(e){return!e||typeof e!=`object`?e:Object.fromEntries(Object.entries(e).map(([e,t])=>[e,async n=>{let r=Xt();r?console.log(`[FlowEngage:voice-tool] ▶`,e,n):console.info(`[FlowEngage] voice tool » ${e}`);let i;try{i=await t(n)}catch(t){let n=`Tool error: ${t?.message||String(t)}`;return console.error(`[FlowEngage] voice tool ${e} threw:`,t),n}let a=typeof i==`string`?i.length>220?`${i.slice(0,220)}…`:i:String(i);return r?console.log(`[FlowEngage:voice-tool] ◀`,e,a):console.info(`[FlowEngage] voice tool « ${e}:`,a),i}]))}var p_={idle:`rgba(99,102,241,0.18)`,listening:`rgba(16,185,129,0.25)`,speaking:`rgba(245,158,11,0.25)`,error:`rgba(239,68,68,0.2)`},m_={idle:`#6366f1`,listening:`#10b981`,speaking:`#f59e0b`,error:`#ef4444`},h_=17,g_=6;function __(e,t){let n=(t||``).trim();return n?!!(/\b(let'?s|let us)\s+(end|stop|finish|wrap up|close)\s+(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\bend\s+(this\s+)?(the\s+)?(voice\s+)?(session|call|chat)\b/i.test(n)||/\b(hang\s+up|disconnect)\b/i.test(n)||/\b(that'?s all|we'?re done)\b/i.test(n)||e===`bot`&&(/\b(I'?ll|I will|Let me|I can|I'?m going to)\s+(end|close)\s+(the\s+)?(voice\s+)?(session|call)\b/i.test(n)||/\b(ending|closing)\s+(the\s+)?(voice\s+)?session\b|\bvoice\s+session\s+(is\s+)?(now\s+)?(ended|over|closing)\b/i.test(n)||/\b(session|call)\s+(is\s+)?(now\s+)?(ended|over)\b/i.test(n)||/\bwe\s+can\s+end\s+(the\s+)?(session|call)?\s*(here|now)\b/i.test(n)||/\b(wrapping\s+up|signing\s+off)\b/i.test(n))||/^(goodbye|bye|that'?s all|we'?re done|hang up|disconnect)\b/i.test(n)):!1}function v_({agentId:e,chatId:t,siteId:n,apiBaseUrl:r,onEnd:i,historyRef:a,hasSyncedRef:o,onMessageSync:s,onStartSync:c}){let[d,f]=(0,l.useState)(`idle`),[p,m]=(0,l.useState)(null),[ee,h]=(0,l.useState)(!1),g=(0,l.useRef)(null),_=(0,l.useRef)(null),te=(0,l.useRef)(``),ne=(0,l.useRef)(async()=>{}),re=(0,l.useRef)(!1),ie=(0,l.useRef)(``),ae=(0,l.useRef)(null),oe=(0,l.useRef)(null),v=(0,l.useRef)(null),se=(0,l.useRef)(null),ce=(0,l.useRef)(null),y=(0,l.useCallback)(()=>{v.current&&=(clearTimeout(v.current),null),se.current&&=(clearInterval(se.current),null),ie.current=``,ae.current=null,oe.current=null,ce.current!=null&&(cancelAnimationFrame(ce.current),ce.current=null);try{mn()}catch{}},[]),le=(0,l.useCallback)(async()=>{y();try{await g.current?.endSession?.()}catch{}g.current=null,h(!1),f(`idle`),re.current=!1,typeof s==`function`&&await s(a.current),typeof i==`function`&&i()},[y,a,s,i]);ne.current=le,(0,l.useEffect)(()=>{let t=!1,i=null;return(async()=>{try{if(await navigator.mediaDevices.getUserMedia({audio:!0}),t)return;a.current=[],te.current=``,re.current=!1;let o=f_(d_({siteId:n||null,apiBaseUrl:r||null,getLastUserVoiceText:()=>te.current,preferLiveSpeechHighlight:!0,requestEndSession:()=>{queueMicrotask(()=>{re.current||(re.current=!0,ne.current?.())})}})),s=()=>{try{let e=ie.current,t=ae.current;if(!e?.trim()||t==null)return;let n=oe.current,r=Date.now(),i;if(n!=null){let t=Math.max(0,(r-n)/1e3),a=Math.min(e.length,Math.floor(t*h_));t>.06&&e.length>=14&&(a=Math.max(a,Math.min(40,e.length))),i=a}else{let n=Math.max(0,(r-t)/1e3);if(n>2.1&&e.length>36)i=Math.min(e.length,Math.floor(Math.max(0,n-.4)*h_));else{let t=Math.min(96,Math.floor(n*g_));i=Math.min(e.length,t)}}let a=e.slice(0,i);if(a.trim().length<6)return;nn();let o=fn(a);o&&pn(o,{speaking:!0})}catch(e){console.warn(`[VoiceInterface] speech highlight failed`,e?.message)}},l=()=>{ce.current??=requestAnimationFrame(()=>{ce.current=null,s()})},u=()=>{v.current&&clearTimeout(v.current),v.current=setTimeout(()=>{v.current=null,s()},120)},d=()=>{se.current||=setInterval(()=>{s()},160)},p=await Rh.startSession({agentId:e,clientTools:o,onUnhandledClientToolCall:e=>{console.error(`[VoiceInterface] ElevenLabs requested a client tool that is not registered in the widget:`,e?.tool_name,e?.parameters,`Add a matching handler in voiceClientTools (snake_case and camelCase are both supported).`)},onModeChange:({mode:e})=>{t||f(e===`speaking`?`speaking`:`listening`)},onAudio:()=>{t||(oe.current??=Date.now(),d(),l())},onAgentChatResponsePart:e=>{if(t)return;let n=e?.text_response_part??e,r=n?.type,i=n?.text??``;r===`start`?(v.current&&=(clearTimeout(v.current),null),se.current&&=(clearInterval(se.current),null),ce.current!=null&&(cancelAnimationFrame(ce.current),ce.current=null),oe.current=null,ie.current=i,ae.current=Date.now(),d()):r===`delta`?(ie.current+=i,ae.current??=Date.now(),d()):r===`stop`?(ie.current+=i,d()):(ie.current+=i,ae.current==null&&i&&(ae.current=Date.now()),d()),ie.current.trim().length>=10&&(u(),l())},onInterruption:()=>{y()},onMessage:e=>{if(t)return;let n=e.role===`user`?`user`:`bot`,r=e.message||e.text||e.content||``;if(!r)return;let i={sender:n,message:r,timestamp:new Date().toISOString()};if(n===`user`)te.current=r;else if(n===`bot`&&r.trim()){let e=r.trim();e.length>(ie.current?.length||0)&&(ie.current=e,ae.current??=Date.now(),d(),e.length>=10&&(u(),l()))}a.current=[...a.current,i],__(n,r)&&queueMicrotask(()=>{re.current||(re.current=!0,ne.current?.())})},onError:e=>{t||(console.error(`[VoiceInterface] ElevenLabs error`,e),y(),f(`error`),m(`Voice session encountered an error.`))},onDisconnect:()=>{t||(console.log(`[VoiceInterface] session disconnected`),y(),h(!1),f(`idle`))}});if(t){p.endSession().catch(()=>{});return}i=p,g.current=p,h(!0),f(`listening`);try{let e=typeof window<`u`?window.location.href:``,t=``;try{t=await o.list_page_forms()}catch{t=`[]`}p.sendContextualUpdate(`Current page URL: ${e}. Site ID: ${n||`unknown`}. Page fields/buttons JSON: ${t}. Navigation: when the user wants to go to any page (contact, pricing, about, services, etc.), call search_site_content then navigate_to_page immediately — never ask permission. After navigating to a page with a form, call list_page_forms and proactively start helping the user fill it. Contact / lead forms: use only the main contact form (Full Name, Email, Message). Ignore footer or secondary marketing URL fields unless the user explicitly asks to use them. Fill in order: name → email → message. Message must be a short visitor note (what they want from the team), not a transcript of the conversation. Forms: use fill_form_fields then click_page_button (e.g. Send Message) when appropriate. Fill each field right after the user gives that value — do not click submit until required fields are filled. Voice: if the user wants to end the voice session, call end_voice_session or confirm and end.`)}catch{}typeof c==`function`&&c()}catch(e){t||(console.error(`[VoiceInterface] startSession failed`,e),f(`error`),m(`Could not start voice session. Please try again.`))}})(),()=>{t=!0,y(),i?i.endSession().catch(()=>{}):g.current&&g.current.endSession().catch(()=>{})}},[e,n,r,a,c,y]);let ue=d===`listening`||d===`speaking`,de=m_[d]||m_.idle,fe=p_[d]||p_.idle;return(0,u.jsxs)(`div`,{ref:_,style:{display:`flex`,flexDirection:`column`,alignItems:`center`,justifyContent:`center`,flex:1,gap:`24px`,padding:`24px 20px`,background:`transparent`},children:[(0,u.jsxs)(`div`,{style:{position:`relative`,width:`140px`,height:`140px`,display:`flex`,alignItems:`center`,justifyContent:`center`},children:[ue&&(0,u.jsx)(`div`,{style:{position:`absolute`,inset:`-16px`,borderRadius:`50%`,border:`2px solid ${de}`,animation:`fe-orb-pulse 1.4s ease-in-out infinite`,opacity:.6}}),ue&&(0,u.jsx)(`div`,{style:{position:`absolute`,inset:`-8px`,borderRadius:`50%`,border:`2px solid ${de}`,animation:`fe-orb-pulse 1.4s ease-in-out 0.35s infinite`,opacity:.4}}),(0,u.jsx)(`div`,{style:{width:`140px`,height:`140px`,borderRadius:`50%`,background:fe,border:`3px solid ${de}`,display:`flex`,alignItems:`center`,justifyContent:`center`,transition:`all 0.35s ease`,transform:d===`speaking`?`scale(1.08)`:`scale(1)`,boxShadow:`0 0 40px ${fe}, 0 8px 32px rgba(0,0,0,0.08)`},children:(0,u.jsx)(kn,{size:44,color:de})})]}),(0,u.jsxs)(`div`,{style:{fontSize:`15px`,fontWeight:600,color:d===`error`?`#ef4444`:`#374151`,letterSpacing:`0.01em`,textAlign:`center`},children:[d===`idle`&&`Starting voice session…`,d===`listening`&&`Listening…`,d===`speaking`&&`AI is speaking…`,d===`error`&&(p||`Error`)]}),(0,u.jsxs)(`button`,{onClick:le,style:{display:`flex`,alignItems:`center`,gap:`8px`,padding:`12px 24px`,borderRadius:`999px`,background:`#fee2e2`,color:`#dc2626`,border:`1px solid #fca5a5`,fontWeight:600,fontSize:`14px`,cursor:`pointer`,transition:`all 0.2s ease`},onMouseEnter:e=>{e.currentTarget.style.background=`#fecaca`},onMouseLeave:e=>{e.currentTarget.style.background=`#fee2e2`},children:[(0,u.jsx)(An,{size:18}),`End Voice Session`]}),(0,u.jsx)(`style`,{children:`
|
|
488
488
|
@keyframes fe-orb-pulse {
|
|
489
489
|
0% { transform: scale(1); opacity: 0.6; }
|
|
490
490
|
50% { transform: scale(1.18); opacity: 0.15; }
|
|
@@ -23337,8 +23337,8 @@ function b_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
23337
23337
|
if (!e?.trim() || t == null) return;
|
|
23338
23338
|
let n = le.current, r = Date.now(), i;
|
|
23339
23339
|
if (n != null) {
|
|
23340
|
-
let t = Math.max(0, (r - n) / 1e3);
|
|
23341
|
-
|
|
23340
|
+
let t = Math.max(0, (r - n) / 1e3), a = Math.min(e.length, Math.floor(t * __));
|
|
23341
|
+
t > .06 && e.length >= 14 && (a = Math.max(a, Math.min(40, e.length))), i = a;
|
|
23342
23342
|
} else {
|
|
23343
23343
|
let n = Math.max(0, (r - t) / 1e3);
|
|
23344
23344
|
if (n > 2.1 && e.length > 36) i = Math.min(e.length, Math.floor(Math.max(0, n - .4) * __));
|
|
@@ -23348,7 +23348,7 @@ function b_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
23348
23348
|
}
|
|
23349
23349
|
}
|
|
23350
23350
|
let a = e.slice(0, i);
|
|
23351
|
-
if (a.trim().length <
|
|
23351
|
+
if (a.trim().length < 6) return;
|
|
23352
23352
|
rn();
|
|
23353
23353
|
let o = pn(a);
|
|
23354
23354
|
o && mn(o, { speaking: !0 });
|
|
@@ -23396,7 +23396,12 @@ function b_({ agentId: e, chatId: t, siteId: r, apiBaseUrl: a, onEnd: c, history
|
|
|
23396
23396
|
message: r,
|
|
23397
23397
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
23398
23398
|
};
|
|
23399
|
-
n === "user"
|
|
23399
|
+
if (n === "user") ae.current = r;
|
|
23400
|
+
else if (n === "bot" && r.trim()) {
|
|
23401
|
+
let e = r.trim();
|
|
23402
|
+
e.length > (v.current?.length || 0) && (v.current = e, ce.current ??= Date.now(), l(), e.length >= 10 && (c(), s()));
|
|
23403
|
+
}
|
|
23404
|
+
d.current = [...d.current, i], y_(n, r) && queueMicrotask(() => {
|
|
23400
23405
|
se.current || (se.current = !0, oe.current?.());
|
|
23401
23406
|
});
|
|
23402
23407
|
},
|