@bitpalm/ai-agents 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.d.cts CHANGED
@@ -1,3 +1,124 @@
1
+ interface ChatCard {
2
+ kind?: string;
3
+ title: string;
4
+ image?: string;
5
+ subtitle?: string;
6
+ fields?: {
7
+ label: string;
8
+ value: string;
9
+ }[];
10
+ cta?: {
11
+ label: string;
12
+ url: string;
13
+ };
14
+ }
15
+ interface ChatMessage {
16
+ role: "user" | "assistant";
17
+ text: string;
18
+ createdAt?: string;
19
+ cards?: ChatCard[];
20
+ /** Photos the user sent, as links. */
21
+ images?: string[];
22
+ /** Written by a person of the team, not by the agent. */
23
+ fromHuman?: boolean;
24
+ }
25
+ interface QuickLink {
26
+ id: string;
27
+ label: string;
28
+ /** Send this as the user's message. */
29
+ message?: string;
30
+ /** Or open this address. */
31
+ url?: string;
32
+ }
33
+ interface AgentConfig {
34
+ name: string;
35
+ logoUrl: string | null;
36
+ primaryColor: string;
37
+ welcomeMessage: string;
38
+ inputPlaceholder: string;
39
+ quickLinks: QuickLink[];
40
+ photoUploads: boolean;
41
+ /** When required is true, show text linked to url in your chat UI. */
42
+ branding: {
43
+ required: boolean;
44
+ text: string;
45
+ url: string;
46
+ };
47
+ }
48
+ interface ChatClientOptions {
49
+ /** App key from the dashboard, starts with bp_pk_. */
50
+ key: string;
51
+ /** Defaults to https://agents.bitpalm.ai. */
52
+ baseUrl?: string;
53
+ /**
54
+ * Id that holds the conversation together. Leave it out: the client
55
+ * creates a random one and remembers it. If you set it, make it
56
+ * unguessable. Never use a plain user id, anyone with the app key could
57
+ * read that user's chats.
58
+ */
59
+ visitorId?: string;
60
+ /** Language for greeting, placeholder and quick links, like "de". */
61
+ locale?: string;
62
+ /** Where visitor and conversation are remembered. Defaults to localStorage when there is one. */
63
+ storage?: Pick<Storage, "getItem" | "setItem" | "removeItem"> | null;
64
+ }
65
+ interface SendOptions {
66
+ /** Facts for this answer, like the cart or the user's plan. At most 4 KB. */
67
+ context?: Record<string, unknown>;
68
+ /** Ids of photos from upload(). */
69
+ fileIds?: string[];
70
+ /** Called as the answer grows: the new piece and the whole answer so far. */
71
+ onDelta?: (piece: string, answer: string) => void;
72
+ signal?: AbortSignal;
73
+ }
74
+ interface SendResult {
75
+ text: string;
76
+ conversationId: string;
77
+ cards?: ChatCard[];
78
+ /**
79
+ * Your team has the conversation now. The agent stays silent in it until
80
+ * the team closes it, the team's replies come with history().
81
+ */
82
+ handoff?: boolean;
83
+ }
84
+ interface Identity {
85
+ name?: string;
86
+ email?: string;
87
+ phone?: string;
88
+ company?: string;
89
+ externalUserId?: string;
90
+ }
91
+ /** An error of the API, with its code, like "invalid_key" or "rate_limited". */
92
+ declare class BitPalmApiError extends Error {
93
+ readonly code: string;
94
+ readonly status: number;
95
+ constructor(code: string, message: string, status: number);
96
+ }
97
+ interface ChatClient {
98
+ readonly visitorId: string;
99
+ readonly conversationId: string | null;
100
+ /** True while your team has the conversation. Updated by send() and history(). */
101
+ readonly handoff: boolean;
102
+ /** Name, greeting, quick links and whether "Powered by BitPalm" has to show. */
103
+ agent(options?: {
104
+ url?: string;
105
+ }): Promise<AgentConfig>;
106
+ send(message: string, options?: SendOptions): Promise<SendResult>;
107
+ /** The messages of the current conversation, or of the latest one of this visitor. */
108
+ history(): Promise<ChatMessage[]>;
109
+ /** Tells BitPalm who the logged-in user is. */
110
+ identify(identity: Identity): Promise<void>;
111
+ /** A photo for the next message, when the agent takes photos. */
112
+ upload(file: Blob, fileName?: string): Promise<{
113
+ id: string;
114
+ url: string;
115
+ }>;
116
+ /** Thumbs up or down for the agent's answer number index (0 is the first answer). */
117
+ feedback(index: number, value: "up" | "down"): Promise<void>;
118
+ /** Starts a new conversation. */
119
+ reset(): void;
120
+ }
121
+
1
122
  /**
2
123
  * Widget color theme. "auto" follows the website: theme classes or
3
124
  * attributes like class="dark" or data-theme="dark" on <html> or <body>,
@@ -27,6 +148,17 @@ interface BitPalmAgentOptions {
27
148
  * effect when the agent has a dark theme set up in the dashboard.
28
149
  */
29
150
  theme?: BitPalmTheme;
151
+ /**
152
+ * Show the round chat button. Set to false when your site has a chat
153
+ * button of its own that calls open() or toggle(). Defaults to true.
154
+ */
155
+ launcher?: boolean;
156
+ /**
157
+ * Proactive messages set up in the dashboard. true shows them as a
158
+ * bubble (default), "events" shows nothing and fires trigger_shown so
159
+ * you can show the message yourself, false switches them off.
160
+ */
161
+ triggers?: boolean | "events";
30
162
  }
31
163
  interface BitPalmIdentifyPayload {
32
164
  /** Stable user id from the host platform (required for signed identify). */
@@ -58,7 +190,11 @@ interface BitPalmIdentifyPayload {
58
190
  */
59
191
  type BitPalmCustomContext = Record<string, unknown>;
60
192
  /** Event types emitted by the widget. */
61
- type BitPalmEventType = "widget_opened" | "widget_closed" | "conversation_started" | "message_sent" | "message_received" | "lead_captured";
193
+ type BitPalmEventType = "widget_opened" | "widget_closed" | "conversation_started" | "message_sent" | "message_received" | "lead_captured"
194
+ /** A proactive message is waiting, with { message, triggerId, triggerType }. Only with triggers: "events". */
195
+ | "trigger_shown"
196
+ /** The waiting message is gone: the chat was opened, or triggers were switched off. */
197
+ | "trigger_hidden";
62
198
  /** Callback for widget events. */
63
199
  type BitPalmEventCallback = (data?: Record<string, unknown>) => void;
64
200
  interface BitPalmAgentInstance {
@@ -114,11 +250,22 @@ interface BitPalmAgentInstance {
114
250
  * widget.setTheme('dark');
115
251
  */
116
252
  setTheme: (theme: BitPalmTheme) => void;
253
+ /** Switch proactive messages off, for example while a checkout is open. */
254
+ disableTriggers: () => void;
255
+ /** Switch them back on, as a bubble or as events, the way the triggers option says. */
256
+ enableTriggers: () => void;
117
257
  /** Remove the widget and clean up all event listeners. */
118
258
  destroy: () => void;
119
259
  }
120
260
 
121
- type BitPalmAgentProps = BitPalmAgentOptions;
261
+ interface BitPalmAgentProps extends BitPalmAgentOptions {
262
+ /**
263
+ * Called once with the widget, for open(), on('trigger_shown', …) and
264
+ * the rest of the API. Needed with launcher={false} and a button of
265
+ * your own.
266
+ */
267
+ onReady?: (widget: BitPalmAgentInstance) => void;
268
+ }
122
269
  /**
123
270
  * React component that mounts the BitPalm AI agent widget.
124
271
  *
@@ -132,5 +279,30 @@ type BitPalmAgentProps = BitPalmAgentOptions;
132
279
  * ```
133
280
  */
134
281
  declare function BitPalmAgent(props: BitPalmAgentProps): null;
282
+ type ChatStatus = "idle" | "streaming" | "error";
283
+ interface UseBitPalmChatOptions extends ChatClientOptions {
284
+ /** Load the last conversation of this visitor on start. Defaults to true. */
285
+ loadHistory?: boolean;
286
+ }
287
+ /**
288
+ * Your own chat UI in React, with BitPalm behind it. Keeps the messages,
289
+ * streams the answer into the last one and remembers the conversation.
290
+ *
291
+ * @example
292
+ * ```tsx
293
+ * const { messages, send, status, agent } = useBitPalmChat({ key: "bp_pk_…" });
294
+ * ```
295
+ */
296
+ declare function useBitPalmChat(options: UseBitPalmChatOptions): {
297
+ messages: ChatMessage[];
298
+ send: (text: string, sendOptions?: Omit<SendOptions, "onDelta">) => Promise<SendResult | null>;
299
+ status: ChatStatus;
300
+ error: BitPalmApiError | null;
301
+ agent: AgentConfig | null;
302
+ handoff: boolean;
303
+ refresh: () => Promise<void>;
304
+ reset: () => void;
305
+ client: ChatClient;
306
+ };
135
307
 
136
- export { BitPalmAgent, type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmAgentProps };
308
+ export { type AgentConfig, BitPalmAgent, type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmAgentProps, BitPalmApiError, type ChatCard, type ChatClient, type ChatClientOptions, type ChatMessage, type ChatStatus, type QuickLink, type SendOptions, type SendResult, type UseBitPalmChatOptions, useBitPalmChat };
package/dist/react.d.ts CHANGED
@@ -1,3 +1,124 @@
1
+ interface ChatCard {
2
+ kind?: string;
3
+ title: string;
4
+ image?: string;
5
+ subtitle?: string;
6
+ fields?: {
7
+ label: string;
8
+ value: string;
9
+ }[];
10
+ cta?: {
11
+ label: string;
12
+ url: string;
13
+ };
14
+ }
15
+ interface ChatMessage {
16
+ role: "user" | "assistant";
17
+ text: string;
18
+ createdAt?: string;
19
+ cards?: ChatCard[];
20
+ /** Photos the user sent, as links. */
21
+ images?: string[];
22
+ /** Written by a person of the team, not by the agent. */
23
+ fromHuman?: boolean;
24
+ }
25
+ interface QuickLink {
26
+ id: string;
27
+ label: string;
28
+ /** Send this as the user's message. */
29
+ message?: string;
30
+ /** Or open this address. */
31
+ url?: string;
32
+ }
33
+ interface AgentConfig {
34
+ name: string;
35
+ logoUrl: string | null;
36
+ primaryColor: string;
37
+ welcomeMessage: string;
38
+ inputPlaceholder: string;
39
+ quickLinks: QuickLink[];
40
+ photoUploads: boolean;
41
+ /** When required is true, show text linked to url in your chat UI. */
42
+ branding: {
43
+ required: boolean;
44
+ text: string;
45
+ url: string;
46
+ };
47
+ }
48
+ interface ChatClientOptions {
49
+ /** App key from the dashboard, starts with bp_pk_. */
50
+ key: string;
51
+ /** Defaults to https://agents.bitpalm.ai. */
52
+ baseUrl?: string;
53
+ /**
54
+ * Id that holds the conversation together. Leave it out: the client
55
+ * creates a random one and remembers it. If you set it, make it
56
+ * unguessable. Never use a plain user id, anyone with the app key could
57
+ * read that user's chats.
58
+ */
59
+ visitorId?: string;
60
+ /** Language for greeting, placeholder and quick links, like "de". */
61
+ locale?: string;
62
+ /** Where visitor and conversation are remembered. Defaults to localStorage when there is one. */
63
+ storage?: Pick<Storage, "getItem" | "setItem" | "removeItem"> | null;
64
+ }
65
+ interface SendOptions {
66
+ /** Facts for this answer, like the cart or the user's plan. At most 4 KB. */
67
+ context?: Record<string, unknown>;
68
+ /** Ids of photos from upload(). */
69
+ fileIds?: string[];
70
+ /** Called as the answer grows: the new piece and the whole answer so far. */
71
+ onDelta?: (piece: string, answer: string) => void;
72
+ signal?: AbortSignal;
73
+ }
74
+ interface SendResult {
75
+ text: string;
76
+ conversationId: string;
77
+ cards?: ChatCard[];
78
+ /**
79
+ * Your team has the conversation now. The agent stays silent in it until
80
+ * the team closes it, the team's replies come with history().
81
+ */
82
+ handoff?: boolean;
83
+ }
84
+ interface Identity {
85
+ name?: string;
86
+ email?: string;
87
+ phone?: string;
88
+ company?: string;
89
+ externalUserId?: string;
90
+ }
91
+ /** An error of the API, with its code, like "invalid_key" or "rate_limited". */
92
+ declare class BitPalmApiError extends Error {
93
+ readonly code: string;
94
+ readonly status: number;
95
+ constructor(code: string, message: string, status: number);
96
+ }
97
+ interface ChatClient {
98
+ readonly visitorId: string;
99
+ readonly conversationId: string | null;
100
+ /** True while your team has the conversation. Updated by send() and history(). */
101
+ readonly handoff: boolean;
102
+ /** Name, greeting, quick links and whether "Powered by BitPalm" has to show. */
103
+ agent(options?: {
104
+ url?: string;
105
+ }): Promise<AgentConfig>;
106
+ send(message: string, options?: SendOptions): Promise<SendResult>;
107
+ /** The messages of the current conversation, or of the latest one of this visitor. */
108
+ history(): Promise<ChatMessage[]>;
109
+ /** Tells BitPalm who the logged-in user is. */
110
+ identify(identity: Identity): Promise<void>;
111
+ /** A photo for the next message, when the agent takes photos. */
112
+ upload(file: Blob, fileName?: string): Promise<{
113
+ id: string;
114
+ url: string;
115
+ }>;
116
+ /** Thumbs up or down for the agent's answer number index (0 is the first answer). */
117
+ feedback(index: number, value: "up" | "down"): Promise<void>;
118
+ /** Starts a new conversation. */
119
+ reset(): void;
120
+ }
121
+
1
122
  /**
2
123
  * Widget color theme. "auto" follows the website: theme classes or
3
124
  * attributes like class="dark" or data-theme="dark" on <html> or <body>,
@@ -27,6 +148,17 @@ interface BitPalmAgentOptions {
27
148
  * effect when the agent has a dark theme set up in the dashboard.
28
149
  */
29
150
  theme?: BitPalmTheme;
151
+ /**
152
+ * Show the round chat button. Set to false when your site has a chat
153
+ * button of its own that calls open() or toggle(). Defaults to true.
154
+ */
155
+ launcher?: boolean;
156
+ /**
157
+ * Proactive messages set up in the dashboard. true shows them as a
158
+ * bubble (default), "events" shows nothing and fires trigger_shown so
159
+ * you can show the message yourself, false switches them off.
160
+ */
161
+ triggers?: boolean | "events";
30
162
  }
31
163
  interface BitPalmIdentifyPayload {
32
164
  /** Stable user id from the host platform (required for signed identify). */
@@ -58,7 +190,11 @@ interface BitPalmIdentifyPayload {
58
190
  */
59
191
  type BitPalmCustomContext = Record<string, unknown>;
60
192
  /** Event types emitted by the widget. */
61
- type BitPalmEventType = "widget_opened" | "widget_closed" | "conversation_started" | "message_sent" | "message_received" | "lead_captured";
193
+ type BitPalmEventType = "widget_opened" | "widget_closed" | "conversation_started" | "message_sent" | "message_received" | "lead_captured"
194
+ /** A proactive message is waiting, with { message, triggerId, triggerType }. Only with triggers: "events". */
195
+ | "trigger_shown"
196
+ /** The waiting message is gone: the chat was opened, or triggers were switched off. */
197
+ | "trigger_hidden";
62
198
  /** Callback for widget events. */
63
199
  type BitPalmEventCallback = (data?: Record<string, unknown>) => void;
64
200
  interface BitPalmAgentInstance {
@@ -114,11 +250,22 @@ interface BitPalmAgentInstance {
114
250
  * widget.setTheme('dark');
115
251
  */
116
252
  setTheme: (theme: BitPalmTheme) => void;
253
+ /** Switch proactive messages off, for example while a checkout is open. */
254
+ disableTriggers: () => void;
255
+ /** Switch them back on, as a bubble or as events, the way the triggers option says. */
256
+ enableTriggers: () => void;
117
257
  /** Remove the widget and clean up all event listeners. */
118
258
  destroy: () => void;
119
259
  }
120
260
 
121
- type BitPalmAgentProps = BitPalmAgentOptions;
261
+ interface BitPalmAgentProps extends BitPalmAgentOptions {
262
+ /**
263
+ * Called once with the widget, for open(), on('trigger_shown', …) and
264
+ * the rest of the API. Needed with launcher={false} and a button of
265
+ * your own.
266
+ */
267
+ onReady?: (widget: BitPalmAgentInstance) => void;
268
+ }
122
269
  /**
123
270
  * React component that mounts the BitPalm AI agent widget.
124
271
  *
@@ -132,5 +279,30 @@ type BitPalmAgentProps = BitPalmAgentOptions;
132
279
  * ```
133
280
  */
134
281
  declare function BitPalmAgent(props: BitPalmAgentProps): null;
282
+ type ChatStatus = "idle" | "streaming" | "error";
283
+ interface UseBitPalmChatOptions extends ChatClientOptions {
284
+ /** Load the last conversation of this visitor on start. Defaults to true. */
285
+ loadHistory?: boolean;
286
+ }
287
+ /**
288
+ * Your own chat UI in React, with BitPalm behind it. Keeps the messages,
289
+ * streams the answer into the last one and remembers the conversation.
290
+ *
291
+ * @example
292
+ * ```tsx
293
+ * const { messages, send, status, agent } = useBitPalmChat({ key: "bp_pk_…" });
294
+ * ```
295
+ */
296
+ declare function useBitPalmChat(options: UseBitPalmChatOptions): {
297
+ messages: ChatMessage[];
298
+ send: (text: string, sendOptions?: Omit<SendOptions, "onDelta">) => Promise<SendResult | null>;
299
+ status: ChatStatus;
300
+ error: BitPalmApiError | null;
301
+ agent: AgentConfig | null;
302
+ handoff: boolean;
303
+ refresh: () => Promise<void>;
304
+ reset: () => void;
305
+ client: ChatClient;
306
+ };
135
307
 
136
- export { BitPalmAgent, type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmAgentProps };
308
+ export { type AgentConfig, BitPalmAgent, type BitPalmAgentInstance, type BitPalmAgentOptions, type BitPalmAgentProps, BitPalmApiError, type ChatCard, type ChatClient, type ChatClientOptions, type ChatMessage, type ChatStatus, type QuickLink, type SendOptions, type SendResult, type UseBitPalmChatOptions, useBitPalmChat };
package/dist/react.js CHANGED
@@ -1,2 +1,13 @@
1
- import{useEffect as rt,useRef as lt}from"react";var ut=["dark","dark-mode","dark-theme","theme-dark"],ft=["light","light-mode","light-theme","theme-light"],Ze=["data-theme","data-color-scheme","data-color-mode","data-mode","data-bs-theme"],Qe="(prefers-color-scheme: dark)";function ne(n){return n==="light"||n==="dark"?n:"auto"}function Ve(n){if(!n)return null;if(ut.some(t=>n.classList.contains(t)))return"dark";if(ft.some(t=>n.classList.contains(t)))return"light";for(let t of Ze){let r=(n.getAttribute(t)||"").toLowerCase();if(r.includes("dark"))return"dark";if(r.includes("light"))return"light"}return null}function be(n){let t=n/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4}function Xe(n,t){if(!n)return null;let r=t.getComputedStyle(n).backgroundColor.match(/rgba?\(([^)]+)\)/);if(!r)return null;let[a,u,y,p=1]=r[1].split(/[\s,/]+/).filter(Boolean).map(Number);return[a,u,y,p].some(g=>Number.isNaN(g))||p<.5?null:.2126*be(a)+.7152*be(u)+.0722*be(y)<.2?"dark":"light"}function pt(n,t){let r=t.getComputedStyle(n.documentElement).colorScheme||"",a=n.querySelector('meta[name="color-scheme"]')?.getAttribute("content")||"",u=`${r} ${a}`.toLowerCase();return u.includes("dark")?u.includes("light")?t.matchMedia?.(Qe).matches?"dark":"light":"dark":null}function z(n=document,t=window){return Ve(n.documentElement)??Ve(n.body)??Xe(n.body,t)??Xe(n.documentElement,t)??pt(n,t)??"light"}function ve(n,t=document,r=window){let a=z(t,r),u=!1,y=()=>{u=!1;let c=z(t,r);c!==a&&(a=c,n(c))},p=()=>{u||(u=!0,typeof r.requestAnimationFrame=="function"?r.requestAnimationFrame(y):setTimeout(y,16))},l=typeof MutationObserver<"u"?new MutationObserver(p):null,g={attributes:!0,attributeFilter:["class","style",...Ze]};l?.observe(t.documentElement,g),t.body&&l?.observe(t.body,g);let b=typeof r.matchMedia=="function"?r.matchMedia(Qe):null;return b?.addEventListener?.("change",p),()=>{l?.disconnect(),b?.removeEventListener?.("change",p)}}var gt="https://agents.bitpalm.ai",v="_bp_",ht=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),yt=8e3,et=4096,tt=`${v}identify_signature`,nt=`${v}identify_fingerprint`,ot=`${v}identify_sent_at`,it="0 4px 14px rgba(0,0,0,0.18)";function bt(n){return[n.external_user_id||"",n.email||"",n.phone||"",n.name||"",n.company||"",n.signature||"",n.signed_at!=null?String(n.signed_at):"",n.signature_version||"",n.identify_source||""].join("|").toLowerCase()}function d(n,t=180){return n?n.replace(/\s+/g," ").trim().slice(0,t):""}function vt(n){return n?` ${n.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function N(n,t){for(let r of t)if(n.includes(r))return!0;return!1}function I(n){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(n)}function _(n){let t=d(n,50);if(!t)return"";let r=t.startsWith("+"),a=t.replace(/\D/g,"");return a.length<6?"":`${r?"+":""}${a.slice(0,20)}`}function st(n){let t=d(n,140).toLowerCase();return!t||!I(t)?"":t}function W(n,t){for(let r of t){let a=n.querySelector(r),u=d(a?.value);if(u)return u}return""}function wt(n){return d(n.getAttribute("data-bp-field")||n.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function Et(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function xt(n,t){let r=[],a=(g,b=140)=>{let c=d(g,b);c&&r.push(c)};a(t.name),a(t.id),a(t.getAttribute("autocomplete")),a(t.getAttribute("placeholder")),a(t.getAttribute("aria-label")),a(t.getAttribute("data-field")),a(t.getAttribute("data-name")),a(t.getAttribute("data-label")),a(t.getAttribute("data-bp-field")),a(t.getAttribute("data-bitpalm-field"));let u=new Set,y=g=>{let b=d(g,200);!b||u.has(b)||(u.add(b),r.push(b))};for(let g of Array.from(t.labels||[]))y(g.textContent);if(t.id){let g=n.querySelector(`label[for="${Et(t.id)}"]`);y(g?.textContent)}let p=t.closest("label");y(p?.textContent);let l=t.getAttribute("aria-labelledby");if(l)for(let g of l.split(/\s+/)){if(!g)continue;let b=n.ownerDocument.getElementById(g);y(b?.textContent)}return r}function Tt(n){let t=d(W(n,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),r=_(W(n,["[data-bp-phone]","[data-bitpalm-phone]"])),a=d(W(n,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),u=d(W(n,["[data-bp-first-name]","[data-bitpalm-first-name]"])),y=d(W(n,["[data-bp-last-name]","[data-bitpalm-last-name]"])),p=d(W(n,["[data-bp-company]","[data-bitpalm-company]"]));for(let c of Array.from(n.elements)){if(!(c instanceof HTMLInputElement||c instanceof HTMLTextAreaElement||c instanceof HTMLSelectElement)||c.disabled||c instanceof HTMLInputElement&&ht.has(c.type.toLowerCase()))continue;let i=wt(c),oe=c.hasAttribute("data-bp-email")||c.hasAttribute("data-bitpalm-email")||c.hasAttribute("data-bp-phone")||c.hasAttribute("data-bitpalm-phone")||c.hasAttribute("data-bp-name")||c.hasAttribute("data-bitpalm-name")||c.hasAttribute("data-bp-full-name")||c.hasAttribute("data-bitpalm-full-name")||c.hasAttribute("data-bp-first-name")||c.hasAttribute("data-bitpalm-first-name")||c.hasAttribute("data-bp-last-name")||c.hasAttribute("data-bitpalm-last-name")||c.hasAttribute("data-bp-company")||c.hasAttribute("data-bitpalm-company")||!!i;if(c instanceof HTMLInputElement&&c.type.toLowerCase()==="hidden"&&!oe)continue;let f=d(c.value);if(!f)continue;let Y=c instanceof HTMLInputElement?c.type.toLowerCase():"",m=vt(xt(n,c).join(" "));if(!t&&i==="email"&&I(f)){t=f.toLowerCase();continue}if(!r&&(i==="phone"||i==="tel"||i==="mobile"||i==="whatsapp")){let S=_(f);if(S){r=S;continue}}if(!p&&i==="company"){p=d(f,160);continue}if(!u&&(i==="first-name"||i==="firstname")){u=d(f,100);continue}if(!y&&(i==="last-name"||i==="lastname"||i==="surname")){y=d(f,100);continue}if(!a&&(i==="name"||i==="full-name"||i==="fullname")){!I(f)&&!_(f)&&(a=d(f,140));continue}let T=Y==="email"||N(m,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),H=Y==="tel"||N(m,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),D=N(m,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),J=N(m,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),F=N(m,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),$=N(m,[" full name "," fullname "," contact name "," name "])&&!T&&!H;if(!t&&T&&I(f)){t=f.toLowerCase();continue}if(!r&&H){let S=_(f);if(S){r=S;continue}}if(!p&&D){p=d(f,160);continue}if(!u&&J){u=d(f,100);continue}if(!y&&F){y=d(f,100);continue}if(!a&&$&&!I(f)&&!_(f)){a=d(f,140);continue}!t&&I(f)&&(t=f.toLowerCase())}if(a&&(I(a)||_(a))&&(a=""),p&&(I(p)||_(p))&&(p=""),a||(a=d([u,y].filter(Boolean).join(" "),140)),a&&t&&a.toLowerCase()===t.toLowerCase()&&(a=""),!!!(t||r)&&!!!(a&&p))return null;let b={...a?{name:a}:{},...t?{email:t}:{},...r?{phone:r}:{},...p?{company:p}:{}};return Object.keys(b).length>0?b:null}function St(){if(typeof document<"u"){let n=document.documentElement.lang;if(n)return n.slice(0,2).toLowerCase()}return"en"}function we(n,t=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(n,{timeout:t});return}setTimeout(n,Math.min(t,300))}function Ee(){if(typeof window>"u")return!1;let n=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(n))return!0;let r=window.matchMedia("(pointer: coarse)").matches,a=window.matchMedia("(hover: none)").matches,u=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return r&&a&&u<=900}function at(n){let{slug:t,locale:r=St(),baseUrl:a=gt,token:u,zIndex:y=9999,autoIdentify:p=!0}=n,l=document,g=ne(n.theme),b=g==="auto"?z():g,c=null,i=l.createElement("iframe"),oe=`${a}/t/${t}/widget`,f=new URLSearchParams({locale:r,theme:b});u&&f.set("token",u),i.src=`${oe}?${f.toString()}`,i.allow="clipboard-write; microphone",i.setAttribute("allowtransparency","true"),i.loading="lazy",i.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${y};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;let Y=new URL(i.src).origin,m=l.createElement("div");if(m.setAttribute("role","button"),m.setAttribute("aria-label","Chat"),m.style.cssText=`position:fixed;bottom:24px;right:24px;width:56px;height:56px;border-radius:50%;display:none;align-items:center;justify-content:center;cursor:pointer;z-index:${y-1};background:#171717;box-shadow:${it};transition:transform .2s,opacity .3s;opacity:0;`,m.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',m.onmouseenter=()=>{m.style.transform="scale(1.05)"},m.onmouseleave=()=>{m.style.transform="scale(1)"},m.onclick=()=>j(),l.body.appendChild(m),!l.getElementById("_bp_fade")){let e=l.createElement("style");e.id="_bp_fade",e.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",l.head.appendChild(e)}let T=null,H=!1,D=!1,J=!1,F=!1,$=!1,S=()=>{J||(J=!0,l.body.appendChild(i))},G=!1,ie=0,K={overflow:"",overscrollBehavior:""},E={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},xe=()=>{if(G||!Ee())return;let s=l.documentElement,o=l.body;ie=window.scrollY||window.pageYOffset||0,K.overflow=s.style.overflow,K.overscrollBehavior=s.style.overscrollBehavior,E.overflow=o.style.overflow,E.overscrollBehavior=o.style.overscrollBehavior,E.position=o.style.position,E.top=o.style.top,E.left=o.style.left,E.right=o.style.right,E.width=o.style.width,s.style.overflow="hidden",s.style.overscrollBehavior="none",o.style.overflow="hidden",o.style.overscrollBehavior="none",o.style.position="fixed",o.style.top=`-${ie}px`,o.style.left="0",o.style.right="0",o.style.width="100%",G=!0},O=()=>{if(!G)return;let e=l.documentElement,s=l.body;e.style.overflow=K.overflow,e.style.overscrollBehavior=K.overscrollBehavior,s.style.overflow=E.overflow,s.style.overscrollBehavior=E.overscrollBehavior,s.style.position=E.position,s.style.top=E.top,s.style.left=E.left,s.style.right=E.right,s.style.width=E.width,window.scrollTo(0,ie),G=!1},Te=()=>{let e=Ee();i.style.display==="none"&&(i.style.display=""),e?(i.style.width="100vw",i.style.height="100dvh",i.style.left="0",i.style.top="0",i.style.bottom="0",i.style.right="0",xe()):(i.style.width="420px",i.style.height="620px",i.style.bottom="24px",i.style.right="24px",i.style.left="",i.style.top="",O()),i.style.opacity="1",i.style.pointerEvents="auto"},C=()=>{T&&(T.remove(),T=null)},V=()=>{},se=()=>{},R=!1,P=new Map;function ae(e,s){let o=P.get(e);if(o)for(let h of o)try{h(s)}catch{}}let Se=e=>{if(e.origin===Y){if(e.data?.type==="bitpalm-widget-config"){D=!1,H=!0,i.style.display==="none"&&(i.style.display=""),e.data.primaryColor&&(m.style.background=e.data.primaryColor,m.style.boxShadow=e.data.chatShadow==="none"?"none":it);let s=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){m.innerHTML="";let o=l.createElement("span");o.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${s}`;let w=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");w?(w.querySelectorAll("script,foreignObject").forEach(B=>B.remove()),w.querySelectorAll("*").forEach(B=>{for(let M of[...B.attributes])(M.name.startsWith("on")||M.value&&M.value.includes("javascript:"))&&B.removeAttribute(M.name)}),w.setAttribute("width","24"),w.setAttribute("height","24"),w.style.display="block",o.appendChild(w)):o.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',m.appendChild(o)}else{let o=m.querySelector("svg");o&&(o.style.stroke=s)}m.style.display="flex",requestAnimationFrame(()=>{m.style.opacity="1"})}if(e.data?.type==="bitpalm-widget-resize"){let s=e.data.width>0,o=R;R=s,s&&!o&&ae("widget_opened"),!s&&o&&ae("widget_closed");let h=Ee();s?(i.style.width=h?"100vw":`${e.data.width}px`,i.style.height=h?"100dvh":`${e.data.height}px`,h?(i.style.left="0",i.style.top="0",i.style.bottom="0",i.style.right="0",xe()):O(),i.style.opacity="1",i.style.pointerEvents="auto"):(O(),i.style.width="1px",i.style.height="1px",i.style.left="",i.style.top="",i.style.opacity="0",i.style.pointerEvents="none"),m.style.display=s?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(D||!H)return;C(),T=l.createElement("div"),T.style.cssText=`position:fixed;bottom:90px;right:24px;max-width:240px;background:#fff;border-radius:16px;padding:12px 32px 12px 12px;box-shadow:0 2px 20px rgba(0,0,0,0.08);cursor:pointer;z-index:${y-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`;let s=(e.data.message||"").replace(/</g,"&lt;");T.innerHTML=`<p style="font-size:14px;color:#1f2937;margin:0;">${s}</p><div style="position:absolute;bottom:-8px;right:20px;width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-top:8px solid #fff;"></div>`;let o=l.createElement("button");o.style.cssText="position:absolute;top:-8px;right:-8px;width:28px;height:28px;border-radius:50%;background:#fff;border:none;box-shadow:0 1px 4px rgba(0,0,0,0.1);cursor:pointer;display:flex;align-items:center;justify-content:center;font-size:14px;color:#9ca3af;",o.innerHTML="&#10005;",o.onclick=h=>{h.stopPropagation(),C(),i.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},T.onclick=()=>{if(C(),m.style.display="none",Te(),S(),!F){$=!0;return}i.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:s},"*")},T.appendChild(o),l.body.appendChild(T)}e.data?.type==="bitpalm-trigger-hide"&&C(),e.data?.type==="bitpalm-request-context"&&V(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&ae(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(D=!0,H=!1,m.style.display="none",C(),O(),i.style.display="none")}};window.addEventListener("message",Se);let L=!1;try{L=localStorage.getItem(`${v}optout`)==="1"}catch{}let X=`${v}vid`,x="";if(!L){try{x=localStorage.getItem(X)||""}catch{}if(!x){let e=l.cookie.match(new RegExp(`(?:^|; )${X}=([^;]+)`));x=e?decodeURIComponent(e[1]):""}x||(x=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(X,x)}catch{}try{l.cookie=`${X}=${encodeURIComponent(x)};path=/;max-age=31536000;SameSite=Lax`}catch{}}L||we(()=>{try{let e=new URLSearchParams(location.search),s={};for(let A of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let w=e.get(A);w&&(s[A]=w)}let o=JSON.stringify({tenant_slug:t,visitor_id:x,url:location.href,referrer:l.referrer||void 0,...Object.keys(s).length>0?{utm:s}:{}}),h=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(h,new Blob([o],{type:"application/json"})):fetch(h,{method:"POST",body:o,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let re="",le="",ce=0;try{re=sessionStorage.getItem(tt)||"",le=sessionStorage.getItem(nt)||"";let e=parseInt(sessionStorage.getItem(ot)||"0",10);Number.isFinite(e)&&e>0&&(ce=e)}catch{}let Le=(e,s="")=>{if(L||!x)return;let o={},h=d(e.name,140),A=st(e.email),w=_(e.phone),B=d(e.company,160),M=d(e.external_user_id,140),Je=d(e.signature,260),ge=Number(e.signed_at);if(h&&(o.name=h),A&&(o.email=A),w&&(o.phone=w),B&&(o.company=B),M&&(o.external_user_id=M),Je&&(o.signature=Je),Number.isFinite(ge)&&ge>0&&(o.signed_at=Math.floor(ge)),(e.signature_version==="v1"||o.signature)&&(o.signature_version="v1"),(e.identify_source==="manual"||e.identify_source==="form")&&(o.identify_source=e.identify_source),!o.name&&!o.email&&!o.phone&&!o.company&&!o.external_user_id)return;let te=bt(o),he=[s.toLowerCase(),te].filter(Boolean).join("|"),ye=Date.now();if(!(ye-ce<yt&&(he===re||te===le))){re=he,le=te,ce=ye;try{sessionStorage.setItem(tt,he),sessionStorage.setItem(nt,te),sessionStorage.setItem(ot,String(ye))}catch{}try{let Ge=JSON.stringify({tenant_slug:t,visitor_id:x,url:location.href,referrer:l.referrer||void 0,...o}),Ke=`${a}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(Ke,new Blob([Ge],{type:"application/json"})):fetch(Ke,{method:"POST",body:Ge,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},Ae=e=>{if(L||!p||!x)return;let s=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(s instanceof HTMLFormElement))return;let o=(s.getAttribute("data-bp-identify")||s.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(o==="off"||o==="false"||o==="0")return;let h=Tt(s);if(!h)return;let A=[s.getAttribute("id")||"",s.getAttribute("name")||"",s.getAttribute("action")||""].join("|");Le({...h,identify_source:"form"},A)};!L&&p&&l.addEventListener("submit",Ae,!0);let U=parseInt(sessionStorage.getItem(`${v}pages`)||"0")+1;sessionStorage.setItem(`${v}pages`,String(U));let k=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");k.push(location.href),k.length>20&&(k=k.slice(-20)),sessionStorage.setItem(`${v}hist`,JSON.stringify(k));let _e=Date.now(),Z=parseInt(sessionStorage.getItem(`${v}site_start`)||"0");Z||(Z=_e,sessionStorage.setItem(`${v}site_start`,String(Z)));let Ie=[];V=()=>{let e=!1;try{e=!!localStorage.getItem(`${v}visited`)}catch{e=!1}if(i.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:l.title,returning:e,pageCount:U,pageHistory:k,loadedAt:_e,siteStart:Z,locale:r,visitorId:L?"":x},"*"),Ne(),!e&&!L)try{localStorage.setItem(`${v}visited`,"1")}catch{}},i.addEventListener("load",()=>{F=!0,V(),[120,450,1100].forEach(e=>{let s=setTimeout(()=>V(),e);Ie.push(s)}),$&&($=!1,se())}),l.readyState==="loading"?l.addEventListener("DOMContentLoaded",()=>we(S,1600),{once:!0}):we(S,1600);let Ce=history.pushState.bind(history),Pe=history.replaceState.bind(history),Q=()=>{U++,sessionStorage.setItem(`${v}pages`,String(U));let e=JSON.parse(sessionStorage.getItem(`${v}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),k=e,sessionStorage.setItem(`${v}hist`,JSON.stringify(e)),i.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:l.title,pageCount:U,pageHistory:e,loadedAt:Date.now()},"*"),!L)try{let s=JSON.stringify({tenant_slug:t,visitor_id:x,url:location.href}),o=`${a}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(o,new Blob([s],{type:"application/json"})):fetch(o,{method:"POST",body:s,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){Ce(...e),Q()},history.replaceState=function(...e){Pe(...e),Q()},window.addEventListener("popstate",Q);let ke=-1,de,Be=()=>{clearTimeout(de),de=setTimeout(()=>{let e=Math.max(l.documentElement.scrollHeight,l.body.scrollHeight)-window.innerHeight,s=e>0?Math.round(window.scrollY/e*100):100;s!==ke&&(ke=s,i.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:s},"*"))},500)};window.addEventListener("scroll",Be,{passive:!0});let Me=e=>{e.clientY<=0&&i.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};l.addEventListener("mouseout",Me);let me,He=!1,ue=()=>{clearTimeout(me),!He&&(me=setTimeout(()=>{He=!0,i.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},$e=["mousemove","keydown","scroll","touchstart"];$e.forEach(e=>l.addEventListener(e,ue,{passive:!0})),ue(),se=()=>{i.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=i.src.split("#")[0];i.src=`${e}#bp-open-${Date.now()}`};let j=()=>{if(m.style.display="none",C(),Te(),S(),!F){$=!0;return}se()},fe=()=>{O(),i.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Oe=e=>{!e||typeof e!="object"||Le({external_user_id:d(e.externalUserId,140)||void 0,name:d(e.name,140)||void 0,email:st(e.email)||void 0,phone:_(e.phone)||void 0,company:d(e.company,160)||void 0,signature:d(e.signature,260)||void 0,signed_at:Number.isFinite(Number(e.signedAt))?Math.floor(Number(e.signedAt)):void 0,signature_version:e.signatureVersion==="v1"?"v1":void 0,identify_source:"manual"},"manual")},ct=()=>{R?fe():j()},dt=()=>R,Re=e=>{if(!e||typeof e!="string")return;let s=e.trim().slice(0,1e4);s&&(R||j(),setTimeout(()=>{i.contentWindow?.postMessage({type:"bitpalm-send-message",message:s},"*")},R?50:500))};function Ne(){i.contentWindow?.postMessage({type:"bitpalm-theme",theme:b},"*")}let ee=e=>{e!==b&&(b=e,Ne())},We=e=>{g=ne(e),c?.(),c=null,g==="auto"?(c=ve(ee),ee(z())):ee(g)};g==="auto"&&(c=ve(ee));let De=e=>{let s=e.detail;if(!s||typeof s!="object")return;let o=d(s.slug,120);o&&o!==t||We(ne(s.theme))};window.addEventListener("bitpalm-theme",De);let q={},Fe=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;q={...q,...e};let s=JSON.stringify(q);s.length>et&&console.warn(`[BitPalm] Custom context exceeds ${et} bytes (${s.length}). It may be truncated.`),i.contentWindow?.postMessage({type:"bitpalm-custom-context",data:q},"*")},mt=()=>{q={},i.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},Ue=e=>{let o=e.detail;if(!o||typeof o!="object")return;let h=d(o.slug,120);if(h&&h!==t)return;let{slug:A,...w}=o;Fe(w)};window.addEventListener("bitpalm-context",Ue);let je=e=>{let o=e.detail;if(!o||typeof o!="object")return;let h=d(o.slug,120);h&&h!==t||Oe(o)};window.addEventListener("bitpalm-identify",je);let pe=e=>{let s=e.detail,o=d(s?.slug,120);return!o||o===t},qe=e=>{pe(e)&&j()},ze=e=>{pe(e)&&fe()},Ye=e=>{if(!pe(e))return;let s=e.detail?.message;typeof s=="string"&&Re(s)};return window.addEventListener("bitpalm-open",qe),window.addEventListener("bitpalm-close",ze),window.addEventListener("bitpalm-send",Ye),{open:j,close:fe,toggle:ct,isOpen:dt,identify:Oe,context:Fe,resetContext:mt,send:Re,on:(e,s)=>(P.has(e)||P.set(e,new Set),P.get(e).add(s),()=>P.get(e)?.delete(s)),off:(e,s)=>{P.get(e)?.delete(s)},setTheme:We,destroy:()=>{window.removeEventListener("message",Se),window.removeEventListener("scroll",Be),window.removeEventListener("popstate",Q),l.removeEventListener("mouseout",Me),l.removeEventListener("submit",Ae,!0),$e.forEach(e=>l.removeEventListener(e,ue)),clearTimeout(de),clearTimeout(me),Ie.forEach(e=>clearTimeout(e)),history.pushState=Ce,history.replaceState=Pe,window.removeEventListener("bitpalm-identify",je),window.removeEventListener("bitpalm-context",Ue),window.removeEventListener("bitpalm-theme",De),window.removeEventListener("bitpalm-open",qe),window.removeEventListener("bitpalm-close",ze),window.removeEventListener("bitpalm-send",Ye),c?.(),P.clear(),O(),C(),m.remove(),i.remove()}}}function Ht(n){let t=lt(null),r=lt(!1);return rt(()=>{t.current?.setTheme(n.theme??"auto")},[n.theme]),rt(()=>{if(!r.current)return r.current=!0,t.current=at(n),()=>{t.current?.destroy(),t.current=null,r.current=!1}},[]),null}export{Ht as BitPalmAgent};
1
+ import{useCallback as _e,useEffect as Me,useRef as fe,useState as J}from"react";function ct(n){if(n===!1)return"off";if(typeof n=="string"){let t=n.trim().toLowerCase();if(["false","off","0","no","none"].includes(t))return"off";if(t==="events")return"events"}return"bubble"}function dt(n,t){let i=n.createElement("div");i.setAttribute("data-bitpalm-trigger",""),i.style.cssText=`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:${t.zIndex-1};font-family:system-ui,sans-serif;animation:_bp_fade .3s;`,i.style.position="fixed",i.style.right="24px",i.style.bottom=`${t.bottom}px`;let s=n.createElement("p");s.style.cssText="font-size:14px;color:#1f2937;margin:0;",s.textContent=t.message;let m=n.createElement("div");m.style.cssText="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;";let g=n.createElement("button");return g.type="button",g.setAttribute("aria-label","Close"),g.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;",g.textContent="\u2715",g.onclick=p=>{p.stopPropagation(),t.onDismiss()},i.onclick=()=>t.onEngage(),i.append(s,m,g),i}var _t=["dark","dark-mode","dark-theme","theme-dark"],Mt=["light","light-mode","light-theme","theme-light"],ft=["data-theme","data-color-scheme","data-color-mode","data-mode","data-bs-theme"],gt="(prefers-color-scheme: dark)";function ue(n){return n==="light"||n==="dark"?n:"auto"}function ut(n){if(!n)return null;if(_t.some(t=>n.classList.contains(t)))return"dark";if(Mt.some(t=>n.classList.contains(t)))return"light";for(let t of ft){let i=(n.getAttribute(t)||"").toLowerCase();if(i.includes("dark"))return"dark";if(i.includes("light"))return"light"}return null}function Ae(n){let t=n/255;return t<=.03928?t/12.92:((t+.055)/1.055)**2.4}function mt(n,t){if(!n)return null;let i=t.getComputedStyle(n).backgroundColor.match(/rgba?\(([^)]+)\)/);if(!i)return null;let[s,m,g,p=1]=i[1].split(/[\s,/]+/).filter(Boolean).map(Number);return[s,m,g,p].some(c=>Number.isNaN(c))||p<.5?null:.2126*Ae(s)+.7152*Ae(m)+.0722*Ae(g)<.2?"dark":"light"}function Bt(n,t){let i=t.getComputedStyle(n.documentElement).colorScheme||"",s=n.querySelector('meta[name="color-scheme"]')?.getAttribute("content")||"",m=`${i} ${s}`.toLowerCase();return m.includes("dark")?m.includes("light")?t.matchMedia?.(gt).matches?"dark":"light":"dark":null}function Z(n=document,t=window){return ut(n.documentElement)??ut(n.body)??mt(n.body,t)??mt(n.documentElement,t)??Bt(n,t)??"light"}function Le(n,t=document,i=window){let s=Z(t,i),m=!1,g=()=>{m=!1;let d=Z(t,i);d!==s&&(s=d,n(d))},p=()=>{m||(m=!0,typeof i.requestAnimationFrame=="function"?i.requestAnimationFrame(g):setTimeout(g,16))},b=typeof MutationObserver<"u"?new MutationObserver(p):null,c={attributes:!0,attributeFilter:["class","style",...ft]};b?.observe(t.documentElement,c),t.body&&b?.observe(t.body,c);let w=typeof i.matchMedia=="function"?i.matchMedia(gt):null;return w?.addEventListener?.("change",p),()=>{b?.disconnect(),w?.removeEventListener?.("change",p)}}var $t="https://agents.bitpalm.ai",I="_bp_",Ot=new Set(["password","file","checkbox","radio","submit","button","reset","image"]),Rt=8e3,pt=4096,ht=`${I}identify_signature`,yt=`${I}identify_fingerprint`,bt=`${I}identify_sent_at`,vt="0 4px 14px rgba(0,0,0,0.18)";function Ht(n){return[n.external_user_id||"",n.email||"",n.phone||"",n.name||"",n.company||"",n.signature||"",n.signed_at!=null?String(n.signed_at):"",n.signature_version||"",n.identify_source||""].join("|").toLowerCase()}function h(n,t=180){return n?n.replace(/\s+/g," ").trim().slice(0,t):""}function Dt(n){return n?` ${n.toLowerCase().replace(/[_-]+/g," ").replace(/[^a-z0-9\s@.]/g," ").replace(/\s+/g," ").trim()} `:""}function z(n,t){for(let i of t)if(n.includes(i))return!0;return!1}function H(n){return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i.test(n)}function $(n){let t=h(n,50);if(!t)return"";let i=t.startsWith("+"),s=t.replace(/\D/g,"");return s.length<6?"":`${i?"+":""}${s.slice(0,20)}`}function wt(n){let t=h(n,140).toLowerCase();return!t||!H(t)?"":t}function Y(n,t){for(let i of t){let s=n.querySelector(i),m=h(s?.value);if(m)return m}return""}function Ut(n){return h(n.getAttribute("data-bp-field")||n.getAttribute("data-bitpalm-field"),64).toLowerCase().replace(/[_\s]+/g,"-")}function Nt(n){return n.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Wt(n,t){let i=[],s=(c,w=140)=>{let d=h(c,w);d&&i.push(d)};s(t.name),s(t.id),s(t.getAttribute("autocomplete")),s(t.getAttribute("placeholder")),s(t.getAttribute("aria-label")),s(t.getAttribute("data-field")),s(t.getAttribute("data-name")),s(t.getAttribute("data-label")),s(t.getAttribute("data-bp-field")),s(t.getAttribute("data-bitpalm-field"));let m=new Set,g=c=>{let w=h(c,200);!w||m.has(w)||(m.add(w),i.push(w))};for(let c of Array.from(t.labels||[]))g(c.textContent);if(t.id){let c=n.querySelector(`label[for="${Nt(t.id)}"]`);g(c?.textContent)}let p=t.closest("label");g(p?.textContent);let b=t.getAttribute("aria-labelledby");if(b)for(let c of b.split(/\s+/)){if(!c)continue;let w=n.ownerDocument.getElementById(c);g(w?.textContent)}return i}function jt(n){let t=h(Y(n,["[data-bp-email]","[data-bitpalm-email]"]),140).toLowerCase(),i=$(Y(n,["[data-bp-phone]","[data-bitpalm-phone]"])),s=h(Y(n,["[data-bp-name]","[data-bitpalm-name]","[data-bp-full-name]","[data-bitpalm-full-name]"])),m=h(Y(n,["[data-bp-first-name]","[data-bitpalm-first-name]"])),g=h(Y(n,["[data-bp-last-name]","[data-bitpalm-last-name]"])),p=h(Y(n,["[data-bp-company]","[data-bitpalm-company]"]));for(let d of Array.from(n.elements)){if(!(d instanceof HTMLInputElement||d instanceof HTMLTextAreaElement||d instanceof HTMLSelectElement)||d.disabled||d instanceof HTMLInputElement&&Ot.has(d.type.toLowerCase()))continue;let y=Ut(d),L=d.hasAttribute("data-bp-email")||d.hasAttribute("data-bitpalm-email")||d.hasAttribute("data-bp-phone")||d.hasAttribute("data-bitpalm-phone")||d.hasAttribute("data-bp-name")||d.hasAttribute("data-bitpalm-name")||d.hasAttribute("data-bp-full-name")||d.hasAttribute("data-bitpalm-full-name")||d.hasAttribute("data-bp-first-name")||d.hasAttribute("data-bitpalm-first-name")||d.hasAttribute("data-bp-last-name")||d.hasAttribute("data-bitpalm-last-name")||d.hasAttribute("data-bp-company")||d.hasAttribute("data-bitpalm-company")||!!y;if(d instanceof HTMLInputElement&&d.type.toLowerCase()==="hidden"&&!L)continue;let l=h(d.value);if(!l)continue;let u=d instanceof HTMLInputElement?d.type.toLowerCase():"",o=Dt(Wt(n,d).join(" "));if(!t&&y==="email"&&H(l)){t=l.toLowerCase();continue}if(!i&&(y==="phone"||y==="tel"||y==="mobile"||y==="whatsapp")){let C=$(l);if(C){i=C;continue}}if(!p&&y==="company"){p=h(l,160);continue}if(!m&&(y==="first-name"||y==="firstname")){m=h(l,100);continue}if(!g&&(y==="last-name"||y==="lastname"||y==="surname")){g=h(l,100);continue}if(!s&&(y==="name"||y==="full-name"||y==="fullname")){!H(l)&&!$(l)&&(s=h(l,140));continue}let v=u==="email"||z(o,[" email "," e mail "," mail "," email adresse "," mailadresse "," correo "]),_=u==="tel"||z(o,[" phone "," phone number "," mobile "," tel "," telefon "," telefonnummer "," whatsapp "," handy "," kontakt "," nummer "]),T=z(o,[" company "," company name "," firma "," firmenname "," organization "," organisation "," business "," unternehmen "," agency "," brokerage "]),f=z(o,[" first name "," firstname "," given name "," givenname "," vorname "," fname "]),S=z(o,[" last name "," lastname "," family name "," familyname "," surname "," nachname "," lname "]),E=z(o,[" full name "," fullname "," contact name "," name "])&&!v&&!_;if(!t&&v&&H(l)){t=l.toLowerCase();continue}if(!i&&_){let C=$(l);if(C){i=C;continue}}if(!p&&T){p=h(l,160);continue}if(!m&&f){m=h(l,100);continue}if(!g&&S){g=h(l,100);continue}if(!s&&E&&!H(l)&&!$(l)){s=h(l,140);continue}!t&&H(l)&&(t=l.toLowerCase())}if(s&&(H(s)||$(s))&&(s=""),p&&(H(p)||$(p))&&(p=""),s||(s=h([m,g].filter(Boolean).join(" "),140)),s&&t&&s.toLowerCase()===t.toLowerCase()&&(s=""),!!!(t||i)&&!!!(s&&p))return null;let w={...s?{name:s}:{},...t?{email:t}:{},...i?{phone:i}:{},...p?{company:p}:{}};return Object.keys(w).length>0?w:null}function Ft(){if(typeof document<"u"){let n=document.documentElement.lang;if(n)return n.slice(0,2).toLowerCase()}return"en"}function ke(n,t=1200){if(typeof window<"u"&&"requestIdleCallback"in window){window.requestIdleCallback(n,{timeout:t});return}setTimeout(n,Math.min(t,300))}function Pe(){if(typeof window>"u")return!1;let n=typeof navigator<"u"?navigator.userAgent:"";if(/Android|iPhone|iPad|iPod|IEMobile|Windows Phone|Mobile/i.test(n))return!0;let i=window.matchMedia("(pointer: coarse)").matches,s=window.matchMedia("(hover: none)").matches,m=Math.min(window.screen?.width||window.innerWidth,window.screen?.height||window.innerHeight);return i&&s&&m<=900}function xt(n){let{slug:t,locale:i=Ft(),baseUrl:s=$t,token:m,zIndex:g=9999,autoIdentify:p=!0,launcher:b=!0}=n,c=document,w=ue(n.theme),d=w==="auto"?Z():w,y=null,L=ct(n.triggers),l=L,u=null,o=c.createElement("iframe");o.setAttribute("data-bitpalm-chat","");let v=`${s}/t/${t}/widget`,_=new URLSearchParams({locale:i,theme:d});m&&_.set("token",m),l==="off"&&_.set("triggers","off"),o.src=`${v}?${_.toString()}`,o.allow="clipboard-write; microphone",o.setAttribute("allowtransparency","true"),o.loading="lazy",o.style.cssText=`position:fixed;bottom:0;right:0;width:1px;height:1px;border:none;z-index:${g};background:transparent;color-scheme:normal;opacity:0;pointer-events:none;`;let T=new URL(o.src).origin,f=c.createElement("div");if(f.setAttribute("role","button"),f.setAttribute("aria-label","Chat"),f.setAttribute("data-bitpalm-launcher",""),f.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:${g-1};background:#171717;box-shadow:${vt};transition:transform .2s,opacity .3s;opacity:0;`,f.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',f.onmouseenter=()=>{f.style.transform="scale(1.05)"},f.onmouseleave=()=>{f.style.transform="scale(1)"},f.onclick=()=>Q(),b&&c.body.appendChild(f),!c.getElementById("_bp_fade")){let e=c.createElement("style");e.id="_bp_fade",e.textContent="@keyframes _bp_fade{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}",c.head.appendChild(e)}let S=null,E=!1,C=!1,D=!1,G=!1,ee=!1,te=()=>{D||(D=!0,c.body.appendChild(o))},ne=!1,ge=0,oe={overflow:"",overscrollBehavior:""},k={overflow:"",overscrollBehavior:"",position:"",top:"",left:"",right:"",width:""},Be=()=>{if(ne||!Pe())return;let r=c.documentElement,a=c.body;ge=window.scrollY||window.pageYOffset||0,oe.overflow=r.style.overflow,oe.overscrollBehavior=r.style.overscrollBehavior,k.overflow=a.style.overflow,k.overscrollBehavior=a.style.overscrollBehavior,k.position=a.style.position,k.top=a.style.top,k.left=a.style.left,k.right=a.style.right,k.width=a.style.width,r.style.overflow="hidden",r.style.overscrollBehavior="none",a.style.overflow="hidden",a.style.overscrollBehavior="none",a.style.position="fixed",a.style.top=`-${ge}px`,a.style.left="0",a.style.right="0",a.style.width="100%",ne=!0},F=()=>{if(!ne)return;let e=c.documentElement,r=c.body;e.style.overflow=oe.overflow,e.style.overscrollBehavior=oe.overscrollBehavior,r.style.overflow=k.overflow,r.style.overscrollBehavior=k.overscrollBehavior,r.style.position=k.position,r.style.top=k.top,r.style.left=k.left,r.style.right=k.right,r.style.width=k.width,window.scrollTo(0,ge),ne=!1},$e=()=>{let e=Pe();o.style.display==="none"&&(o.style.display=""),e?(o.style.width="100vw",o.style.height="100dvh",o.style.left="0",o.style.top="0",o.style.bottom="0",o.style.right="0",Be()):(o.style.width="420px",o.style.height="620px",o.style.bottom="24px",o.style.right="24px",o.style.left="",o.style.top="",F()),o.style.opacity="1",o.style.pointerEvents="auto"},R=()=>{S&&(S.remove(),S=null)},re=()=>{u!==null&&(u=null,K("trigger_hidden"))},Oe=()=>{o.contentWindow?.postMessage({type:"bitpalm-triggers",enabled:l!=="off"},"*")},ie=()=>{},pe=()=>{},q=!1,U=new Map;function K(e,r){let a=U.get(e);if(a)for(let x of a)try{x(r)}catch{}}let Re=e=>{if(e.origin===T){if(e.data?.type==="bitpalm-widget-config"){C=!1,E=!0,o.style.display==="none"&&(o.style.display=""),e.data.primaryColor&&(f.style.background=e.data.primaryColor,f.style.boxShadow=e.data.chatShadow==="none"?"none":vt);let r=e.data.chatButtonIconColor||"black";if(e.data.chatButtonIconSvg){f.innerHTML="";let a=c.createElement("span");a.style.cssText=`display:flex;align-items:center;justify-content:center;width:24px;height:24px;color:${r}`;let A=new DOMParser().parseFromString(e.data.chatButtonIconSvg,"image/svg+xml").querySelector("svg");A?(A.querySelectorAll("script,foreignObject").forEach(W=>W.remove()),A.querySelectorAll("*").forEach(W=>{for(let j of[...W.attributes])(j.name.startsWith("on")||j.value&&j.value.includes("javascript:"))&&W.removeAttribute(j.name)}),A.setAttribute("width","24"),A.setAttribute("height","24"),A.style.display="block",a.appendChild(A)):a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22Z"/></svg>',f.appendChild(a)}else{let a=f.querySelector("svg");a&&(a.style.stroke=r)}b&&(f.style.display="flex",requestAnimationFrame(()=>{f.style.opacity="1"})),Oe()}if(e.data?.type==="bitpalm-widget-resize"){let r=e.data.width>0,a=q;q=r,r&&!a&&K("widget_opened"),!r&&a&&K("widget_closed");let x=Pe();r?(o.style.width=x?"100vw":`${e.data.width}px`,o.style.height=x?"100dvh":`${e.data.height}px`,x?(o.style.left="0",o.style.top="0",o.style.bottom="0",o.style.right="0",Be()):F(),o.style.opacity="1",o.style.pointerEvents="auto"):(F(),o.style.width="1px",o.style.height="1px",o.style.left="",o.style.top="",o.style.opacity="0",o.style.pointerEvents="none"),f.style.display=r||!b?"none":"flex"}if(e.data?.type==="bitpalm-trigger-show"){if(C||!E||l==="off")return;let r=typeof e.data.message=="string"?e.data.message:"";if(!r)return;if(l==="events"){u=r,K("trigger_shown",{message:r,triggerId:e.data.triggerId,triggerType:e.data.triggerType});return}R(),S=dt(c,{message:r,zIndex:g,bottom:b?90:24,onDismiss:()=>{R(),o.contentWindow?.postMessage({type:"bitpalm-trigger-dismiss"},"*")},onEngage:()=>{if(R(),f.style.display="none",$e(),te(),!G){ee=!0;return}o.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:r},"*")}}),c.body.appendChild(S)}e.data?.type==="bitpalm-trigger-hide"&&(R(),re()),e.data?.type==="bitpalm-request-context"&&ie(),e.data?.type==="bitpalm-chat-event"&&e.data.event&&K(e.data.event,e.data.data),e.data?.type==="bitpalm-widget-blocked"&&(C=!0,E=!1,f.style.display="none",R(),re(),F(),o.style.display="none")}};window.addEventListener("message",Re);let M=!1;try{M=localStorage.getItem(`${I}optout`)==="1"}catch{}let se=`${I}vid`,P="";if(!M){try{P=localStorage.getItem(se)||""}catch{}if(!P){let e=c.cookie.match(new RegExp(`(?:^|; )${se}=([^;]+)`));P=e?decodeURIComponent(e[1]):""}P||(P=crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.random().toString(36).slice(2,11)}`);try{localStorage.setItem(se,P)}catch{}try{c.cookie=`${se}=${encodeURIComponent(P)};path=/;max-age=31536000;SameSite=Lax`}catch{}}M||ke(()=>{try{let e=new URLSearchParams(location.search),r={};for(let B of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let A=e.get(B);A&&(r[B]=A)}let a=JSON.stringify({tenant_slug:t,visitor_id:P,url:location.href,referrer:c.referrer||void 0,...Object.keys(r).length>0?{utm:r}:{}}),x=`${s}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(x,new Blob([a],{type:"application/json"})):fetch(x,{method:"POST",body:a,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}},2e3);let he="",ye="",be=0;try{he=sessionStorage.getItem(ht)||"",ye=sessionStorage.getItem(yt)||"";let e=parseInt(sessionStorage.getItem(bt)||"0",10);Number.isFinite(e)&&e>0&&(be=e)}catch{}let He=(e,r="")=>{if(M||!P)return;let a={},x=h(e.name,140),B=wt(e.email),A=$(e.phone),W=h(e.company,160),j=h(e.external_user_id,140),st=h(e.signature,260),Te=Number(e.signed_at);if(x&&(a.name=x),B&&(a.email=B),A&&(a.phone=A),W&&(a.company=W),j&&(a.external_user_id=j),st&&(a.signature=st),Number.isFinite(Te)&&Te>0&&(a.signed_at=Math.floor(Te)),(e.signature_version==="v1"||a.signature)&&(a.signature_version="v1"),(e.identify_source==="manual"||e.identify_source==="form")&&(a.identify_source=e.identify_source),!a.name&&!a.email&&!a.phone&&!a.company&&!a.external_user_id)return;let de=Ht(a),Ce=[r.toLowerCase(),de].filter(Boolean).join("|"),Ie=Date.now();if(!(Ie-be<Rt&&(Ce===he||de===ye))){he=Ce,ye=de,be=Ie;try{sessionStorage.setItem(ht,Ce),sessionStorage.setItem(yt,de),sessionStorage.setItem(bt,String(Ie))}catch{}try{let at=JSON.stringify({tenant_slug:t,visitor_id:P,url:location.href,referrer:c.referrer||void 0,...a}),lt=`${s}/api/widget/identify`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(lt,new Blob([at],{type:"application/json"})):fetch(lt,{method:"POST",body:at,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}}},De=e=>{if(M||!p||!P)return;let r=e.target instanceof HTMLFormElement?e.target:e.target instanceof Element?e.target.closest("form"):null;if(!(r instanceof HTMLFormElement))return;let a=(r.getAttribute("data-bp-identify")||r.getAttribute("data-bitpalm-identify")||"").toLowerCase();if(a==="off"||a==="false"||a==="0")return;let x=jt(r);if(!x)return;let B=[r.getAttribute("id")||"",r.getAttribute("name")||"",r.getAttribute("action")||""].join("|");He({...x,identify_source:"form"},B)};!M&&p&&c.addEventListener("submit",De,!0);let V=parseInt(sessionStorage.getItem(`${I}pages`)||"0")+1;sessionStorage.setItem(`${I}pages`,String(V));let N=JSON.parse(sessionStorage.getItem(`${I}hist`)||"[]");N.push(location.href),N.length>20&&(N=N.slice(-20)),sessionStorage.setItem(`${I}hist`,JSON.stringify(N));let Ue=Date.now(),ae=parseInt(sessionStorage.getItem(`${I}site_start`)||"0");ae||(ae=Ue,sessionStorage.setItem(`${I}site_start`,String(ae)));let Ne=[];ie=()=>{let e=!1;try{e=!!localStorage.getItem(`${I}visited`)}catch{e=!1}if(o.contentWindow?.postMessage({type:"bitpalm-parent-context",url:location.href,title:c.title,returning:e,pageCount:V,pageHistory:N,loadedAt:Ue,siteStart:ae,locale:i,visitorId:M?"":P},"*"),Qe(),!e&&!M)try{localStorage.setItem(`${I}visited`,"1")}catch{}},o.addEventListener("load",()=>{G=!0,ie(),[120,450,1100].forEach(e=>{let r=setTimeout(()=>ie(),e);Ne.push(r)}),ee&&(ee=!1,pe())}),c.readyState==="loading"?c.addEventListener("DOMContentLoaded",()=>ke(te,1600),{once:!0}):ke(te,1600);let We=history.pushState.bind(history),je=history.replaceState.bind(history),le=()=>{V++,sessionStorage.setItem(`${I}pages`,String(V));let e=JSON.parse(sessionStorage.getItem(`${I}hist`)||"[]");if(e.push(location.href),e.length>20&&e.splice(0,e.length-20),N=e,sessionStorage.setItem(`${I}hist`,JSON.stringify(e)),o.contentWindow?.postMessage({type:"bitpalm-page-change",url:location.href,title:c.title,pageCount:V,pageHistory:e,loadedAt:Date.now()},"*"),!M)try{let r=JSON.stringify({tenant_slug:t,visitor_id:P,url:location.href}),a=`${s}/api/widget/impression`;typeof navigator.sendBeacon=="function"?navigator.sendBeacon(a,new Blob([r],{type:"application/json"})):fetch(a,{method:"POST",body:r,headers:{"Content-Type":"application/json"},keepalive:!0}).catch(()=>{})}catch{}};history.pushState=function(...e){We(...e),le()},history.replaceState=function(...e){je(...e),le()},window.addEventListener("popstate",le);let Fe=-1,ve,qe=()=>{clearTimeout(ve),ve=setTimeout(()=>{let e=Math.max(c.documentElement.scrollHeight,c.body.scrollHeight)-window.innerHeight,r=e>0?Math.round(window.scrollY/e*100):100;r!==Fe&&(Fe=r,o.contentWindow?.postMessage({type:"bitpalm-scroll-depth",percent:r},"*"))},500)};window.addEventListener("scroll",qe,{passive:!0});let ze=e=>{e.clientY<=0&&o.contentWindow?.postMessage({type:"bitpalm-exit-intent"},"*")};c.addEventListener("mouseout",ze);let we,Ye=!1,xe=()=>{clearTimeout(we),!Ye&&(we=setTimeout(()=>{Ye=!0,o.contentWindow?.postMessage({type:"bitpalm-inactivity"},"*")},15e3))},Je=["mousemove","keydown","scroll","touchstart"];Je.forEach(e=>c.addEventListener(e,xe,{passive:!0})),xe(),pe=()=>{o.contentWindow?.postMessage({type:"bitpalm-open"},"*");let e=o.src.split("#")[0];o.src=`${e}#bp-open-${Date.now()}`};let Q=()=>{if(f.style.display="none",R(),$e(),te(),!G){ee=!0;return}if(u!==null){let e=u;re(),o.contentWindow?.postMessage({type:"bitpalm-trigger-engaged",message:e},"*");return}pe()},Ge=e=>{l=e,e==="off"&&(R(),re()),Oe()},It=()=>Ge("off"),At=()=>Ge(L==="off"?"bubble":L),Ee=()=>{F(),o.contentWindow?.postMessage({type:"bitpalm-close"},"*")},Ke=e=>{!e||typeof e!="object"||He({external_user_id:h(e.externalUserId,140)||void 0,name:h(e.name,140)||void 0,email:wt(e.email)||void 0,phone:$(e.phone)||void 0,company:h(e.company,160)||void 0,signature:h(e.signature,260)||void 0,signed_at:Number.isFinite(Number(e.signedAt))?Math.floor(Number(e.signedAt)):void 0,signature_version:e.signatureVersion==="v1"?"v1":void 0,identify_source:"manual"},"manual")},Lt=()=>{q?Ee():Q()},kt=()=>q,Ve=e=>{if(!e||typeof e!="string")return;let r=e.trim().slice(0,1e4);r&&(q||Q(),setTimeout(()=>{o.contentWindow?.postMessage({type:"bitpalm-send-message",message:r},"*")},q?50:500))};function Qe(){o.contentWindow?.postMessage({type:"bitpalm-theme",theme:d},"*")}let ce=e=>{e!==d&&(d=e,Qe())},Xe=e=>{w=ue(e),y?.(),y=null,w==="auto"?(y=Le(ce),ce(Z())):ce(w)};w==="auto"&&(y=Le(ce));let Ze=e=>{let r=e.detail;if(!r||typeof r!="object")return;let a=h(r.slug,120);a&&a!==t||Xe(ue(r.theme))};window.addEventListener("bitpalm-theme",Ze);let X={},et=e=>{if(!e||typeof e!="object"||Array.isArray(e))return;X={...X,...e};let r=JSON.stringify(X);r.length>pt&&console.warn(`[BitPalm] Custom context exceeds ${pt} bytes (${r.length}). It may be truncated.`),o.contentWindow?.postMessage({type:"bitpalm-custom-context",data:X},"*")},Pt=()=>{X={},o.contentWindow?.postMessage({type:"bitpalm-custom-context",data:{}},"*")},tt=e=>{let a=e.detail;if(!a||typeof a!="object")return;let x=h(a.slug,120);if(x&&x!==t)return;let{slug:B,...A}=a;et(A)};window.addEventListener("bitpalm-context",tt);let nt=e=>{let a=e.detail;if(!a||typeof a!="object")return;let x=h(a.slug,120);x&&x!==t||Ke(a)};window.addEventListener("bitpalm-identify",nt);let Se=e=>{let r=e.detail,a=h(r?.slug,120);return!a||a===t},ot=e=>{Se(e)&&Q()},rt=e=>{Se(e)&&Ee()},it=e=>{if(!Se(e))return;let r=e.detail?.message;typeof r=="string"&&Ve(r)};return window.addEventListener("bitpalm-open",ot),window.addEventListener("bitpalm-close",rt),window.addEventListener("bitpalm-send",it),{open:Q,close:Ee,toggle:Lt,isOpen:kt,identify:Ke,context:et,resetContext:Pt,send:Ve,on:(e,r)=>(U.has(e)||U.set(e,new Set),U.get(e).add(r),()=>U.get(e)?.delete(r)),off:(e,r)=>{U.get(e)?.delete(r)},setTheme:Xe,disableTriggers:It,enableTriggers:At,destroy:()=>{window.removeEventListener("message",Re),window.removeEventListener("scroll",qe),window.removeEventListener("popstate",le),c.removeEventListener("mouseout",ze),c.removeEventListener("submit",De,!0),Je.forEach(e=>c.removeEventListener(e,xe)),clearTimeout(ve),clearTimeout(we),Ne.forEach(e=>clearTimeout(e)),history.pushState=We,history.replaceState=je,window.removeEventListener("bitpalm-identify",nt),window.removeEventListener("bitpalm-context",tt),window.removeEventListener("bitpalm-theme",Ze),window.removeEventListener("bitpalm-open",ot),window.removeEventListener("bitpalm-close",rt),window.removeEventListener("bitpalm-send",it),y?.(),U.clear(),F(),R(),f.remove(),o.remove()}}}function qt(n){let t=n.split(`
2
+ `).filter(i=>i.startsWith("data:")).map(i=>i.slice(5).trimStart()).join(`
3
+ `);if(!t)return null;try{let i=JSON.parse(t);return i&&typeof i.type=="string"?i:null}catch{return null}}function me(n){let t=[],i=n.replace(/\r\n/g,`
4
+ `),s=i.indexOf(`
5
+
6
+ `);for(;s>=0;){let m=qt(i.slice(0,s));m&&t.push(m),i=i.slice(s+2),s=i.indexOf(`
7
+
8
+ `)}return{events:t,rest:i}}function Et(n){return me(`${n}
9
+
10
+ `).events}var O=class extends Error{constructor(i,s,m){super(s);this.code=i;this.status=m;this.name="BitPalmApiError"}},zt="https://agents.bitpalm.ai";function Yt(){try{return typeof localStorage>"u"?null:localStorage}catch{return null}}function Jt(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`v-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,12)}`}async function Gt(n){let t=await n.json().catch(()=>null);return new O(t?.error?.code??"server_error",t?.error?.message??`Request failed (${n.status})`,n.status)}function St(n){if(!n?.key?.startsWith("bp_pk_"))throw new Error("createChatClient needs an app key (bp_pk_\u2026) from the BitPalm dashboard.");let t=(n.baseUrl??zt).replace(/\/+$/,""),i=n.storage===void 0?Yt():n.storage,s=`bitpalm:${n.key.slice(0,14)}`,m=l=>{try{return i?.getItem(`${s}:${l}`)??null}catch{return null}},g=(l,u)=>{try{u===null?i?.removeItem(`${s}:${l}`):i?.setItem(`${s}:${l}`,u)}catch{}},p=n.visitorId??m("visitor")??Jt();n.visitorId||g("visitor",p);let b=m("conversation"),c=!1,w={Authorization:`Bearer ${n.key}`},d=async(l,u)=>{let o=await fetch(`${t}${l}`,{...u,headers:{...w,...u?.headers??{}}});if(!o.ok)throw await Gt(o);return o},y=l=>{b=l,g("conversation",l)},L=(l,u,o)=>{for(let v of l)if(v.type==="delta")u.text+=v.text,o?.(v.text,u.text);else if(v.type==="replace")u.text=v.text,o?.("",u.text);else if(v.type==="done")u.result={text:u.text,conversationId:v.conversationId,...v.cards?{cards:v.cards}:{},...v.handoff?{handoff:!0}:{}};else if(v.type==="error")throw new O("server_error",v.message,500)};return{visitorId:p,get conversationId(){return b},get handoff(){return c},async agent(l){let u=new URLSearchParams({locale:n.locale??"en"});return l?.url&&u.set("url",l.url),(await d(`/api/v1/agent?${u.toString()}`)).json()},async send(l,u={}){let o=await d("/api/v1/chat",{method:"POST",headers:{"Content-Type":"application/json"},signal:u.signal,body:JSON.stringify({message:l,visitorId:p,conversationId:b??void 0,context:u.context,fileIds:u.fileIds})}),v={text:"",result:null},_=o.body&&typeof o.body.getReader=="function"?o.body.getReader():null;if(_){let f=new TextDecoder,S="";for(;;){let{done:E,value:C}=await _.read();if(E)break;let D=me(S+f.decode(C,{stream:!0}));S=D.rest,L(D.events,v,u.onDelta)}L(me(`${S}
11
+
12
+ `).events,v,u.onDelta)}else L(Et(await o.text()),v,u.onDelta);let T=v.result??{text:v.text,conversationId:b??""};return T.conversationId&&y(T.conversationId),c=T.handoff===!0,T},async history(){let l=new URLSearchParams({visitorId:p});b&&l.set("conversationId",b);let u=await(await d(`/api/v1/chat/history?${l.toString()}`)).json();return u.conversationId&&y(u.conversationId),c=u.handoff===!0,u.messages},async identify(l){await d("/api/v1/identify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({...l,visitorId:p})})},async upload(l,u="photo.jpg"){let o=new FormData;o.append("file",l,u),o.append("visitorId",p),b&&o.append("conversationId",b);let v=await(await d("/api/v1/chat/upload",{method:"POST",body:o})).json();return{id:v.id,url:v.url}},async feedback(l,u){if(!b)throw new O("bad_request","There is no conversation yet.",400);await d("/api/v1/chat/feedback",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({visitorId:p,conversationId:b,messageIndex:l,feedback:u})})},reset(){y(null),c=!1}}}function un(n){let t=fe(null),i=fe(!1);return Me(()=>{t.current?.setTheme(n.theme??"auto")},[n.theme]),Me(()=>{if(i.current)return;i.current=!0;let{onReady:s,...m}=n;return t.current=xt(m),s?.(t.current),()=>{t.current?.destroy(),t.current=null,i.current=!1}},[]),null}function Tt(n,t){return[...n.slice(0,-1),t]}function Ct(n){let t=n[n.length-1];return t?.role==="assistant"&&!t.text&&!t.cards?.length?n.slice(0,-1):n}function mn(n){let[t]=J(()=>St(n)),[i,s]=J([]),[m,g]=J("idle"),[p,b]=J(null),[c,w]=J(null),[d,y]=J(!1),L=fe(!1),l=fe(0),u=n.loadHistory!==!1;Me(()=>{let T=!0;return t.agent().then(f=>T&&w(f)).catch(()=>{}),u&&t.history().then(f=>{T&&(s(S=>S.length?S:f),y(t.handoff))}).catch(()=>{}),()=>{T=!1}},[t,u]);let o=_e(async(T,f={})=>{let S=T.trim();if(!S&&!f.fileIds?.length)return null;s(E=>[...E,{role:"user",text:S},{role:"assistant",text:""}]),g("streaming"),b(null),L.current=!0,l.current+=1;try{let E=await t.send(S,{...f,onDelta:(C,D)=>s(G=>Tt(G,{role:"assistant",text:D}))});return s(C=>Ct(Tt(C,{role:"assistant",text:E.text,...E.cards?{cards:E.cards}:{}}))),y(E.handoff===!0),g("idle"),E}catch(E){let C=E instanceof O?E:new O("network_error",String(E),0);return s(Ct),b(C),g("error"),null}finally{L.current=!1}},[t]),v=_e(async()=>{if(L.current)return;let T=l.current,f=await t.history();L.current||l.current!==T||(s(f),y(t.handoff))},[t]),_=_e(()=>{t.reset(),s([]),b(null),y(!1),g("idle")},[t]);return{messages:i,send:o,status:m,error:p,agent:c,handoff:d,refresh:v,reset:_,client:t}}export{un as BitPalmAgent,O as BitPalmApiError,mn as useBitPalmChat};
2
13
  //# sourceMappingURL=react.js.map