@bitpalm/ai-agents 0.4.0 → 0.5.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/README.md +49 -200
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -1
- package/dist/index.d.ts +30 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1 -1
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +19 -0
- package/dist/react.d.ts +19 -0
- package/dist/react.js +1 -1
- package/dist/react.js.map +1 -1
- package/dist/widget.global.js +1 -1
- package/dist/widget.global.js.map +1 -1
- package/package.json +10 -18
package/dist/react.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var me=Object.defineProperty;var Ye=Object.getOwnPropertyDescriptor;var Je=Object.getOwnPropertyNames;var Ge=Object.prototype.hasOwnProperty;var Ve=(i,o)=>{for(var c in o)me(i,c,{get:o[c],enumerable:!0})},Ke=(i,o,c,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let p of Je(o))!Ge.call(i,p)&&p!==c&&me(i,p,{get:()=>o[p],enumerable:!(a=Ye(o,p))||a.enumerable});return i};var Xe=i=>Ke(me({},"__esModule",{value:!0}),i);var ct={};Ve(ct,{BitPalmAgent:()=>lt});module.exports=Xe(ct);var J=require("react");var Ze="https://agents.bitpalm.ai",h="_bp_",Qe=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),et=8e3,He=4096,Re=`${h}identify_signature`,Ne=`${h}identify_fingerprint`,Fe=`${h}identify_sent_at`;function tt(i){return[i.external_user_id||"",i.email||"",i.phone||"",i.name||"",i.company||"",i.signature||"",i.signed_at!=null?String(i.signed_at):"",i.signature_version||"",i.identify_source||""].join("|").toLowerCase()}function m(i,o=180){return i?i.replace(/\s+/g," ").trim().slice(0,o):""}function nt(i){return i?` ${i.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function W(i,o){for(let c of o)if(i.includes(c))return!0;return!1}function A(i){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(i)}function _(i){let o=m(i,50);if(!o)return"";let c=o.startsWith("+"),a=o.replace(/\D/g,"");return a.length<6?"":`${c?"+":""}${a.slice(0,20)}`}function De(i){let o=m(i,140).toLowerCase();return!o||!A(o)?"":o}function j(i,o){for(let c of o){let a=i.querySelector(c),p=m(a?.value);if(p)return p}return""}function ot(i){return m(i.getAttribute("data-bp-field")||i.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function it(i){return i.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function st(i,o){let c=[],a=(n,x=140)=>{let l=m(n,x);l&&c.push(l)};a(o.name),a(o.id),a(o.getAttribute("autocomplete")),a(o.getAttribute("placeholder")),a(o.getAttribute("aria-label")),a(o.getAttribute("data-field")),a(o.getAttribute("data-name")),a(o.getAttribute("data-label")),a(o.getAttribute("data-bp-field")),a(o.getAttribute("data-bitpalm-field"));let p=new Set,w=n=>{let x=m(n,200);!x||p.has(x)||(p.add(x),c.push(x))};for(let n of Array.from(o.labels||[]))w(n.textContent);if(o.id){let n=i.querySelector(`label[for="${it(o.id)}"]`);w(n?.textContent)}let y=o.closest("label");w(y?.textContent);let r=o.getAttribute("aria-labelledby");if(r)for(let n of r.split(/\s+/)){if(!n)continue;let x=i.ownerDocument.getElementById(n);w(x?.textContent)}return c}function at(i){let o=m(j(i,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),c=_(j(i,["[data-bp-phone]","[data-bitpalm-phone]"])),a=m(j(i,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),p=m(j(i,["[data-bp-first-name]","[data-bitpalm-first-name]"])),w=m(j(i,["[data-bp-last-name]","[data-bitpalm-last-name]"])),y=m(j(i,["[data-bp-company]","[data-bitpalm-company]"]));for(let l of Array.from(i.elements)){if(!(l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)||l.disabled||l instanceof HTMLInputElement&&Qe.has(l.type.toLowerCase()))continue;let g=ot(l),u=l.hasAttribute("data-bp-email")||l.hasAttribute("data-bitpalm-email")||l.hasAttribute("data-bp-phone")||l.hasAttribute("data-bitpalm-phone")||l.hasAttribute("data-bp-name")||l.hasAttribute("data-bitpalm-name")||l.hasAttribute("data-bp-full-name")||l.hasAttribute("data-bitpalm-full-name")||l.hasAttribute("data-bp-first-name")||l.hasAttribute("data-bitpalm-first-name")||l.hasAttribute("data-bp-last-name")||l.hasAttribute("data-bitpalm-last-name")||l.hasAttribute("data-bp-company")||l.hasAttribute("data-bitpalm-company")||!!g;if(l instanceof HTMLInputElement&&l.type.toLowerCase()==="hidden"&&!u)continue;let d=m(l.value);if(!d)continue;let $=l instanceof HTMLInputElement?l.type.toLowerCase():"",S=nt(st(i,l).join(" "));if(!o&&g==="email"&&A(d)){o=d.toLowerCase();continue}if(!c&&(g==="phone"||g==="tel"||g==="mobile"||g==="whatsapp")){let T=_(d);if(T){c=T;continue}}if(!y&&g==="company"){y=m(d,160);continue}if(!p&&(g==="first-name"||g==="firstname")){p=m(d,100);continue}if(!w&&(g==="last-name"||g==="lastname"||g==="surname")){w=m(d,100);continue}if(!a&&(g==="name"||g==="full-name"||g==="fullname")){!A(d)&&!_(d)&&(a=m(d,140));continue}let U=$==="email"||W(S,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),O=$==="tel"||W(S,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),H=W(S,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),R=W(S,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),N=W(S,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),q=W(S,[" full name "," fullname "," contact name "," name "])&&!U&&!O;if(!o&&U&&A(d)){o=d.toLowerCase();continue}if(!c&&O){let T=_(d);if(T){c=T;continue}}if(!y&&H){y=m(d,160);continue}if(!p&&R){p=m(d,100);continue}if(!w&&N){w=m(d,100);continue}if(!a&&q&&!A(d)&&!_(d)){a=m(d,140);continue}!o&&A(d)&&(o=d.toLowerCase())}if(a&&(A(a)||_(a))&&(a=""),y&&(A(y)||_(y))&&(y=""),a||(a=m([p,w].filter(Boolean).join(" "),140)),a&&o&&a.toLowerCase()===o.toLowerCase()&&(a=""),!!!(o||c)&&!!!(a&&y))return null;let x={...a?{name:a}:{},...o?{email:o}:{},...c?{phone:c}:{},...y?{company:y}:{}};return Object.keys(x).length>0?x:null}function rt(){if(typeof document<"u"){let i=document.documentElement.lang;if(i)return i.slice(0,2).toLowerCase()}return"en"}function ue(i,o=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(i,{timeout:o});return}setTimeout(i,Math.min(o,300))}function fe(){if(typeof window>"u")return!1;let i=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(i))return!0;let c=window.matchMedia("(pointer: coarse)").matches,a=window.matchMedia("(hover: none)").matches,p=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return c&&a&&p<=900}function We(i){let{slug:o,locale:c=rt(),baseUrl:a=Ze,token:p,zIndex:w=9999,autoIdentify:y=!0}=i,r=document,n=r.createElement("iframe"),x=`${a}/t/${o}/widget`,l=new URLSearchParams({locale:c});p&&l.set("token",p),n.src=`${x}?${l.toString()}`,n.allow="clipboard-write; microphone",n.setAttribute("allowtransparency","true"),n.loading="lazy",n.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${w};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;let g=new URL(n.src).origin,u=r.createElement("div");if(u.setAttribute("role","button"),u.setAttribute("aria-label","Chat"),u.style.cssText=`position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${w-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s,opacity .3s;opacity:0;`,u.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',u.onmouseenter=()=>{u.style.transform="scale(1.1)"},u.onmouseleave=()=>{u.style.transform="scale(1)"},u.onclick=()=>Z(),r.body.appendChild(u),!r.getElementById("_bp_fade")){let e=r.createElement("style");e.id="_bp_fade",e.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",r.head.appendChild(e)}let d=null,$=!1,S=!1,U=!1,O=!1,H=!1,R=()=>{U||(U=!0,r.body.appendChild(n))},N=!1,q=0,T={overflow:"",overscrollBehavior:""},v={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},pe=()=>{if(N||!fe())return;let s=r.documentElement,t=r.body;q=window.scrollY||window.pageYOffset||0,T.overflow=s.style.overflow,T.overscrollBehavior=s.style.overscrollBehavior,v.overflow=t.style.overflow,v.overscrollBehavior=t.style.overscrollBehavior,v.position=t.style.position,v.top=t.style.top,v.left=t.style.left,v.right=t.style.right,v.width=t.style.width,s.style.overflow="hidden",s.style.overscrollBehavior="none",t.style.overflow="hidden",t.style.overscrollBehavior="none",t.style.position="fixed",t.style.top=`-${q}px`,t.style.left="0",t.style.right="0",t.style.width="100%",N=!0},F=()=>{if(!N)return;let e=r.documentElement,s=r.body;e.style.overflow=T.overflow,e.style.overscrollBehavior=T.overscrollBehavior,s.style.overflow=v.overflow,s.style.overscrollBehavior=v.overscrollBehavior,s.style.position=v.position,s.style.top=v.top,s.style.left=v.left,s.style.right=v.right,s.style.width=v.width,window.scrollTo(0,q),N=!1},ge=()=>{let e=fe();n.style.display==="none"&&(n.style.display=""),e?(n.style.width="100vw",n.style.height="100dvh",n.style.left="0",n.style.top="0",n.style.bottom="0",n.style.right="0",pe()):(n.style.width="420px",n.style.height="620px",n.style.bottom="24px",n.style.right="24px",n.style.left="",n.style.top="",F()),n.style.opacity="1",n.style.pointerEvents="auto"},P=()=>{d&&(d.remove(),d=null)},G=()=>{},ee=()=>{},D=!1,C=new Map;function te(e,s){let t=C.get(e);if(t)for(let f of t)try{f(s)}catch{}}let ye=e=>{if(e.origin===g){if(e.data?.type==="bitpalm-widget-config"){S=!1,$=!0,n.style.display==="none"&&(n.style.display=""),e.data.primaryColor&&(u.style.background=e.data.primaryColor,u.style.boxShadow=e.data.chatShadow==="none"?"none":`0 0 15px ${e.data.primaryColor}50`);let s=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){u.innerHTML="";let t=r.createElement("span");t.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${s}`;let b=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");b?(b.querySelectorAll("script,foreignObject").forEach(M=>M.remove()),b.querySelectorAll("*").forEach(M=>{for(let k of[...M.attributes])(k.name.startsWith("on")||k.value&&k.value.includes("javascript:"))&&M.removeAttribute(k.name)}),b.setAttribute("width","24"),b.setAttribute("height","24"),b.style.display="block",t.appendChild(b)):t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',u.appendChild(t)}else{let t=u.querySelector("svg");t&&(t.style.stroke=s)}u.style.display="flex",requestAnimationFrame(()=>{u.style.opacity="1"})}if(e.data?.type==="bitpalm-widget-resize"){let s=e.data.width>0,t=D;D=s,s&&!t&&te("widget_opened"),!s&&t&&te("widget_closed");let f=fe();s?(n.style.width=f?"100vw":`${e.data.width}px`,n.style.height=f?"100dvh":`${e.data.height}px`,f?(n.style.left="0",n.style.top="0",n.style.bottom="0",n.style.right="0",pe()):F(),n.style.opacity="1",n.style.pointerEvents="auto"):(F(),n.style.width="1px",n.style.height="1px",n.style.left="",n.style.top="",n.style.opacity="0",n.style.pointerEvents="none"),u.style.display=s?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(S||!$)return;P(),d=r.createElement("div"),d.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${w-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let s=(e.data.message||"").replace(/</g,"<");d.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${s}</p><div style="position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;"></div>`;let t=r.createElement("button");t.style.cssText="position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;",t.innerHTML="✕",t.onclick=f=>{f.stopPropagation(),P(),n.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},d.onclick=()=>{if(P(),u.style.display="none",ge(),R(),!O){H=!0;return}n.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:s},"*")},d.appendChild(t),r.body.appendChild(d)}e.data?.type==="bitpalm-trigger-hide"&&P(),e.data?.type==="bitpalm-request-context"&&G(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&te(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(S=!0,$=!1,u.style.display="none",P(),F(),n.style.display="none")}};window.addEventListener("message",ye);let I=!1;try{I=localStorage.getItem(`${h}optout`)==="1"}catch{}let V=`${h}vid`,E="";if(!I){try{E=localStorage.getItem(V)||""}catch{}if(!E){let e=r.cookie.match(new RegExp(`(?:^|; )${V}=([^;]+)`));E=e?decodeURIComponent(e[1]):""}E||(E=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(V,E)}catch{}try{r.cookie=`${V}=${encodeURIComponent(E)};path=/;max-age=31536000;SameSite=Lax`}catch{}}I||ue(()=>{try{let e=new URLSearchParams(location.search),s={};for(let L of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let b=e.get(L);b&&(s[L]=b)}let t=JSON.stringify({tenant_slug:o,visitor_id:E,url:location.href,referrer:r.referrer||void 0,...Object.keys(s).length>0?{utm:s}:{}}),f=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(f,new Blob([t],{type:"application/json"})):fetch(f,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let ne="",oe="",ie=0;try{ne=sessionStorage.getItem(Re)||"",oe=sessionStorage.getItem(Ne)||"";let e=parseInt(sessionStorage.getItem(Fe)||"0",10);Number.isFinite(e)&&e>0&&(ie=e)}catch{}let he=(e,s="")=>{if(I||!E)return;let t={},f=m(e.name,140),L=De(e.email),b=_(e.phone),M=m(e.company,160),k=m(e.external_user_id,140),ke=m(e.signature,260),le=Number(e.signed_at);if(f&&(t.name=f),L&&(t.email=L),b&&(t.phone=b),M&&(t.company=M),k&&(t.external_user_id=k),ke&&(t.signature=ke),Number.isFinite(le)&&le>0&&(t.signed_at=Math.floor(le)),(e.signature_version==="v1"||t.signature)&&(t.signature_version="v1"),(e.identify_source==="manual"||e.identify_source==="form")&&(t.identify_source=e.identify_source),!t.name&&!t.email&&!t.phone&&!t.company&&!t.external_user_id)return;let Q=tt(t),ce=[s.toLowerCase(),Q].filter(Boolean).join("|"),de=Date.now();if(!(de-ie<et&&(ce===ne||Q===oe))){ne=ce,oe=Q,ie=de;try{sessionStorage.setItem(Re,ce),sessionStorage.setItem(Ne,Q),sessionStorage.setItem(Fe,String(de))}catch{}try{let $e=JSON.stringify({tenant_slug:o,visitor_id:E,url:location.href,referrer:r.referrer||void 0,...t}),Oe=`${a}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(Oe,new Blob([$e],{type:"application/json"})):fetch(Oe,{method:"POST",body:$e,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},be=e=>{if(I||!y||!E)return;let s=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(s instanceof HTMLFormElement))return;let t=(s.getAttribute("data-bp-identify")||s.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(t==="off"||t==="false"||t==="0")return;let f=at(s);if(!f)return;let L=[s.getAttribute("id")||"",s.getAttribute("name")||"",s.getAttribute("action")||""].join("|");he({...f,identify_source:"form"},L)};!I&&y&&r.addEventListener("submit",be,!0);let z=parseInt(sessionStorage.getItem(`${h}pages`)||"0")+1;sessionStorage.setItem(`${h}pages`,String(z));let B=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");B.push(location.href),B.length>20&&(B=B.slice(-20)),sessionStorage.setItem(`${h}hist`,JSON.stringify(B));let we=Date.now(),K=parseInt(sessionStorage.getItem(`${h}site_start`)||"0");K||(K=we,sessionStorage.setItem(`${h}site_start`,String(K)));let ve=[];G=()=>{let e=!1;try{e=!!localStorage.getItem(`${h}visited`)}catch{e=!1}if(n.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:r.title,returning:e,pageCount:z,pageHistory:B,loadedAt:we,siteStart:K,locale:c,visitorId:I?"":E},"*"),!e&&!I)try{localStorage.setItem(`${h}visited`,"1")}catch{}},n.addEventListener("load",()=>{O=!0,G(),[120,450,1100].forEach(e=>{let s=setTimeout(()=>G(),e);ve.push(s)}),H&&(H=!1,ee())}),r.readyState==="loading"?r.addEventListener("DOMContentLoaded",()=>ue(R,1600),{once:!0}):ue(R,1600);let xe=history.pushState.bind(history),Ee=history.replaceState.bind(history),X=()=>{z++,sessionStorage.setItem(`${h}pages`,String(z));let e=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),B=e,sessionStorage.setItem(`${h}hist`,JSON.stringify(e)),n.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:r.title,pageCount:z,pageHistory:e,loadedAt:Date.now()},"*"),!I)try{let s=JSON.stringify({tenant_slug:o,visitor_id:E,url:location.href}),t=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(t,new Blob([s],{type:"application/json"})):fetch(t,{method:"POST",body:s,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){xe(...e),X()},history.replaceState=function(...e){Ee(...e),X()},window.addEventListener("popstate",X);let Se=-1,se,Te=()=>{clearTimeout(se),se=setTimeout(()=>{let e=Math.max(r.documentElement.scrollHeight,r.body.scrollHeight)-window.innerHeight,s=e>0?Math.round(window.scrollY/e*100):100;s!==Se&&(Se=s,n.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:s},"*"))},500)};window.addEventListener("scroll",Te,{passive:!0});let Ie=e=>{e.clientY<=0&&n.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};r.addEventListener("mouseout",Ie);let ae,Le=!1,re=()=>{clearTimeout(ae),!Le&&(ae=setTimeout(()=>{Le=!0,n.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},_e=["mousemove","keydown","scroll","touchstart"];_e.forEach(e=>r.addEventListener(e,re,{passive:!0})),re(),ee=()=>{n.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=n.src.split("#")[0];n.src=`${e}#bp-open-${Date.now()}`};let Z=()=>{if(u.style.display="none",P(),ge(),R(),!O){H=!0;return}ee()},Ae=()=>{F(),n.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Pe=e=>{!e||typeof e!="object"||he({external_user_id:m(e.externalUserId,140)||void 0,name:m(e.name,140)||void 0,email:De(e.email)||void 0,phone:_(e.phone)||void 0,company:m(e.company,160)||void 0,signature:m(e.signature,260)||void 0,signed_at:Number.isFinite(Number(e.signedAt))?Math.floor(Number(e.signedAt)):void 0,signature_version:e.signatureVersion==="v1"?"v1":void 0,identify_source:"manual"},"manual")},je=()=>{D?Ae():Z()},Ue=()=>D,qe=e=>{if(!e||typeof e!="string")return;let s=e.trim().slice(0,1e4);s&&(D||Z(),setTimeout(()=>{n.contentWindow?.postMessage({type:"bitpalm-send-message",message:s},"*")},D?50:500))},Y={},Ce=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;Y={...Y,...e};let s=JSON.stringify(Y);s.length>He&&console.warn(`[BitPalm] Custom context exceeds ${He} bytes (${s.length}). It may be truncated.`),n.contentWindow?.postMessage({type:"bitpalm-custom-context",data:Y},"*")},ze=()=>{Y={},n.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},Be=e=>{let t=e.detail;if(!t||typeof t!="object")return;let f=m(t.slug,120);if(f&&f!==o)return;let{slug:L,...b}=t;Ce(b)};window.addEventListener("bitpalm-context",Be);let Me=e=>{let t=e.detail;if(!t||typeof t!="object")return;let f=m(t.slug,120);f&&f!==o||Pe(t)};return window.addEventListener("bitpalm-identify",Me),{open:Z,close:Ae,toggle:je,isOpen:Ue,identify:Pe,context:Ce,resetContext:ze,send:qe,on:(e,s)=>(C.has(e)||C.set(e,new Set),C.get(e).add(s),()=>C.get(e)?.delete(s)),off:(e,s)=>{C.get(e)?.delete(s)},destroy:()=>{window.removeEventListener("message",ye),window.removeEventListener("scroll",Te),window.removeEventListener("popstate",X),r.removeEventListener("mouseout",Ie),r.removeEventListener("submit",be,!0),_e.forEach(e=>r.removeEventListener(e,re)),clearTimeout(se),clearTimeout(ae),ve.forEach(e=>clearTimeout(e)),history.pushState=xe,history.replaceState=Ee,window.removeEventListener("bitpalm-identify",Me),window.removeEventListener("bitpalm-context",Be),C.clear(),F(),P(),u.remove(),n.remove()}}}function lt(i){let o=(0,J.useRef)(null),c=(0,J.useRef)(!1);return(0,J.useEffect)(()=>{if(!c.current)return c.current=!0,o.current=We(i),()=>{o.current?.destroy(),o.current=null,c.current=!1}},[]),null}0&&(module.exports={BitPalmAgent});
|
|
1
|
+
"use strict";var ve=Object.defineProperty;var ut=Object.getOwnPropertyDescriptor;var ft=Object.getOwnPropertyNames;var pt=Object.prototype.hasOwnProperty;var gt=(n,t)=>{for(var r in t)ve(n,r,{get:t[r],enumerable:!0})},ht=(n,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let m of ft(t))!pt.call(n,m)&&m!==r&&ve(n,m,{get:()=>t[m],enumerable:!(a=ut(t,m))||a.enumerable});return n};var yt=n=>ht(ve({},"__esModule",{value:!0}),n);var Bt={};gt(Bt,{BitPalmAgent:()=>kt});module.exports=yt(Bt);var D=require("react");var bt=["dark","dark-mode","dark-theme","theme-dark"],vt=["light","light-mode","light-theme","theme-light"],et=["data-theme","data-color-scheme","data-color-mode","data-mode","data-bs-theme"],tt="(prefers-color-scheme: dark)";function oe(n){return n==="light"||n==="dark"?n:"auto"}function Ze(n){if(!n)return null;if(bt.some(t=>n.classList.contains(t)))return"dark";if(vt.some(t=>n.classList.contains(t)))return"light";for(let t of et){let r=(n.getAttribute(t)||"").toLowerCase();if(r.includes("dark"))return"dark";if(r.includes("light"))return"light"}return null}function we(n){let t=n/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4}function Qe(n,t){if(!n)return null;let r=t.getComputedStyle(n).backgroundColor.match(/rgba?\(([^)]+)\)/);if(!r)return null;let[a,m,y,p=1]=r[1].split(/[\s,/]+/).filter(Boolean).map(Number);return[a,m,y,p].some(g=>Number.isNaN(g))||p<.5?null:.2126*we(a)+.7152*we(m)+.0722*we(y)<.2?"dark":"light"}function wt(n,t){let r=t.getComputedStyle(n.documentElement).colorScheme||"",a=n.querySelector('meta[name="color-scheme"]')?.getAttribute("content")||"",m=`${r} ${a}`.toLowerCase();return m.includes("dark")?m.includes("light")?t.matchMedia?.(tt).matches?"dark":"light":"dark":null}function Y(n=document,t=window){return Ze(n.documentElement)??Ze(n.body)??Qe(n.body,t)??Qe(n.documentElement,t)??wt(n,t)??"light"}function Ee(n,t=document,r=window){let a=Y(t,r),m=!1,y=()=>{m=!1;let c=Y(t,r);c!==a&&(a=c,n(c))},p=()=>{m||(m=!0,typeof r.requestAnimationFrame=="function"?r.requestAnimationFrame(y):setTimeout(y,16))},l=typeof MutationObserver<"u"?new MutationObserver(p):null,g={attributes:!0,attributeFilter:["class","style",...et]};l?.observe(t.documentElement,g),t.body&&l?.observe(t.body,g);let b=typeof r.matchMedia=="function"?r.matchMedia(tt):null;return b?.addEventListener?.("change",p),()=>{l?.disconnect(),b?.removeEventListener?.("change",p)}}var Et="https://agents.bitpalm.ai",v="_bp_",xt=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),Tt=8e3,nt=4096,ot=`${v}identify_signature`,it=`${v}identify_fingerprint`,st=`${v}identify_sent_at`,at="0 4px 14px rgba(0,0,0,0.18)";function St(n){return[n.external_user_id||"",n.email||"",n.phone||"",n.name||"",n.company||"",n.signature||"",n.signed_at!=null?String(n.signed_at):"",n.signature_version||"",n.identify_source||""].join("|").toLowerCase()}function d(n,t=180){return n?n.replace(/\s+/g," ").trim().slice(0,t):""}function Lt(n){return n?` ${n.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function N(n,t){for(let r of t)if(n.includes(r))return!0;return!1}function I(n){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(n)}function _(n){let t=d(n,50);if(!t)return"";let r=t.startsWith("+"),a=t.replace(/\D/g,"");return a.length<6?"":`${r?"+":""}${a.slice(0,20)}`}function rt(n){let t=d(n,140).toLowerCase();return!t||!I(t)?"":t}function W(n,t){for(let r of t){let a=n.querySelector(r),m=d(a?.value);if(m)return m}return""}function At(n){return d(n.getAttribute("data-bp-field")||n.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function _t(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function It(n,t){let r=[],a=(g,b=140)=>{let c=d(g,b);c&&r.push(c)};a(t.name),a(t.id),a(t.getAttribute("autocomplete")),a(t.getAttribute("placeholder")),a(t.getAttribute("aria-label")),a(t.getAttribute("data-field")),a(t.getAttribute("data-name")),a(t.getAttribute("data-label")),a(t.getAttribute("data-bp-field")),a(t.getAttribute("data-bitpalm-field"));let m=new Set,y=g=>{let b=d(g,200);!b||m.has(b)||(m.add(b),r.push(b))};for(let g of Array.from(t.labels||[]))y(g.textContent);if(t.id){let g=n.querySelector(`label[for="${_t(t.id)}"]`);y(g?.textContent)}let p=t.closest("label");y(p?.textContent);let l=t.getAttribute("aria-labelledby");if(l)for(let g of l.split(/\s+/)){if(!g)continue;let b=n.ownerDocument.getElementById(g);y(b?.textContent)}return r}function Ct(n){let t=d(W(n,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),r=_(W(n,["[data-bp-phone]","[data-bitpalm-phone]"])),a=d(W(n,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),m=d(W(n,["[data-bp-first-name]","[data-bitpalm-first-name]"])),y=d(W(n,["[data-bp-last-name]","[data-bitpalm-last-name]"])),p=d(W(n,["[data-bp-company]","[data-bitpalm-company]"]));for(let c of Array.from(n.elements)){if(!(c instanceof HTMLInputElement||c instanceof HTMLTextAreaElement||c instanceof HTMLSelectElement)||c.disabled||c instanceof HTMLInputElement&&xt.has(c.type.toLowerCase()))continue;let i=At(c),ie=c.hasAttribute("data-bp-email")||c.hasAttribute("data-bitpalm-email")||c.hasAttribute("data-bp-phone")||c.hasAttribute("data-bitpalm-phone")||c.hasAttribute("data-bp-name")||c.hasAttribute("data-bitpalm-name")||c.hasAttribute("data-bp-full-name")||c.hasAttribute("data-bitpalm-full-name")||c.hasAttribute("data-bp-first-name")||c.hasAttribute("data-bitpalm-first-name")||c.hasAttribute("data-bp-last-name")||c.hasAttribute("data-bitpalm-last-name")||c.hasAttribute("data-bp-company")||c.hasAttribute("data-bitpalm-company")||!!i;if(c instanceof HTMLInputElement&&c.type.toLowerCase()==="hidden"&&!ie)continue;let f=d(c.value);if(!f)continue;let J=c instanceof HTMLInputElement?c.type.toLowerCase():"",u=Lt(It(n,c).join(" "));if(!t&&i==="email"&&I(f)){t=f.toLowerCase();continue}if(!r&&(i==="phone"||i==="tel"||i==="mobile"||i==="whatsapp")){let S=_(f);if(S){r=S;continue}}if(!p&&i==="company"){p=d(f,160);continue}if(!m&&(i==="first-name"||i==="firstname")){m=d(f,100);continue}if(!y&&(i==="last-name"||i==="lastname"||i==="surname")){y=d(f,100);continue}if(!a&&(i==="name"||i==="full-name"||i==="fullname")){!I(f)&&!_(f)&&(a=d(f,140));continue}let T=J==="email"||N(u,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),H=J==="tel"||N(u,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),F=N(u,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),G=N(u,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),U=N(u,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),$=N(u,[" full name "," fullname "," contact name "," name "])&&!T&&!H;if(!t&&T&&I(f)){t=f.toLowerCase();continue}if(!r&&H){let S=_(f);if(S){r=S;continue}}if(!p&&F){p=d(f,160);continue}if(!m&&G){m=d(f,100);continue}if(!y&&U){y=d(f,100);continue}if(!a&&$&&!I(f)&&!_(f)){a=d(f,140);continue}!t&&I(f)&&(t=f.toLowerCase())}if(a&&(I(a)||_(a))&&(a=""),p&&(I(p)||_(p))&&(p=""),a||(a=d([m,y].filter(Boolean).join(" "),140)),a&&t&&a.toLowerCase()===t.toLowerCase()&&(a=""),!!!(t||r)&&!!!(a&&p))return null;let b={...a?{name:a}:{},...t?{email:t}:{},...r?{phone:r}:{},...p?{company:p}:{}};return Object.keys(b).length>0?b:null}function Pt(){if(typeof document<"u"){let n=document.documentElement.lang;if(n)return n.slice(0,2).toLowerCase()}return"en"}function xe(n,t=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(n,{timeout:t});return}setTimeout(n,Math.min(t,300))}function Te(){if(typeof window>"u")return!1;let n=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(n))return!0;let r=window.matchMedia("(pointer: coarse)").matches,a=window.matchMedia("(hover: none)").matches,m=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return r&&a&&m<=900}function lt(n){let{slug:t,locale:r=Pt(),baseUrl:a=Et,token:m,zIndex:y=9999,autoIdentify:p=!0}=n,l=document,g=oe(n.theme),b=g==="auto"?Y():g,c=null,i=l.createElement("iframe"),ie=`${a}/t/${t}/widget`,f=new URLSearchParams({locale:r,theme:b});m&&f.set("token",m),i.src=`${ie}?${f.toString()}`,i.allow="clipboard-write; microphone",i.setAttribute("allowtransparency","true"),i.loading="lazy",i.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${y};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;let J=new URL(i.src).origin,u=l.createElement("div");if(u.setAttribute("role","button"),u.setAttribute("aria-label","Chat"),u.style.cssText=`position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${y-1};background:#171717;box-shadow:${at};transition:transform .2s,opacity .3s;opacity:0;`,u.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',u.onmouseenter=()=>{u.style.transform="scale(1.05)"},u.onmouseleave=()=>{u.style.transform="scale(1)"},u.onclick=()=>q(),l.body.appendChild(u),!l.getElementById("_bp_fade")){let e=l.createElement("style");e.id="_bp_fade",e.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",l.head.appendChild(e)}let T=null,H=!1,F=!1,G=!1,U=!1,$=!1,S=()=>{G||(G=!0,l.body.appendChild(i))},K=!1,se=0,V={overflow:"",overscrollBehavior:""},E={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},Se=()=>{if(K||!Te())return;let s=l.documentElement,o=l.body;se=window.scrollY||window.pageYOffset||0,V.overflow=s.style.overflow,V.overscrollBehavior=s.style.overscrollBehavior,E.overflow=o.style.overflow,E.overscrollBehavior=o.style.overscrollBehavior,E.position=o.style.position,E.top=o.style.top,E.left=o.style.left,E.right=o.style.right,E.width=o.style.width,s.style.overflow="hidden",s.style.overscrollBehavior="none",o.style.overflow="hidden",o.style.overscrollBehavior="none",o.style.position="fixed",o.style.top=`-${se}px`,o.style.left="0",o.style.right="0",o.style.width="100%",K=!0},O=()=>{if(!K)return;let e=l.documentElement,s=l.body;e.style.overflow=V.overflow,e.style.overscrollBehavior=V.overscrollBehavior,s.style.overflow=E.overflow,s.style.overscrollBehavior=E.overscrollBehavior,s.style.position=E.position,s.style.top=E.top,s.style.left=E.left,s.style.right=E.right,s.style.width=E.width,window.scrollTo(0,se),K=!1},Le=()=>{let e=Te();i.style.display==="none"&&(i.style.display=""),e?(i.style.width="100vw",i.style.height="100dvh",i.style.left="0",i.style.top="0",i.style.bottom="0",i.style.right="0",Se()):(i.style.width="420px",i.style.height="620px",i.style.bottom="24px",i.style.right="24px",i.style.left="",i.style.top="",O()),i.style.opacity="1",i.style.pointerEvents="auto"},C=()=>{T&&(T.remove(),T=null)},X=()=>{},ae=()=>{},R=!1,P=new Map;function re(e,s){let o=P.get(e);if(o)for(let h of o)try{h(s)}catch{}}let Ae=e=>{if(e.origin===J){if(e.data?.type==="bitpalm-widget-config"){F=!1,H=!0,i.style.display==="none"&&(i.style.display=""),e.data.primaryColor&&(u.style.background=e.data.primaryColor,u.style.boxShadow=e.data.chatShadow==="none"?"none":at);let s=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){u.innerHTML="";let o=l.createElement("span");o.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${s}`;let w=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");w?(w.querySelectorAll("script,foreignObject").forEach(B=>B.remove()),w.querySelectorAll("*").forEach(B=>{for(let M of[...B.attributes])(M.name.startsWith("on")||M.value&&M.value.includes("javascript:"))&&B.removeAttribute(M.name)}),w.setAttribute("width","24"),w.setAttribute("height","24"),w.style.display="block",o.appendChild(w)):o.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',u.appendChild(o)}else{let o=u.querySelector("svg");o&&(o.style.stroke=s)}u.style.display="flex",requestAnimationFrame(()=>{u.style.opacity="1"})}if(e.data?.type==="bitpalm-widget-resize"){let s=e.data.width>0,o=R;R=s,s&&!o&&re("widget_opened"),!s&&o&&re("widget_closed");let h=Te();s?(i.style.width=h?"100vw":`${e.data.width}px`,i.style.height=h?"100dvh":`${e.data.height}px`,h?(i.style.left="0",i.style.top="0",i.style.bottom="0",i.style.right="0",Se()):O(),i.style.opacity="1",i.style.pointerEvents="auto"):(O(),i.style.width="1px",i.style.height="1px",i.style.left="",i.style.top="",i.style.opacity="0",i.style.pointerEvents="none"),u.style.display=s?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(F||!H)return;C(),T=l.createElement("div"),T.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${y-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let s=(e.data.message||"").replace(/</g,"<");T.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${s}</p><div style="position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;"></div>`;let o=l.createElement("button");o.style.cssText="position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;",o.innerHTML="✕",o.onclick=h=>{h.stopPropagation(),C(),i.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},T.onclick=()=>{if(C(),u.style.display="none",Le(),S(),!U){$=!0;return}i.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:s},"*")},T.appendChild(o),l.body.appendChild(T)}e.data?.type==="bitpalm-trigger-hide"&&C(),e.data?.type==="bitpalm-request-context"&&X(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&re(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(F=!0,H=!1,u.style.display="none",C(),O(),i.style.display="none")}};window.addEventListener("message",Ae);let L=!1;try{L=localStorage.getItem(`${v}optout`)==="1"}catch{}let Z=`${v}vid`,x="";if(!L){try{x=localStorage.getItem(Z)||""}catch{}if(!x){let e=l.cookie.match(new RegExp(`(?:^|; )${Z}=([^;]+)`));x=e?decodeURIComponent(e[1]):""}x||(x=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(Z,x)}catch{}try{l.cookie=`${Z}=${encodeURIComponent(x)};path=/;max-age=31536000;SameSite=Lax`}catch{}}L||xe(()=>{try{let e=new URLSearchParams(location.search),s={};for(let A of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let w=e.get(A);w&&(s[A]=w)}let o=JSON.stringify({tenant_slug:t,visitor_id:x,url:location.href,referrer:l.referrer||void 0,...Object.keys(s).length>0?{utm:s}:{}}),h=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(h,new Blob([o],{type:"application/json"})):fetch(h,{method:"POST",body:o,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let le="",ce="",de=0;try{le=sessionStorage.getItem(ot)||"",ce=sessionStorage.getItem(it)||"";let e=parseInt(sessionStorage.getItem(st)||"0",10);Number.isFinite(e)&&e>0&&(de=e)}catch{}let _e=(e,s="")=>{if(L||!x)return;let o={},h=d(e.name,140),A=rt(e.email),w=_(e.phone),B=d(e.company,160),M=d(e.external_user_id,140),Ke=d(e.signature,260),he=Number(e.signed_at);if(h&&(o.name=h),A&&(o.email=A),w&&(o.phone=w),B&&(o.company=B),M&&(o.external_user_id=M),Ke&&(o.signature=Ke),Number.isFinite(he)&&he>0&&(o.signed_at=Math.floor(he)),(e.signature_version==="v1"||o.signature)&&(o.signature_version="v1"),(e.identify_source==="manual"||e.identify_source==="form")&&(o.identify_source=e.identify_source),!o.name&&!o.email&&!o.phone&&!o.company&&!o.external_user_id)return;let ne=St(o),ye=[s.toLowerCase(),ne].filter(Boolean).join("|"),be=Date.now();if(!(be-de<Tt&&(ye===le||ne===ce))){le=ye,ce=ne,de=be;try{sessionStorage.setItem(ot,ye),sessionStorage.setItem(it,ne),sessionStorage.setItem(st,String(be))}catch{}try{let Ve=JSON.stringify({tenant_slug:t,visitor_id:x,url:location.href,referrer:l.referrer||void 0,...o}),Xe=`${a}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(Xe,new Blob([Ve],{type:"application/json"})):fetch(Xe,{method:"POST",body:Ve,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},Ie=e=>{if(L||!p||!x)return;let s=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(s instanceof HTMLFormElement))return;let o=(s.getAttribute("data-bp-identify")||s.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(o==="off"||o==="false"||o==="0")return;let h=Ct(s);if(!h)return;let A=[s.getAttribute("id")||"",s.getAttribute("name")||"",s.getAttribute("action")||""].join("|");_e({...h,identify_source:"form"},A)};!L&&p&&l.addEventListener("submit",Ie,!0);let j=parseInt(sessionStorage.getItem(`${v}pages`)||"0")+1;sessionStorage.setItem(`${v}pages`,String(j));let k=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");k.push(location.href),k.length>20&&(k=k.slice(-20)),sessionStorage.setItem(`${v}hist`,JSON.stringify(k));let Ce=Date.now(),Q=parseInt(sessionStorage.getItem(`${v}site_start`)||"0");Q||(Q=Ce,sessionStorage.setItem(`${v}site_start`,String(Q)));let Pe=[];X=()=>{let e=!1;try{e=!!localStorage.getItem(`${v}visited`)}catch{e=!1}if(i.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:l.title,returning:e,pageCount:j,pageHistory:k,loadedAt:Ce,siteStart:Q,locale:r,visitorId:L?"":x},"*"),De(),!e&&!L)try{localStorage.setItem(`${v}visited`,"1")}catch{}},i.addEventListener("load",()=>{U=!0,X(),[120,450,1100].forEach(e=>{let s=setTimeout(()=>X(),e);Pe.push(s)}),$&&($=!1,ae())}),l.readyState==="loading"?l.addEventListener("DOMContentLoaded",()=>xe(S,1600),{once:!0}):xe(S,1600);let ke=history.pushState.bind(history),Be=history.replaceState.bind(history),ee=()=>{j++,sessionStorage.setItem(`${v}pages`,String(j));let e=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),k=e,sessionStorage.setItem(`${v}hist`,JSON.stringify(e)),i.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:l.title,pageCount:j,pageHistory:e,loadedAt:Date.now()},"*"),!L)try{let s=JSON.stringify({tenant_slug:t,visitor_id:x,url:location.href}),o=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(o,new Blob([s],{type:"application/json"})):fetch(o,{method:"POST",body:s,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){ke(...e),ee()},history.replaceState=function(...e){Be(...e),ee()},window.addEventListener("popstate",ee);let Me=-1,me,He=()=>{clearTimeout(me),me=setTimeout(()=>{let e=Math.max(l.documentElement.scrollHeight,l.body.scrollHeight)-window.innerHeight,s=e>0?Math.round(window.scrollY/e*100):100;s!==Me&&(Me=s,i.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:s},"*"))},500)};window.addEventListener("scroll",He,{passive:!0});let $e=e=>{e.clientY<=0&&i.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};l.addEventListener("mouseout",$e);let ue,Oe=!1,fe=()=>{clearTimeout(ue),!Oe&&(ue=setTimeout(()=>{Oe=!0,i.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},Re=["mousemove","keydown","scroll","touchstart"];Re.forEach(e=>l.addEventListener(e,fe,{passive:!0})),fe(),ae=()=>{i.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=i.src.split("#")[0];i.src=`${e}#bp-open-${Date.now()}`};let q=()=>{if(u.style.display="none",C(),Le(),S(),!U){$=!0;return}ae()},pe=()=>{O(),i.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Ne=e=>{!e||typeof e!="object"||_e({external_user_id:d(e.externalUserId,140)||void 0,name:d(e.name,140)||void 0,email:rt(e.email)||void 0,phone:_(e.phone)||void 0,company:d(e.company,160)||void 0,signature:d(e.signature,260)||void 0,signed_at:Number.isFinite(Number(e.signedAt))?Math.floor(Number(e.signedAt)):void 0,signature_version:e.signatureVersion==="v1"?"v1":void 0,identify_source:"manual"},"manual")},ct=()=>{R?pe():q()},dt=()=>R,We=e=>{if(!e||typeof e!="string")return;let s=e.trim().slice(0,1e4);s&&(R||q(),setTimeout(()=>{i.contentWindow?.postMessage({type:"bitpalm-send-message",message:s},"*")},R?50:500))};function De(){i.contentWindow?.postMessage({type:"bitpalm-theme",theme:b},"*")}let te=e=>{e!==b&&(b=e,De())},Fe=e=>{g=oe(e),c?.(),c=null,g==="auto"?(c=Ee(te),te(Y())):te(g)};g==="auto"&&(c=Ee(te));let Ue=e=>{let s=e.detail;if(!s||typeof s!="object")return;let o=d(s.slug,120);o&&o!==t||Fe(oe(s.theme))};window.addEventListener("bitpalm-theme",Ue);let z={},je=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;z={...z,...e};let s=JSON.stringify(z);s.length>nt&&console.warn(`[BitPalm] Custom context exceeds ${nt} bytes (${s.length}). It may be truncated.`),i.contentWindow?.postMessage({type:"bitpalm-custom-context",data:z},"*")},mt=()=>{z={},i.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},qe=e=>{let o=e.detail;if(!o||typeof o!="object")return;let h=d(o.slug,120);if(h&&h!==t)return;let{slug:A,...w}=o;je(w)};window.addEventListener("bitpalm-context",qe);let ze=e=>{let o=e.detail;if(!o||typeof o!="object")return;let h=d(o.slug,120);h&&h!==t||Ne(o)};window.addEventListener("bitpalm-identify",ze);let ge=e=>{let s=e.detail,o=d(s?.slug,120);return!o||o===t},Ye=e=>{ge(e)&&q()},Je=e=>{ge(e)&&pe()},Ge=e=>{if(!ge(e))return;let s=e.detail?.message;typeof s=="string"&&We(s)};return window.addEventListener("bitpalm-open",Ye),window.addEventListener("bitpalm-close",Je),window.addEventListener("bitpalm-send",Ge),{open:q,close:pe,toggle:ct,isOpen:dt,identify:Ne,context:je,resetContext:mt,send:We,on:(e,s)=>(P.has(e)||P.set(e,new Set),P.get(e).add(s),()=>P.get(e)?.delete(s)),off:(e,s)=>{P.get(e)?.delete(s)},setTheme:Fe,destroy:()=>{window.removeEventListener("message",Ae),window.removeEventListener("scroll",He),window.removeEventListener("popstate",ee),l.removeEventListener("mouseout",$e),l.removeEventListener("submit",Ie,!0),Re.forEach(e=>l.removeEventListener(e,fe)),clearTimeout(me),clearTimeout(ue),Pe.forEach(e=>clearTimeout(e)),history.pushState=ke,history.replaceState=Be,window.removeEventListener("bitpalm-identify",ze),window.removeEventListener("bitpalm-context",qe),window.removeEventListener("bitpalm-theme",Ue),window.removeEventListener("bitpalm-open",Ye),window.removeEventListener("bitpalm-close",Je),window.removeEventListener("bitpalm-send",Ge),c?.(),P.clear(),O(),C(),u.remove(),i.remove()}}}function kt(n){let t=(0,D.useRef)(null),r=(0,D.useRef)(!1);return(0,D.useEffect)(()=>{t.current?.setTheme(n.theme??"auto")},[n.theme]),(0,D.useEffect)(()=>{if(!r.current)return r.current=!0,t.current=lt(n),()=>{t.current?.destroy(),t.current=null,r.current=!1}},[]),null}0&&(module.exports={BitPalmAgent});
|
|
2
2
|
//# sourceMappingURL=react.cjs.map
|
package/dist/react.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type BitPalmAgentProps = BitPalmAgentOptions;\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n instanceRef.current = createWidget(props);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ai\";\nconst STORAGE_PREFIX = \"_bp_\";\nconst IGNORED_INPUT_TYPES = new Set([\"password\", \"file\", \"checkbox\", \"radio\", \"submit\", \"button\", \"reset\", \"image\"]);\nconst IDENTITY_DEDUPE_WINDOW_MS = 8_000;\nconst CUSTOM_CONTEXT_MAX_BYTES = 4096;\nconst IDENTITY_SIGNATURE_KEY = `${STORAGE_PREFIX}identify_signature`;\nconst IDENTITY_FINGERPRINT_KEY = `${STORAGE_PREFIX}identify_fingerprint`;\nconst IDENTITY_SENT_AT_KEY = `${STORAGE_PREFIX}identify_sent_at`;\n\ntype FormFieldElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n\ntype IdentityPayload = {\n name?: string;\n email?: string;\n phone?: string;\n company?: string;\n};\n\ntype IdentifyRequestPayload = IdentityPayload & {\n external_user_id?: string;\n signature?: string;\n signed_at?: number;\n signature_version?: \"v1\";\n identify_source?: \"manual\" | \"form\";\n};\n\nfunction buildIdentityFingerprint(payload: IdentifyRequestPayload): string {\n return [\n payload.external_user_id || \"\",\n payload.email || \"\",\n payload.phone || \"\",\n payload.name || \"\",\n payload.company || \"\",\n payload.signature || \"\",\n payload.signed_at != null ? String(payload.signed_at) : \"\",\n payload.signature_version || \"\",\n payload.identify_source || \"\",\n ]\n .join(\"|\")\n .toLowerCase();\n}\n\nfunction normalizeText(value: string | null | undefined, maxLen = 180): string {\n if (!value) return \"\";\n return value.replace(/\\s+/g, \" \").trim().slice(0, maxLen);\n}\n\nfunction normalizeTokens(value: string | null | undefined): string {\n if (!value) return \"\";\n return ` ${value.toLowerCase().replace(/[_-]+/g, \" \").replace(/[^a-z0-9\\s@.]/g, \" \").replace(/\\s+/g, \" \").trim()} `;\n}\n\nfunction includesAny(haystack: string, needles: string[]): boolean {\n for (const needle of needles) {\n if (haystack.includes(needle)) return true;\n }\n return false;\n}\n\nfunction isEmail(value: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/i.test(value);\n}\n\nfunction normalizePhone(value: string | null | undefined): string {\n const trimmed = normalizeText(value, 50);\n if (!trimmed) return \"\";\n const hasPlus = trimmed.startsWith(\"+\");\n const digits = trimmed.replace(/\\D/g, \"\");\n if (digits.length < 6) return \"\";\n return `${hasPlus ? \"+\" : \"\"}${digits.slice(0, 20)}`;\n}\n\nfunction normalizeEmail(value: string | null | undefined): string {\n const normalized = normalizeText(value, 140).toLowerCase();\n if (!normalized) return \"\";\n if (!isEmail(normalized)) return \"\";\n return normalized;\n}\n\nfunction getExplicitValue(form: HTMLFormElement, selectors: string[]): string {\n for (const selector of selectors) {\n const el = form.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(selector);\n const value = normalizeText(el?.value);\n if (value) return value;\n }\n return \"\";\n}\n\nfunction getFieldHint(el: FormFieldElement): string {\n return normalizeText(el.getAttribute(\"data-bp-field\") || el.getAttribute(\"data-bitpalm-field\"), 64)\n .toLowerCase()\n .replace(/[_\\s]+/g, \"-\");\n}\n\nfunction escapeAttrSelectorValue(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction collectElementTokenParts(form: HTMLFormElement, el: FormFieldElement): string[] {\n const parts: string[] = [];\n const pushText = (value: string | null | undefined, maxLen = 140) => {\n const clean = normalizeText(value, maxLen);\n if (clean) parts.push(clean);\n };\n\n pushText(el.name);\n pushText(el.id);\n pushText(el.getAttribute(\"autocomplete\"));\n pushText(el.getAttribute(\"placeholder\"));\n pushText(el.getAttribute(\"aria-label\"));\n pushText(el.getAttribute(\"data-field\"));\n pushText(el.getAttribute(\"data-name\"));\n pushText(el.getAttribute(\"data-label\"));\n pushText(el.getAttribute(\"data-bp-field\"));\n pushText(el.getAttribute(\"data-bitpalm-field\"));\n\n const seenLabels = new Set<string>();\n const pushLabel = (value: string | null | undefined) => {\n const label = normalizeText(value, 200);\n if (!label || seenLabels.has(label)) return;\n seenLabels.add(label);\n parts.push(label);\n };\n\n for (const label of Array.from(el.labels || [])) {\n pushLabel(label.textContent);\n }\n\n if (el.id) {\n const forLabel = form.querySelector(`label[for=\"${escapeAttrSelectorValue(el.id)}\"]`);\n pushLabel(forLabel?.textContent);\n }\n\n const nearestLabel = el.closest(\"label\");\n pushLabel(nearestLabel?.textContent);\n\n const ariaLabelledBy = el.getAttribute(\"aria-labelledby\");\n if (ariaLabelledBy) {\n for (const id of ariaLabelledBy.split(/\\s+/)) {\n if (!id) continue;\n const ref = form.ownerDocument.getElementById(id);\n pushLabel(ref?.textContent);\n }\n }\n\n return parts;\n}\n\nfunction extractIdentityFromForm(form: HTMLFormElement): IdentityPayload | null {\n let email = normalizeText(getExplicitValue(form, [\n \"[data-bp-email]\",\n \"[data-bitpalm-email]\",\n ]), 140).toLowerCase();\n\n let phone = normalizePhone(getExplicitValue(form, [\n \"[data-bp-phone]\",\n \"[data-bitpalm-phone]\",\n ]));\n\n let name = normalizeText(getExplicitValue(form, [\n \"[data-bp-name]\",\n \"[data-bitpalm-name]\",\n \"[data-bp-full-name]\",\n \"[data-bitpalm-full-name]\",\n ]));\n\n let firstName = normalizeText(getExplicitValue(form, [\n \"[data-bp-first-name]\",\n \"[data-bitpalm-first-name]\",\n ]));\n\n let lastName = normalizeText(getExplicitValue(form, [\n \"[data-bp-last-name]\",\n \"[data-bitpalm-last-name]\",\n ]));\n\n let company = normalizeText(getExplicitValue(form, [\n \"[data-bp-company]\",\n \"[data-bitpalm-company]\",\n ]));\n\n for (const rawEl of Array.from(form.elements)) {\n if (!(rawEl instanceof HTMLInputElement || rawEl instanceof HTMLTextAreaElement || rawEl instanceof HTMLSelectElement)) continue;\n if (rawEl.disabled) continue;\n if (rawEl instanceof HTMLInputElement && IGNORED_INPUT_TYPES.has(rawEl.type.toLowerCase())) continue;\n const fieldHint = getFieldHint(rawEl);\n\n const explicitField =\n rawEl.hasAttribute(\"data-bp-email\") ||\n rawEl.hasAttribute(\"data-bitpalm-email\") ||\n rawEl.hasAttribute(\"data-bp-phone\") ||\n rawEl.hasAttribute(\"data-bitpalm-phone\") ||\n rawEl.hasAttribute(\"data-bp-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-name\") ||\n rawEl.hasAttribute(\"data-bp-full-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-full-name\") ||\n rawEl.hasAttribute(\"data-bp-first-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-first-name\") ||\n rawEl.hasAttribute(\"data-bp-last-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-last-name\") ||\n rawEl.hasAttribute(\"data-bp-company\") ||\n rawEl.hasAttribute(\"data-bitpalm-company\") ||\n !!fieldHint;\n\n if (rawEl instanceof HTMLInputElement && rawEl.type.toLowerCase() === \"hidden\" && !explicitField) continue;\n\n const value = normalizeText(rawEl.value);\n if (!value) continue;\n\n const type = rawEl instanceof HTMLInputElement ? rawEl.type.toLowerCase() : \"\";\n const tokens = normalizeTokens(collectElementTokenParts(form, rawEl).join(\" \"));\n\n if (!email && fieldHint === \"email\" && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && (fieldHint === \"phone\" || fieldHint === \"tel\" || fieldHint === \"mobile\" || fieldHint === \"whatsapp\")) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && fieldHint === \"company\") {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && (fieldHint === \"first-name\" || fieldHint === \"firstname\")) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && (fieldHint === \"last-name\" || fieldHint === \"lastname\" || fieldHint === \"surname\")) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && (fieldHint === \"name\" || fieldHint === \"full-name\" || fieldHint === \"fullname\")) {\n if (!isEmail(value) && !normalizePhone(value)) name = normalizeText(value, 140);\n continue;\n }\n\n const emailLike = type === \"email\" || includesAny(tokens, [\" email \", \" e mail \", \" mail \", \" email adresse \", \" mailadresse \", \" correo \"]);\n const phoneLike = type === \"tel\" || includesAny(tokens, [\" phone \", \" phone number \", \" mobile \", \" tel \", \" telefon \", \" telefonnummer \", \" whatsapp \", \" handy \", \" kontakt \", \" nummer \"]);\n const companyLike = includesAny(tokens, [\" company \", \" company name \", \" firma \", \" firmenname \", \" organization \", \" organisation \", \" business \", \" unternehmen \", \" agency \", \" brokerage \"]);\n const firstNameLike = includesAny(tokens, [\" first name \", \" firstname \", \" given name \", \" givenname \", \" vorname \", \" fname \"]);\n const lastNameLike = includesAny(tokens, [\" last name \", \" lastname \", \" family name \", \" familyname \", \" surname \", \" nachname \", \" lname \"]);\n const fullNameLike = includesAny(tokens, [\" full name \", \" fullname \", \" contact name \", \" name \"]) && !emailLike && !phoneLike;\n\n if (!email && emailLike && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && phoneLike) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && companyLike) {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && firstNameLike) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && lastNameLike) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && fullNameLike && !isEmail(value) && !normalizePhone(value)) {\n name = normalizeText(value, 140);\n continue;\n }\n\n if (!email && isEmail(value)) {\n email = value.toLowerCase();\n }\n }\n\n if (name && (isEmail(name) || normalizePhone(name))) {\n name = \"\";\n }\n if (company && (isEmail(company) || normalizePhone(company))) {\n company = \"\";\n }\n\n if (!name) {\n name = normalizeText([firstName, lastName].filter(Boolean).join(\" \"), 140);\n }\n\n if (name && email && name.toLowerCase() === email.toLowerCase()) {\n name = \"\";\n }\n\n const hasContactSignal = !!(email || phone);\n const hasStrongProfileSignal = !!(name && company);\n if (!hasContactSignal && !hasStrongProfileSignal) {\n return null;\n }\n\n const identity: IdentityPayload = {\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n ...(phone ? { phone } : {}),\n ...(company ? { company } : {}),\n };\n\n return Object.keys(identity).length > 0 ? identity : null;\n}\n\nfunction detectLocale(): string {\n if (typeof document !== \"undefined\") {\n const lang = document.documentElement.lang;\n if (lang) return lang.slice(0, 2).toLowerCase();\n }\n return \"en\";\n}\n\nfunction runWhenIdle(task: () => void, timeout = 1200) {\n if (typeof window !== \"undefined\" && \"requestIdleCallback\" in window) {\n (\n window as unknown as {\n requestIdleCallback: (cb: () => void, opts?: { timeout?: number }) => number;\n }\n ).requestIdleCallback(task, { timeout });\n return;\n }\n setTimeout(task, Math.min(timeout, 300));\n}\n\nfunction isMobileWidgetDevice(): boolean {\n if (typeof window === \"undefined\") return false;\n const userAgent = typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n const isMobileUa = /Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(userAgent);\n if (isMobileUa) return true;\n\n const coarsePointer = window.matchMedia(\"(pointer: coarse)\").matches;\n const noHover = window.matchMedia(\"(hover: none)\").matches;\n const minScreenSide = Math.min(\n window.screen?.width || window.innerWidth,\n window.screen?.height || window.innerHeight,\n );\n return coarsePointer && noHover && minScreenSide <= 900;\n}\n\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n token,\n zIndex = 9999,\n autoIdentify = true,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n const qs = new URLSearchParams({ locale });\n if (token) qs.set(\"token\", token);\n iframe.src = `${widgetUrl}?${qs.toString()}`;\n // Explicitly grant the iframe permission to use the visitor's\n // microphone — required for the voice-input feature on cross-origin\n // iframes. Without this, Chrome silently denies getUserMedia /\n // SpeechRecognition without ever prompting the user.\n iframe.allow = \"clipboard-write; microphone\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\n iframe.loading = \"lazy\";\n iframe.style.cssText = `position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${zIndex};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;\n\n const origin = new URL(iframe.src).origin;\n\n // --- Native launcher button ---\n const btn = d.createElement(\"div\");\n btn.setAttribute(\"role\", \"button\");\n btn.setAttribute(\"aria-label\", \"Chat\");\n btn.style.cssText = `position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${zIndex - 1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s,opacity .3s;opacity:0;`;\n btn.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"black\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n btn.onmouseenter = () => { btn.style.transform = \"scale(1.1)\"; };\n btn.onmouseleave = () => { btn.style.transform = \"scale(1)\"; };\n btn.onclick = () => openWidget();\n d.body.appendChild(btn);\n\n // --- Fade animation for trigger bubbles ---\n if (!d.getElementById(\"_bp_fade\")) {\n const s = d.createElement(\"style\");\n s.id = \"_bp_fade\";\n s.textContent = \"@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\";\n d.head.appendChild(s);\n }\n\n // --- Trigger bubble ---\n let bubble: HTMLDivElement | null = null;\n let launcherReady = false;\n let widgetBlocked = false;\n let iframeMounted = false;\n let iframeReady = false;\n let pendingOpen = false;\n const mountIframe = () => {\n if (iframeMounted) return;\n iframeMounted = true;\n d.body.appendChild(iframe);\n };\n let mobileScrollLocked = false;\n let scrollLockY = 0;\n const prevHtmlStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n };\n const prevBodyStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n position: \"\",\n top: \"\",\n left: \"\",\n right: \"\",\n width: \"\",\n };\n const lockMobilePageScroll = () => {\n if (mobileScrollLocked) return;\n const mobile = isMobileWidgetDevice();\n if (!mobile) return;\n const html = d.documentElement;\n const body = d.body;\n scrollLockY = window.scrollY || window.pageYOffset || 0;\n prevHtmlStyle.overflow = html.style.overflow;\n prevHtmlStyle.overscrollBehavior = html.style.overscrollBehavior;\n prevBodyStyle.overflow = body.style.overflow;\n prevBodyStyle.overscrollBehavior = body.style.overscrollBehavior;\n prevBodyStyle.position = body.style.position;\n prevBodyStyle.top = body.style.top;\n prevBodyStyle.left = body.style.left;\n prevBodyStyle.right = body.style.right;\n prevBodyStyle.width = body.style.width;\n html.style.overflow = \"hidden\";\n html.style.overscrollBehavior = \"none\";\n body.style.overflow = \"hidden\";\n body.style.overscrollBehavior = \"none\";\n body.style.position = \"fixed\";\n body.style.top = `-${scrollLockY}px`;\n body.style.left = \"0\";\n body.style.right = \"0\";\n body.style.width = \"100%\";\n mobileScrollLocked = true;\n };\n const unlockMobilePageScroll = () => {\n if (!mobileScrollLocked) return;\n const html = d.documentElement;\n const body = d.body;\n html.style.overflow = prevHtmlStyle.overflow;\n html.style.overscrollBehavior = prevHtmlStyle.overscrollBehavior;\n body.style.overflow = prevBodyStyle.overflow;\n body.style.overscrollBehavior = prevBodyStyle.overscrollBehavior;\n body.style.position = prevBodyStyle.position;\n body.style.top = prevBodyStyle.top;\n body.style.left = prevBodyStyle.left;\n body.style.right = prevBodyStyle.right;\n body.style.width = prevBodyStyle.width;\n window.scrollTo(0, scrollLockY);\n mobileScrollLocked = false;\n };\n const prepareIframeForOpen = () => {\n const mobile = isMobileWidgetDevice();\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (mobile) {\n iframe.style.width = \"100vw\";\n iframe.style.height = \"100dvh\";\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n // Match desktop widget target size so the opening animation is visible from frame 1.\n iframe.style.width = \"420px\";\n iframe.style.height = \"620px\";\n iframe.style.bottom = \"24px\";\n iframe.style.right = \"24px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n };\n const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\n };\n let sendParentContext = () => {};\n let sendOpenSignal = () => {};\n\n // --- Widget state & event bus ---\n let widgetIsOpen = false;\n const eventListeners = new Map<BitPalmEventType, Set<BitPalmEventCallback>>();\n\n function emit(event: BitPalmEventType, data?: Record<string, unknown>) {\n const listeners = eventListeners.get(event);\n if (!listeners) return;\n for (const cb of listeners) {\n try { cb(data); } catch { /* don't let listener errors break the widget */ }\n }\n }\n\n // --- postMessage handler ---\n const handleMessage = (e: MessageEvent) => {\n if (e.origin !== origin) return;\n\n // Widget config (colors, icon)\n if (e.data?.type === \"bitpalm-widget-config\") {\n widgetBlocked = false;\n launcherReady = true;\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (e.data.primaryColor) {\n btn.style.background = e.data.primaryColor;\n btn.style.boxShadow = e.data.chatShadow === \"none\" ? \"none\" : `0 0 15px ${e.data.primaryColor}50`;\n }\n const ic = e.data.chatButtonIconColor || \"black\";\n if (e.data.chatButtonIconSvg) {\n btn.innerHTML = \"\";\n const sp = d.createElement(\"span\");\n sp.style.cssText = `display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${ic}`;\n const parser = new DOMParser();\n const doc = parser.parseFromString(e.data.chatButtonIconSvg, \"image/svg+xml\");\n const svg = doc.querySelector(\"svg\");\n if (svg) {\n // Remove dangerous elements and attributes\n svg.querySelectorAll(\"script,foreignObject\").forEach(el => el.remove());\n svg.querySelectorAll(\"*\").forEach(el => {\n for (const attr of [...el.attributes]) {\n if (attr.name.startsWith(\"on\") || (attr.value && attr.value.includes(\"javascript:\"))) {\n el.removeAttribute(attr.name);\n }\n }\n });\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\n sp.appendChild(svg);\n } else {\n // Fallback: use default icon\n sp.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n }\n btn.appendChild(sp);\n } else {\n const sv = btn.querySelector(\"svg\");\n if (sv) (sv as SVGElement).style.stroke = ic;\n }\n btn.style.display = \"flex\";\n // Fade in after styles are applied\n requestAnimationFrame(() => { btn.style.opacity = \"1\"; });\n }\n\n // Resize — use full viewport on mobile\n if (e.data?.type === \"bitpalm-widget-resize\") {\n const isOpen = e.data.width > 0;\n const wasOpen = widgetIsOpen;\n widgetIsOpen = isOpen;\n if (isOpen && !wasOpen) emit(\"widget_opened\");\n if (!isOpen && wasOpen) emit(\"widget_closed\");\n const mobile = isMobileWidgetDevice();\n if (isOpen) {\n iframe.style.width = mobile ? \"100vw\" : `${e.data.width}px`;\n iframe.style.height = mobile ? \"100dvh\" : `${e.data.height}px`;\n if (mobile) {\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\n unlockMobilePageScroll();\n iframe.style.width = \"1px\";\n iframe.style.height = \"1px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n iframe.style.opacity = \"0\";\n iframe.style.pointerEvents = \"none\";\n }\n btn.style.display = isOpen ? \"none\" : \"flex\";\n }\n\n // Trigger bubble show\n if (e.data?.type === \"bitpalm-trigger-show\") {\n if (widgetBlocked || !launcherReady) return;\n removeBubble();\n bubble = d.createElement(\"div\");\n bubble.style.cssText = `position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${zIndex - 1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;\n const msg = (e.data.message || \"\").replace(/</g, \"<\");\n bubble.innerHTML = `<p style=\"font-size:14px;color:#1f2937;margin:0;\">${msg}</p><div style=\"position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;\"></div>`;\n const close = d.createElement(\"button\");\n close.style.cssText = \"position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;\";\n close.innerHTML = \"✕\";\n close.onclick = (ev) => { ev.stopPropagation(); removeBubble(); iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-dismiss\" }, \"*\"); };\n bubble.onclick = () => {\n removeBubble();\n btn.style.display = \"none\";\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\", message: msg }, \"*\");\n };\n bubble.appendChild(close);\n d.body.appendChild(bubble);\n }\n\n // Trigger bubble hide\n if (e.data?.type === \"bitpalm-trigger-hide\") { removeBubble(); }\n\n // Iframe requests latest parent context (avoids first-load race conditions)\n if (e.data?.type === \"bitpalm-request-context\") {\n sendParentContext();\n }\n\n // Chat events from iframe → emit to SDK listeners\n if (e.data?.type === \"bitpalm-chat-event\" && e.data.event) {\n emit(e.data.event as BitPalmEventType, e.data.data);\n }\n\n // Widget blocked (excluded path or access denied) — hide button & iframe\n if (e.data?.type === \"bitpalm-widget-blocked\") {\n widgetBlocked = true;\n launcherReady = false;\n btn.style.display = \"none\";\n removeBubble();\n unlockMobilePageScroll();\n iframe.style.display = \"none\";\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // --- Privacy opt-out check ---\n let optedOut = false;\n try { optedOut = localStorage.getItem(`${STORAGE_PREFIX}optout`) === \"1\"; } catch { /* ignore */ }\n\n // --- Persistent Visitor ID (skip if opted out) ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\n if (!optedOut) {\n try { visitorId = localStorage.getItem(VID_KEY) || \"\"; } catch { /* ignore */ }\n if (!visitorId) {\n // Fallback: try reading from cookie\n const match = d.cookie.match(new RegExp(`(?:^|; )${VID_KEY}=([^;]+)`));\n visitorId = match ? decodeURIComponent(match[1]) : \"\";\n }\n if (!visitorId) {\n visitorId = crypto.randomUUID ? crypto.randomUUID() : (`${Date.now()}-${Math.random().toString(36).slice(2, 11)}`);\n }\n // Persist in both localStorage and cookie (cookie survives Safari ITP clearing localStorage)\n try { localStorage.setItem(VID_KEY, visitorId); } catch { /* ignore */ }\n try {\n const maxAge = 365 * 24 * 60 * 60; // 1 year\n d.cookie = `${VID_KEY}=${encodeURIComponent(visitorId)};path=/;max-age=${maxAge};SameSite=Lax`;\n } catch { /* ignore */ }\n }\n\n // --- Visitor beacon: track page view even without chat (skip if opted out) ---\n if (!optedOut) {\n runWhenIdle(() => {\n try {\n const utmParams = new URLSearchParams(location.search);\n const utm: Record<string, string> = {};\n for (const key of [\"utm_source\", \"utm_medium\", \"utm_campaign\", \"utm_term\", \"utm_content\"]) {\n const val = utmParams.get(key);\n if (val) utm[key] = val;\n }\n const beaconPayload = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...(Object.keys(utm).length > 0 ? { utm } : {}),\n });\n const beaconUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(beaconUrl, new Blob([beaconPayload], { type: \"application/json\" }));\n } else {\n fetch(beaconUrl, { method: \"POST\", body: beaconPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }, 2000);\n }\n\n // --- Auto-identify visitor from form submissions on host page ---\n let lastIdentitySignature = \"\";\n let lastIdentityFingerprint = \"\";\n let lastIdentitySentAt = 0;\n try {\n lastIdentitySignature = sessionStorage.getItem(IDENTITY_SIGNATURE_KEY) || \"\";\n lastIdentityFingerprint = sessionStorage.getItem(IDENTITY_FINGERPRINT_KEY) || \"\";\n const storedAt = parseInt(sessionStorage.getItem(IDENTITY_SENT_AT_KEY) || \"0\", 10);\n if (Number.isFinite(storedAt) && storedAt > 0) {\n lastIdentitySentAt = storedAt;\n }\n } catch {\n // ignore\n }\n\n const dispatchIdentify = (payloadInput: IdentifyRequestPayload, scopeSignature = \"\") => {\n if (optedOut || !visitorId) return;\n\n const payload: IdentifyRequestPayload = {};\n const name = normalizeText(payloadInput.name, 140);\n const email = normalizeEmail(payloadInput.email);\n const phone = normalizePhone(payloadInput.phone);\n const company = normalizeText(payloadInput.company, 160);\n const externalUserId = normalizeText(payloadInput.external_user_id, 140);\n const requestSignature = normalizeText(payloadInput.signature, 260);\n const signedAtRaw = Number(payloadInput.signed_at);\n\n if (name) payload.name = name;\n if (email) payload.email = email;\n if (phone) payload.phone = phone;\n if (company) payload.company = company;\n if (externalUserId) payload.external_user_id = externalUserId;\n if (requestSignature) payload.signature = requestSignature;\n if (Number.isFinite(signedAtRaw) && signedAtRaw > 0) {\n payload.signed_at = Math.floor(signedAtRaw);\n }\n if (payloadInput.signature_version === \"v1\" || payload.signature) {\n payload.signature_version = \"v1\";\n }\n if (payloadInput.identify_source === \"manual\" || payloadInput.identify_source === \"form\") {\n payload.identify_source = payloadInput.identify_source;\n }\n\n if (!payload.name && !payload.email && !payload.phone && !payload.company && !payload.external_user_id) {\n return;\n }\n\n const identityFingerprint = buildIdentityFingerprint(payload);\n const dedupeSignature = [scopeSignature.toLowerCase(), identityFingerprint].filter(Boolean).join(\"|\");\n\n const now = Date.now();\n const insideDedupWindow = now - lastIdentitySentAt < IDENTITY_DEDUPE_WINDOW_MS;\n if (insideDedupWindow && (dedupeSignature === lastIdentitySignature || identityFingerprint === lastIdentityFingerprint)) {\n return;\n }\n\n lastIdentitySignature = dedupeSignature;\n lastIdentityFingerprint = identityFingerprint;\n lastIdentitySentAt = now;\n try {\n sessionStorage.setItem(IDENTITY_SIGNATURE_KEY, dedupeSignature);\n sessionStorage.setItem(IDENTITY_FINGERPRINT_KEY, identityFingerprint);\n sessionStorage.setItem(IDENTITY_SENT_AT_KEY, String(now));\n } catch {\n // ignore\n }\n\n try {\n const requestBody = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...payload,\n });\n const identifyUrl = `${baseUrl}/api/widget/identify`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(identifyUrl, new Blob([requestBody], { type: \"application/json\" }));\n } else {\n fetch(identifyUrl, { method: \"POST\", body: requestBody, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch {\n // ignore\n }\n };\n\n const handleFormSubmit = (event: Event) => {\n if (optedOut || !autoIdentify || !visitorId) return;\n\n const form = event.target instanceof HTMLFormElement\n ? event.target\n : event.target instanceof Element\n ? event.target.closest(\"form\")\n : null;\n if (!(form instanceof HTMLFormElement)) return;\n\n const formIdentifySetting = (form.getAttribute(\"data-bp-identify\") || form.getAttribute(\"data-bitpalm-identify\") || \"\").toLowerCase();\n if (formIdentifySetting === \"off\" || formIdentifySetting === \"false\" || formIdentifySetting === \"0\") return;\n\n const identity = extractIdentityFromForm(form);\n if (!identity) return;\n\n const formSignature = [\n form.getAttribute(\"id\") || \"\",\n form.getAttribute(\"name\") || \"\",\n form.getAttribute(\"action\") || \"\",\n ].join(\"|\");\n\n dispatchIdentify({ ...identity, identify_source: \"form\" }, formSignature);\n };\n\n if (!optedOut && autoIdentify) {\n d.addEventListener(\"submit\", handleFormSubmit, true);\n }\n\n // --- Visitor Intelligence: page counter + history ---\n let pageCount = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}pages`) || \"0\") + 1;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n\n let hist: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n hist.push(location.href);\n if (hist.length > 20) hist = hist.slice(-20);\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(hist));\n\n const loadedAt = Date.now();\n let siteStart = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}site_start`) || \"0\");\n if (!siteStart) {\n siteStart = loadedAt;\n sessionStorage.setItem(`${STORAGE_PREFIX}site_start`, String(siteStart));\n }\n\n const contextRetryTimers: ReturnType<typeof setTimeout>[] = [];\n sendParentContext = () => {\n let returning = false;\n try {\n returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\n } catch {\n returning = false;\n }\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-parent-context\",\n url: location.href,\n title: d.title,\n returning,\n pageCount,\n pageHistory: hist,\n loadedAt,\n siteStart,\n locale,\n visitorId: optedOut ? \"\" : visitorId,\n }, \"*\");\n if (!returning && !optedOut) {\n try { localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\"); } catch { /* ignore */ }\n }\n };\n\n // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n iframeReady = true;\n sendParentContext();\n [120, 450, 1100].forEach((delay) => {\n const timer = setTimeout(() => sendParentContext(), delay);\n contextRetryTimers.push(timer);\n });\n if (pendingOpen) {\n pendingOpen = false;\n sendOpenSignal();\n }\n });\n\n // Lazy-mount iframe after initial paint/idle to reduce impact on host load.\n if (d.readyState === \"loading\") {\n d.addEventListener(\"DOMContentLoaded\", () => runWhenIdle(mountIframe, 1600), { once: true });\n } else {\n runWhenIdle(mountIframe, 1600);\n }\n\n // --- SPA navigation detection ---\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n const onNav = () => {\n pageCount++;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n const h: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n h.push(location.href);\n if (h.length > 20) h.splice(0, h.length - 20);\n hist = h;\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(h));\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-page-change\",\n url: location.href,\n title: d.title,\n pageCount,\n pageHistory: h,\n loadedAt: Date.now(),\n }, \"*\");\n // Track page view for visitor (skip if opted out)\n if (!optedOut) {\n try {\n const navPayload = JSON.stringify({ tenant_slug: slug, visitor_id: visitorId, url: location.href });\n const navUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(navUrl, new Blob([navPayload], { type: \"application/json\" }));\n } else {\n fetch(navUrl, { method: \"POST\", body: navPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }\n };\n\n history.pushState = function (...args: Parameters<typeof history.pushState>) {\n origPush(...args);\n onNav();\n };\n history.replaceState = function (...args: Parameters<typeof history.replaceState>) {\n origReplace(...args);\n onNav();\n };\n window.addEventListener(\"popstate\", onNav);\n\n // --- Scroll depth tracking ---\n let lastScrollDepth = -1;\n let scrollTimeout: ReturnType<typeof setTimeout>;\n const handleScroll = () => {\n clearTimeout(scrollTimeout);\n scrollTimeout = setTimeout(() => {\n const total = Math.max(d.documentElement.scrollHeight, d.body.scrollHeight) - window.innerHeight;\n const pct = total > 0 ? Math.round(window.scrollY / total * 100) : 100;\n if (pct !== lastScrollDepth) {\n lastScrollDepth = pct;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-scroll-depth\", percent: pct }, \"*\");\n }\n }, 500);\n };\n window.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n // --- Exit intent ---\n const handleMouseOut = (e: MouseEvent) => {\n if (e.clientY <= 0) {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-exit-intent\" }, \"*\");\n }\n };\n d.addEventListener(\"mouseout\", handleMouseOut);\n\n // --- Inactivity detection (15s) ---\n let idleTimer: ReturnType<typeof setTimeout>;\n let idleFired = false;\n const resetIdle = () => {\n clearTimeout(idleTimer);\n if (idleFired) return;\n idleTimer = setTimeout(() => {\n idleFired = true;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-inactivity\" }, \"*\");\n }, 15_000);\n };\n const idleEvents = [\"mousemove\", \"keydown\", \"scroll\", \"touchstart\"] as const;\n idleEvents.forEach((ev) => d.addEventListener(ev, resetIdle, { passive: true }));\n resetIdle();\n\n sendOpenSignal = () => {\n // Primary: postMessage\n iframe.contentWindow?.postMessage({ type: \"bitpalm-open\" }, \"*\");\n // Fallback for mobile: trigger hashchange inside iframe (no reload)\n const base = iframe.src.split(\"#\")[0];\n iframe.src = `${base}#bp-open-${Date.now()}`;\n };\n\n // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n sendOpenSignal();\n };\n\n const closeWidget = () => {\n unlockMobilePageScroll();\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\n };\n\n const identify = (input: BitPalmIdentifyPayload) => {\n if (!input || typeof input !== \"object\") return;\n dispatchIdentify({\n external_user_id: normalizeText(input.externalUserId, 140) || undefined,\n name: normalizeText(input.name, 140) || undefined,\n email: normalizeEmail(input.email) || undefined,\n phone: normalizePhone(input.phone) || undefined,\n company: normalizeText(input.company, 160) || undefined,\n signature: normalizeText(input.signature, 260) || undefined,\n signed_at: Number.isFinite(Number(input.signedAt)) ? Math.floor(Number(input.signedAt)) : undefined,\n signature_version: input.signatureVersion === \"v1\" ? \"v1\" : undefined,\n identify_source: \"manual\",\n }, \"manual\");\n };\n\n const toggleWidget = () => {\n if (widgetIsOpen) closeWidget();\n else openWidget();\n };\n\n const getIsOpen = () => widgetIsOpen;\n\n const sendMessage = (message: string) => {\n if (!message || typeof message !== \"string\") return;\n const text = message.trim().slice(0, 10_000);\n if (!text) return;\n if (!widgetIsOpen) openWidget();\n // Small delay to ensure widget is open before sending\n setTimeout(() => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-send-message\", message: text }, \"*\");\n }, widgetIsOpen ? 50 : 500);\n };\n\n // --- Custom context for AI ---\n let customContext: Record<string, unknown> = {};\n\n const setCustomContext = (data: BitPalmCustomContext) => {\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return;\n customContext = { ...customContext, ...data };\n const json = JSON.stringify(customContext);\n if (json.length > CUSTOM_CONTEXT_MAX_BYTES) {\n console.warn(\n `[BitPalm] Custom context exceeds ${CUSTOM_CONTEXT_MAX_BYTES} bytes (${json.length}). It may be truncated.`\n );\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: customContext }, \"*\");\n };\n\n const clearCustomContext = () => {\n customContext = {};\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: {} }, \"*\");\n };\n\n const handleContextEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmCustomContext & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText((detail as Record<string, unknown>).slug as string, 120);\n if (targetSlug && targetSlug !== slug) return;\n const { slug: _s, ...contextData } = detail as Record<string, unknown>;\n setCustomContext(contextData);\n };\n\n window.addEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n\n const handleIdentifyEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmIdentifyPayload & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText(detail.slug, 120);\n if (targetSlug && targetSlug !== slug) return;\n identify(detail);\n };\n\n window.addEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n\n const onEvent = (event: BitPalmEventType, callback: BitPalmEventCallback): (() => void) => {\n if (!eventListeners.has(event)) eventListeners.set(event, new Set());\n eventListeners.get(event)!.add(callback);\n return () => eventListeners.get(event)?.delete(callback);\n };\n\n const offEvent = (event: BitPalmEventType, callback: BitPalmEventCallback) => {\n eventListeners.get(event)?.delete(callback);\n };\n\n const destroy = () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"scroll\", handleScroll);\n window.removeEventListener(\"popstate\", onNav);\n d.removeEventListener(\"mouseout\", handleMouseOut);\n d.removeEventListener(\"submit\", handleFormSubmit, true);\n idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n contextRetryTimers.forEach((t) => clearTimeout(t));\n history.pushState = origPush;\n history.replaceState = origReplace;\n window.removeEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n window.removeEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n eventListeners.clear();\n unlockMobilePageScroll();\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return {\n open: openWidget,\n close: closeWidget,\n toggle: toggleWidget,\n isOpen: getIsOpen,\n identify,\n context: setCustomContext,\n resetContext: clearCustomContext,\n send: sendMessage,\n on: onEvent,\n off: offEvent,\n destroy,\n };\n}\n"],"mappings":"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","names":["react_exports","__export","BitPalmAgent","__toCommonJS","import_react","DEFAULT_BASE_URL","STORAGE_PREFIX","IGNORED_INPUT_TYPES","IDENTITY_DEDUPE_WINDOW_MS","CUSTOM_CONTEXT_MAX_BYTES","IDENTITY_SIGNATURE_KEY","IDENTITY_FINGERPRINT_KEY","IDENTITY_SENT_AT_KEY","buildIdentityFingerprint","payload","normalizeText","value","maxLen","normalizeTokens","includesAny","haystack","needles","needle","isEmail","normalizePhone","trimmed","hasPlus","digits","normalizeEmail","normalized","getExplicitValue","form","selectors","selector","el","getFieldHint","escapeAttrSelectorValue","collectElementTokenParts","parts","pushText","clean","seenLabels","pushLabel","label","forLabel","nearestLabel","ariaLabelledBy","id","ref","extractIdentityFromForm","email","phone","name","firstName","lastName","company","rawEl","fieldHint","explicitField","type","tokens","emailLike","phoneLike","companyLike","firstNameLike","lastNameLike","fullNameLike","identity","detectLocale","lang","runWhenIdle","task","timeout","isMobileWidgetDevice","userAgent","coarsePointer","noHover","minScreenSide","createWidget","options","slug","locale","baseUrl","token","zIndex","autoIdentify","d","iframe","widgetUrl","qs","origin","btn","openWidget","s","bubble","launcherReady","widgetBlocked","iframeMounted","iframeReady","pendingOpen","mountIframe","mobileScrollLocked","scrollLockY","prevHtmlStyle","prevBodyStyle","lockMobilePageScroll","html","body","unlockMobilePageScroll","prepareIframeForOpen","mobile","removeBubble","sendParentContext","sendOpenSignal","widgetIsOpen","eventListeners","emit","event","data","listeners","cb","handleMessage","ic","sp","svg","attr","sv","isOpen","wasOpen","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","lastIdentitySignature","lastIdentityFingerprint","lastIdentitySentAt","storedAt","dispatchIdentify","payloadInput","scopeSignature","externalUserId","requestSignature","signedAtRaw","identityFingerprint","dedupeSignature","now","requestBody","identifyUrl","handleFormSubmit","formIdentifySetting","formSignature","pageCount","hist","loadedAt","siteStart","contextRetryTimers","returning","delay","timer","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","closeWidget","identify","input","toggleWidget","getIsOpen","sendMessage","message","text","customContext","setCustomContext","json","clearCustomContext","handleContextEvent","detail","targetSlug","_s","contextData","handleIdentifyEvent","callback","t","BitPalmAgent","props","instanceRef","mountedRef","createWidget"]}
|
|
1
|
+
{"version":3,"sources":["../src/react.ts","../src/theme.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type BitPalmAgentProps = BitPalmAgentOptions;\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n // The widget mounts once, later theme prop changes go through setTheme.\n useEffect(() => {\n instanceRef.current?.setTheme(props.theme ?? \"auto\");\n }, [props.theme]);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n instanceRef.current = createWidget(props);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","import type { BitPalmTheme } from \"./types\";\n\nexport type HostTheme = \"light\" | \"dark\";\n\nconst DARK_CLASSES = [\"dark\", \"dark-mode\", \"dark-theme\", \"theme-dark\"];\nconst LIGHT_CLASSES = [\"light\", \"light-mode\", \"light-theme\", \"theme-light\"];\nconst THEME_ATTRIBUTES = [\"data-theme\", \"data-color-scheme\", \"data-color-mode\", \"data-mode\", \"data-bs-theme\"];\nconst DARK_QUERY = \"(prefers-color-scheme: dark)\";\n\nexport function normalizeThemeSetting(value: unknown): BitPalmTheme {\n return value === \"light\" || value === \"dark\" ? value : \"auto\";\n}\n\n/** Theme set explicitly on an element: a class like \"dark\" or an attribute like data-theme=\"dark\". */\nfunction explicitTheme(el: Element | null): HostTheme | null {\n if (!el) return null;\n if (DARK_CLASSES.some((name) => el.classList.contains(name))) return \"dark\";\n if (LIGHT_CLASSES.some((name) => el.classList.contains(name))) return \"light\";\n for (const attr of THEME_ATTRIBUTES) {\n const value = (el.getAttribute(attr) || \"\").toLowerCase();\n if (value.includes(\"dark\")) return \"dark\";\n if (value.includes(\"light\")) return \"light\";\n }\n return null;\n}\n\nfunction channel(value: number): number {\n const s = value / 255;\n return s <= 0.03928 ? s / 12.92 : ((s + 0.055) / 1.055) ** 2.4;\n}\n\n/** Dark or light from an element's own opaque background color. */\nfunction backgroundTheme(el: Element | null, win: Window): HostTheme | null {\n if (!el) return null;\n const match = win.getComputedStyle(el).backgroundColor.match(/rgba?\\(([^)]+)\\)/);\n if (!match) return null;\n const [r, g, b, a = 1] = match[1].split(/[\\s,/]+/).filter(Boolean).map(Number);\n if ([r, g, b, a].some((n) => Number.isNaN(n)) || a < 0.5) return null;\n const luminance = 0.2126 * channel(r) + 0.7152 * channel(g) + 0.0722 * channel(b);\n return luminance < 0.2 ? \"dark\" : \"light\";\n}\n\n/** The site declares color-scheme: only dark, or both and the visitor's system decides. */\nfunction colorSchemeTheme(doc: Document, win: Window): HostTheme | null {\n const computed = win.getComputedStyle(doc.documentElement).colorScheme || \"\";\n const meta = doc.querySelector('meta[name=\"color-scheme\"]')?.getAttribute(\"content\") || \"\";\n const scheme = `${computed} ${meta}`.toLowerCase();\n if (!scheme.includes(\"dark\")) return null;\n if (!scheme.includes(\"light\")) return \"dark\";\n return win.matchMedia?.(DARK_QUERY).matches ? \"dark\" : \"light\";\n}\n\n/**\n * Best guess of the host page's current theme, most explicit signal first:\n * theme classes and attributes on <html> or <body>, then the page background,\n * then a declared color-scheme. Pages without any of these count as light, so\n * a light-only site never gets a dark widget just because the visitor's\n * system is dark.\n */\nexport function detectHostTheme(doc: Document = document, win: Window = window): HostTheme {\n return (\n explicitTheme(doc.documentElement) ??\n explicitTheme(doc.body) ??\n backgroundTheme(doc.body, win) ??\n backgroundTheme(doc.documentElement, win) ??\n colorSchemeTheme(doc, win) ??\n \"light\"\n );\n}\n\n/**\n * Calls onChange when the detected theme changes: class or attribute changes\n * on <html> and <body>, and system theme changes. Returns a stop function.\n */\nexport function watchHostTheme(\n onChange: (theme: HostTheme) => void,\n doc: Document = document,\n win: Window = window,\n): () => void {\n let last = detectHostTheme(doc, win);\n let scheduled = false;\n\n const check = () => {\n scheduled = false;\n const next = detectHostTheme(doc, win);\n if (next === last) return;\n last = next;\n onChange(next);\n };\n // Theme switches often touch several attributes at once, check once per frame.\n const schedule = () => {\n if (scheduled) return;\n scheduled = true;\n if (typeof win.requestAnimationFrame === \"function\") win.requestAnimationFrame(check);\n else setTimeout(check, 16);\n };\n\n const observer = typeof MutationObserver !== \"undefined\" ? new MutationObserver(schedule) : null;\n const observed = { attributes: true, attributeFilter: [\"class\", \"style\", ...THEME_ATTRIBUTES] };\n observer?.observe(doc.documentElement, observed);\n if (doc.body) observer?.observe(doc.body, observed);\n\n const media = typeof win.matchMedia === \"function\" ? win.matchMedia(DARK_QUERY) : null;\n media?.addEventListener?.(\"change\", schedule);\n\n return () => {\n observer?.disconnect();\n media?.removeEventListener?.(\"change\", schedule);\n };\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback, BitPalmTheme } from \"./types\";\nimport { detectHostTheme, normalizeThemeSetting, watchHostTheme, type HostTheme } from \"./theme\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ai\";\nconst STORAGE_PREFIX = \"_bp_\";\nconst IGNORED_INPUT_TYPES = new Set([\"password\", \"file\", \"checkbox\", \"radio\", \"submit\", \"button\", \"reset\", \"image\"]);\nconst IDENTITY_DEDUPE_WINDOW_MS = 8_000;\nconst CUSTOM_CONTEXT_MAX_BYTES = 4096;\nconst IDENTITY_SIGNATURE_KEY = `${STORAGE_PREFIX}identify_signature`;\nconst IDENTITY_FINGERPRINT_KEY = `${STORAGE_PREFIX}identify_fingerprint`;\nconst IDENTITY_SENT_AT_KEY = `${STORAGE_PREFIX}identify_sent_at`;\nconst LAUNCHER_SHADOW = \"0 4px 14px rgba(0,0,0,0.18)\";\n\ntype FormFieldElement = HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n\ntype IdentityPayload = {\n name?: string;\n email?: string;\n phone?: string;\n company?: string;\n};\n\ntype IdentifyRequestPayload = IdentityPayload & {\n external_user_id?: string;\n signature?: string;\n signed_at?: number;\n signature_version?: \"v1\";\n identify_source?: \"manual\" | \"form\";\n};\n\nfunction buildIdentityFingerprint(payload: IdentifyRequestPayload): string {\n return [\n payload.external_user_id || \"\",\n payload.email || \"\",\n payload.phone || \"\",\n payload.name || \"\",\n payload.company || \"\",\n payload.signature || \"\",\n payload.signed_at != null ? String(payload.signed_at) : \"\",\n payload.signature_version || \"\",\n payload.identify_source || \"\",\n ]\n .join(\"|\")\n .toLowerCase();\n}\n\nfunction normalizeText(value: string | null | undefined, maxLen = 180): string {\n if (!value) return \"\";\n return value.replace(/\\s+/g, \" \").trim().slice(0, maxLen);\n}\n\nfunction normalizeTokens(value: string | null | undefined): string {\n if (!value) return \"\";\n return ` ${value.toLowerCase().replace(/[_-]+/g, \" \").replace(/[^a-z0-9\\s@.]/g, \" \").replace(/\\s+/g, \" \").trim()} `;\n}\n\nfunction includesAny(haystack: string, needles: string[]): boolean {\n for (const needle of needles) {\n if (haystack.includes(needle)) return true;\n }\n return false;\n}\n\nfunction isEmail(value: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/i.test(value);\n}\n\nfunction normalizePhone(value: string | null | undefined): string {\n const trimmed = normalizeText(value, 50);\n if (!trimmed) return \"\";\n const hasPlus = trimmed.startsWith(\"+\");\n const digits = trimmed.replace(/\\D/g, \"\");\n if (digits.length < 6) return \"\";\n return `${hasPlus ? \"+\" : \"\"}${digits.slice(0, 20)}`;\n}\n\nfunction normalizeEmail(value: string | null | undefined): string {\n const normalized = normalizeText(value, 140).toLowerCase();\n if (!normalized) return \"\";\n if (!isEmail(normalized)) return \"\";\n return normalized;\n}\n\nfunction getExplicitValue(form: HTMLFormElement, selectors: string[]): string {\n for (const selector of selectors) {\n const el = form.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>(selector);\n const value = normalizeText(el?.value);\n if (value) return value;\n }\n return \"\";\n}\n\nfunction getFieldHint(el: FormFieldElement): string {\n return normalizeText(el.getAttribute(\"data-bp-field\") || el.getAttribute(\"data-bitpalm-field\"), 64)\n .toLowerCase()\n .replace(/[_\\s]+/g, \"-\");\n}\n\nfunction escapeAttrSelectorValue(value: string): string {\n return value.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n}\n\nfunction collectElementTokenParts(form: HTMLFormElement, el: FormFieldElement): string[] {\n const parts: string[] = [];\n const pushText = (value: string | null | undefined, maxLen = 140) => {\n const clean = normalizeText(value, maxLen);\n if (clean) parts.push(clean);\n };\n\n pushText(el.name);\n pushText(el.id);\n pushText(el.getAttribute(\"autocomplete\"));\n pushText(el.getAttribute(\"placeholder\"));\n pushText(el.getAttribute(\"aria-label\"));\n pushText(el.getAttribute(\"data-field\"));\n pushText(el.getAttribute(\"data-name\"));\n pushText(el.getAttribute(\"data-label\"));\n pushText(el.getAttribute(\"data-bp-field\"));\n pushText(el.getAttribute(\"data-bitpalm-field\"));\n\n const seenLabels = new Set<string>();\n const pushLabel = (value: string | null | undefined) => {\n const label = normalizeText(value, 200);\n if (!label || seenLabels.has(label)) return;\n seenLabels.add(label);\n parts.push(label);\n };\n\n for (const label of Array.from(el.labels || [])) {\n pushLabel(label.textContent);\n }\n\n if (el.id) {\n const forLabel = form.querySelector(`label[for=\"${escapeAttrSelectorValue(el.id)}\"]`);\n pushLabel(forLabel?.textContent);\n }\n\n const nearestLabel = el.closest(\"label\");\n pushLabel(nearestLabel?.textContent);\n\n const ariaLabelledBy = el.getAttribute(\"aria-labelledby\");\n if (ariaLabelledBy) {\n for (const id of ariaLabelledBy.split(/\\s+/)) {\n if (!id) continue;\n const ref = form.ownerDocument.getElementById(id);\n pushLabel(ref?.textContent);\n }\n }\n\n return parts;\n}\n\nfunction extractIdentityFromForm(form: HTMLFormElement): IdentityPayload | null {\n let email = normalizeText(getExplicitValue(form, [\n \"[data-bp-email]\",\n \"[data-bitpalm-email]\",\n ]), 140).toLowerCase();\n\n let phone = normalizePhone(getExplicitValue(form, [\n \"[data-bp-phone]\",\n \"[data-bitpalm-phone]\",\n ]));\n\n let name = normalizeText(getExplicitValue(form, [\n \"[data-bp-name]\",\n \"[data-bitpalm-name]\",\n \"[data-bp-full-name]\",\n \"[data-bitpalm-full-name]\",\n ]));\n\n let firstName = normalizeText(getExplicitValue(form, [\n \"[data-bp-first-name]\",\n \"[data-bitpalm-first-name]\",\n ]));\n\n let lastName = normalizeText(getExplicitValue(form, [\n \"[data-bp-last-name]\",\n \"[data-bitpalm-last-name]\",\n ]));\n\n let company = normalizeText(getExplicitValue(form, [\n \"[data-bp-company]\",\n \"[data-bitpalm-company]\",\n ]));\n\n for (const rawEl of Array.from(form.elements)) {\n if (!(rawEl instanceof HTMLInputElement || rawEl instanceof HTMLTextAreaElement || rawEl instanceof HTMLSelectElement)) continue;\n if (rawEl.disabled) continue;\n if (rawEl instanceof HTMLInputElement && IGNORED_INPUT_TYPES.has(rawEl.type.toLowerCase())) continue;\n const fieldHint = getFieldHint(rawEl);\n\n const explicitField =\n rawEl.hasAttribute(\"data-bp-email\") ||\n rawEl.hasAttribute(\"data-bitpalm-email\") ||\n rawEl.hasAttribute(\"data-bp-phone\") ||\n rawEl.hasAttribute(\"data-bitpalm-phone\") ||\n rawEl.hasAttribute(\"data-bp-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-name\") ||\n rawEl.hasAttribute(\"data-bp-full-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-full-name\") ||\n rawEl.hasAttribute(\"data-bp-first-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-first-name\") ||\n rawEl.hasAttribute(\"data-bp-last-name\") ||\n rawEl.hasAttribute(\"data-bitpalm-last-name\") ||\n rawEl.hasAttribute(\"data-bp-company\") ||\n rawEl.hasAttribute(\"data-bitpalm-company\") ||\n !!fieldHint;\n\n if (rawEl instanceof HTMLInputElement && rawEl.type.toLowerCase() === \"hidden\" && !explicitField) continue;\n\n const value = normalizeText(rawEl.value);\n if (!value) continue;\n\n const type = rawEl instanceof HTMLInputElement ? rawEl.type.toLowerCase() : \"\";\n const tokens = normalizeTokens(collectElementTokenParts(form, rawEl).join(\" \"));\n\n if (!email && fieldHint === \"email\" && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && (fieldHint === \"phone\" || fieldHint === \"tel\" || fieldHint === \"mobile\" || fieldHint === \"whatsapp\")) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && fieldHint === \"company\") {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && (fieldHint === \"first-name\" || fieldHint === \"firstname\")) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && (fieldHint === \"last-name\" || fieldHint === \"lastname\" || fieldHint === \"surname\")) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && (fieldHint === \"name\" || fieldHint === \"full-name\" || fieldHint === \"fullname\")) {\n if (!isEmail(value) && !normalizePhone(value)) name = normalizeText(value, 140);\n continue;\n }\n\n const emailLike = type === \"email\" || includesAny(tokens, [\" email \", \" e mail \", \" mail \", \" email adresse \", \" mailadresse \", \" correo \"]);\n const phoneLike = type === \"tel\" || includesAny(tokens, [\" phone \", \" phone number \", \" mobile \", \" tel \", \" telefon \", \" telefonnummer \", \" whatsapp \", \" handy \", \" kontakt \", \" nummer \"]);\n const companyLike = includesAny(tokens, [\" company \", \" company name \", \" firma \", \" firmenname \", \" organization \", \" organisation \", \" business \", \" unternehmen \", \" agency \", \" brokerage \"]);\n const firstNameLike = includesAny(tokens, [\" first name \", \" firstname \", \" given name \", \" givenname \", \" vorname \", \" fname \"]);\n const lastNameLike = includesAny(tokens, [\" last name \", \" lastname \", \" family name \", \" familyname \", \" surname \", \" nachname \", \" lname \"]);\n const fullNameLike = includesAny(tokens, [\" full name \", \" fullname \", \" contact name \", \" name \"]) && !emailLike && !phoneLike;\n\n if (!email && emailLike && isEmail(value)) {\n email = value.toLowerCase();\n continue;\n }\n if (!phone && phoneLike) {\n const normalized = normalizePhone(value);\n if (normalized) {\n phone = normalized;\n continue;\n }\n }\n if (!company && companyLike) {\n company = normalizeText(value, 160);\n continue;\n }\n if (!firstName && firstNameLike) {\n firstName = normalizeText(value, 100);\n continue;\n }\n if (!lastName && lastNameLike) {\n lastName = normalizeText(value, 100);\n continue;\n }\n if (!name && fullNameLike && !isEmail(value) && !normalizePhone(value)) {\n name = normalizeText(value, 140);\n continue;\n }\n\n if (!email && isEmail(value)) {\n email = value.toLowerCase();\n }\n }\n\n if (name && (isEmail(name) || normalizePhone(name))) {\n name = \"\";\n }\n if (company && (isEmail(company) || normalizePhone(company))) {\n company = \"\";\n }\n\n if (!name) {\n name = normalizeText([firstName, lastName].filter(Boolean).join(\" \"), 140);\n }\n\n if (name && email && name.toLowerCase() === email.toLowerCase()) {\n name = \"\";\n }\n\n const hasContactSignal = !!(email || phone);\n const hasStrongProfileSignal = !!(name && company);\n if (!hasContactSignal && !hasStrongProfileSignal) {\n return null;\n }\n\n const identity: IdentityPayload = {\n ...(name ? { name } : {}),\n ...(email ? { email } : {}),\n ...(phone ? { phone } : {}),\n ...(company ? { company } : {}),\n };\n\n return Object.keys(identity).length > 0 ? identity : null;\n}\n\nfunction detectLocale(): string {\n if (typeof document !== \"undefined\") {\n const lang = document.documentElement.lang;\n if (lang) return lang.slice(0, 2).toLowerCase();\n }\n return \"en\";\n}\n\nfunction runWhenIdle(task: () => void, timeout = 1200) {\n if (typeof window !== \"undefined\" && \"requestIdleCallback\" in window) {\n (\n window as unknown as {\n requestIdleCallback: (cb: () => void, opts?: { timeout?: number }) => number;\n }\n ).requestIdleCallback(task, { timeout });\n return;\n }\n setTimeout(task, Math.min(timeout, 300));\n}\n\nfunction isMobileWidgetDevice(): boolean {\n if (typeof window === \"undefined\") return false;\n const userAgent = typeof navigator !== \"undefined\" ? navigator.userAgent : \"\";\n const isMobileUa = /Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(userAgent);\n if (isMobileUa) return true;\n\n const coarsePointer = window.matchMedia(\"(pointer: coarse)\").matches;\n const noHover = window.matchMedia(\"(hover: none)\").matches;\n const minScreenSide = Math.min(\n window.screen?.width || window.innerWidth,\n window.screen?.height || window.innerHeight,\n );\n return coarsePointer && noHover && minScreenSide <= 900;\n}\n\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n token,\n zIndex = 9999,\n autoIdentify = true,\n } = options;\n\n const d = document;\n\n // --- Theme ---\n let themeSetting: BitPalmTheme = normalizeThemeSetting(options.theme);\n let currentTheme: HostTheme = themeSetting === \"auto\" ? detectHostTheme() : themeSetting;\n let stopThemeWatch: (() => void) | null = null;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n const qs = new URLSearchParams({ locale, theme: currentTheme });\n if (token) qs.set(\"token\", token);\n iframe.src = `${widgetUrl}?${qs.toString()}`;\n // Explicitly grant the iframe permission to use the visitor's\n // microphone — required for the voice-input feature on cross-origin\n // iframes. Without this, Chrome silently denies getUserMedia /\n // SpeechRecognition without ever prompting the user.\n iframe.allow = \"clipboard-write; microphone\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\n iframe.loading = \"lazy\";\n iframe.style.cssText = `position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${zIndex};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;\n\n const origin = new URL(iframe.src).origin;\n\n // --- Native launcher button ---\n const btn = d.createElement(\"div\");\n btn.setAttribute(\"role\", \"button\");\n btn.setAttribute(\"aria-label\", \"Chat\");\n btn.style.cssText = `position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${zIndex - 1};background:#171717;box-shadow:${LAUNCHER_SHADOW};transition:transform .2s,opacity .3s;opacity:0;`;\n btn.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n btn.onmouseenter = () => { btn.style.transform = \"scale(1.05)\"; };\n btn.onmouseleave = () => { btn.style.transform = \"scale(1)\"; };\n btn.onclick = () => openWidget();\n d.body.appendChild(btn);\n\n // --- Fade animation for trigger bubbles ---\n if (!d.getElementById(\"_bp_fade\")) {\n const s = d.createElement(\"style\");\n s.id = \"_bp_fade\";\n s.textContent = \"@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}\";\n d.head.appendChild(s);\n }\n\n // --- Trigger bubble ---\n let bubble: HTMLDivElement | null = null;\n let launcherReady = false;\n let widgetBlocked = false;\n let iframeMounted = false;\n let iframeReady = false;\n let pendingOpen = false;\n const mountIframe = () => {\n if (iframeMounted) return;\n iframeMounted = true;\n d.body.appendChild(iframe);\n };\n let mobileScrollLocked = false;\n let scrollLockY = 0;\n const prevHtmlStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n };\n const prevBodyStyle = {\n overflow: \"\",\n overscrollBehavior: \"\",\n position: \"\",\n top: \"\",\n left: \"\",\n right: \"\",\n width: \"\",\n };\n const lockMobilePageScroll = () => {\n if (mobileScrollLocked) return;\n const mobile = isMobileWidgetDevice();\n if (!mobile) return;\n const html = d.documentElement;\n const body = d.body;\n scrollLockY = window.scrollY || window.pageYOffset || 0;\n prevHtmlStyle.overflow = html.style.overflow;\n prevHtmlStyle.overscrollBehavior = html.style.overscrollBehavior;\n prevBodyStyle.overflow = body.style.overflow;\n prevBodyStyle.overscrollBehavior = body.style.overscrollBehavior;\n prevBodyStyle.position = body.style.position;\n prevBodyStyle.top = body.style.top;\n prevBodyStyle.left = body.style.left;\n prevBodyStyle.right = body.style.right;\n prevBodyStyle.width = body.style.width;\n html.style.overflow = \"hidden\";\n html.style.overscrollBehavior = \"none\";\n body.style.overflow = \"hidden\";\n body.style.overscrollBehavior = \"none\";\n body.style.position = \"fixed\";\n body.style.top = `-${scrollLockY}px`;\n body.style.left = \"0\";\n body.style.right = \"0\";\n body.style.width = \"100%\";\n mobileScrollLocked = true;\n };\n const unlockMobilePageScroll = () => {\n if (!mobileScrollLocked) return;\n const html = d.documentElement;\n const body = d.body;\n html.style.overflow = prevHtmlStyle.overflow;\n html.style.overscrollBehavior = prevHtmlStyle.overscrollBehavior;\n body.style.overflow = prevBodyStyle.overflow;\n body.style.overscrollBehavior = prevBodyStyle.overscrollBehavior;\n body.style.position = prevBodyStyle.position;\n body.style.top = prevBodyStyle.top;\n body.style.left = prevBodyStyle.left;\n body.style.right = prevBodyStyle.right;\n body.style.width = prevBodyStyle.width;\n window.scrollTo(0, scrollLockY);\n mobileScrollLocked = false;\n };\n const prepareIframeForOpen = () => {\n const mobile = isMobileWidgetDevice();\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (mobile) {\n iframe.style.width = \"100vw\";\n iframe.style.height = \"100dvh\";\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n // Match desktop widget target size so the opening animation is visible from frame 1.\n iframe.style.width = \"420px\";\n iframe.style.height = \"620px\";\n iframe.style.bottom = \"24px\";\n iframe.style.right = \"24px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n };\n const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\n };\n let sendParentContext = () => {};\n let sendOpenSignal = () => {};\n\n // --- Widget state & event bus ---\n let widgetIsOpen = false;\n const eventListeners = new Map<BitPalmEventType, Set<BitPalmEventCallback>>();\n\n function emit(event: BitPalmEventType, data?: Record<string, unknown>) {\n const listeners = eventListeners.get(event);\n if (!listeners) return;\n for (const cb of listeners) {\n try { cb(data); } catch { /* don't let listener errors break the widget */ }\n }\n }\n\n // --- postMessage handler ---\n const handleMessage = (e: MessageEvent) => {\n if (e.origin !== origin) return;\n\n // Widget config (colors, icon)\n if (e.data?.type === \"bitpalm-widget-config\") {\n widgetBlocked = false;\n launcherReady = true;\n if (iframe.style.display === \"none\") iframe.style.display = \"\";\n if (e.data.primaryColor) {\n btn.style.background = e.data.primaryColor;\n btn.style.boxShadow = e.data.chatShadow === \"none\" ? \"none\" : LAUNCHER_SHADOW;\n }\n const ic = e.data.chatButtonIconColor || \"black\";\n if (e.data.chatButtonIconSvg) {\n btn.innerHTML = \"\";\n const sp = d.createElement(\"span\");\n sp.style.cssText = `display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${ic}`;\n const parser = new DOMParser();\n const doc = parser.parseFromString(e.data.chatButtonIconSvg, \"image/svg+xml\");\n const svg = doc.querySelector(\"svg\");\n if (svg) {\n // Remove dangerous elements and attributes\n svg.querySelectorAll(\"script,foreignObject\").forEach(el => el.remove());\n svg.querySelectorAll(\"*\").forEach(el => {\n for (const attr of [...el.attributes]) {\n if (attr.name.startsWith(\"on\") || (attr.value && attr.value.includes(\"javascript:\"))) {\n el.removeAttribute(attr.name);\n }\n }\n });\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\n sp.appendChild(svg);\n } else {\n // Fallback: use default icon\n sp.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\"/></svg>';\n }\n btn.appendChild(sp);\n } else {\n const sv = btn.querySelector(\"svg\");\n if (sv) (sv as SVGElement).style.stroke = ic;\n }\n btn.style.display = \"flex\";\n // Fade in after styles are applied\n requestAnimationFrame(() => { btn.style.opacity = \"1\"; });\n }\n\n // Resize — use full viewport on mobile\n if (e.data?.type === \"bitpalm-widget-resize\") {\n const isOpen = e.data.width > 0;\n const wasOpen = widgetIsOpen;\n widgetIsOpen = isOpen;\n if (isOpen && !wasOpen) emit(\"widget_opened\");\n if (!isOpen && wasOpen) emit(\"widget_closed\");\n const mobile = isMobileWidgetDevice();\n if (isOpen) {\n iframe.style.width = mobile ? \"100vw\" : `${e.data.width}px`;\n iframe.style.height = mobile ? \"100dvh\" : `${e.data.height}px`;\n if (mobile) {\n iframe.style.left = \"0\";\n iframe.style.top = \"0\";\n iframe.style.bottom = \"0\";\n iframe.style.right = \"0\";\n lockMobilePageScroll();\n } else {\n unlockMobilePageScroll();\n }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\n unlockMobilePageScroll();\n iframe.style.width = \"1px\";\n iframe.style.height = \"1px\";\n iframe.style.left = \"\";\n iframe.style.top = \"\";\n iframe.style.opacity = \"0\";\n iframe.style.pointerEvents = \"none\";\n }\n btn.style.display = isOpen ? \"none\" : \"flex\";\n }\n\n // Trigger bubble show\n if (e.data?.type === \"bitpalm-trigger-show\") {\n if (widgetBlocked || !launcherReady) return;\n removeBubble();\n bubble = d.createElement(\"div\");\n bubble.style.cssText = `position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${zIndex - 1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;\n const msg = (e.data.message || \"\").replace(/</g, \"<\");\n bubble.innerHTML = `<p style=\"font-size:14px;color:#1f2937;margin:0;\">${msg}</p><div style=\"position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;\"></div>`;\n const close = d.createElement(\"button\");\n close.style.cssText = \"position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;\";\n close.innerHTML = \"✕\";\n close.onclick = (ev) => { ev.stopPropagation(); removeBubble(); iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-dismiss\" }, \"*\"); };\n bubble.onclick = () => {\n removeBubble();\n btn.style.display = \"none\";\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\", message: msg }, \"*\");\n };\n bubble.appendChild(close);\n d.body.appendChild(bubble);\n }\n\n // Trigger bubble hide\n if (e.data?.type === \"bitpalm-trigger-hide\") { removeBubble(); }\n\n // Iframe requests latest parent context (avoids first-load race conditions)\n if (e.data?.type === \"bitpalm-request-context\") {\n sendParentContext();\n }\n\n // Chat events from iframe → emit to SDK listeners\n if (e.data?.type === \"bitpalm-chat-event\" && e.data.event) {\n emit(e.data.event as BitPalmEventType, e.data.data);\n }\n\n // Widget blocked (excluded path or access denied) — hide button & iframe\n if (e.data?.type === \"bitpalm-widget-blocked\") {\n widgetBlocked = true;\n launcherReady = false;\n btn.style.display = \"none\";\n removeBubble();\n unlockMobilePageScroll();\n iframe.style.display = \"none\";\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // --- Privacy opt-out check ---\n let optedOut = false;\n try { optedOut = localStorage.getItem(`${STORAGE_PREFIX}optout`) === \"1\"; } catch { /* ignore */ }\n\n // --- Persistent Visitor ID (skip if opted out) ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\n if (!optedOut) {\n try { visitorId = localStorage.getItem(VID_KEY) || \"\"; } catch { /* ignore */ }\n if (!visitorId) {\n // Fallback: try reading from cookie\n const match = d.cookie.match(new RegExp(`(?:^|; )${VID_KEY}=([^;]+)`));\n visitorId = match ? decodeURIComponent(match[1]) : \"\";\n }\n if (!visitorId) {\n visitorId = crypto.randomUUID ? crypto.randomUUID() : (`${Date.now()}-${Math.random().toString(36).slice(2, 11)}`);\n }\n // Persist in both localStorage and cookie (cookie survives Safari ITP clearing localStorage)\n try { localStorage.setItem(VID_KEY, visitorId); } catch { /* ignore */ }\n try {\n const maxAge = 365 * 24 * 60 * 60; // 1 year\n d.cookie = `${VID_KEY}=${encodeURIComponent(visitorId)};path=/;max-age=${maxAge};SameSite=Lax`;\n } catch { /* ignore */ }\n }\n\n // --- Visitor beacon: track page view even without chat (skip if opted out) ---\n if (!optedOut) {\n runWhenIdle(() => {\n try {\n const utmParams = new URLSearchParams(location.search);\n const utm: Record<string, string> = {};\n for (const key of [\"utm_source\", \"utm_medium\", \"utm_campaign\", \"utm_term\", \"utm_content\"]) {\n const val = utmParams.get(key);\n if (val) utm[key] = val;\n }\n const beaconPayload = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...(Object.keys(utm).length > 0 ? { utm } : {}),\n });\n const beaconUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(beaconUrl, new Blob([beaconPayload], { type: \"application/json\" }));\n } else {\n fetch(beaconUrl, { method: \"POST\", body: beaconPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }, 2000);\n }\n\n // --- Auto-identify visitor from form submissions on host page ---\n let lastIdentitySignature = \"\";\n let lastIdentityFingerprint = \"\";\n let lastIdentitySentAt = 0;\n try {\n lastIdentitySignature = sessionStorage.getItem(IDENTITY_SIGNATURE_KEY) || \"\";\n lastIdentityFingerprint = sessionStorage.getItem(IDENTITY_FINGERPRINT_KEY) || \"\";\n const storedAt = parseInt(sessionStorage.getItem(IDENTITY_SENT_AT_KEY) || \"0\", 10);\n if (Number.isFinite(storedAt) && storedAt > 0) {\n lastIdentitySentAt = storedAt;\n }\n } catch {\n // ignore\n }\n\n const dispatchIdentify = (payloadInput: IdentifyRequestPayload, scopeSignature = \"\") => {\n if (optedOut || !visitorId) return;\n\n const payload: IdentifyRequestPayload = {};\n const name = normalizeText(payloadInput.name, 140);\n const email = normalizeEmail(payloadInput.email);\n const phone = normalizePhone(payloadInput.phone);\n const company = normalizeText(payloadInput.company, 160);\n const externalUserId = normalizeText(payloadInput.external_user_id, 140);\n const requestSignature = normalizeText(payloadInput.signature, 260);\n const signedAtRaw = Number(payloadInput.signed_at);\n\n if (name) payload.name = name;\n if (email) payload.email = email;\n if (phone) payload.phone = phone;\n if (company) payload.company = company;\n if (externalUserId) payload.external_user_id = externalUserId;\n if (requestSignature) payload.signature = requestSignature;\n if (Number.isFinite(signedAtRaw) && signedAtRaw > 0) {\n payload.signed_at = Math.floor(signedAtRaw);\n }\n if (payloadInput.signature_version === \"v1\" || payload.signature) {\n payload.signature_version = \"v1\";\n }\n if (payloadInput.identify_source === \"manual\" || payloadInput.identify_source === \"form\") {\n payload.identify_source = payloadInput.identify_source;\n }\n\n if (!payload.name && !payload.email && !payload.phone && !payload.company && !payload.external_user_id) {\n return;\n }\n\n const identityFingerprint = buildIdentityFingerprint(payload);\n const dedupeSignature = [scopeSignature.toLowerCase(), identityFingerprint].filter(Boolean).join(\"|\");\n\n const now = Date.now();\n const insideDedupWindow = now - lastIdentitySentAt < IDENTITY_DEDUPE_WINDOW_MS;\n if (insideDedupWindow && (dedupeSignature === lastIdentitySignature || identityFingerprint === lastIdentityFingerprint)) {\n return;\n }\n\n lastIdentitySignature = dedupeSignature;\n lastIdentityFingerprint = identityFingerprint;\n lastIdentitySentAt = now;\n try {\n sessionStorage.setItem(IDENTITY_SIGNATURE_KEY, dedupeSignature);\n sessionStorage.setItem(IDENTITY_FINGERPRINT_KEY, identityFingerprint);\n sessionStorage.setItem(IDENTITY_SENT_AT_KEY, String(now));\n } catch {\n // ignore\n }\n\n try {\n const requestBody = JSON.stringify({\n tenant_slug: slug,\n visitor_id: visitorId,\n url: location.href,\n referrer: d.referrer || undefined,\n ...payload,\n });\n const identifyUrl = `${baseUrl}/api/widget/identify`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(identifyUrl, new Blob([requestBody], { type: \"application/json\" }));\n } else {\n fetch(identifyUrl, { method: \"POST\", body: requestBody, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch {\n // ignore\n }\n };\n\n const handleFormSubmit = (event: Event) => {\n if (optedOut || !autoIdentify || !visitorId) return;\n\n const form = event.target instanceof HTMLFormElement\n ? event.target\n : event.target instanceof Element\n ? event.target.closest(\"form\")\n : null;\n if (!(form instanceof HTMLFormElement)) return;\n\n const formIdentifySetting = (form.getAttribute(\"data-bp-identify\") || form.getAttribute(\"data-bitpalm-identify\") || \"\").toLowerCase();\n if (formIdentifySetting === \"off\" || formIdentifySetting === \"false\" || formIdentifySetting === \"0\") return;\n\n const identity = extractIdentityFromForm(form);\n if (!identity) return;\n\n const formSignature = [\n form.getAttribute(\"id\") || \"\",\n form.getAttribute(\"name\") || \"\",\n form.getAttribute(\"action\") || \"\",\n ].join(\"|\");\n\n dispatchIdentify({ ...identity, identify_source: \"form\" }, formSignature);\n };\n\n if (!optedOut && autoIdentify) {\n d.addEventListener(\"submit\", handleFormSubmit, true);\n }\n\n // --- Visitor Intelligence: page counter + history ---\n let pageCount = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}pages`) || \"0\") + 1;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n\n let hist: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n hist.push(location.href);\n if (hist.length > 20) hist = hist.slice(-20);\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(hist));\n\n const loadedAt = Date.now();\n let siteStart = parseInt(sessionStorage.getItem(`${STORAGE_PREFIX}site_start`) || \"0\");\n if (!siteStart) {\n siteStart = loadedAt;\n sessionStorage.setItem(`${STORAGE_PREFIX}site_start`, String(siteStart));\n }\n\n const contextRetryTimers: ReturnType<typeof setTimeout>[] = [];\n sendParentContext = () => {\n let returning = false;\n try {\n returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\n } catch {\n returning = false;\n }\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-parent-context\",\n url: location.href,\n title: d.title,\n returning,\n pageCount,\n pageHistory: hist,\n loadedAt,\n siteStart,\n locale,\n visitorId: optedOut ? \"\" : visitorId,\n }, \"*\");\n sendTheme();\n if (!returning && !optedOut) {\n try { localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\"); } catch { /* ignore */ }\n }\n };\n\n // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n iframeReady = true;\n sendParentContext();\n [120, 450, 1100].forEach((delay) => {\n const timer = setTimeout(() => sendParentContext(), delay);\n contextRetryTimers.push(timer);\n });\n if (pendingOpen) {\n pendingOpen = false;\n sendOpenSignal();\n }\n });\n\n // Lazy-mount iframe after initial paint/idle to reduce impact on host load.\n if (d.readyState === \"loading\") {\n d.addEventListener(\"DOMContentLoaded\", () => runWhenIdle(mountIframe, 1600), { once: true });\n } else {\n runWhenIdle(mountIframe, 1600);\n }\n\n // --- SPA navigation detection ---\n const origPush = history.pushState.bind(history);\n const origReplace = history.replaceState.bind(history);\n\n const onNav = () => {\n pageCount++;\n sessionStorage.setItem(`${STORAGE_PREFIX}pages`, String(pageCount));\n const h: string[] = JSON.parse(sessionStorage.getItem(`${STORAGE_PREFIX}hist`) || \"[]\");\n h.push(location.href);\n if (h.length > 20) h.splice(0, h.length - 20);\n hist = h;\n sessionStorage.setItem(`${STORAGE_PREFIX}hist`, JSON.stringify(h));\n iframe.contentWindow?.postMessage({\n type: \"bitpalm-page-change\",\n url: location.href,\n title: d.title,\n pageCount,\n pageHistory: h,\n loadedAt: Date.now(),\n }, \"*\");\n // Track page view for visitor (skip if opted out)\n if (!optedOut) {\n try {\n const navPayload = JSON.stringify({ tenant_slug: slug, visitor_id: visitorId, url: location.href });\n const navUrl = `${baseUrl}/api/widget/impression`;\n if (typeof navigator.sendBeacon === \"function\") {\n navigator.sendBeacon(navUrl, new Blob([navPayload], { type: \"application/json\" }));\n } else {\n fetch(navUrl, { method: \"POST\", body: navPayload, headers: { \"Content-Type\": \"application/json\" }, keepalive: true }).catch(() => {});\n }\n } catch { /* ignore */ }\n }\n };\n\n history.pushState = function (...args: Parameters<typeof history.pushState>) {\n origPush(...args);\n onNav();\n };\n history.replaceState = function (...args: Parameters<typeof history.replaceState>) {\n origReplace(...args);\n onNav();\n };\n window.addEventListener(\"popstate\", onNav);\n\n // --- Scroll depth tracking ---\n let lastScrollDepth = -1;\n let scrollTimeout: ReturnType<typeof setTimeout>;\n const handleScroll = () => {\n clearTimeout(scrollTimeout);\n scrollTimeout = setTimeout(() => {\n const total = Math.max(d.documentElement.scrollHeight, d.body.scrollHeight) - window.innerHeight;\n const pct = total > 0 ? Math.round(window.scrollY / total * 100) : 100;\n if (pct !== lastScrollDepth) {\n lastScrollDepth = pct;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-scroll-depth\", percent: pct }, \"*\");\n }\n }, 500);\n };\n window.addEventListener(\"scroll\", handleScroll, { passive: true });\n\n // --- Exit intent ---\n const handleMouseOut = (e: MouseEvent) => {\n if (e.clientY <= 0) {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-exit-intent\" }, \"*\");\n }\n };\n d.addEventListener(\"mouseout\", handleMouseOut);\n\n // --- Inactivity detection (15s) ---\n let idleTimer: ReturnType<typeof setTimeout>;\n let idleFired = false;\n const resetIdle = () => {\n clearTimeout(idleTimer);\n if (idleFired) return;\n idleTimer = setTimeout(() => {\n idleFired = true;\n iframe.contentWindow?.postMessage({ type: \"bitpalm-inactivity\" }, \"*\");\n }, 15_000);\n };\n const idleEvents = [\"mousemove\", \"keydown\", \"scroll\", \"touchstart\"] as const;\n idleEvents.forEach((ev) => d.addEventListener(ev, resetIdle, { passive: true }));\n resetIdle();\n\n sendOpenSignal = () => {\n // Primary: postMessage\n iframe.contentWindow?.postMessage({ type: \"bitpalm-open\" }, \"*\");\n // Fallback for mobile: trigger hashchange inside iframe (no reload)\n const base = iframe.src.split(\"#\")[0];\n iframe.src = `${base}#bp-open-${Date.now()}`;\n };\n\n // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\n prepareIframeForOpen();\n mountIframe();\n if (!iframeReady) {\n pendingOpen = true;\n return;\n }\n sendOpenSignal();\n };\n\n const closeWidget = () => {\n unlockMobilePageScroll();\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\n };\n\n const identify = (input: BitPalmIdentifyPayload) => {\n if (!input || typeof input !== \"object\") return;\n dispatchIdentify({\n external_user_id: normalizeText(input.externalUserId, 140) || undefined,\n name: normalizeText(input.name, 140) || undefined,\n email: normalizeEmail(input.email) || undefined,\n phone: normalizePhone(input.phone) || undefined,\n company: normalizeText(input.company, 160) || undefined,\n signature: normalizeText(input.signature, 260) || undefined,\n signed_at: Number.isFinite(Number(input.signedAt)) ? Math.floor(Number(input.signedAt)) : undefined,\n signature_version: input.signatureVersion === \"v1\" ? \"v1\" : undefined,\n identify_source: \"manual\",\n }, \"manual\");\n };\n\n const toggleWidget = () => {\n if (widgetIsOpen) closeWidget();\n else openWidget();\n };\n\n const getIsOpen = () => widgetIsOpen;\n\n const sendMessage = (message: string) => {\n if (!message || typeof message !== \"string\") return;\n const text = message.trim().slice(0, 10_000);\n if (!text) return;\n if (!widgetIsOpen) openWidget();\n // Small delay to ensure widget is open before sending\n setTimeout(() => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-send-message\", message: text }, \"*\");\n }, widgetIsOpen ? 50 : 500);\n };\n\n // --- Theme switching ---\n function sendTheme() {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-theme\", theme: currentTheme }, \"*\");\n }\n\n const applyTheme = (theme: HostTheme) => {\n if (theme === currentTheme) return;\n currentTheme = theme;\n sendTheme();\n };\n\n const setTheme = (theme: BitPalmTheme) => {\n themeSetting = normalizeThemeSetting(theme);\n stopThemeWatch?.();\n stopThemeWatch = null;\n if (themeSetting === \"auto\") {\n stopThemeWatch = watchHostTheme(applyTheme);\n applyTheme(detectHostTheme());\n } else {\n applyTheme(themeSetting);\n }\n };\n\n if (themeSetting === \"auto\") stopThemeWatch = watchHostTheme(applyTheme);\n\n const handleThemeEvent = (event: Event) => {\n const detail = (event as CustomEvent<{ slug?: string; theme?: BitPalmTheme }>).detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText(detail.slug, 120);\n if (targetSlug && targetSlug !== slug) return;\n setTheme(normalizeThemeSetting(detail.theme));\n };\n window.addEventListener(\"bitpalm-theme\", handleThemeEvent as EventListener);\n\n // --- Custom context for AI ---\n let customContext: Record<string, unknown> = {};\n\n const setCustomContext = (data: BitPalmCustomContext) => {\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return;\n customContext = { ...customContext, ...data };\n const json = JSON.stringify(customContext);\n if (json.length > CUSTOM_CONTEXT_MAX_BYTES) {\n console.warn(\n `[BitPalm] Custom context exceeds ${CUSTOM_CONTEXT_MAX_BYTES} bytes (${json.length}). It may be truncated.`\n );\n }\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: customContext }, \"*\");\n };\n\n const clearCustomContext = () => {\n customContext = {};\n iframe.contentWindow?.postMessage({ type: \"bitpalm-custom-context\", data: {} }, \"*\");\n };\n\n const handleContextEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmCustomContext & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText((detail as Record<string, unknown>).slug as string, 120);\n if (targetSlug && targetSlug !== slug) return;\n const { slug: _s, ...contextData } = detail as Record<string, unknown>;\n setCustomContext(contextData);\n };\n\n window.addEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n\n const handleIdentifyEvent = (event: Event) => {\n const customEvent = event as CustomEvent<BitPalmIdentifyPayload & { slug?: string }>;\n const detail = customEvent.detail;\n if (!detail || typeof detail !== \"object\") return;\n const targetSlug = normalizeText(detail.slug, 120);\n if (targetSlug && targetSlug !== slug) return;\n identify(detail);\n };\n\n window.addEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n\n // open, close and send for setups without an instance (script tag)\n const targetsThisWidget = (event: Event) => {\n const detail = (event as CustomEvent<{ slug?: string }>).detail;\n const targetSlug = normalizeText(detail?.slug, 120);\n return !targetSlug || targetSlug === slug;\n };\n const handleOpenEvent = (event: Event) => { if (targetsThisWidget(event)) openWidget(); };\n const handleCloseEvent = (event: Event) => { if (targetsThisWidget(event)) closeWidget(); };\n const handleSendEvent = (event: Event) => {\n if (!targetsThisWidget(event)) return;\n const message = (event as CustomEvent<{ message?: string }>).detail?.message;\n if (typeof message === \"string\") sendMessage(message);\n };\n window.addEventListener(\"bitpalm-open\", handleOpenEvent);\n window.addEventListener(\"bitpalm-close\", handleCloseEvent);\n window.addEventListener(\"bitpalm-send\", handleSendEvent);\n\n const onEvent = (event: BitPalmEventType, callback: BitPalmEventCallback): (() => void) => {\n if (!eventListeners.has(event)) eventListeners.set(event, new Set());\n eventListeners.get(event)!.add(callback);\n return () => eventListeners.get(event)?.delete(callback);\n };\n\n const offEvent = (event: BitPalmEventType, callback: BitPalmEventCallback) => {\n eventListeners.get(event)?.delete(callback);\n };\n\n const destroy = () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"scroll\", handleScroll);\n window.removeEventListener(\"popstate\", onNav);\n d.removeEventListener(\"mouseout\", handleMouseOut);\n d.removeEventListener(\"submit\", handleFormSubmit, true);\n idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n contextRetryTimers.forEach((t) => clearTimeout(t));\n history.pushState = origPush;\n history.replaceState = origReplace;\n window.removeEventListener(\"bitpalm-identify\", handleIdentifyEvent as EventListener);\n window.removeEventListener(\"bitpalm-context\", handleContextEvent as EventListener);\n window.removeEventListener(\"bitpalm-theme\", handleThemeEvent as EventListener);\n window.removeEventListener(\"bitpalm-open\", handleOpenEvent);\n window.removeEventListener(\"bitpalm-close\", handleCloseEvent);\n window.removeEventListener(\"bitpalm-send\", handleSendEvent);\n stopThemeWatch?.();\n eventListeners.clear();\n unlockMobilePageScroll();\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return {\n open: openWidget,\n close: closeWidget,\n toggle: toggleWidget,\n isOpen: getIsOpen,\n identify,\n context: setCustomContext,\n resetContext: clearCustomContext,\n send: sendMessage,\n on: onEvent,\n off: offEvent,\n setTheme,\n destroy,\n };\n}\n"],"mappings":"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","names":["react_exports","__export","BitPalmAgent","__toCommonJS","import_react","DARK_CLASSES","LIGHT_CLASSES","THEME_ATTRIBUTES","DARK_QUERY","normalizeThemeSetting","value","explicitTheme","el","name","attr","channel","s","backgroundTheme","win","match","r","g","b","a","n","colorSchemeTheme","doc","computed","meta","scheme","detectHostTheme","watchHostTheme","onChange","last","scheduled","check","next","schedule","observer","observed","media","DEFAULT_BASE_URL","STORAGE_PREFIX","IGNORED_INPUT_TYPES","IDENTITY_DEDUPE_WINDOW_MS","CUSTOM_CONTEXT_MAX_BYTES","IDENTITY_SIGNATURE_KEY","IDENTITY_FINGERPRINT_KEY","IDENTITY_SENT_AT_KEY","LAUNCHER_SHADOW","buildIdentityFingerprint","payload","normalizeText","value","maxLen","normalizeTokens","includesAny","haystack","needles","needle","isEmail","normalizePhone","trimmed","hasPlus","digits","normalizeEmail","normalized","getExplicitValue","form","selectors","selector","el","getFieldHint","escapeAttrSelectorValue","collectElementTokenParts","parts","pushText","clean","seenLabels","pushLabel","label","forLabel","nearestLabel","ariaLabelledBy","id","ref","extractIdentityFromForm","email","phone","name","firstName","lastName","company","rawEl","fieldHint","explicitField","type","tokens","emailLike","phoneLike","companyLike","firstNameLike","lastNameLike","fullNameLike","identity","detectLocale","lang","runWhenIdle","task","timeout","isMobileWidgetDevice","userAgent","coarsePointer","noHover","minScreenSide","createWidget","options","slug","locale","baseUrl","token","zIndex","autoIdentify","d","themeSetting","normalizeThemeSetting","currentTheme","detectHostTheme","stopThemeWatch","iframe","widgetUrl","qs","origin","btn","openWidget","s","bubble","launcherReady","widgetBlocked","iframeMounted","iframeReady","pendingOpen","mountIframe","mobileScrollLocked","scrollLockY","prevHtmlStyle","prevBodyStyle","lockMobilePageScroll","html","body","unlockMobilePageScroll","prepareIframeForOpen","mobile","removeBubble","sendParentContext","sendOpenSignal","widgetIsOpen","eventListeners","emit","event","data","listeners","cb","handleMessage","ic","sp","svg","attr","sv","isOpen","wasOpen","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","lastIdentitySignature","lastIdentityFingerprint","lastIdentitySentAt","storedAt","dispatchIdentify","payloadInput","scopeSignature","externalUserId","requestSignature","signedAtRaw","identityFingerprint","dedupeSignature","now","requestBody","identifyUrl","handleFormSubmit","formIdentifySetting","formSignature","pageCount","hist","loadedAt","siteStart","contextRetryTimers","returning","sendTheme","delay","timer","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","closeWidget","identify","input","toggleWidget","getIsOpen","sendMessage","message","text","applyTheme","theme","setTheme","watchHostTheme","handleThemeEvent","detail","targetSlug","customContext","setCustomContext","json","clearCustomContext","handleContextEvent","_s","contextData","handleIdentifyEvent","targetsThisWidget","handleOpenEvent","handleCloseEvent","handleSendEvent","callback","t","BitPalmAgent","props","instanceRef","mountedRef","createWidget"]}
|
package/dist/react.d.cts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget color theme. "auto" follows the website: theme classes or
|
|
3
|
+
* attributes like class="dark" or data-theme="dark" on <html> or <body>,
|
|
4
|
+
* the page background, or a declared color-scheme.
|
|
5
|
+
*/
|
|
6
|
+
type BitPalmTheme = "auto" | "light" | "dark";
|
|
1
7
|
interface BitPalmAgentOptions {
|
|
2
8
|
/** Your agent slug from the BitPalm dashboard. */
|
|
3
9
|
slug: string;
|
|
@@ -15,6 +21,12 @@ interface BitPalmAgentOptions {
|
|
|
15
21
|
* Defaults to true.
|
|
16
22
|
*/
|
|
17
23
|
autoIdentify?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Light or dark widget colors. Defaults to "auto", which follows the
|
|
26
|
+
* website's theme and switches live when the site switches. Only has an
|
|
27
|
+
* effect when the agent has a dark theme set up in the dashboard.
|
|
28
|
+
*/
|
|
29
|
+
theme?: BitPalmTheme;
|
|
18
30
|
}
|
|
19
31
|
interface BitPalmIdentifyPayload {
|
|
20
32
|
/** Stable user id from the host platform (required for signed identify). */
|
|
@@ -95,6 +107,13 @@ interface BitPalmAgentInstance {
|
|
|
95
107
|
on: (event: BitPalmEventType, callback: BitPalmEventCallback) => () => void;
|
|
96
108
|
/** Unsubscribe from a widget event. */
|
|
97
109
|
off: (event: BitPalmEventType, callback: BitPalmEventCallback) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Switch the widget theme. "auto" goes back to following the website.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* widget.setTheme('dark');
|
|
115
|
+
*/
|
|
116
|
+
setTheme: (theme: BitPalmTheme) => void;
|
|
98
117
|
/** Remove the widget and clean up all event listeners. */
|
|
99
118
|
destroy: () => void;
|
|
100
119
|
}
|
package/dist/react.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Widget color theme. "auto" follows the website: theme classes or
|
|
3
|
+
* attributes like class="dark" or data-theme="dark" on <html> or <body>,
|
|
4
|
+
* the page background, or a declared color-scheme.
|
|
5
|
+
*/
|
|
6
|
+
type BitPalmTheme = "auto" | "light" | "dark";
|
|
1
7
|
interface BitPalmAgentOptions {
|
|
2
8
|
/** Your agent slug from the BitPalm dashboard. */
|
|
3
9
|
slug: string;
|
|
@@ -15,6 +21,12 @@ interface BitPalmAgentOptions {
|
|
|
15
21
|
* Defaults to true.
|
|
16
22
|
*/
|
|
17
23
|
autoIdentify?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Light or dark widget colors. Defaults to "auto", which follows the
|
|
26
|
+
* website's theme and switches live when the site switches. Only has an
|
|
27
|
+
* effect when the agent has a dark theme set up in the dashboard.
|
|
28
|
+
*/
|
|
29
|
+
theme?: BitPalmTheme;
|
|
18
30
|
}
|
|
19
31
|
interface BitPalmIdentifyPayload {
|
|
20
32
|
/** Stable user id from the host platform (required for signed identify). */
|
|
@@ -95,6 +107,13 @@ interface BitPalmAgentInstance {
|
|
|
95
107
|
on: (event: BitPalmEventType, callback: BitPalmEventCallback) => () => void;
|
|
96
108
|
/** Unsubscribe from a widget event. */
|
|
97
109
|
off: (event: BitPalmEventType, callback: BitPalmEventCallback) => void;
|
|
110
|
+
/**
|
|
111
|
+
* Switch the widget theme. "auto" goes back to following the website.
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* widget.setTheme('dark');
|
|
115
|
+
*/
|
|
116
|
+
setTheme: (theme: BitPalmTheme) => void;
|
|
98
117
|
/** Remove the widget and clean up all event listeners. */
|
|
99
118
|
destroy: () => void;
|
|
100
119
|
}
|