@bitpalm/ai-agents 0.1.19 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -34,20 +34,71 @@ interface BitPalmIdentifyPayload {
34
34
  /** Signature schema version. Defaults to "v1". */
35
35
  signatureVersion?: "v1";
36
36
  }
37
+ /**
38
+ * Custom context data to pass to the AI chatbot.
39
+ * The bot uses this as additional context for more relevant answers.
40
+ *
41
+ * @example
42
+ * BitPalm('context', {
43
+ * cart: { items: [{ name: 'Nike Air Max', size: '42', price: 149.99 }], total: 149.99 },
44
+ * customerTier: 'premium',
45
+ * });
46
+ */
47
+ type BitPalmCustomContext = Record<string, unknown>;
48
+ /** Event types emitted by the widget. */
49
+ type BitPalmEventType = "widget_opened" | "widget_closed" | "conversation_started" | "message_sent" | "message_received" | "lead_captured";
50
+ /** Callback for widget events. */
51
+ type BitPalmEventCallback = (data?: Record<string, unknown>) => void;
37
52
  interface BitPalmAgentInstance {
38
53
  /** Open the chat widget programmatically. */
39
54
  open: () => void;
40
55
  /** Close the chat widget programmatically. */
41
56
  close: () => void;
57
+ /** Toggle the widget open/closed. */
58
+ toggle: () => void;
59
+ /** Returns true if the chat widget is currently open. */
60
+ isOpen: () => boolean;
42
61
  /**
43
62
  * Manually identify the current visitor with trusted platform user data.
44
63
  * Use this after your user login state is known.
45
64
  */
46
65
  identify: (payload: BitPalmIdentifyPayload) => void;
66
+ /**
67
+ * Pass custom context data to the AI chatbot.
68
+ * Merges with any previously set context (does not replace).
69
+ * The bot uses this to give more relevant, business-specific answers.
70
+ *
71
+ * @example
72
+ * BitPalm('context', { cart: { items: [...], total: 99.99 } });
73
+ * BitPalm('context', { promoCode: 'SUMMER20' }); // merges, doesn't replace cart
74
+ */
75
+ context: (data: BitPalmCustomContext) => void;
76
+ /** Clear all custom context data. Use after purchase completion, logout, etc. */
77
+ resetContext: () => void;
78
+ /**
79
+ * Programmatically send a message as the user.
80
+ * Opens the widget if closed, then sends the message to the AI.
81
+ *
82
+ * @example
83
+ * widget.send('Tell me more about the Enterprise plan');
84
+ */
85
+ send: (message: string) => void;
86
+ /**
87
+ * Subscribe to widget events.
88
+ * @returns Unsubscribe function.
89
+ *
90
+ * @example
91
+ * const unsub = widget.on('lead_captured', (data) => {
92
+ * gtag('event', 'lead_captured', data);
93
+ * });
94
+ */
95
+ on: (event: BitPalmEventType, callback: BitPalmEventCallback) => () => void;
96
+ /** Unsubscribe from a widget event. */
97
+ off: (event: BitPalmEventType, callback: BitPalmEventCallback) => void;
47
98
  /** Remove the widget and clean up all event listeners. */
48
99
  destroy: () => void;
49
100
  }
50
101
 
51
102
  declare function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance;
52
103
 
53
- export { type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmIdentifyPayload, createWidget };
104
+ export { type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmCustomContext, type BitPalmEventCallback, type BitPalmEventType, type BitPalmIdentifyPayload, createWidget };
package/dist/index.d.ts CHANGED
@@ -34,20 +34,71 @@ interface BitPalmIdentifyPayload {
34
34
  /** Signature schema version. Defaults to "v1". */
35
35
  signatureVersion?: "v1";
36
36
  }
37
+ /**
38
+ * Custom context data to pass to the AI chatbot.
39
+ * The bot uses this as additional context for more relevant answers.
40
+ *
41
+ * @example
42
+ * BitPalm('context', {
43
+ * cart: { items: [{ name: 'Nike Air Max', size: '42', price: 149.99 }], total: 149.99 },
44
+ * customerTier: 'premium',
45
+ * });
46
+ */
47
+ type BitPalmCustomContext = Record<string, unknown>;
48
+ /** Event types emitted by the widget. */
49
+ type BitPalmEventType = "widget_opened" | "widget_closed" | "conversation_started" | "message_sent" | "message_received" | "lead_captured";
50
+ /** Callback for widget events. */
51
+ type BitPalmEventCallback = (data?: Record<string, unknown>) => void;
37
52
  interface BitPalmAgentInstance {
38
53
  /** Open the chat widget programmatically. */
39
54
  open: () => void;
40
55
  /** Close the chat widget programmatically. */
41
56
  close: () => void;
57
+ /** Toggle the widget open/closed. */
58
+ toggle: () => void;
59
+ /** Returns true if the chat widget is currently open. */
60
+ isOpen: () => boolean;
42
61
  /**
43
62
  * Manually identify the current visitor with trusted platform user data.
44
63
  * Use this after your user login state is known.
45
64
  */
46
65
  identify: (payload: BitPalmIdentifyPayload) => void;
66
+ /**
67
+ * Pass custom context data to the AI chatbot.
68
+ * Merges with any previously set context (does not replace).
69
+ * The bot uses this to give more relevant, business-specific answers.
70
+ *
71
+ * @example
72
+ * BitPalm('context', { cart: { items: [...], total: 99.99 } });
73
+ * BitPalm('context', { promoCode: 'SUMMER20' }); // merges, doesn't replace cart
74
+ */
75
+ context: (data: BitPalmCustomContext) => void;
76
+ /** Clear all custom context data. Use after purchase completion, logout, etc. */
77
+ resetContext: () => void;
78
+ /**
79
+ * Programmatically send a message as the user.
80
+ * Opens the widget if closed, then sends the message to the AI.
81
+ *
82
+ * @example
83
+ * widget.send('Tell me more about the Enterprise plan');
84
+ */
85
+ send: (message: string) => void;
86
+ /**
87
+ * Subscribe to widget events.
88
+ * @returns Unsubscribe function.
89
+ *
90
+ * @example
91
+ * const unsub = widget.on('lead_captured', (data) => {
92
+ * gtag('event', 'lead_captured', data);
93
+ * });
94
+ */
95
+ on: (event: BitPalmEventType, callback: BitPalmEventCallback) => () => void;
96
+ /** Unsubscribe from a widget event. */
97
+ off: (event: BitPalmEventType, callback: BitPalmEventCallback) => void;
47
98
  /** Remove the widget and clean up all event listeners. */
48
99
  destroy: () => void;
49
100
  }
50
101
 
51
102
  declare function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance;
52
103
 
53
- export { type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmIdentifyPayload, createWidget };
104
+ export { type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmCustomContext, type BitPalmEventCallback, type BitPalmEventType, type BitPalmIdentifyPayload, createWidget };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var Be="https://agents.bitpalm.ae",y="_bp_",$e=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),He=8e3,_e=`${y}identify_signature`,Me=`${y}identify_fingerprint`,ke=`${y}identify_sent_at`;function Ne(t){return[t.external_user_id||"",t.email||"",t.phone||"",t.name||"",t.company||"",t.signature||"",t.signed_at!=null?String(t.signed_at):"",t.signature_version||""].join("|").toLowerCase()}function d(t,o=180){return t?t.replace(/\s+/g," ").trim().slice(0,o):""}function Fe(t){return t?` ${t.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function D(t,o){for(let u of o)if(t.includes(u))return!0;return!1}function _(t){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(t)}function T(t){let o=d(t,50);if(!o)return"";let u=o.startsWith("+"),s=o.replace(/\D/g,"");return s.length<6?"":`${u?"+":""}${s.slice(0,20)}`}function Pe(t){let o=d(t,140).toLowerCase();return!o||!_(o)?"":o}function R(t,o){for(let u of o){let s=t.querySelector(u),p=d(s?.value);if(p)return p}return""}function Oe(t){return d(t.getAttribute("data-bp-field")||t.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function De(t){return t.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Re(t,o){let u=[],s=(i,v=140)=>{let l=d(i,v);l&&u.push(l)};s(o.name),s(o.id),s(o.getAttribute("autocomplete")),s(o.getAttribute("placeholder")),s(o.getAttribute("aria-label")),s(o.getAttribute("data-field")),s(o.getAttribute("data-name")),s(o.getAttribute("data-label")),s(o.getAttribute("data-bp-field")),s(o.getAttribute("data-bitpalm-field"));let p=new Set,h=i=>{let v=d(i,200);!v||p.has(v)||(p.add(v),u.push(v))};for(let i of Array.from(o.labels||[]))h(i.textContent);if(o.id){let i=t.querySelector(`label[for="${De(o.id)}"]`);h(i?.textContent)}let g=o.closest("label");h(g?.textContent);let r=o.getAttribute("aria-labelledby");if(r)for(let i of r.split(/\s+/)){if(!i)continue;let v=t.ownerDocument.getElementById(i);h(v?.textContent)}return u}function Ue(t){let o=d(R(t,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),u=T(R(t,["[data-bp-phone]","[data-bitpalm-phone]"])),s=d(R(t,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),p=d(R(t,["[data-bp-first-name]","[data-bitpalm-first-name]"])),h=d(R(t,["[data-bp-last-name]","[data-bitpalm-last-name]"])),g=d(R(t,["[data-bp-company]","[data-bitpalm-company]"]));for(let l of Array.from(t.elements)){if(!(l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)||l.disabled||l instanceof HTMLInputElement&&$e.has(l.type.toLowerCase()))continue;let f=Oe(l),m=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")||!!f;if(l instanceof HTMLInputElement&&l.type.toLowerCase()==="hidden"&&!m)continue;let c=d(l.value);if(!c)continue;let B=l instanceof HTMLInputElement?l.type.toLowerCase():"",E=Fe(Re(t,l).join(" "));if(!o&&f==="email"&&_(c)){o=c.toLowerCase();continue}if(!u&&(f==="phone"||f==="tel"||f==="mobile"||f==="whatsapp")){let I=T(c);if(I){u=I;continue}}if(!g&&f==="company"){g=d(c,160);continue}if(!p&&(f==="first-name"||f==="firstname")){p=d(c,100);continue}if(!h&&(f==="last-name"||f==="lastname"||f==="surname")){h=d(c,100);continue}if(!s&&(f==="name"||f==="full-name"||f==="fullname")){!_(c)&&!T(c)&&(s=d(c,140));continue}let U=B==="email"||D(E,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),$=B==="tel"||D(E,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),H=D(E,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),N=D(E,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),F=D(E,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),W=D(E,[" full name "," fullname "," contact name "," name "])&&!U&&!$;if(!o&&U&&_(c)){o=c.toLowerCase();continue}if(!u&&$){let I=T(c);if(I){u=I;continue}}if(!g&&H){g=d(c,160);continue}if(!p&&N){p=d(c,100);continue}if(!h&&F){h=d(c,100);continue}if(!s&&W&&!_(c)&&!T(c)){s=d(c,140);continue}!o&&_(c)&&(o=c.toLowerCase())}if(s&&(_(s)||T(s))&&(s=""),g&&(_(g)||T(g))&&(g=""),s||(s=d([p,h].filter(Boolean).join(" "),140)),s&&o&&s.toLowerCase()===o.toLowerCase()&&(s=""),!!!(o||u)&&!!!(s&&g))return null;let v={...s?{name:s}:{},...o?{email:o}:{},...u?{phone:u}:{},...g?{company:g}:{}};return Object.keys(v).length>0?v:null}function We(){if(typeof document<"u"){let t=document.documentElement.lang;if(t)return t.slice(0,2).toLowerCase()}return"en"}function ae(t,o=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(t,{timeout:o});return}setTimeout(t,Math.min(o,300))}function se(){if(typeof window>"u")return!1;let t=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(t))return!0;let u=window.matchMedia("(pointer: coarse)").matches,s=window.matchMedia("(hover: none)").matches,p=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return u&&s&&p<=900}function re(t){let{slug:o,locale:u=We(),baseUrl:s=Be,token:p,zIndex:h=9999,autoIdentify:g=!0}=t,r=document,i=r.createElement("iframe"),v=`${s}/t/${o}/widget`,l=new URLSearchParams({locale:u});p&&l.set("token",p),i.src=`${v}?${l.toString()}`,i.allow="clipboard-write",i.setAttribute("allowtransparency","true"),i.loading="lazy",i.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${h};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;let f=new URL(i.src).origin,m=r.createElement("div");if(m.setAttribute("role","button"),m.setAttribute("aria-label","Chat"),m.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:${h-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s,opacity .3s;opacity:0;`,m.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>',m.onmouseenter=()=>{m.style.transform="scale(1.1)"},m.onmouseleave=()=>{m.style.transform="scale(1)"},m.onclick=()=>Se(),r.body.appendChild(m),!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 c=null,B=!1,E=!1,U=!1,$=!1,H=!1,N=()=>{U||(U=!0,r.body.appendChild(i))},F=!1,W=0,I={overflow:"",overscrollBehavior:""},b={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},le=()=>{if(F||!se())return;let a=r.documentElement,n=r.body;W=window.scrollY||window.pageYOffset||0,I.overflow=a.style.overflow,I.overscrollBehavior=a.style.overscrollBehavior,b.overflow=n.style.overflow,b.overscrollBehavior=n.style.overscrollBehavior,b.position=n.style.position,b.top=n.style.top,b.left=n.style.left,b.right=n.style.right,b.width=n.style.width,a.style.overflow="hidden",a.style.overscrollBehavior="none",n.style.overflow="hidden",n.style.overscrollBehavior="none",n.style.position="fixed",n.style.top=`-${W}px`,n.style.left="0",n.style.right="0",n.style.width="100%",F=!0},O=()=>{if(!F)return;let e=r.documentElement,a=r.body;e.style.overflow=I.overflow,e.style.overscrollBehavior=I.overscrollBehavior,a.style.overflow=b.overflow,a.style.overscrollBehavior=b.overscrollBehavior,a.style.position=b.position,a.style.top=b.top,a.style.left=b.left,a.style.right=b.right,a.style.width=b.width,window.scrollTo(0,W),F=!1},ce=()=>{let e=se();i.style.display==="none"&&(i.style.display=""),e?(i.style.width="100vw",i.style.height="100dvh",i.style.left="0",i.style.top="0",le()):(i.style.width="420px",i.style.height="620px",i.style.left="",i.style.top="",O()),i.style.opacity="1",i.style.pointerEvents="auto"},M=()=>{c&&(c.remove(),c=null)},z=()=>{},V=()=>{},de=e=>{if(e.origin===f){if(e.data?.type==="bitpalm-widget-config"){E=!1,B=!0,i.style.display==="none"&&(i.style.display=""),e.data.primaryColor&&(m.style.background=e.data.primaryColor,m.style.boxShadow=e.data.chatShadow==="none"?"none":`0 0 15px ${e.data.primaryColor}50`);let a=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){m.innerHTML="";let n=r.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${a}`;let S=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");S?(S.querySelectorAll("script,foreignObject").forEach(P=>P.remove()),S.querySelectorAll("*").forEach(P=>{for(let C of[...P.attributes])(C.name.startsWith("on")||C.value&&C.value.includes("javascript:"))&&P.removeAttribute(C.name)}),S.setAttribute("width","24"),S.setAttribute("height","24"),S.style.display="block",n.appendChild(S)):n.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>',m.appendChild(n)}else{let n=m.querySelector("svg");n&&(n.style.stroke=a)}m.style.display="flex",requestAnimationFrame(()=>{m.style.opacity="1"})}if(e.data?.type==="bitpalm-widget-resize"){let a=e.data.width>0,n=se();a?(i.style.width=n?"100vw":`${e.data.width}px`,i.style.height=n?"100dvh":`${e.data.height}px`,n?(i.style.left="0",i.style.top="0",le()):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"),m.style.display=a?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(E||!B)return;M(),c=r.createElement("div"),c.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:${h-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let a=(e.data.message||"").replace(/</g,"&lt;");c.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${a}</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 n=r.createElement("button");n.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.innerHTML="&#10005;",n.onclick=w=>{w.stopPropagation(),M(),i.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},c.onclick=()=>{if(M(),m.style.display="none",ce(),N(),!$){H=!0;return}i.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},c.appendChild(n),r.body.appendChild(c)}e.data?.type==="bitpalm-trigger-hide"&&M(),e.data?.type==="bitpalm-request-context"&&z(),e.data?.type==="bitpalm-widget-blocked"&&(E=!0,B=!1,m.style.display="none",M(),O(),i.style.display="none")}};window.addEventListener("message",de);let L=!1;try{L=localStorage.getItem(`${y}optout`)==="1"}catch{}let q=`${y}vid`,x="";if(!L){try{x=localStorage.getItem(q)||""}catch{}if(!x){let e=r.cookie.match(new RegExp(`(?:^|; )${q}=([^;]+)`));x=e?decodeURIComponent(e[1]):""}x||(x=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(q,x)}catch{}try{r.cookie=`${q}=${encodeURIComponent(x)};path=/;max-age=31536000;SameSite=Lax`}catch{}}L||ae(()=>{try{let e=new URLSearchParams(location.search),a={};for(let A of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let S=e.get(A);S&&(a[A]=S)}let n=JSON.stringify({tenant_slug:o,visitor_id:x,url:location.href,referrer:r.referrer||void 0,...Object.keys(a).length>0?{utm:a}:{}}),w=`${s}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(w,new Blob([n],{type:"application/json"})):fetch(w,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let K="",Z="",X=0;try{K=sessionStorage.getItem(_e)||"",Z=sessionStorage.getItem(Me)||"";let e=parseInt(sessionStorage.getItem(ke)||"0",10);Number.isFinite(e)&&e>0&&(X=e)}catch{}let me=(e,a="")=>{if(L||!x)return;let n={},w=d(e.name,140),A=Pe(e.email),S=T(e.phone),P=d(e.company,160),C=d(e.external_user_id,140),Le=d(e.signature,260),ne=Number(e.signed_at);if(w&&(n.name=w),A&&(n.email=A),S&&(n.phone=S),P&&(n.company=P),C&&(n.external_user_id=C),Le&&(n.signature=Le),Number.isFinite(ne)&&ne>0&&(n.signed_at=Math.floor(ne)),(e.signature_version==="v1"||n.signature)&&(n.signature_version="v1"),!n.name&&!n.email&&!n.phone&&!n.company&&!n.external_user_id)return;let G=Ne(n),ie=[a.toLowerCase(),G].filter(Boolean).join("|"),oe=Date.now();if(!(oe-X<He&&(ie===K||G===Z))){K=ie,Z=G,X=oe;try{sessionStorage.setItem(_e,ie),sessionStorage.setItem(Me,G),sessionStorage.setItem(ke,String(oe))}catch{}try{let Te=JSON.stringify({tenant_slug:o,visitor_id:x,url:location.href,referrer:r.referrer||void 0,...n}),Ae=`${s}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(Ae,new Blob([Te],{type:"application/json"})):fetch(Ae,{method:"POST",body:Te,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},ue=e=>{if(L||!g||!x)return;let a=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(a instanceof HTMLFormElement))return;let n=(a.getAttribute("data-bp-identify")||a.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(n==="off"||n==="false"||n==="0")return;let w=Ue(a);if(!w)return;let A=[a.getAttribute("id")||"",a.getAttribute("name")||"",a.getAttribute("action")||""].join("|");me(w,A)};!L&&g&&r.addEventListener("submit",ue,!0);let j=parseInt(sessionStorage.getItem(`${y}pages`)||"0")+1;sessionStorage.setItem(`${y}pages`,String(j));let k=JSON.parse(sessionStorage.getItem(`${y}hist`)||"[]");k.push(location.href),k.length>20&&(k=k.slice(-20)),sessionStorage.setItem(`${y}hist`,JSON.stringify(k));let fe=Date.now(),Y=parseInt(sessionStorage.getItem(`${y}site_start`)||"0");Y||(Y=fe,sessionStorage.setItem(`${y}site_start`,String(Y)));let pe=[];z=()=>{let e=!1;try{e=!!localStorage.getItem(`${y}visited`)}catch{e=!1}if(i.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:r.title,returning:e,pageCount:j,pageHistory:k,loadedAt:fe,siteStart:Y,locale:u,visitorId:L?"":x},"*"),!e&&!L)try{localStorage.setItem(`${y}visited`,"1")}catch{}},i.addEventListener("load",()=>{$=!0,z(),[120,450,1100].forEach(e=>{let a=setTimeout(()=>z(),e);pe.push(a)}),H&&(H=!1,V())}),r.readyState==="loading"?r.addEventListener("DOMContentLoaded",()=>ae(N,1600),{once:!0}):ae(N,1600);let ge=history.pushState.bind(history),ye=history.replaceState.bind(history),J=()=>{j++,sessionStorage.setItem(`${y}pages`,String(j));let e=JSON.parse(sessionStorage.getItem(`${y}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),k=e,sessionStorage.setItem(`${y}hist`,JSON.stringify(e)),i.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:r.title,pageCount:j,pageHistory:e,loadedAt:Date.now()},"*"),!L)try{let a=JSON.stringify({tenant_slug:o,visitor_id:x,url:location.href}),n=`${s}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(n,new Blob([a],{type:"application/json"})):fetch(n,{method:"POST",body:a,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){ge(...e),J()},history.replaceState=function(...e){ye(...e),J()},window.addEventListener("popstate",J);let he=-1,Q,be=()=>{clearTimeout(Q),Q=setTimeout(()=>{let e=Math.max(r.documentElement.scrollHeight,r.body.scrollHeight)-window.innerHeight,a=e>0?Math.round(window.scrollY/e*100):100;a!==he&&(he=a,i.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:a},"*"))},500)};window.addEventListener("scroll",be,{passive:!0});let we=e=>{e.clientY<=0&&i.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};r.addEventListener("mouseout",we);let ee,ve=!1,te=()=>{clearTimeout(ee),!ve&&(ee=setTimeout(()=>{ve=!0,i.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},xe=["mousemove","keydown","scroll","touchstart"];xe.forEach(e=>r.addEventListener(e,te,{passive:!0})),te(),V=()=>{i.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=i.src.split("#")[0];i.src=`${e}#bp-open-${Date.now()}`};let Se=()=>{if(m.style.display="none",M(),ce(),N(),!$){H=!0;return}V()},Ce=()=>{O(),i.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Ee=e=>{!e||typeof e!="object"||me({external_user_id:d(e.externalUserId,140)||void 0,name:d(e.name,140)||void 0,email:Pe(e.email)||void 0,phone:T(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},"manual")},Ie=e=>{let n=e.detail;if(!n||typeof n!="object")return;let w=d(n.slug,120);w&&w!==o||Ee(n)};return window.addEventListener("bitpalm-identify",Ie),{open:Se,close:Ce,identify:Ee,destroy:()=>{window.removeEventListener("message",de),window.removeEventListener("scroll",be),window.removeEventListener("popstate",J),r.removeEventListener("mouseout",we),r.removeEventListener("submit",ue,!0),xe.forEach(e=>r.removeEventListener(e,te)),clearTimeout(Q),clearTimeout(ee),pe.forEach(e=>clearTimeout(e)),history.pushState=ge,history.replaceState=ye,window.removeEventListener("bitpalm-identify",Ie),O(),M(),m.remove(),i.remove()}}}function je(t){if(t==null)return;let o=t.trim().toLowerCase();if(["1","true","yes","on"].includes(o))return!0;if(["0","false","no","off"].includes(o))return!1}if(typeof document<"u"){let t=document.currentScript;if(t?.dataset.slug){let o=()=>{re({slug:t.dataset.slug,locale:t.dataset.locale,baseUrl:t.dataset.baseUrl,token:t.dataset.token,zIndex:t.dataset.zIndex?Number(t.dataset.zIndex):void 0,autoIdentify:je(t.dataset.autoIdentify)})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",o):o()}}export{re as createWidget};
1
+ var ze="https://agents.bitpalm.ae",h="_bp_",qe=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),Ye=8e3,Oe=4096,He=`${h}identify_signature`,Ne=`${h}identify_fingerprint`,Re=`${h}identify_sent_at`;function Je(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,s=180){return n?n.replace(/\s+/g," ").trim().slice(0,s):""}function Ge(n){return n?` ${n.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function W(n,s){for(let f of s)if(n.includes(f))return!0;return!1}function A(n){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(n)}function _(n){let s=d(n,50);if(!s)return"";let f=s.startsWith("+"),a=s.replace(/\D/g,"");return a.length<6?"":`${f?"+":""}${a.slice(0,20)}`}function Fe(n){let s=d(n,140).toLowerCase();return!s||!A(s)?"":s}function U(n,s){for(let f of s){let a=n.querySelector(f),g=d(a?.value);if(g)return g}return""}function Ve(n){return d(n.getAttribute("data-bp-field")||n.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function Ke(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Xe(n,s){let f=[],a=(i,E=140)=>{let l=d(i,E);l&&f.push(l)};a(s.name),a(s.id),a(s.getAttribute("autocomplete")),a(s.getAttribute("placeholder")),a(s.getAttribute("aria-label")),a(s.getAttribute("data-field")),a(s.getAttribute("data-name")),a(s.getAttribute("data-label")),a(s.getAttribute("data-bp-field")),a(s.getAttribute("data-bitpalm-field"));let g=new Set,w=i=>{let E=d(i,200);!E||g.has(E)||(g.add(E),f.push(E))};for(let i of Array.from(s.labels||[]))w(i.textContent);if(s.id){let i=n.querySelector(`label[for="${Ke(s.id)}"]`);w(i?.textContent)}let y=s.closest("label");w(y?.textContent);let r=s.getAttribute("aria-labelledby");if(r)for(let i of r.split(/\s+/)){if(!i)continue;let E=n.ownerDocument.getElementById(i);w(E?.textContent)}return f}function Ze(n){let s=d(U(n,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),f=_(U(n,["[data-bp-phone]","[data-bitpalm-phone]"])),a=d(U(n,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),g=d(U(n,["[data-bp-first-name]","[data-bitpalm-first-name]"])),w=d(U(n,["[data-bp-last-name]","[data-bitpalm-last-name]"])),y=d(U(n,["[data-bp-company]","[data-bitpalm-company]"]));for(let l of Array.from(n.elements)){if(!(l instanceof HTMLInputElement||l instanceof HTMLTextAreaElement||l instanceof HTMLSelectElement)||l.disabled||l instanceof HTMLInputElement&&qe.has(l.type.toLowerCase()))continue;let p=Ve(l),m=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")||!!p;if(l instanceof HTMLInputElement&&l.type.toLowerCase()==="hidden"&&!m)continue;let c=d(l.value);if(!c)continue;let $=l instanceof HTMLInputElement?l.type.toLowerCase():"",S=Ge(Xe(n,l).join(" "));if(!s&&p==="email"&&A(c)){s=c.toLowerCase();continue}if(!f&&(p==="phone"||p==="tel"||p==="mobile"||p==="whatsapp")){let I=_(c);if(I){f=I;continue}}if(!y&&p==="company"){y=d(c,160);continue}if(!g&&(p==="first-name"||p==="firstname")){g=d(c,100);continue}if(!w&&(p==="last-name"||p==="lastname"||p==="surname")){w=d(c,100);continue}if(!a&&(p==="name"||p==="full-name"||p==="fullname")){!A(c)&&!_(c)&&(a=d(c,140));continue}let j=$==="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 "]),N=W(S,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),R=W(S,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),z=W(S,[" full name "," fullname "," contact name "," name "])&&!j&&!O;if(!s&&j&&A(c)){s=c.toLowerCase();continue}if(!f&&O){let I=_(c);if(I){f=I;continue}}if(!y&&H){y=d(c,160);continue}if(!g&&N){g=d(c,100);continue}if(!w&&R){w=d(c,100);continue}if(!a&&z&&!A(c)&&!_(c)){a=d(c,140);continue}!s&&A(c)&&(s=c.toLowerCase())}if(a&&(A(a)||_(a))&&(a=""),y&&(A(y)||_(y))&&(y=""),a||(a=d([g,w].filter(Boolean).join(" "),140)),a&&s&&a.toLowerCase()===s.toLowerCase()&&(a=""),!!!(s||f)&&!!!(a&&y))return null;let E={...a?{name:a}:{},...s?{email:s}:{},...f?{phone:f}:{},...y?{company:y}:{}};return Object.keys(E).length>0?E:null}function Qe(){if(typeof document<"u"){let n=document.documentElement.lang;if(n)return n.slice(0,2).toLowerCase()}return"en"}function de(n,s=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(n,{timeout:s});return}setTimeout(n,Math.min(s,300))}function me(){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 f=window.matchMedia("(pointer: coarse)").matches,a=window.matchMedia("(hover: none)").matches,g=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return f&&a&&g<=900}function ue(n){let{slug:s,locale:f=Qe(),baseUrl:a=ze,token:g,zIndex:w=9999,autoIdentify:y=!0}=n,r=document,i=r.createElement("iframe"),E=`${a}/t/${s}/widget`,l=new URLSearchParams({locale:f});g&&l.set("token",g),i.src=`${E}?${l.toString()}`,i.allow="clipboard-write",i.setAttribute("allowtransparency","true"),i.loading="lazy",i.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 p=new URL(i.src).origin,m=r.createElement("div");if(m.setAttribute("role","button"),m.setAttribute("aria-label","Chat"),m.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;`,m.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>',m.onmouseenter=()=>{m.style.transform="scale(1.1)"},m.onmouseleave=()=>{m.style.transform="scale(1)"},m.onclick=()=>X(),r.body.appendChild(m),!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 c=null,$=!1,S=!1,j=!1,O=!1,H=!1,N=()=>{j||(j=!0,r.body.appendChild(i))},R=!1,z=0,I={overflow:"",overscrollBehavior:""},v={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},fe=()=>{if(R||!me())return;let o=r.documentElement,t=r.body;z=window.scrollY||window.pageYOffset||0,I.overflow=o.style.overflow,I.overscrollBehavior=o.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,o.style.overflow="hidden",o.style.overscrollBehavior="none",t.style.overflow="hidden",t.style.overscrollBehavior="none",t.style.position="fixed",t.style.top=`-${z}px`,t.style.left="0",t.style.right="0",t.style.width="100%",R=!0},F=()=>{if(!R)return;let e=r.documentElement,o=r.body;e.style.overflow=I.overflow,e.style.overscrollBehavior=I.overscrollBehavior,o.style.overflow=v.overflow,o.style.overscrollBehavior=v.overscrollBehavior,o.style.position=v.position,o.style.top=v.top,o.style.left=v.left,o.style.right=v.right,o.style.width=v.width,window.scrollTo(0,z),R=!1},pe=()=>{let e=me();i.style.display==="none"&&(i.style.display=""),e?(i.style.width="100vw",i.style.height="100dvh",i.style.left="0",i.style.top="0",fe()):(i.style.width="420px",i.style.height="620px",i.style.left="",i.style.top="",F()),i.style.opacity="1",i.style.pointerEvents="auto"},C=()=>{c&&(c.remove(),c=null)},J=()=>{},Q=()=>{},D=!1,P=new Map;function ee(e,o){let t=P.get(e);if(t)for(let u of t)try{u(o)}catch{}}let ge=e=>{if(e.origin===p){if(e.data?.type==="bitpalm-widget-config"){S=!1,$=!0,i.style.display==="none"&&(i.style.display=""),e.data.primaryColor&&(m.style.background=e.data.primaryColor,m.style.boxShadow=e.data.chatShadow==="none"?"none":`0 0 15px ${e.data.primaryColor}50`);let o=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){m.innerHTML="";let t=r.createElement("span");t.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${o}`;let b=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");b?(b.querySelectorAll("script,foreignObject").forEach(B=>B.remove()),b.querySelectorAll("*").forEach(B=>{for(let k of[...B.attributes])(k.name.startsWith("on")||k.value&&k.value.includes("javascript:"))&&B.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>',m.appendChild(t)}else{let t=m.querySelector("svg");t&&(t.style.stroke=o)}m.style.display="flex",requestAnimationFrame(()=>{m.style.opacity="1"})}if(e.data?.type==="bitpalm-widget-resize"){let o=e.data.width>0,t=D;D=o,o&&!t&&ee("widget_opened"),!o&&t&&ee("widget_closed");let u=me();o?(i.style.width=u?"100vw":`${e.data.width}px`,i.style.height=u?"100dvh":`${e.data.height}px`,u?(i.style.left="0",i.style.top="0",fe()):F(),i.style.opacity="1",i.style.pointerEvents="auto"):(F(),i.style.width="1px",i.style.height="1px",i.style.left="",i.style.top="",i.style.opacity="0",i.style.pointerEvents="none"),m.style.display=o?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(S||!$)return;C(),c=r.createElement("div"),c.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 o=(e.data.message||"").replace(/</g,"&lt;");c.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${o}</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="&#10005;",t.onclick=u=>{u.stopPropagation(),C(),i.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},c.onclick=()=>{if(C(),m.style.display="none",pe(),N(),!O){H=!0;return}i.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},c.appendChild(t),r.body.appendChild(c)}e.data?.type==="bitpalm-trigger-hide"&&C(),e.data?.type==="bitpalm-request-context"&&J(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&ee(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(S=!0,$=!1,m.style.display="none",C(),F(),i.style.display="none")}};window.addEventListener("message",ge);let L=!1;try{L=localStorage.getItem(`${h}optout`)==="1"}catch{}let G=`${h}vid`,x="";if(!L){try{x=localStorage.getItem(G)||""}catch{}if(!x){let e=r.cookie.match(new RegExp(`(?:^|; )${G}=([^;]+)`));x=e?decodeURIComponent(e[1]):""}x||(x=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(G,x)}catch{}try{r.cookie=`${G}=${encodeURIComponent(x)};path=/;max-age=31536000;SameSite=Lax`}catch{}}L||de(()=>{try{let e=new URLSearchParams(location.search),o={};for(let T of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let b=e.get(T);b&&(o[T]=b)}let t=JSON.stringify({tenant_slug:s,visitor_id:x,url:location.href,referrer:r.referrer||void 0,...Object.keys(o).length>0?{utm:o}:{}}),u=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(u,new Blob([t],{type:"application/json"})):fetch(u,{method:"POST",body:t,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let te="",ne="",ie=0;try{te=sessionStorage.getItem(He)||"",ne=sessionStorage.getItem(Ne)||"";let e=parseInt(sessionStorage.getItem(Re)||"0",10);Number.isFinite(e)&&e>0&&(ie=e)}catch{}let ye=(e,o="")=>{if(L||!x)return;let t={},u=d(e.name,140),T=Fe(e.email),b=_(e.phone),B=d(e.company,160),k=d(e.external_user_id,140),Be=d(e.signature,260),re=Number(e.signed_at);if(u&&(t.name=u),T&&(t.email=T),b&&(t.phone=b),B&&(t.company=B),k&&(t.external_user_id=k),Be&&(t.signature=Be),Number.isFinite(re)&&re>0&&(t.signed_at=Math.floor(re)),(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 Z=Je(t),le=[o.toLowerCase(),Z].filter(Boolean).join("|"),ce=Date.now();if(!(ce-ie<Ye&&(le===te||Z===ne))){te=le,ne=Z,ie=ce;try{sessionStorage.setItem(He,le),sessionStorage.setItem(Ne,Z),sessionStorage.setItem(Re,String(ce))}catch{}try{let ke=JSON.stringify({tenant_slug:s,visitor_id:x,url:location.href,referrer:r.referrer||void 0,...t}),$e=`${a}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon($e,new Blob([ke],{type:"application/json"})):fetch($e,{method:"POST",body:ke,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},he=e=>{if(L||!y||!x)return;let o=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(o instanceof HTMLFormElement))return;let t=(o.getAttribute("data-bp-identify")||o.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(t==="off"||t==="false"||t==="0")return;let u=Ze(o);if(!u)return;let T=[o.getAttribute("id")||"",o.getAttribute("name")||"",o.getAttribute("action")||""].join("|");ye({...u,identify_source:"form"},T)};!L&&y&&r.addEventListener("submit",he,!0);let q=parseInt(sessionStorage.getItem(`${h}pages`)||"0")+1;sessionStorage.setItem(`${h}pages`,String(q));let M=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");M.push(location.href),M.length>20&&(M=M.slice(-20)),sessionStorage.setItem(`${h}hist`,JSON.stringify(M));let be=Date.now(),V=parseInt(sessionStorage.getItem(`${h}site_start`)||"0");V||(V=be,sessionStorage.setItem(`${h}site_start`,String(V)));let we=[];J=()=>{let e=!1;try{e=!!localStorage.getItem(`${h}visited`)}catch{e=!1}if(i.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:r.title,returning:e,pageCount:q,pageHistory:M,loadedAt:be,siteStart:V,locale:f,visitorId:L?"":x},"*"),!e&&!L)try{localStorage.setItem(`${h}visited`,"1")}catch{}},i.addEventListener("load",()=>{O=!0,J(),[120,450,1100].forEach(e=>{let o=setTimeout(()=>J(),e);we.push(o)}),H&&(H=!1,Q())}),r.readyState==="loading"?r.addEventListener("DOMContentLoaded",()=>de(N,1600),{once:!0}):de(N,1600);let ve=history.pushState.bind(history),Ee=history.replaceState.bind(history),K=()=>{q++,sessionStorage.setItem(`${h}pages`,String(q));let e=JSON.parse(sessionStorage.getItem(`${h}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),M=e,sessionStorage.setItem(`${h}hist`,JSON.stringify(e)),i.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:r.title,pageCount:q,pageHistory:e,loadedAt:Date.now()},"*"),!L)try{let o=JSON.stringify({tenant_slug:s,visitor_id:x,url:location.href}),t=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(t,new Blob([o],{type:"application/json"})):fetch(t,{method:"POST",body:o,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){ve(...e),K()},history.replaceState=function(...e){Ee(...e),K()},window.addEventListener("popstate",K);let xe=-1,oe,Se=()=>{clearTimeout(oe),oe=setTimeout(()=>{let e=Math.max(r.documentElement.scrollHeight,r.body.scrollHeight)-window.innerHeight,o=e>0?Math.round(window.scrollY/e*100):100;o!==xe&&(xe=o,i.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:o},"*"))},500)};window.addEventListener("scroll",Se,{passive:!0});let Ie=e=>{e.clientY<=0&&i.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};r.addEventListener("mouseout",Ie);let se,Le=!1,ae=()=>{clearTimeout(se),!Le&&(se=setTimeout(()=>{Le=!0,i.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},Te=["mousemove","keydown","scroll","touchstart"];Te.forEach(e=>r.addEventListener(e,ae,{passive:!0})),ae(),Q=()=>{i.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=i.src.split("#")[0];i.src=`${e}#bp-open-${Date.now()}`};let X=()=>{if(m.style.display="none",C(),pe(),N(),!O){H=!0;return}Q()},_e=()=>{F(),i.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Ae=e=>{!e||typeof e!="object"||ye({external_user_id:d(e.externalUserId,140)||void 0,name:d(e.name,140)||void 0,email:Fe(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")},De=()=>{D?_e():X()},We=()=>D,Ue=e=>{if(!e||typeof e!="string")return;let o=e.trim().slice(0,1e4);o&&(D||X(),setTimeout(()=>{i.contentWindow?.postMessage({type:"bitpalm-send-message",message:o},"*")},D?50:500))},Y={},Ce=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;Y={...Y,...e};let o=JSON.stringify(Y);o.length>Oe&&console.warn(`[BitPalm] Custom context exceeds ${Oe} bytes (${o.length}). It may be truncated.`),i.contentWindow?.postMessage({type:"bitpalm-custom-context",data:Y},"*")},je=()=>{Y={},i.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},Pe=e=>{let t=e.detail;if(!t||typeof t!="object")return;let u=d(t.slug,120);if(u&&u!==s)return;let{slug:T,...b}=t;Ce(b)};window.addEventListener("bitpalm-context",Pe);let Me=e=>{let t=e.detail;if(!t||typeof t!="object")return;let u=d(t.slug,120);u&&u!==s||Ae(t)};return window.addEventListener("bitpalm-identify",Me),{open:X,close:_e,toggle:De,isOpen:We,identify:Ae,context:Ce,resetContext:je,send:Ue,on:(e,o)=>(P.has(e)||P.set(e,new Set),P.get(e).add(o),()=>P.get(e)?.delete(o)),off:(e,o)=>{P.get(e)?.delete(o)},destroy:()=>{window.removeEventListener("message",ge),window.removeEventListener("scroll",Se),window.removeEventListener("popstate",K),r.removeEventListener("mouseout",Ie),r.removeEventListener("submit",he,!0),Te.forEach(e=>r.removeEventListener(e,ae)),clearTimeout(oe),clearTimeout(se),we.forEach(e=>clearTimeout(e)),history.pushState=ve,history.replaceState=Ee,window.removeEventListener("bitpalm-identify",Me),window.removeEventListener("bitpalm-context",Pe),P.clear(),F(),C(),m.remove(),i.remove()}}}function et(n){if(n==null)return;let s=n.trim().toLowerCase();if(["1","true","yes","on"].includes(s))return!0;if(["0","false","no","off"].includes(s))return!1}if(typeof document<"u"){let n=document.currentScript;if(n?.dataset.slug){let s=()=>{ue({slug:n.dataset.slug,locale:n.dataset.locale,baseUrl:n.dataset.baseUrl,token:n.dataset.token,zIndex:n.dataset.zIndex?Number(n.dataset.zIndex):void 0,autoIdentify:et(n.dataset.autoIdentify)})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",s):s()}}export{ue as createWidget};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/widget.ts","../src/index.ts"],"sourcesContent":["import type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\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 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};\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 ]\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 iframe.allow = \"clipboard-write\";\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 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.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 // --- 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 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 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, \"&lt;\");\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 = \"&#10005;\";\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\" }, \"*\");\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 // 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\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, 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 }, \"manual\");\n };\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 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 unlockMobilePageScroll();\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, identify, destroy };\n}\n","export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload } from \"./types\";\n\nimport { createWidget } from \"./widget\";\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value == null) return undefined;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return undefined;\n}\n\n/**\n * Auto-init from script tag:\n * <script src=\"https://cdn.bitpalm.ae/widget.js\" data-slug=\"my-agent\"></script>\n */\nif (typeof document !== \"undefined\") {\n const script = document.currentScript as HTMLScriptElement | null;\n if (script?.dataset.slug) {\n const init = () => {\n createWidget({\n slug: script!.dataset.slug!,\n locale: script!.dataset.locale,\n baseUrl: script!.dataset.baseUrl,\n token: script!.dataset.token,\n zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n autoIdentify: parseBoolean(script!.dataset.autoIdentify),\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n"],"mappings":"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","names":["DEFAULT_BASE_URL","STORAGE_PREFIX","IGNORED_INPUT_TYPES","IDENTITY_DEDUPE_WINDOW_MS","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","handleMessage","ic","sp","svg","attr","sv","isOpen","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","event","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","handleIdentifyEvent","detail","targetSlug","t","parseBoolean","value","normalized","script","init","createWidget"]}
1
+ {"version":3,"sources":["../src/widget.ts","../src/index.ts"],"sourcesContent":["import type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\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 iframe.allow = \"clipboard-write\";\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 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.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 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, \"&lt;\");\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 = \"&#10005;\";\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\" }, \"*\");\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","export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance, BitPalmIdentifyPayload, BitPalmCustomContext, BitPalmEventType, BitPalmEventCallback } from \"./types\";\n\nimport { createWidget } from \"./widget\";\n\nfunction parseBoolean(value: string | undefined): boolean | undefined {\n if (value == null) return undefined;\n const normalized = value.trim().toLowerCase();\n if ([\"1\", \"true\", \"yes\", \"on\"].includes(normalized)) return true;\n if ([\"0\", \"false\", \"no\", \"off\"].includes(normalized)) return false;\n return undefined;\n}\n\n/**\n * Auto-init from script tag:\n * <script src=\"https://cdn.bitpalm.ae/widget.js\" data-slug=\"my-agent\"></script>\n */\nif (typeof document !== \"undefined\") {\n const script = document.currentScript as HTMLScriptElement | null;\n if (script?.dataset.slug) {\n const init = () => {\n createWidget({\n slug: script!.dataset.slug!,\n locale: script!.dataset.locale,\n baseUrl: script!.dataset.baseUrl,\n token: script!.dataset.token,\n zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n autoIdentify: parseBoolean(script!.dataset.autoIdentify),\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n"],"mappings":"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","names":["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","parseBoolean","value","normalized","script","init","createWidget"]}