@bitpalm/ai-agents 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -58,9 +58,11 @@ No build step required — add a single script tag to any HTML page:
58
58
  ## Features
59
59
 
60
60
  - **Visitor Intelligence** — automatically sends page URL, title, and navigation history to the agent for context-aware responses
61
+ - **Returning visitor detection** — recognizes returning visitors, restores chat history, and enables session/page-count-based triggers
61
62
  - **SPA support** — detects client-side navigation (`pushState` / `replaceState`) and keeps the widget alive across route changes
62
- - **Trigger bubbles** — proactive chat bubbles configured from the dashboard
63
+ - **Trigger bubbles** — proactive chat bubbles configured from the dashboard, including visitor-data-driven triggers (session count, visited pages)
63
64
  - **Scroll & exit tracking** — scroll depth and exit intent signals for smart triggers
65
+ - **Privacy-friendly** — respects visitor opt-out (`_bp_optout` in localStorage); when opted out, no tracking beacons are sent and no visitor ID is stored
64
66
  - **Light & fast** — no dependencies (React is optional), tiny bundle size
65
67
 
66
68
  ## License
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var I=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var N=(i,r)=>{for(var m in r)I(i,m,{get:r[m],enumerable:!0})},J=(i,r,m,h)=>{if(r&&typeof r=="object"||typeof r=="function")for(let p of z(r))!j.call(i,p)&&p!==m&&I(i,p,{get:()=>r[p],enumerable:!(h=D(r,p))||h.enumerable});return i};var Y=i=>J(I({},"__esModule",{value:!0}),i);var G={};N(G,{createWidget:()=>v});module.exports=Y(G);var F="https://agents.bitpalm.ae",l="_bp_";function q(){if(typeof document<"u"){let i=document.documentElement.lang;if(i)return i.slice(0,2).toLowerCase()}return"en"}function v(i){let{slug:r,locale:m=q(),baseUrl:h=F,zIndex:p=9999}=i,o=document,e=o.createElement("iframe"),T=`${h}/t/${r}/widget`;e.src=`${T}${T.includes("?")?"&":"?"}locale=${m}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${p};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,o.body.appendChild(e);let R=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${p-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>O(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let d=null,y=()=>{d&&(d.remove(),d=null)},L=t=>{if(t.origin===R){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let a=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${a}`,n.innerHTML=t.data.chatButtonIconSvg;let g=n.querySelector("svg");g&&(g.setAttribute("width","24"),g.setAttribute("height","24"),g.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=a)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let a=t.data.width>0,n=window.innerWidth<=640;a?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=a?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){y(),d=o.createElement("div"),d.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${p-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let a=(t.data.message||"").replace(/</g,"&lt;");d.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=o.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=g=>{g.stopPropagation(),y(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},d.onclick=()=>{y(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},d.appendChild(n),o.body.appendChild(d)}t.data?.type==="bitpalm-trigger-hide"&&y()}};window.addEventListener("message",L);let b=`${l}vid`,c="";try{c=localStorage.getItem(b)||""}catch{}if(!c){let t=o.cookie.match(new RegExp(`(?:^|; )${b}=([^;]+)`));c=t?decodeURIComponent(t[1]):""}c||(c=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(b,c)}catch{}try{o.cookie=`${b}=${encodeURIComponent(c)};path=/;max-age=31536000;SameSite=Lax`}catch{}try{let t=new URLSearchParams(location.search),a={};for(let U of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let H=t.get(U);H&&(a[U]=H)}let n=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href,referrer:o.referrer||void 0,...Object.keys(a).length>0?{utm:a}:{}}),g=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(g,new Blob([n],{type:"application/json"})):fetch(g,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let f=parseInt(sessionStorage.getItem(`${l}pages`)||"0")+1;sessionStorage.setItem(`${l}pages`,String(f));let u=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");u.push(location.href),u.length>20&&(u=u.slice(-20)),sessionStorage.setItem(`${l}hist`,JSON.stringify(u));let _=Date.now(),x=parseInt(sessionStorage.getItem(`${l}site_start`)||"0");x||(x=_,sessionStorage.setItem(`${l}site_start`,String(x))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${l}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:f,pageHistory:u,loadedAt:_,siteStart:x,locale:m,visitorId:c},"*"),t||localStorage.setItem(`${l}visited`,"1")});let M=history.pushState.bind(history),k=history.replaceState.bind(history),w=()=>{f++,sessionStorage.setItem(`${l}pages`,String(f));let t=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${l}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:f,pageHistory:t,loadedAt:Date.now()},"*");try{let a=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href}),n=`${h}/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(...t){M(...t),w()},history.replaceState=function(...t){k(...t),w()},window.addEventListener("popstate",w);let A=-1,S,B=()=>{clearTimeout(S),S=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,a=t>0?Math.round(window.scrollY/t*100):100;a!==A&&(A=a,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:a},"*"))},500)};window.addEventListener("scroll",B,{passive:!0});let C=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",C);let E,P=!1,$=()=>{clearTimeout(E),!P&&(E=setTimeout(()=>{P=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},W=["mousemove","keydown","scroll","touchstart"];W.forEach(t=>o.addEventListener(t,$,{passive:!0})),$();let O=()=>{s.style.display="none",y(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:O,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",L),window.removeEventListener("scroll",B),window.removeEventListener("popstate",w),o.removeEventListener("mouseout",C),W.forEach(t=>o.removeEventListener(t,$)),clearTimeout(S),clearTimeout(E),history.pushState=M,history.replaceState=k,y(),s.remove(),e.remove()}}}if(typeof document<"u"){let i=document.currentScript;if(i?.dataset.slug){let r=()=>{v({slug:i.dataset.slug,locale:i.dataset.locale,baseUrl:i.dataset.baseUrl,zIndex:i.dataset.zIndex?Number(i.dataset.zIndex):void 0})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",r):r()}}0&&(module.exports={createWidget});
1
+ "use strict";var T=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var J=(i,r)=>{for(var m in r)T(i,m,{get:r[m],enumerable:!0})},Y=(i,r,m,h)=>{if(r&&typeof r=="object"||typeof r=="function")for(let p of j(r))!N.call(i,p)&&p!==m&&T(i,p,{get:()=>r[p],enumerable:!(h=z(r,p))||h.enumerable});return i};var F=i=>Y(T({},"__esModule",{value:!0}),i);var V={};J(V,{createWidget:()=>S});module.exports=F(V);var q="https://agents.bitpalm.ae",l="_bp_";function G(){if(typeof document<"u"){let i=document.documentElement.lang;if(i)return i.slice(0,2).toLowerCase()}return"en"}function S(i){let{slug:r,locale:m=G(),baseUrl:h=q,zIndex:p=9999}=i,o=document,e=o.createElement("iframe"),L=`${h}/t/${r}/widget`;e.src=`${L}${L.includes("?")?"&":"?"}locale=${m}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${p};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,o.body.appendChild(e);let D=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${p-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>U(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let d=null,y=()=>{d&&(d.remove(),d=null)},_=t=>{if(t.origin===D){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let a=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${a}`,n.innerHTML=t.data.chatButtonIconSvg;let g=n.querySelector("svg");g&&(g.setAttribute("width","24"),g.setAttribute("height","24"),g.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=a)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let a=t.data.width>0,n=window.innerWidth<=640;a?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=a?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){y(),d=o.createElement("div"),d.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${p-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let a=(t.data.message||"").replace(/</g,"&lt;");d.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=o.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=g=>{g.stopPropagation(),y(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},d.onclick=()=>{y(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},d.appendChild(n),o.body.appendChild(d)}t.data?.type==="bitpalm-trigger-hide"&&y()}};window.addEventListener("message",_);let u=!1;try{u=localStorage.getItem(`${l}optout`)==="1"}catch{}let x=`${l}vid`,c="";if(!u){try{c=localStorage.getItem(x)||""}catch{}if(!c){let t=o.cookie.match(new RegExp(`(?:^|; )${x}=([^;]+)`));c=t?decodeURIComponent(t[1]):""}c||(c=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(x,c)}catch{}try{o.cookie=`${x}=${encodeURIComponent(c)};path=/;max-age=31536000;SameSite=Lax`}catch{}}if(!u)try{let t=new URLSearchParams(location.search),a={};for(let H of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let R=t.get(H);R&&(a[H]=R)}let n=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href,referrer:o.referrer||void 0,...Object.keys(a).length>0?{utm:a}:{}}),g=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(g,new Blob([n],{type:"application/json"})):fetch(g,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let b=parseInt(sessionStorage.getItem(`${l}pages`)||"0")+1;sessionStorage.setItem(`${l}pages`,String(b));let f=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");f.push(location.href),f.length>20&&(f=f.slice(-20)),sessionStorage.setItem(`${l}hist`,JSON.stringify(f));let M=Date.now(),w=parseInt(sessionStorage.getItem(`${l}site_start`)||"0");w||(w=M,sessionStorage.setItem(`${l}site_start`,String(w))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${l}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:b,pageHistory:f,loadedAt:M,siteStart:w,locale:m,visitorId:u?"":c},"*"),!t&&!u&&localStorage.setItem(`${l}visited`,"1")});let k=history.pushState.bind(history),A=history.replaceState.bind(history),v=()=>{b++,sessionStorage.setItem(`${l}pages`,String(b));let t=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");if(t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${l}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:b,pageHistory:t,loadedAt:Date.now()},"*"),!u)try{let a=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href}),n=`${h}/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(...t){k(...t),v()},history.replaceState=function(...t){A(...t),v()},window.addEventListener("popstate",v);let B=-1,$,C=()=>{clearTimeout($),$=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,a=t>0?Math.round(window.scrollY/t*100):100;a!==B&&(B=a,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:a},"*"))},500)};window.addEventListener("scroll",C,{passive:!0});let O=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",O);let E,P=!1,I=()=>{clearTimeout(E),!P&&(E=setTimeout(()=>{P=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},W=["mousemove","keydown","scroll","touchstart"];W.forEach(t=>o.addEventListener(t,I,{passive:!0})),I();let U=()=>{s.style.display="none",y(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:U,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",_),window.removeEventListener("scroll",C),window.removeEventListener("popstate",v),o.removeEventListener("mouseout",O),W.forEach(t=>o.removeEventListener(t,I)),clearTimeout($),clearTimeout(E),history.pushState=k,history.replaceState=A,y(),s.remove(),e.remove()}}}if(typeof document<"u"){let i=document.currentScript;if(i?.dataset.slug){let r=()=>{S({slug:i.dataset.slug,locale:i.dataset.locale,baseUrl:i.dataset.baseUrl,zIndex:i.dataset.zIndex?Number(i.dataset.zIndex):void 0})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",r):r()}}0&&(module.exports={createWidget});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/widget.ts"],"sourcesContent":["export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\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 zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 window.addEventListener(\"message\", handleMessage);\n\n // --- Persistent Visitor ID ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\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 // --- Visitor beacon: track page view even without chat ---\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\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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,\n }, \"*\");\n if (!returning) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["src_exports","__export","createWidget","__toCommonJS","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","script","init","createWidget"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/widget.ts"],"sourcesContent":["export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\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 zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 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 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 }\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["src_exports","__export","createWidget","__toCommonJS","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","script","init","createWidget"]}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var R="https://agents.bitpalm.ae",a="_bp_";function D(){if(typeof document<"u"){let r=document.documentElement.lang;if(r)return r.slice(0,2).toLowerCase()}return"en"}function E(r){let{slug:d,locale:$=D(),baseUrl:b=R,zIndex:x=9999}=r,o=document,e=o.createElement("iframe"),I=`${b}/t/${d}/widget`;e.src=`${I}${I.includes("?")?"&":"?"}locale=${$}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${x};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,o.body.appendChild(e);let H=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${x-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>W(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let c=null,g=()=>{c&&(c.remove(),c=null)},T=t=>{if(t.origin===H){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let i=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${i}`,n.innerHTML=t.data.chatButtonIconSvg;let p=n.querySelector("svg");p&&(p.setAttribute("width","24"),p.setAttribute("height","24"),p.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=i)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let i=t.data.width>0,n=window.innerWidth<=640;i?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=i?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){g(),c=o.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:${x-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let i=(t.data.message||"").replace(/</g,"&lt;");c.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${i}</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=o.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=p=>{p.stopPropagation(),g(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},c.onclick=()=>{g(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},c.appendChild(n),o.body.appendChild(c)}t.data?.type==="bitpalm-trigger-hide"&&g()}};window.addEventListener("message",T);let y=`${a}vid`,l="";try{l=localStorage.getItem(y)||""}catch{}if(!l){let t=o.cookie.match(new RegExp(`(?:^|; )${y}=([^;]+)`));l=t?decodeURIComponent(t[1]):""}l||(l=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(y,l)}catch{}try{o.cookie=`${y}=${encodeURIComponent(l)};path=/;max-age=31536000;SameSite=Lax`}catch{}try{let t=new URLSearchParams(location.search),i={};for(let O of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let U=t.get(O);U&&(i[O]=U)}let n=JSON.stringify({tenant_slug:d,visitor_id:l,url:location.href,referrer:o.referrer||void 0,...Object.keys(i).length>0?{utm:i}:{}}),p=`${b}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(p,new Blob([n],{type:"application/json"})):fetch(p,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let h=parseInt(sessionStorage.getItem(`${a}pages`)||"0")+1;sessionStorage.setItem(`${a}pages`,String(h));let m=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");m.push(location.href),m.length>20&&(m=m.slice(-20)),sessionStorage.setItem(`${a}hist`,JSON.stringify(m));let L=Date.now(),u=parseInt(sessionStorage.getItem(`${a}site_start`)||"0");u||(u=L,sessionStorage.setItem(`${a}site_start`,String(u))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${a}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:h,pageHistory:m,loadedAt:L,siteStart:u,locale:$,visitorId:l},"*"),t||localStorage.setItem(`${a}visited`,"1")});let _=history.pushState.bind(history),M=history.replaceState.bind(history),f=()=>{h++,sessionStorage.setItem(`${a}pages`,String(h));let t=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${a}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:h,pageHistory:t,loadedAt:Date.now()},"*");try{let i=JSON.stringify({tenant_slug:d,visitor_id:l,url:location.href}),n=`${b}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(n,new Blob([i],{type:"application/json"})):fetch(n,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...t){_(...t),f()},history.replaceState=function(...t){M(...t),f()},window.addEventListener("popstate",f);let k=-1,w,A=()=>{clearTimeout(w),w=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,i=t>0?Math.round(window.scrollY/t*100):100;i!==k&&(k=i,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:i},"*"))},500)};window.addEventListener("scroll",A,{passive:!0});let B=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",B);let v,C=!1,S=()=>{clearTimeout(v),!C&&(v=setTimeout(()=>{C=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},P=["mousemove","keydown","scroll","touchstart"];P.forEach(t=>o.addEventListener(t,S,{passive:!0})),S();let W=()=>{s.style.display="none",g(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:W,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",T),window.removeEventListener("scroll",A),window.removeEventListener("popstate",f),o.removeEventListener("mouseout",B),P.forEach(t=>o.removeEventListener(t,S)),clearTimeout(w),clearTimeout(v),history.pushState=_,history.replaceState=M,g(),s.remove(),e.remove()}}}if(typeof document<"u"){let r=document.currentScript;if(r?.dataset.slug){let d=()=>{E({slug:r.dataset.slug,locale:r.dataset.locale,baseUrl:r.dataset.baseUrl,zIndex:r.dataset.zIndex?Number(r.dataset.zIndex):void 0})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",d):d()}}export{E as createWidget};
1
+ var D="https://agents.bitpalm.ae",a="_bp_";function z(){if(typeof document<"u"){let r=document.documentElement.lang;if(r)return r.slice(0,2).toLowerCase()}return"en"}function E(r){let{slug:d,locale:I=z(),baseUrl:x=D,zIndex:w=9999}=r,o=document,e=o.createElement("iframe"),T=`${x}/t/${d}/widget`;e.src=`${T}${T.includes("?")?"&":"?"}locale=${I}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.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;`,o.body.appendChild(e);let R=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>W(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let c=null,g=()=>{c&&(c.remove(),c=null)},L=t=>{if(t.origin===R){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let i=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${i}`,n.innerHTML=t.data.chatButtonIconSvg;let p=n.querySelector("svg");p&&(p.setAttribute("width","24"),p.setAttribute("height","24"),p.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=i)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let i=t.data.width>0,n=window.innerWidth<=640;i?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=i?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){g(),c=o.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 i=(t.data.message||"").replace(/</g,"&lt;");c.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${i}</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=o.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=p=>{p.stopPropagation(),g(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},c.onclick=()=>{g(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},c.appendChild(n),o.body.appendChild(c)}t.data?.type==="bitpalm-trigger-hide"&&g()}};window.addEventListener("message",L);let m=!1;try{m=localStorage.getItem(`${a}optout`)==="1"}catch{}let u=`${a}vid`,l="";if(!m){try{l=localStorage.getItem(u)||""}catch{}if(!l){let t=o.cookie.match(new RegExp(`(?:^|; )${u}=([^;]+)`));l=t?decodeURIComponent(t[1]):""}l||(l=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(u,l)}catch{}try{o.cookie=`${u}=${encodeURIComponent(l)};path=/;max-age=31536000;SameSite=Lax`}catch{}}if(!m)try{let t=new URLSearchParams(location.search),i={};for(let U of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let H=t.get(U);H&&(i[U]=H)}let n=JSON.stringify({tenant_slug:d,visitor_id:l,url:location.href,referrer:o.referrer||void 0,...Object.keys(i).length>0?{utm:i}:{}}),p=`${x}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(p,new Blob([n],{type:"application/json"})):fetch(p,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let y=parseInt(sessionStorage.getItem(`${a}pages`)||"0")+1;sessionStorage.setItem(`${a}pages`,String(y));let h=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");h.push(location.href),h.length>20&&(h=h.slice(-20)),sessionStorage.setItem(`${a}hist`,JSON.stringify(h));let _=Date.now(),f=parseInt(sessionStorage.getItem(`${a}site_start`)||"0");f||(f=_,sessionStorage.setItem(`${a}site_start`,String(f))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${a}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:y,pageHistory:h,loadedAt:_,siteStart:f,locale:I,visitorId:m?"":l},"*"),!t&&!m&&localStorage.setItem(`${a}visited`,"1")});let M=history.pushState.bind(history),k=history.replaceState.bind(history),b=()=>{y++,sessionStorage.setItem(`${a}pages`,String(y));let t=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");if(t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${a}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:y,pageHistory:t,loadedAt:Date.now()},"*"),!m)try{let i=JSON.stringify({tenant_slug:d,visitor_id:l,url:location.href}),n=`${x}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(n,new Blob([i],{type:"application/json"})):fetch(n,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...t){M(...t),b()},history.replaceState=function(...t){k(...t),b()},window.addEventListener("popstate",b);let A=-1,v,B=()=>{clearTimeout(v),v=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,i=t>0?Math.round(window.scrollY/t*100):100;i!==A&&(A=i,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:i},"*"))},500)};window.addEventListener("scroll",B,{passive:!0});let C=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",C);let S,O=!1,$=()=>{clearTimeout(S),!O&&(S=setTimeout(()=>{O=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},P=["mousemove","keydown","scroll","touchstart"];P.forEach(t=>o.addEventListener(t,$,{passive:!0})),$();let W=()=>{s.style.display="none",g(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:W,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",L),window.removeEventListener("scroll",B),window.removeEventListener("popstate",b),o.removeEventListener("mouseout",C),P.forEach(t=>o.removeEventListener(t,$)),clearTimeout(v),clearTimeout(S),history.pushState=M,history.replaceState=k,g(),s.remove(),e.remove()}}}if(typeof document<"u"){let r=document.currentScript;if(r?.dataset.slug){let d=()=>{E({slug:r.dataset.slug,locale:r.dataset.locale,baseUrl:r.dataset.baseUrl,zIndex:r.dataset.zIndex?Number(r.dataset.zIndex):void 0})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",d):d()}}export{E 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 } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 window.addEventListener(\"message\", handleMessage);\n\n // --- Persistent Visitor ID ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\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 // --- Visitor beacon: track page view even without chat ---\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\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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,\n }, \"*\");\n if (!returning) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n","export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\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 zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\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","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","script","init","createWidget"]}
1
+ {"version":3,"sources":["../src/widget.ts","../src/index.ts"],"sourcesContent":["import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 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 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 }\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n","export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\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 zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\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","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","script","init","createWidget"]}
package/dist/react.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var I=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var J=(r,a)=>{for(var c in a)I(r,c,{get:a[c],enumerable:!0})},Y=(r,a,c,h)=>{if(a&&typeof a=="object"||typeof a=="function")for(let d of z(a))!N.call(r,d)&&d!==c&&I(r,d,{get:()=>a[d],enumerable:!(h=j(a,d))||h.enumerable});return r};var F=r=>Y(I({},"__esModule",{value:!0}),r);var K={};J(K,{BitPalmAgent:()=>V});module.exports=F(K);var b=require("react");var q="https://agents.bitpalm.ae",l="_bp_";function G(){if(typeof document<"u"){let r=document.documentElement.lang;if(r)return r.slice(0,2).toLowerCase()}return"en"}function H(r){let{slug:a,locale:c=G(),baseUrl:h=q,zIndex:d=9999}=r,n=document,e=n.createElement("iframe"),T=`${h}/t/${a}/widget`;e.src=`${T}${T.includes("?")?"&":"?"}locale=${c}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${d};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,n.body.appendChild(e);let D=new URL(e.src).origin,s=n.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${d-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>W(),n.body.appendChild(s),!n.getElementById("_bp_fade")){let t=n.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",n.head.appendChild(t)}let g=null,u=()=>{g&&(g.remove(),g=null)},A=t=>{if(t.origin===D){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let i=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let o=n.createElement("span");o.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${i}`,o.innerHTML=t.data.chatButtonIconSvg;let m=o.querySelector("svg");m&&(m.setAttribute("width","24"),m.setAttribute("height","24"),m.style.display="block"),s.appendChild(o)}else{let o=s.querySelector("svg");o&&(o.style.stroke=i)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let i=t.data.width>0,o=window.innerWidth<=640;i?(e.style.width=o?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=o?`${window.innerHeight}px`:`${t.data.height}px`,o&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=i?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){u(),g=n.createElement("div"),g.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:${d-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let i=(t.data.message||"").replace(/</g,"&lt;");g.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${i}</p><div style="position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;"></div>`;let o=n.createElement("button");o.style.cssText="position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;",o.innerHTML="&#10005;",o.onclick=m=>{m.stopPropagation(),u(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},g.onclick=()=>{u(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},g.appendChild(o),n.body.appendChild(g)}t.data?.type==="bitpalm-trigger-hide"&&u()}};window.addEventListener("message",A);let x=`${l}vid`,p="";try{p=localStorage.getItem(x)||""}catch{}if(!p){let t=n.cookie.match(new RegExp(`(?:^|; )${x}=([^;]+)`));p=t?decodeURIComponent(t[1]):""}p||(p=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(x,p)}catch{}try{n.cookie=`${x}=${encodeURIComponent(p)};path=/;max-age=31536000;SameSite=Lax`}catch{}try{let t=new URLSearchParams(location.search),i={};for(let R of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let U=t.get(R);U&&(i[R]=U)}let o=JSON.stringify({tenant_slug:a,visitor_id:p,url:location.href,referrer:n.referrer||void 0,...Object.keys(i).length>0?{utm:i}:{}}),m=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(m,new Blob([o],{type:"application/json"})):fetch(m,{method:"POST",body:o,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let f=parseInt(sessionStorage.getItem(`${l}pages`)||"0")+1;sessionStorage.setItem(`${l}pages`,String(f));let y=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");y.push(location.href),y.length>20&&(y=y.slice(-20)),sessionStorage.setItem(`${l}hist`,JSON.stringify(y));let B=Date.now(),w=parseInt(sessionStorage.getItem(`${l}site_start`)||"0");w||(w=B,sessionStorage.setItem(`${l}site_start`,String(w))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${l}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:n.title,returning:t,pageCount:f,pageHistory:y,loadedAt:B,siteStart:w,locale:c,visitorId:p},"*"),t||localStorage.setItem(`${l}visited`,"1")});let P=history.pushState.bind(history),_=history.replaceState.bind(history),v=()=>{f++,sessionStorage.setItem(`${l}pages`,String(f));let t=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${l}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:n.title,pageCount:f,pageHistory:t,loadedAt:Date.now()},"*");try{let i=JSON.stringify({tenant_slug:a,visitor_id:p,url:location.href}),o=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(o,new Blob([i],{type:"application/json"})):fetch(o,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...t){P(...t),v()},history.replaceState=function(...t){_(...t),v()},window.addEventListener("popstate",v);let L=-1,S,k=()=>{clearTimeout(S),S=setTimeout(()=>{let t=Math.max(n.documentElement.scrollHeight,n.body.scrollHeight)-window.innerHeight,i=t>0?Math.round(window.scrollY/t*100):100;i!==L&&(L=i,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:i},"*"))},500)};window.addEventListener("scroll",k,{passive:!0});let M=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};n.addEventListener("mouseout",M);let $,C=!1,E=()=>{clearTimeout($),!C&&($=setTimeout(()=>{C=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},O=["mousemove","keydown","scroll","touchstart"];O.forEach(t=>n.addEventListener(t,E,{passive:!0})),E();let W=()=>{s.style.display="none",u(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:W,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",A),window.removeEventListener("scroll",k),window.removeEventListener("popstate",v),n.removeEventListener("mouseout",M),O.forEach(t=>n.removeEventListener(t,E)),clearTimeout(S),clearTimeout($),history.pushState=P,history.replaceState=_,u(),s.remove(),e.remove()}}}function V(r){let a=(0,b.useRef)(null),c=(0,b.useRef)(!1);return(0,b.useEffect)(()=>{if(!c.current)return c.current=!0,a.current=H(r),()=>{a.current?.destroy(),a.current=null,c.current=!1}},[]),null}0&&(module.exports={BitPalmAgent});
1
+ "use strict";var T=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var Y=(r,a)=>{for(var c in a)T(r,c,{get:a[c],enumerable:!0})},F=(r,a,c,h)=>{if(a&&typeof a=="object"||typeof a=="function")for(let d of N(a))!J.call(r,d)&&d!==c&&T(r,d,{get:()=>a[d],enumerable:!(h=z(a,d))||h.enumerable});return r};var q=r=>F(T({},"__esModule",{value:!0}),r);var X={};Y(X,{BitPalmAgent:()=>K});module.exports=q(X);var x=require("react");var G="https://agents.bitpalm.ae",l="_bp_";function V(){if(typeof document<"u"){let r=document.documentElement.lang;if(r)return r.slice(0,2).toLowerCase()}return"en"}function D(r){let{slug:a,locale:c=V(),baseUrl:h=G,zIndex:d=9999}=r,o=document,e=o.createElement("iframe"),A=`${h}/t/${a}/widget`;e.src=`${A}${A.includes("?")?"&":"?"}locale=${c}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${d};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,o.body.appendChild(e);let j=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${d-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>R(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let g=null,u=()=>{g&&(g.remove(),g=null)},B=t=>{if(t.origin===j){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let i=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${i}`,n.innerHTML=t.data.chatButtonIconSvg;let m=n.querySelector("svg");m&&(m.setAttribute("width","24"),m.setAttribute("height","24"),m.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=i)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let i=t.data.width>0,n=window.innerWidth<=640;i?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=i?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){u(),g=o.createElement("div"),g.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:${d-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let i=(t.data.message||"").replace(/</g,"&lt;");g.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${i}</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=o.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=m=>{m.stopPropagation(),u(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},g.onclick=()=>{u(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},g.appendChild(n),o.body.appendChild(g)}t.data?.type==="bitpalm-trigger-hide"&&u()}};window.addEventListener("message",B);let y=!1;try{y=localStorage.getItem(`${l}optout`)==="1"}catch{}let w=`${l}vid`,p="";if(!y){try{p=localStorage.getItem(w)||""}catch{}if(!p){let t=o.cookie.match(new RegExp(`(?:^|; )${w}=([^;]+)`));p=t?decodeURIComponent(t[1]):""}p||(p=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(w,p)}catch{}try{o.cookie=`${w}=${encodeURIComponent(p)};path=/;max-age=31536000;SameSite=Lax`}catch{}}if(!y)try{let t=new URLSearchParams(location.search),i={};for(let U of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let H=t.get(U);H&&(i[U]=H)}let n=JSON.stringify({tenant_slug:a,visitor_id:p,url:location.href,referrer:o.referrer||void 0,...Object.keys(i).length>0?{utm:i}:{}}),m=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(m,new Blob([n],{type:"application/json"})):fetch(m,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let b=parseInt(sessionStorage.getItem(`${l}pages`)||"0")+1;sessionStorage.setItem(`${l}pages`,String(b));let f=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");f.push(location.href),f.length>20&&(f=f.slice(-20)),sessionStorage.setItem(`${l}hist`,JSON.stringify(f));let P=Date.now(),v=parseInt(sessionStorage.getItem(`${l}site_start`)||"0");v||(v=P,sessionStorage.setItem(`${l}site_start`,String(v))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${l}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:b,pageHistory:f,loadedAt:P,siteStart:v,locale:c,visitorId:y?"":p},"*"),!t&&!y&&localStorage.setItem(`${l}visited`,"1")});let _=history.pushState.bind(history),L=history.replaceState.bind(history),S=()=>{b++,sessionStorage.setItem(`${l}pages`,String(b));let t=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");if(t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${l}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:b,pageHistory:t,loadedAt:Date.now()},"*"),!y)try{let i=JSON.stringify({tenant_slug:a,visitor_id:p,url:location.href}),n=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(n,new Blob([i],{type:"application/json"})):fetch(n,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...t){_(...t),S()},history.replaceState=function(...t){L(...t),S()},window.addEventListener("popstate",S);let k=-1,$,M=()=>{clearTimeout($),$=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,i=t>0?Math.round(window.scrollY/t*100):100;i!==k&&(k=i,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:i},"*"))},500)};window.addEventListener("scroll",M,{passive:!0});let C=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",C);let E,O=!1,I=()=>{clearTimeout(E),!O&&(E=setTimeout(()=>{O=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},W=["mousemove","keydown","scroll","touchstart"];W.forEach(t=>o.addEventListener(t,I,{passive:!0})),I();let R=()=>{s.style.display="none",u(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:R,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",B),window.removeEventListener("scroll",M),window.removeEventListener("popstate",S),o.removeEventListener("mouseout",C),W.forEach(t=>o.removeEventListener(t,I)),clearTimeout($),clearTimeout(E),history.pushState=_,history.replaceState=L,u(),s.remove(),e.remove()}}}function K(r){let a=(0,x.useRef)(null),c=(0,x.useRef)(!1);return(0,x.useEffect)(()=>{if(!c.current)return c.current=!0,a.current=D(r),()=>{a.current?.destroy(),a.current=null,c.current=!1}},[]),null}0&&(module.exports={BitPalmAgent});
2
2
  //# sourceMappingURL=react.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type BitPalmAgentProps = BitPalmAgentOptions;\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n instanceRef.current = createWidget(props);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 window.addEventListener(\"message\", handleMessage);\n\n // --- Persistent Visitor ID ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\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 // --- Visitor beacon: track page view even without chat ---\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\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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,\n }, \"*\");\n if (!returning) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["react_exports","__export","BitPalmAgent","__toCommonJS","import_react","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","BitPalmAgent","props","instanceRef","mountedRef","createWidget"]}
1
+ {"version":3,"sources":["../src/react.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type BitPalmAgentProps = BitPalmAgentOptions;\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n instanceRef.current = createWidget(props);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 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 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 }\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["react_exports","__export","BitPalmAgent","__toCommonJS","import_react","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","BitPalmAgent","props","instanceRef","mountedRef","createWidget"]}
package/dist/react.js CHANGED
@@ -1,2 +1,2 @@
1
- import{useEffect as z,useRef as U}from"react";var D="https://agents.bitpalm.ae",a="_bp_";function j(){if(typeof document<"u"){let d=document.documentElement.lang;if(d)return d.slice(0,2).toLowerCase()}return"en"}function R(d){let{slug:p,locale:g=j(),baseUrl:x=D,zIndex:w=9999}=d,n=document,e=n.createElement("iframe"),E=`${x}/t/${p}/widget`;e.src=`${E}${E.includes("?")?"&":"?"}locale=${g}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.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;`,n.body.appendChild(e);let H=new URL(e.src).origin,s=n.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>C(),n.body.appendChild(s),!n.getElementById("_bp_fade")){let t=n.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",n.head.appendChild(t)}let l=null,m=()=>{l&&(l.remove(),l=null)},I=t=>{if(t.origin===H){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let i=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let o=n.createElement("span");o.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${i}`,o.innerHTML=t.data.chatButtonIconSvg;let c=o.querySelector("svg");c&&(c.setAttribute("width","24"),c.setAttribute("height","24"),c.style.display="block"),s.appendChild(o)}else{let o=s.querySelector("svg");o&&(o.style.stroke=i)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let i=t.data.width>0,o=window.innerWidth<=640;i?(e.style.width=o?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=o?`${window.innerHeight}px`:`${t.data.height}px`,o&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=i?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){m(),l=n.createElement("div"),l.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 i=(t.data.message||"").replace(/</g,"&lt;");l.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${i}</p><div style="position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;"></div>`;let o=n.createElement("button");o.style.cssText="position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;",o.innerHTML="&#10005;",o.onclick=c=>{c.stopPropagation(),m(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},l.onclick=()=>{m(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},l.appendChild(o),n.body.appendChild(l)}t.data?.type==="bitpalm-trigger-hide"&&m()}};window.addEventListener("message",I);let y=`${a}vid`,r="";try{r=localStorage.getItem(y)||""}catch{}if(!r){let t=n.cookie.match(new RegExp(`(?:^|; )${y}=([^;]+)`));r=t?decodeURIComponent(t[1]):""}r||(r=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(y,r)}catch{}try{n.cookie=`${y}=${encodeURIComponent(r)};path=/;max-age=31536000;SameSite=Lax`}catch{}try{let t=new URLSearchParams(location.search),i={};for(let O of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let W=t.get(O);W&&(i[O]=W)}let o=JSON.stringify({tenant_slug:p,visitor_id:r,url:location.href,referrer:n.referrer||void 0,...Object.keys(i).length>0?{utm:i}:{}}),c=`${x}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(c,new Blob([o],{type:"application/json"})):fetch(c,{method:"POST",body:o,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let u=parseInt(sessionStorage.getItem(`${a}pages`)||"0")+1;sessionStorage.setItem(`${a}pages`,String(u));let h=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");h.push(location.href),h.length>20&&(h=h.slice(-20)),sessionStorage.setItem(`${a}hist`,JSON.stringify(h));let T=Date.now(),f=parseInt(sessionStorage.getItem(`${a}site_start`)||"0");f||(f=T,sessionStorage.setItem(`${a}site_start`,String(f))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${a}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:n.title,returning:t,pageCount:u,pageHistory:h,loadedAt:T,siteStart:f,locale:g,visitorId:r},"*"),t||localStorage.setItem(`${a}visited`,"1")});let A=history.pushState.bind(history),B=history.replaceState.bind(history),b=()=>{u++,sessionStorage.setItem(`${a}pages`,String(u));let t=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${a}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:n.title,pageCount:u,pageHistory:t,loadedAt:Date.now()},"*");try{let i=JSON.stringify({tenant_slug:p,visitor_id:r,url:location.href}),o=`${x}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(o,new Blob([i],{type:"application/json"})):fetch(o,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...t){A(...t),b()},history.replaceState=function(...t){B(...t),b()},window.addEventListener("popstate",b);let P=-1,v,_=()=>{clearTimeout(v),v=setTimeout(()=>{let t=Math.max(n.documentElement.scrollHeight,n.body.scrollHeight)-window.innerHeight,i=t>0?Math.round(window.scrollY/t*100):100;i!==P&&(P=i,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:i},"*"))},500)};window.addEventListener("scroll",_,{passive:!0});let L=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};n.addEventListener("mouseout",L);let S,k=!1,$=()=>{clearTimeout(S),!k&&(S=setTimeout(()=>{k=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},M=["mousemove","keydown","scroll","touchstart"];M.forEach(t=>n.addEventListener(t,$,{passive:!0})),$();let C=()=>{s.style.display="none",m(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:C,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",I),window.removeEventListener("scroll",_),window.removeEventListener("popstate",b),n.removeEventListener("mouseout",L),M.forEach(t=>n.removeEventListener(t,$)),clearTimeout(v),clearTimeout(S),history.pushState=A,history.replaceState=B,m(),s.remove(),e.remove()}}}function G(d){let p=U(null),g=U(!1);return z(()=>{if(!g.current)return g.current=!0,p.current=R(d),()=>{p.current?.destroy(),p.current=null,g.current=!1}},[]),null}export{G as BitPalmAgent};
1
+ import{useEffect as N,useRef as H}from"react";var j="https://agents.bitpalm.ae",a="_bp_";function z(){if(typeof document<"u"){let d=document.documentElement.lang;if(d)return d.slice(0,2).toLowerCase()}return"en"}function U(d){let{slug:p,locale:g=z(),baseUrl:w=j,zIndex:v=9999}=d,o=document,e=o.createElement("iframe"),I=`${w}/t/${p}/widget`;e.src=`${I}${I.includes("?")?"&":"?"}locale=${g}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${v};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,o.body.appendChild(e);let D=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${v-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>O(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let l=null,m=()=>{l&&(l.remove(),l=null)},T=t=>{if(t.origin===D){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let i=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${i}`,n.innerHTML=t.data.chatButtonIconSvg;let c=n.querySelector("svg");c&&(c.setAttribute("width","24"),c.setAttribute("height","24"),c.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=i)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let i=t.data.width>0,n=window.innerWidth<=640;i?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=i?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){m(),l=o.createElement("div"),l.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:${v-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let i=(t.data.message||"").replace(/</g,"&lt;");l.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${i}</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=o.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=c=>{c.stopPropagation(),m(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},l.onclick=()=>{m(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},l.appendChild(n),o.body.appendChild(l)}t.data?.type==="bitpalm-trigger-hide"&&m()}};window.addEventListener("message",T);let h=!1;try{h=localStorage.getItem(`${a}optout`)==="1"}catch{}let f=`${a}vid`,r="";if(!h){try{r=localStorage.getItem(f)||""}catch{}if(!r){let t=o.cookie.match(new RegExp(`(?:^|; )${f}=([^;]+)`));r=t?decodeURIComponent(t[1]):""}r||(r=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(f,r)}catch{}try{o.cookie=`${f}=${encodeURIComponent(r)};path=/;max-age=31536000;SameSite=Lax`}catch{}}if(!h)try{let t=new URLSearchParams(location.search),i={};for(let W of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let R=t.get(W);R&&(i[W]=R)}let n=JSON.stringify({tenant_slug:p,visitor_id:r,url:location.href,referrer:o.referrer||void 0,...Object.keys(i).length>0?{utm:i}:{}}),c=`${w}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(c,new Blob([n],{type:"application/json"})):fetch(c,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let y=parseInt(sessionStorage.getItem(`${a}pages`)||"0")+1;sessionStorage.setItem(`${a}pages`,String(y));let u=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");u.push(location.href),u.length>20&&(u=u.slice(-20)),sessionStorage.setItem(`${a}hist`,JSON.stringify(u));let A=Date.now(),b=parseInt(sessionStorage.getItem(`${a}site_start`)||"0");b||(b=A,sessionStorage.setItem(`${a}site_start`,String(b))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${a}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:y,pageHistory:u,loadedAt:A,siteStart:b,locale:g,visitorId:h?"":r},"*"),!t&&!h&&localStorage.setItem(`${a}visited`,"1")});let B=history.pushState.bind(history),P=history.replaceState.bind(history),x=()=>{y++,sessionStorage.setItem(`${a}pages`,String(y));let t=JSON.parse(sessionStorage.getItem(`${a}hist`)||"[]");if(t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${a}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:y,pageHistory:t,loadedAt:Date.now()},"*"),!h)try{let i=JSON.stringify({tenant_slug:p,visitor_id:r,url:location.href}),n=`${w}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(n,new Blob([i],{type:"application/json"})):fetch(n,{method:"POST",body:i,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...t){B(...t),x()},history.replaceState=function(...t){P(...t),x()},window.addEventListener("popstate",x);let _=-1,S,L=()=>{clearTimeout(S),S=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,i=t>0?Math.round(window.scrollY/t*100):100;i!==_&&(_=i,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:i},"*"))},500)};window.addEventListener("scroll",L,{passive:!0});let k=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",k);let $,M=!1,E=()=>{clearTimeout($),!M&&($=setTimeout(()=>{M=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},C=["mousemove","keydown","scroll","touchstart"];C.forEach(t=>o.addEventListener(t,E,{passive:!0})),E();let O=()=>{s.style.display="none",m(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:O,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",T),window.removeEventListener("scroll",L),window.removeEventListener("popstate",x),o.removeEventListener("mouseout",k),C.forEach(t=>o.removeEventListener(t,E)),clearTimeout(S),clearTimeout($),history.pushState=B,history.replaceState=P,m(),s.remove(),e.remove()}}}function V(d){let p=H(null),g=H(!1);return N(()=>{if(!g.current)return g.current=!0,p.current=U(d),()=>{p.current?.destroy(),p.current=null,g.current=!1}},[]),null}export{V as BitPalmAgent};
2
2
  //# sourceMappingURL=react.js.map
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type BitPalmAgentProps = BitPalmAgentOptions;\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n instanceRef.current = createWidget(props);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 window.addEventListener(\"message\", handleMessage);\n\n // --- Persistent Visitor ID ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\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 // --- Visitor beacon: track page view even without chat ---\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\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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,\n }, \"*\");\n if (!returning) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["useEffect","useRef","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","BitPalmAgent","props","instanceRef","useRef","mountedRef","useEffect","createWidget"]}
1
+ {"version":3,"sources":["../src/react.ts","../src/widget.ts"],"sourcesContent":["import { useEffect, useRef } from \"react\";\nimport { createWidget } from \"./widget\";\nimport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nexport type BitPalmAgentProps = BitPalmAgentOptions;\n\n/**\n * React component that mounts the BitPalm AI agent widget.\n *\n * @example\n * ```tsx\n * import { BitPalmAgent } from '@bitpalm/ai-agents/react';\n *\n * export default function App() {\n * return <BitPalmAgent slug=\"my-agent\" />;\n * }\n * ```\n */\nexport function BitPalmAgent(props: BitPalmAgentProps): null {\n const instanceRef = useRef<BitPalmAgentInstance | null>(null);\n const mountedRef = useRef(false);\n\n useEffect(() => {\n if (mountedRef.current) return;\n mountedRef.current = true;\n\n instanceRef.current = createWidget(props);\n\n return () => {\n instanceRef.current?.destroy();\n instanceRef.current = null;\n mountedRef.current = false;\n };\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n return null;\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 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 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 }\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["useEffect","useRef","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","BitPalmAgent","props","instanceRef","useRef","mountedRef","useEffect","createWidget"]}
@@ -1,2 +1,2 @@
1
- "use strict";var BitPalmAgents=(()=>{var I=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var N=(i,r)=>{for(var m in r)I(i,m,{get:r[m],enumerable:!0})},J=(i,r,m,h)=>{if(r&&typeof r=="object"||typeof r=="function")for(let p of z(r))!j.call(i,p)&&p!==m&&I(i,p,{get:()=>r[p],enumerable:!(h=D(r,p))||h.enumerable});return i};var Y=i=>J(I({},"__esModule",{value:!0}),i);var G={};N(G,{createWidget:()=>v});var F="https://agents.bitpalm.ae",l="_bp_";function q(){if(typeof document<"u"){let i=document.documentElement.lang;if(i)return i.slice(0,2).toLowerCase()}return"en"}function v(i){let{slug:r,locale:m=q(),baseUrl:h=F,zIndex:p=9999}=i,o=document,e=o.createElement("iframe"),T=`${h}/t/${r}/widget`;e.src=`${T}${T.includes("?")?"&":"?"}locale=${m}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${p};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,o.body.appendChild(e);let R=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${p-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>O(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let d=null,y=()=>{d&&(d.remove(),d=null)},L=t=>{if(t.origin===R){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let a=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${a}`,n.innerHTML=t.data.chatButtonIconSvg;let g=n.querySelector("svg");g&&(g.setAttribute("width","24"),g.setAttribute("height","24"),g.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=a)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let a=t.data.width>0,n=window.innerWidth<=640;a?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=a?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){y(),d=o.createElement("div"),d.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${p-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let a=(t.data.message||"").replace(/</g,"&lt;");d.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=o.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=g=>{g.stopPropagation(),y(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},d.onclick=()=>{y(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},d.appendChild(n),o.body.appendChild(d)}t.data?.type==="bitpalm-trigger-hide"&&y()}};window.addEventListener("message",L);let b=`${l}vid`,c="";try{c=localStorage.getItem(b)||""}catch{}if(!c){let t=o.cookie.match(new RegExp(`(?:^|; )${b}=([^;]+)`));c=t?decodeURIComponent(t[1]):""}c||(c=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(b,c)}catch{}try{o.cookie=`${b}=${encodeURIComponent(c)};path=/;max-age=31536000;SameSite=Lax`}catch{}try{let t=new URLSearchParams(location.search),a={};for(let U of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let H=t.get(U);H&&(a[U]=H)}let n=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href,referrer:o.referrer||void 0,...Object.keys(a).length>0?{utm:a}:{}}),g=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(g,new Blob([n],{type:"application/json"})):fetch(g,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let f=parseInt(sessionStorage.getItem(`${l}pages`)||"0")+1;sessionStorage.setItem(`${l}pages`,String(f));let u=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");u.push(location.href),u.length>20&&(u=u.slice(-20)),sessionStorage.setItem(`${l}hist`,JSON.stringify(u));let _=Date.now(),x=parseInt(sessionStorage.getItem(`${l}site_start`)||"0");x||(x=_,sessionStorage.setItem(`${l}site_start`,String(x))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${l}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:f,pageHistory:u,loadedAt:_,siteStart:x,locale:m,visitorId:c},"*"),t||localStorage.setItem(`${l}visited`,"1")});let M=history.pushState.bind(history),k=history.replaceState.bind(history),w=()=>{f++,sessionStorage.setItem(`${l}pages`,String(f));let t=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${l}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:f,pageHistory:t,loadedAt:Date.now()},"*");try{let a=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href}),n=`${h}/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(...t){M(...t),w()},history.replaceState=function(...t){k(...t),w()},window.addEventListener("popstate",w);let A=-1,S,B=()=>{clearTimeout(S),S=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,a=t>0?Math.round(window.scrollY/t*100):100;a!==A&&(A=a,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:a},"*"))},500)};window.addEventListener("scroll",B,{passive:!0});let C=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",C);let E,P=!1,$=()=>{clearTimeout(E),!P&&(E=setTimeout(()=>{P=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},W=["mousemove","keydown","scroll","touchstart"];W.forEach(t=>o.addEventListener(t,$,{passive:!0})),$();let O=()=>{s.style.display="none",y(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:O,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",L),window.removeEventListener("scroll",B),window.removeEventListener("popstate",w),o.removeEventListener("mouseout",C),W.forEach(t=>o.removeEventListener(t,$)),clearTimeout(S),clearTimeout(E),history.pushState=M,history.replaceState=k,y(),s.remove(),e.remove()}}}if(typeof document<"u"){let i=document.currentScript;if(i?.dataset.slug){let r=()=>{v({slug:i.dataset.slug,locale:i.dataset.locale,baseUrl:i.dataset.baseUrl,zIndex:i.dataset.zIndex?Number(i.dataset.zIndex):void 0})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",r):r()}}return Y(G);})();
1
+ "use strict";var BitPalmAgents=(()=>{var T=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var J=(i,r)=>{for(var m in r)T(i,m,{get:r[m],enumerable:!0})},Y=(i,r,m,h)=>{if(r&&typeof r=="object"||typeof r=="function")for(let p of j(r))!N.call(i,p)&&p!==m&&T(i,p,{get:()=>r[p],enumerable:!(h=z(r,p))||h.enumerable});return i};var F=i=>Y(T({},"__esModule",{value:!0}),i);var V={};J(V,{createWidget:()=>S});var q="https://agents.bitpalm.ae",l="_bp_";function G(){if(typeof document<"u"){let i=document.documentElement.lang;if(i)return i.slice(0,2).toLowerCase()}return"en"}function S(i){let{slug:r,locale:m=G(),baseUrl:h=q,zIndex:p=9999}=i,o=document,e=o.createElement("iframe"),L=`${h}/t/${r}/widget`;e.src=`${L}${L.includes("?")?"&":"?"}locale=${m}`,e.allow="clipboard-write",e.setAttribute("allowtransparency","true"),e.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${p};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`,o.body.appendChild(e);let D=new URL(e.src).origin,s=o.createElement("div");if(s.setAttribute("role","button"),s.setAttribute("aria-label","Chat"),s.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:${p-1};background:#00ff41;box-shadow:0 0 15px rgba(0,255,65,0.31);transition:transform .2s;`,s.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>',s.onmouseenter=()=>{s.style.transform="scale(1.1)"},s.onmouseleave=()=>{s.style.transform="scale(1)"},s.onclick=()=>U(),o.body.appendChild(s),!o.getElementById("_bp_fade")){let t=o.createElement("style");t.id="_bp_fade",t.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",o.head.appendChild(t)}let d=null,y=()=>{d&&(d.remove(),d=null)},_=t=>{if(t.origin===D){if(t.data?.type==="bitpalm-widget-config"){t.data.primaryColor&&(s.style.background=t.data.primaryColor,s.style.boxShadow=t.data.chatShadow==="none"?"none":`0 0 15px ${t.data.primaryColor}50`);let a=t.data.chatButtonIconColor||"black";if(t.data.chatButtonIconSvg){s.innerHTML="";let n=o.createElement("span");n.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${a}`,n.innerHTML=t.data.chatButtonIconSvg;let g=n.querySelector("svg");g&&(g.setAttribute("width","24"),g.setAttribute("height","24"),g.style.display="block"),s.appendChild(n)}else{let n=s.querySelector("svg");n&&(n.style.stroke=a)}s.style.display="flex"}if(t.data?.type==="bitpalm-widget-resize"){let a=t.data.width>0,n=window.innerWidth<=640;a?(e.style.width=n?`${window.innerWidth}px`:`${t.data.width}px`,e.style.height=n?`${window.innerHeight}px`:`${t.data.height}px`,n&&(e.style.left="0",e.style.top="0"),e.style.opacity="1",e.style.pointerEvents="auto"):(e.style.width="1px",e.style.height="1px",e.style.left="",e.style.top="",e.style.opacity="0",e.style.pointerEvents="none"),s.style.display=a?"none":"flex"}if(t.data?.type==="bitpalm-trigger-show"){y(),d=o.createElement("div"),d.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${p-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let a=(t.data.message||"").replace(/</g,"&lt;");d.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=o.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=g=>{g.stopPropagation(),y(),e.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},d.onclick=()=>{y(),s.style.display="none",e.contentWindow?.postMessage({type:"bitpalm-trigger-engaged"},"*")},d.appendChild(n),o.body.appendChild(d)}t.data?.type==="bitpalm-trigger-hide"&&y()}};window.addEventListener("message",_);let u=!1;try{u=localStorage.getItem(`${l}optout`)==="1"}catch{}let x=`${l}vid`,c="";if(!u){try{c=localStorage.getItem(x)||""}catch{}if(!c){let t=o.cookie.match(new RegExp(`(?:^|; )${x}=([^;]+)`));c=t?decodeURIComponent(t[1]):""}c||(c=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(x,c)}catch{}try{o.cookie=`${x}=${encodeURIComponent(c)};path=/;max-age=31536000;SameSite=Lax`}catch{}}if(!u)try{let t=new URLSearchParams(location.search),a={};for(let H of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let R=t.get(H);R&&(a[H]=R)}let n=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href,referrer:o.referrer||void 0,...Object.keys(a).length>0?{utm:a}:{}}),g=`${h}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(g,new Blob([n],{type:"application/json"})):fetch(g,{method:"POST",body:n,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}let b=parseInt(sessionStorage.getItem(`${l}pages`)||"0")+1;sessionStorage.setItem(`${l}pages`,String(b));let f=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");f.push(location.href),f.length>20&&(f=f.slice(-20)),sessionStorage.setItem(`${l}hist`,JSON.stringify(f));let M=Date.now(),w=parseInt(sessionStorage.getItem(`${l}site_start`)||"0");w||(w=M,sessionStorage.setItem(`${l}site_start`,String(w))),e.addEventListener("load",()=>{let t=!!localStorage.getItem(`${l}visited`);e.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:o.title,returning:t,pageCount:b,pageHistory:f,loadedAt:M,siteStart:w,locale:m,visitorId:u?"":c},"*"),!t&&!u&&localStorage.setItem(`${l}visited`,"1")});let k=history.pushState.bind(history),A=history.replaceState.bind(history),v=()=>{b++,sessionStorage.setItem(`${l}pages`,String(b));let t=JSON.parse(sessionStorage.getItem(`${l}hist`)||"[]");if(t.push(location.href),t.length>20&&t.splice(0,t.length-20),sessionStorage.setItem(`${l}hist`,JSON.stringify(t)),e.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:o.title,pageCount:b,pageHistory:t,loadedAt:Date.now()},"*"),!u)try{let a=JSON.stringify({tenant_slug:r,visitor_id:c,url:location.href}),n=`${h}/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(...t){k(...t),v()},history.replaceState=function(...t){A(...t),v()},window.addEventListener("popstate",v);let B=-1,$,C=()=>{clearTimeout($),$=setTimeout(()=>{let t=Math.max(o.documentElement.scrollHeight,o.body.scrollHeight)-window.innerHeight,a=t>0?Math.round(window.scrollY/t*100):100;a!==B&&(B=a,e.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:a},"*"))},500)};window.addEventListener("scroll",C,{passive:!0});let O=t=>{t.clientY<=0&&e.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};o.addEventListener("mouseout",O);let E,P=!1,I=()=>{clearTimeout(E),!P&&(E=setTimeout(()=>{P=!0,e.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},W=["mousemove","keydown","scroll","touchstart"];W.forEach(t=>o.addEventListener(t,I,{passive:!0})),I();let U=()=>{s.style.display="none",y(),e.contentWindow?.postMessage({type:"bitpalm-open"},"*");let t=e.src.split("#")[0];e.src=`${t}#bp-open-${Date.now()}`};return{open:U,close:()=>{e.contentWindow?.postMessage({type:"bitpalm-close"},"*")},destroy:()=>{window.removeEventListener("message",_),window.removeEventListener("scroll",C),window.removeEventListener("popstate",v),o.removeEventListener("mouseout",O),W.forEach(t=>o.removeEventListener(t,I)),clearTimeout($),clearTimeout(E),history.pushState=k,history.replaceState=A,y(),s.remove(),e.remove()}}}if(typeof document<"u"){let i=document.currentScript;if(i?.dataset.slug){let r=()=>{S({slug:i.dataset.slug,locale:i.dataset.locale,baseUrl:i.dataset.baseUrl,zIndex:i.dataset.zIndex?Number(i.dataset.zIndex):void 0})};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",r):r()}}return F(V);})();
2
2
  //# sourceMappingURL=widget.global.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/widget.ts"],"sourcesContent":["export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\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 zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 window.addEventListener(\"message\", handleMessage);\n\n // --- Persistent Visitor ID ---\n const VID_KEY = `${STORAGE_PREFIX}vid`;\n let visitorId = \"\";\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 // --- Visitor beacon: track page view even without chat ---\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\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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,\n }, \"*\");\n if (!returning) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["src_exports","__export","createWidget","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","script","init","createWidget"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/widget.ts"],"sourcesContent":["export { createWidget } from \"./widget\";\nexport type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nimport { createWidget } from \"./widget\";\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 zIndex: script!.dataset.zIndex ? Number(script!.dataset.zIndex) : undefined,\n });\n };\n\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", init);\n } else {\n init();\n }\n }\n}\n","import type { BitPalmAgentOptions, BitPalmAgentInstance } from \"./types\";\n\nconst DEFAULT_BASE_URL = \"https://agents.bitpalm.ae\";\nconst STORAGE_PREFIX = \"_bp_\";\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\nexport function createWidget(options: BitPalmAgentOptions): BitPalmAgentInstance {\n const {\n slug,\n locale = detectLocale(),\n baseUrl = DEFAULT_BASE_URL,\n zIndex = 9999,\n } = options;\n\n const d = document;\n\n // --- Iframe ---\n const iframe = d.createElement(\"iframe\");\n const widgetUrl = `${baseUrl}/t/${slug}/widget`;\n iframe.src = `${widgetUrl}${widgetUrl.includes(\"?\") ? \"&\" : \"?\"}locale=${locale}`;\n iframe.allow = \"clipboard-write\";\n iframe.setAttribute(\"allowtransparency\", \"true\");\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 d.body.appendChild(iframe);\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;`;\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 const removeBubble = () => {\n if (bubble) { bubble.remove(); bubble = null; }\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 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 sp.innerHTML = e.data.chatButtonIconSvg;\n const svg = sp.querySelector(\"svg\");\n if (svg) {\n svg.setAttribute(\"width\", \"24\");\n svg.setAttribute(\"height\", \"24\");\n svg.style.display = \"block\";\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 }\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 = window.innerWidth <= 640;\n if (isOpen) {\n iframe.style.width = mobile ? `${window.innerWidth}px` : `${e.data.width}px`;\n iframe.style.height = mobile ? `${window.innerHeight}px` : `${e.data.height}px`;\n if (mobile) { iframe.style.left = \"0\"; iframe.style.top = \"0\"; }\n iframe.style.opacity = \"1\";\n iframe.style.pointerEvents = \"auto\";\n } else {\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 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 = () => { removeBubble(); btn.style.display = \"none\"; iframe.contentWindow?.postMessage({ type: \"bitpalm-trigger-engaged\" }, \"*\"); };\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 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 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 }\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 // --- Send parent context on iframe load ---\n iframe.addEventListener(\"load\", () => {\n const returning = !!localStorage.getItem(`${STORAGE_PREFIX}visited`);\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) localStorage.setItem(`${STORAGE_PREFIX}visited`, \"1\");\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 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 // --- Public API ---\n const openWidget = () => {\n btn.style.display = \"none\";\n removeBubble();\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 const closeWidget = () => {\n iframe.contentWindow?.postMessage({ type: \"bitpalm-close\" }, \"*\");\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 idleEvents.forEach((ev) => d.removeEventListener(ev, resetIdle));\n clearTimeout(scrollTimeout);\n clearTimeout(idleTimer);\n history.pushState = origPush;\n history.replaceState = origReplace;\n removeBubble();\n btn.remove();\n iframe.remove();\n };\n\n return { open: openWidget, close: closeWidget, destroy };\n}\n"],"mappings":"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","names":["src_exports","__export","createWidget","DEFAULT_BASE_URL","STORAGE_PREFIX","detectLocale","lang","createWidget","options","slug","locale","baseUrl","zIndex","d","iframe","widgetUrl","origin","btn","openWidget","s","bubble","removeBubble","handleMessage","e","ic","sp","svg","sv","isOpen","mobile","msg","close","ev","optedOut","VID_KEY","visitorId","match","utmParams","utm","key","val","beaconPayload","beaconUrl","pageCount","hist","loadedAt","siteStart","returning","origPush","origReplace","onNav","h","navPayload","navUrl","args","lastScrollDepth","scrollTimeout","handleScroll","total","pct","handleMouseOut","idleTimer","idleFired","resetIdle","idleEvents","base","script","init","createWidget"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitpalm/ai-agents",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Drop-in AI chat agent widget for any website. Includes visitor intelligence, SPA navigation tracking, trigger bubbles, and more.",
5
5
  "license": "MIT",
6
6
  "author": "BitPalm <agents@bitpalm.ae>",