@heedb/web-sdk 0.1.4 → 0.1.6

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.
Files changed (3) hide show
  1. package/dist/widget.js +44 -30
  2. package/package.json +1 -1
  3. package/widget.js +44 -30
package/dist/widget.js CHANGED
@@ -1,11 +1,11 @@
1
- /* Heedb Widget — https://heedb.com */
2
- "use strict";(()=>{(function(){var W,U,K,J,G;let k=document.currentScript||document.querySelector("script[data-api-key]"),L=(W=k==null?void 0:k.getAttribute("data-api-key"))!=null?W:"",N=(U=k==null?void 0:k.src)!=null?U:"",_=(k==null?void 0:k.getAttribute("data-host"))||(N?new URL(N).origin:"");if(!L){console.warn("[Heedb] Missing data-api-key on <script> tag.");return}let p={},m=!1,Y={primary:"#18181b",text:"#18181b",bg:"#ffffff"},Q={primary:"#e4e4e7",text:"#e4e4e7",bg:"#1a1a1a"};function q(){return p.mode==="dark"?!0:p.mode==="light"?!1:p.mode==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches:!1}function V(){return m?Q:Y}function S(e,t){let n=p[e];return n!=null?String(n):t}let C=!1,b="contact",A="",E=(K=localStorage.getItem("heedb_name"))!=null?K:"",f=(J=localStorage.getItem("heedb_email"))!=null?J:"",x=(G=localStorage.getItem("heedb_token"))!=null?G:"",y=null,H=null;async function X(e,t){try{let n=await P("/api/threads/token",{api_key:L,email:e,userHash:t});if(n.ok){let o=await n.json();if(o.widgetToken){x=o.widgetToken,localStorage.setItem("heedb_token",o.widgetToken);return}}x="",localStorage.removeItem("heedb_token")}catch(n){x="",localStorage.removeItem("heedb_token")}}window.Heedb={init(e={}){e.name&&(E=e.name,localStorage.setItem("heedb_name",e.name)),e.email&&(f=e.email,localStorage.setItem("heedb_email",e.email),e.userHash?X(e.email,e.userHash).then(()=>{I(),C&&y&&v()}):(I(),C&&y&&v()))},reset(){E="",f="",x="",localStorage.removeItem("heedb_name"),localStorage.removeItem("heedb_email"),localStorage.removeItem("heedb_token"),b="contact",C=!1,y&&(y.style.display="none"),I()}};function P(e,t){return fetch(`${_}${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function Z(e){let t=new URL(`${_}/api/threads`);return t.searchParams.set("api_key",L),t.searchParams.set("email",e),x&&t.searchParams.set("token",x),fetch(t.toString()).then(n=>n.json())}function ee(e){let t=new URL(`${_}/api/threads/${e}`);return t.searchParams.set("api_key",L),t.searchParams.set("email",f),t.searchParams.set("token",x),fetch(t.toString()).then(n=>n.json())}function te(e,t){return P(`/api/threads/${e}/reply`,{api_key:L,email:f,token:x,message:t})}async function ne(){var e;try{let t=new URL(`${_}/api/widget-config`);t.searchParams.set("api_key",L);let n=await fetch(t.toString());if(n.ok)return(e=(await n.json()).config)!=null?e:{}}catch(t){}return{}}function R(){var c;let e=V(),t=S(m?"darkPrimaryColor":"primaryColor",e.primary),n=S(m?"darkTextColor":"textColor",e.text),o=S(m?"darkBgColor":"bgColor",e.bg),l=(c=p.borderRadius)!=null?c:16,s=p.fontFamily||"system-ui, -apple-system, sans-serif",d=p.position==="bottom-left",u=l>=20?"50%":`${l}px`,i=Math.round(l*.5);return`
1
+ /* Heedb Widget v0.1.6 — https://heedb.com */
2
+ "use strict";(()=>{(function(){var W,U,K,J,V;let w=document.currentScript||document.querySelector("script[data-api-key]"),E=(W=w==null?void 0:w.getAttribute("data-api-key"))!=null?W:"",N=(U=w==null?void 0:w.src)!=null?U:"",I=(w==null?void 0:w.getAttribute("data-host"))||(N?new URL(N).origin:"");if(!E){console.warn("[Heedb] Missing data-api-key on <script> tag.");return}let p={},u=!1,X={primary:"#18181b",text:"#18181b",bg:"#ffffff"},G={primary:"#e4e4e7",text:"#e4e4e7",bg:"#1a1a1a"};function R(){return p.mode==="dark"?!0:p.mode==="light"?!1:p.mode==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches:!1}function Y(){return u?G:X}function S(e,t){let n=p[e];return n!=null?String(n):t}let L=!1,h="contact",A="",C=(K=localStorage.getItem("heedb_name"))!=null?K:"",b=(J=localStorage.getItem("heedb_email"))!=null?J:"",y=(V=localStorage.getItem("heedb_token"))!=null?V:"",v=null,H=null;async function Q(e,t){try{let n=await D("/api/threads/token",{api_key:E,email:e,userHash:t});if(n.ok){let l=await n.json();if(l.widgetToken){y=l.widgetToken,localStorage.setItem("heedb_token",l.widgetToken);return}}y="",localStorage.removeItem("heedb_token")}catch(n){y="",localStorage.removeItem("heedb_token")}}window.Heedb={version:"0.1.6",init(e={}){e.name&&(C=e.name,localStorage.setItem("heedb_name",e.name)),e.email&&(b=e.email,localStorage.setItem("heedb_email",e.email),e.userHash?Q(e.email,e.userHash).then(()=>{z(),L&&v&&k()}):(z(),L&&v&&k()))},reset(){C="",b="",y="",localStorage.removeItem("heedb_name"),localStorage.removeItem("heedb_email"),localStorage.removeItem("heedb_token"),h="contact",L=!1,v&&(v.style.display="none"),z()}};function D(e,t){return fetch(`${I}${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function Z(e){let t=new URL(`${I}/api/threads`);return t.searchParams.set("api_key",E),t.searchParams.set("email",e),y&&t.searchParams.set("token",y),fetch(t.toString()).then(n=>n.json())}function ee(e){let t=new URL(`${I}/api/threads/${e}`);return t.searchParams.set("api_key",E),t.searchParams.set("email",b),t.searchParams.set("token",y),fetch(t.toString()).then(n=>n.json())}function te(e,t){return D(`/api/threads/${e}/reply`,{api_key:E,email:b,token:y,message:t})}async function ne(){var e;try{let t=new URL(`${I}/api/widget-config`);t.searchParams.set("api_key",E);let n=await fetch(t.toString());if(n.ok)return(e=(await n.json()).config)!=null?e:{}}catch(t){}return{}}function O(){var f,x;let e=Y(),t=S(u?"darkPrimaryColor":"primaryColor",e.primary),n=S(u?"darkTextColor":"textColor",e.text),l=S(u?"darkBgColor":"bgColor",e.bg),o=(f=p.borderRadius)!=null?f:16,r=(x=p.buttonRadius)!=null?x:50,c=p.fontFamily||"system-ui, -apple-system, sans-serif",m=p.position==="bottom-left",d=r>=50?"50%":`${r}px`,s=Math.round(o*.5),i=p.triggerMode==="tag",g=p.triggerMode==="embedded"||i;return`
3
3
  .llp-btn {
4
- position: fixed; bottom: 24px; ${d?"left: 24px":"right: 24px"}; z-index: 999998;
5
- width: 52px; height: 52px; border-radius: ${u}; border: none;
4
+ position: fixed; bottom: 24px; ${m?"left: 24px":"right: 24px"}; z-index: 999998;
5
+ width: 52px; height: 52px; border-radius: ${d}; border: none;
6
6
  background: ${t}; color: #fff; font-size: 22px; cursor: pointer;
7
7
  box-shadow: 0 4px 16px rgba(0,0,0,.25);
8
- display: ${p.triggerMode==="embedded"?"none":"flex"}; align-items: center; justify-content: center;
8
+ display: ${g?"none":"flex"}; align-items: center; justify-content: center;
9
9
  transition: transform .15s;
10
10
  }
11
11
  .llp-btn:hover { transform: scale(1.08); }
@@ -13,12 +13,26 @@
13
13
  .llp-btn-icon { display: flex; align-items: center; justify-content: center; }
14
14
  .llp-btn-icon svg { width: 22px; height: 22px; fill: currentColor; }
15
15
  .llp-btn:has(.llp-btn-label) { width: auto; padding: 0 18px; gap: 4px; }
16
+ .llp-tag {
17
+ position: fixed; ${m?"left: 0":"right: 0"}; top: 50%; z-index: 999998;
18
+ transform: ${m?"rotate(90deg) translateX(-50%)":"rotate(-90deg) translateX(50%)"};
19
+ transform-origin: ${m?"left top":"right top"};
20
+ background: ${t}; color: #fff; border: none; cursor: pointer;
21
+ padding: 8px 18px; font-size: 13px; font-weight: 600;
22
+ font-family: ${c};
23
+ border-radius: ${Math.min(r,12)}px ${Math.min(r,12)}px 0 0;
24
+ box-shadow: 0 2px 12px rgba(0,0,0,.2);
25
+ display: flex; align-items: center; gap: 6px;
26
+ transition: opacity .15s;
27
+ }
28
+ .llp-tag:hover { opacity: .9; }
29
+ .llp-tag-icon { font-size: 16px; }
16
30
  .llp-panel {
17
- position: fixed; bottom: 88px; ${d?"left: 24px":"right: 24px"}; z-index: 999999;
18
- width: 370px; max-height: 560px; border-radius: ${l}px;
19
- background: ${o}; box-shadow: 0 8px 32px rgba(0,0,0,.18);
31
+ position: fixed; bottom: 88px; ${m?"left: 24px":"right: 24px"}; z-index: 999999;
32
+ width: 370px; max-height: 560px; border-radius: ${o}px;
33
+ background: ${l}; box-shadow: 0 8px 32px rgba(0,0,0,.18);
20
34
  display: flex; flex-direction: column; overflow: hidden;
21
- font-family: ${s}; font-size: 14px; color: ${n};
35
+ font-family: ${c}; font-size: 14px; color: ${n};
22
36
  transition: opacity .15s, transform .15s;
23
37
  }
24
38
  .llp-header {
@@ -31,7 +45,7 @@
31
45
  font-size: 18px; line-height: 1; padding: 0;
32
46
  }
33
47
  .llp-tabs {
34
- display: flex; border-bottom: 1px solid ${m?"#333":"#e4e4e7"};
48
+ display: flex; border-bottom: 1px solid ${u?"#333":"#e4e4e7"};
35
49
  }
36
50
  .llp-tab {
37
51
  flex: 1; padding: 10px 0; border: none; background: none;
@@ -43,9 +57,9 @@
43
57
  .llp-label { display: block; font-size: 12px; font-weight: 600; color: #52525b; margin-bottom: 4px; }
44
58
  .llp-input, .llp-textarea, .llp-select {
45
59
  width: 100%; box-sizing: border-box; padding: 8px 10px;
46
- border: 1px solid ${m?"#444":"#d4d4d8"}; border-radius: ${i}px;
60
+ border: 1px solid ${u?"#444":"#d4d4d8"}; border-radius: ${s}px;
47
61
  font-size: 13px; color: ${n}; margin-bottom: 10px;
48
- font-family: inherit; background: ${m?"#222":o};
62
+ font-family: inherit; background: ${u?"#222":l};
49
63
  }
50
64
  .llp-textarea { min-height: 80px; resize: vertical; }
51
65
  .llp-input:focus, .llp-textarea:focus, .llp-select:focus {
@@ -53,7 +67,7 @@
53
67
  }
54
68
  .llp-btn-submit {
55
69
  width: 100%; padding: 10px; background: ${t}; color: #fff;
56
- border: none; border-radius: ${i}px; font-size: 14px; font-weight: 600;
70
+ border: none; border-radius: ${s}px; font-size: 14px; font-weight: 600;
57
71
  cursor: pointer; transition: opacity .15s;
58
72
  }
59
73
  .llp-btn-submit:hover { opacity: .85; }
@@ -64,25 +78,25 @@
64
78
  .llp-success h3 { margin: 12px 0 6px; font-size: 15px; color: ${n}; }
65
79
  .llp-success p { margin: 0; color: #71717a; font-size: 13px; line-height: 1.5; }
66
80
  .llp-thread-item {
67
- padding: 10px 12px; border: 1px solid ${m?"#333":"#e4e4e7"}; border-radius: ${i}px;
81
+ padding: 10px 12px; border: 1px solid ${u?"#333":"#e4e4e7"}; border-radius: ${s}px;
68
82
  margin-bottom: 8px; cursor: pointer; display: block; color: inherit;
69
83
  transition: background .1s; background: none;
70
84
  }
71
- .llp-thread-item:hover { background: ${m?"#252525":"#f4f4f5"}; }
85
+ .llp-thread-item:hover { background: ${u?"#252525":"#f4f4f5"}; }
72
86
  .llp-thread-label { font-size: 12px; color: #71717a; margin-bottom: 2px; }
73
87
  .llp-thread-text { font-size: 13px; color: ${n}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
74
88
  .llp-thread-meta { font-size: 11px; color: #a1a1aa; margin-top: 3px; }
75
89
  .llp-badge { display: inline-block; padding: 1px 6px; border-radius: 9999px; font-size: 10px; font-weight: 600; }
76
90
  .llp-badge-open { background: #d1fae5; color: #065f46; }
77
91
  .llp-badge-replied { background: #dbeafe; color: #1e40af; }
78
- .llp-new-msg { margin-top: 12px; padding-top: 12px; border-top: 1px solid ${m?"#333":"#e4e4e7"}; }
92
+ .llp-new-msg { margin-top: 12px; padding-top: 12px; border-top: 1px solid ${u?"#333":"#e4e4e7"}; }
79
93
  .llp-new-msg button {
80
- width: 100%; padding: 8px; background: none; border: 1px solid ${m?"#444":"#d4d4d8"};
81
- border-radius: ${i}px; font-size: 13px; cursor: pointer; color: ${m?"#999":"#52525b"};
94
+ width: 100%; padding: 8px; background: none; border: 1px solid ${u?"#444":"#d4d4d8"};
95
+ border-radius: ${s}px; font-size: 13px; cursor: pointer; color: ${u?"#999":"#52525b"};
82
96
  }
83
- .llp-new-msg button:hover { background: ${m?"#252525":"#f4f4f5"}; }
97
+ .llp-new-msg button:hover { background: ${u?"#252525":"#f4f4f5"}; }
84
98
  .llp-footer {
85
- padding: 6px 16px; text-align: center; border-top: 1px solid ${m?"#333":"#f0f0f0"};
99
+ padding: 6px 16px; text-align: center; border-top: 1px solid ${u?"#333":"#f0f0f0"};
86
100
  }
87
101
  .llp-footer a {
88
102
  font-size: 10px; color: #a1a1aa; text-decoration: none; font-weight: 500;
@@ -101,12 +115,12 @@
101
115
  max-height: 320px; overflow-y: auto;
102
116
  }
103
117
  .llp-chat-bubble {
104
- padding: 8px 12px; border-radius: ${Math.max(i,8)}px; font-size: 13px;
118
+ padding: 8px 12px; border-radius: ${Math.max(s,8)}px; font-size: 13px;
105
119
  line-height: 1.45; max-width: 85%; word-wrap: break-word;
106
120
  white-space: pre-wrap;
107
121
  }
108
122
  .llp-chat-inbound {
109
- background: ${m?"#252525":"#f4f4f5"}; color: ${n}; align-self: flex-start;
123
+ background: ${u?"#252525":"#f4f4f5"}; color: ${n}; align-self: flex-start;
110
124
  border-bottom-left-radius: 4px;
111
125
  }
112
126
  .llp-chat-outbound {
@@ -118,25 +132,25 @@
118
132
  }
119
133
  .llp-chat-time-right { text-align: right; }
120
134
  .llp-chat-reply {
121
- display: flex; gap: 8px; border-top: 1px solid ${m?"#333":"#e4e4e7"}; padding-top: 12px;
135
+ display: flex; gap: 8px; border-top: 1px solid ${u?"#333":"#e4e4e7"}; padding-top: 12px;
122
136
  }
123
137
  .llp-chat-reply-input {
124
- flex: 1; padding: 8px 10px; border: 1px solid ${m?"#444":"#d4d4d8"}; border-radius: ${i}px;
125
- font-size: 13px; font-family: inherit; color: ${n}; background: ${m?"#222":o};
138
+ flex: 1; padding: 8px 10px; border: 1px solid ${u?"#444":"#d4d4d8"}; border-radius: ${s}px;
139
+ font-size: 13px; font-family: inherit; color: ${n}; background: ${u?"#222":l};
126
140
  resize: none; min-height: 36px; max-height: 80px; box-sizing: border-box;
127
141
  }
128
142
  .llp-chat-reply-input:focus { outline: none; border-color: ${t}; }
129
143
  .llp-chat-send {
130
144
  padding: 8px 14px; background: ${t}; color: #fff; border: none;
131
- border-radius: ${i}px; font-size: 13px; font-weight: 600; cursor: pointer;
145
+ border-radius: ${s}px; font-size: 13px; font-weight: 600; cursor: pointer;
132
146
  transition: opacity .15s; white-space: nowrap; align-self: flex-end;
133
147
  }
134
148
  .llp-chat-send:hover { opacity: .85; }
135
149
  .llp-chat-send:disabled { opacity: .5; cursor: not-allowed; }
136
- `}function a(e,t={},n=[]){let o=document.createElement(e);for(let[l,s]of Object.entries(t))l==="class"?o.className=s:l==="style"?o.setAttribute("style",s):l.startsWith("on")&&typeof s=="function"?o.addEventListener(l.slice(2),s):o.setAttribute(l,String(s));for(let l of n)o.appendChild(typeof l=="string"?document.createTextNode(l):l);return o}function j(e,t,n=""){let o=document.createElement("input");return o.type=e,o.id=t,o.placeholder=n,o.className="llp-input",o}function le(e,t=""){let n=document.createElement("textarea");return n.id=e,n.placeholder=t,n.className="llp-textarea",n}function ae(e,t){let n=document.createElement("select");n.id=e,n.className="llp-select";for(let o of t){let l=document.createElement("option");l.value=o.value,l.textContent=o.label,n.appendChild(l)}return n}function v(){if(!y)return;let e=y.querySelector(".llp-body");e.innerHTML="",b==="contact"?oe(e):b==="privacy"?ie(e):b==="threads"?re(e):b==="thread-detail"&&ce(e),M&&(M.style.display=b==="thread-detail"?"none":"flex")}function oe(e,t=""){let n=!!(E&&f),o=a("label",{class:"llp-label"},["Name"]),l=j("text","llp-name","Jane Smith");E&&(l.value=E);let s=a("label",{class:"llp-label"},["Email"]),d=j("email","llp-email","jane@example.com");(t||f)&&(d.value=t||f);let u=a("label",{class:"llp-label"},["Message"]),i=le("llp-message","How can we help?"),c=a("div",{class:"llp-error",style:"display:none"}),r=a("button",{class:"llp-btn-submit"},["Send message"]);r.onclick=async()=>{let g=l.value.trim(),h=d.value.trim(),w=i.value.trim();if(c.style.display="none",!g||!h||!w){c.textContent="Please fill in all fields.",c.style.display="block";return}r.disabled=!0,r.textContent="Sending\u2026";try{let T=await P("/api/contact",{api_key:L,name:g,email:h,message:w});if(T.ok)f=h,localStorage.setItem("heedb_email",h),I(),O(e,"Message sent!","We'll get back to you soon. Check your inbox for a confirmation email.");else{let me=await T.json();c.textContent=me.error||"Something went wrong.",c.style.display="block",r.disabled=!1,r.textContent="Send message"}}catch(T){c.textContent="Network error. Please try again.",c.style.display="block",r.disabled=!1,r.textContent="Send message"}},n?e.append(u,i,c,r):e.append(o,l,s,d,u,i,c,r)}function ie(e){let t=!!(E&&f),n=a("label",{class:"llp-label"},["Name"]),o=j("text","llp-priv-name","Jane Smith");E&&(o.value=E);let l=a("label",{class:"llp-label"},["Email"]),s=j("email","llp-priv-email","jane@example.com");f&&(s.value=f);let d=a("label",{class:"llp-label"},["Request type"]),u=ae("llp-priv-type",[{value:"deletion",label:"Delete my data"},{value:"access",label:"Access my data"},{value:"portability",label:"Export my data"},{value:"correction",label:"Correct my data"},{value:"restriction",label:"Restrict processing"},{value:"objection",label:"Object to processing"},{value:"other",label:"Other"}]),i=a("div",{class:"llp-error",style:"display:none"}),c=a("button",{class:"llp-btn-submit"},["Submit request"]);c.onclick=async()=>{let r=o.value.trim(),g=s.value.trim(),h=u.value;if(i.style.display="none",!r||!g){i.textContent="Please fill in all fields.",i.style.display="block";return}c.disabled=!0,c.textContent="Submitting\u2026";try{let w=await P("/api/privacy-request",{api_key:L,name:r,email:g,request_type:h});if(w.ok)f=g,localStorage.setItem("heedb_email",g),I(),O(e,"Request submitted!","Your privacy request has been received. We'll respond within 30 days.");else{let T=await w.json();i.textContent=T.error||"Something went wrong.",i.style.display="block",c.disabled=!1,c.textContent="Submit request"}}catch(w){i.textContent="Network error. Please try again.",i.style.display="block",c.disabled=!1,c.textContent="Submit request"}},t?e.append(d,u,i,c):e.append(n,o,l,s,d,u,i,c)}async function re(e){var t;if(!x){e.innerHTML="";let n=a("p",{style:"color:#71717a;text-align:center;margin:8px 0;font-size:13px;line-height:1.5"},["Send a message below to view your message history."]),o=a("div",{class:"llp-new-msg"}),l=a("button",{},["+ Send a message"]);l.onclick=()=>{b="contact",$("contact"),v()},o.appendChild(l),e.append(n,o);return}e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';try{let{threads:n}=await Z(f);if(e.innerHTML="",n.length===0){let s=a("p",{style:"color:#71717a;text-align:center;margin:8px 0"},["No open messages yet."]);e.appendChild(s)}else for(let s of n){let d=a("span",{class:`llp-badge llp-badge-${s.status}`},[s.status]),u=a("div",{class:"llp-thread-label"},[s.type==="privacy"?"Privacy request":"Message"," \u2022 "]);u.appendChild(d);let i=a("div",{class:"llp-thread-text"},[(t=s.preview)!=null?t:""]),c=new Date(s.createdAt).toLocaleDateString(),r=a("div",{class:"llp-thread-meta"},[c]),g=a("div",{class:"llp-thread-item"});g.append(u,i,r),g.onclick=()=>se(s.id),e.appendChild(g)}let o=a("div",{class:"llp-new-msg"}),l=a("button",{},["+ Send a new message"]);l.onclick=()=>{b="contact",$("contact"),v()},o.appendChild(l),e.appendChild(o)}catch(n){e.innerHTML='<p style="color:#ef4444;text-align:center">Failed to load messages.</p>'}}function se(e){A=e,b="thread-detail",v()}async function ce(e){e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';let t=a("button",{class:"llp-chat-back"},["\u2190 Back to messages"]);t.onclick=()=>{b="threads",$("threads"),v()};try{let o=(await ee(A)).messages||[];e.innerHTML="",e.style.padding="12px",e.appendChild(t);let l=a("div",{class:"llp-chat-messages"});for(let r of o){let g=r.direction==="inbound",h=a("div",{style:`display:flex;flex-direction:column;${g?"align-items:flex-start":"align-items:flex-end"}`}),w=a("div",{class:`llp-chat-bubble ${g?"llp-chat-inbound":"llp-chat-outbound"}`},[de(r.body)]),T=a("div",{class:`llp-chat-time ${g?"":"llp-chat-time-right"}`},[pe(r.createdAt)]);h.append(w,T),l.appendChild(h)}e.appendChild(l),requestAnimationFrame(()=>{l.scrollTop=l.scrollHeight});let s=a("div",{class:"llp-chat-reply"}),d=document.createElement("textarea");d.className="llp-chat-reply-input",d.placeholder="Type a reply\u2026",d.rows=1,d.addEventListener("input",()=>{d.style.height="auto",d.style.height=Math.min(d.scrollHeight,80)+"px"});let u=a("button",{class:"llp-chat-send"},["Send"]),i=a("div",{class:"llp-error",style:"display:none;margin-top:4px"});async function c(){let r=d.value.trim();if(r){u.disabled=!0,u.textContent="\u2026",i.style.display="none";try{let g=await te(A,r);if(g.ok){let h=a("div",{style:"display:flex;flex-direction:column;align-items:flex-start"}),w=a("div",{class:"llp-chat-bubble llp-chat-inbound"},[r]),T=a("div",{class:"llp-chat-time"},["Just now"]);h.append(w,T),l.appendChild(h),l.scrollTop=l.scrollHeight,d.value="",d.style.height="auto"}else{let h=await g.json();i.textContent=h.error||"Failed to send.",i.style.display="block"}}catch(g){i.textContent="Network error. Please try again.",i.style.display="block"}u.disabled=!1,u.textContent="Send"}}u.onclick=c,d.addEventListener("keydown",r=>{r.key==="Enter"&&!r.shiftKey&&(r.preventDefault(),c())}),s.append(d,u),e.append(s,i),requestAnimationFrame(()=>d.focus())}catch(n){e.innerHTML="",e.appendChild(t),e.appendChild(a("p",{style:"color:#ef4444;text-align:center"},["Failed to load conversation."]))}}function de(e){let t=e.split(`
137
- `),n=[];for(let o of t){let l=o.trim();if(/^(On|Em|El|Le|Am|Il giorno) .+(<[^>]+@[^>]+>).*(wrote|escreveu|escribi|crit|schrieb|scritto)\s?:$/i.test(l)||/<[^>]+@[^>]+>/.test(l)&&l.endsWith(":")||/^-{3,}$/.test(l))break;/^>{1,}\s/.test(l)||n.push(o)}return n.join(`
138
- `).trim()}function pe(e){let t=new Date(e),o=new Date().getTime()-t.getTime(),l=Math.floor(o/6e4);if(l<1)return"Just now";if(l<60)return`${l}m ago`;let s=Math.floor(l/60);return s<24?`${s}h ago`:t.toLocaleDateString()}function O(e,t,n){e.innerHTML="";let o=a("div",{class:"llp-success"});o.innerHTML=`
150
+ `}function a(e,t={},n=[]){let l=document.createElement(e);for(let[o,r]of Object.entries(t))o==="class"?l.className=r:o==="style"?l.setAttribute("style",r):o.startsWith("on")&&typeof r=="function"?l.addEventListener(o.slice(2),r):l.setAttribute(o,String(r));for(let o of n)l.appendChild(typeof o=="string"?document.createTextNode(o):o);return l}function P(e,t,n=""){let l=document.createElement("input");return l.type=e,l.id=t,l.placeholder=n,l.className="llp-input",l}function ae(e,t=""){let n=document.createElement("textarea");return n.id=e,n.placeholder=t,n.className="llp-textarea",n}function oe(e,t){let n=document.createElement("select");n.id=e,n.className="llp-select";for(let l of t){let o=document.createElement("option");o.value=l.value,o.textContent=l.label,n.appendChild(o)}return n}function k(){if(!v)return;let e=v.querySelector(".llp-body");e.innerHTML="",h==="contact"?le(e):h==="privacy"?ie(e):h==="threads"?re(e):h==="thread-detail"&&ce(e),M&&(M.style.display=h==="thread-detail"?"none":"flex")}function le(e,t=""){let n=!!(C&&b),l=a("label",{class:"llp-label"},["Name"]),o=P("text","llp-name","Jane Smith");C&&(o.value=C);let r=a("label",{class:"llp-label"},["Email"]),c=P("email","llp-email","jane@example.com");(t||b)&&(c.value=t||b);let m=a("label",{class:"llp-label"},["Message"]),d=ae("llp-message","How can we help?"),s=a("div",{class:"llp-error",style:"display:none"}),i=a("button",{class:"llp-btn-submit"},["Send message"]);i.onclick=async()=>{let g=o.value.trim(),f=c.value.trim(),x=d.value.trim();if(s.style.display="none",!g||!f||!x){s.textContent="Please fill in all fields.",s.style.display="block";return}i.disabled=!0,i.textContent="Sending\u2026";try{let T=await D("/api/contact",{api_key:E,name:g,email:f,message:x});if(T.ok)b=f,localStorage.setItem("heedb_email",f),z(),q(e,"Message sent!","We'll get back to you soon. Check your inbox for a confirmation email.");else{let me=await T.json();s.textContent=me.error||"Something went wrong.",s.style.display="block",i.disabled=!1,i.textContent="Send message"}}catch(T){s.textContent="Network error. Please try again.",s.style.display="block",i.disabled=!1,i.textContent="Send message"}},n?e.append(m,d,s,i):e.append(l,o,r,c,m,d,s,i)}function ie(e){let t=!!(C&&b),n=a("label",{class:"llp-label"},["Name"]),l=P("text","llp-priv-name","Jane Smith");C&&(l.value=C);let o=a("label",{class:"llp-label"},["Email"]),r=P("email","llp-priv-email","jane@example.com");b&&(r.value=b);let c=a("label",{class:"llp-label"},["Request type"]),m=oe("llp-priv-type",[{value:"deletion",label:"Delete my data"},{value:"access",label:"Access my data"},{value:"portability",label:"Export my data"},{value:"correction",label:"Correct my data"},{value:"restriction",label:"Restrict processing"},{value:"objection",label:"Object to processing"},{value:"other",label:"Other"}]),d=a("div",{class:"llp-error",style:"display:none"}),s=a("button",{class:"llp-btn-submit"},["Submit request"]);s.onclick=async()=>{let i=l.value.trim(),g=r.value.trim(),f=m.value;if(d.style.display="none",!i||!g){d.textContent="Please fill in all fields.",d.style.display="block";return}s.disabled=!0,s.textContent="Submitting\u2026";try{let x=await D("/api/privacy-request",{api_key:E,name:i,email:g,request_type:f});if(x.ok)b=g,localStorage.setItem("heedb_email",g),z(),q(e,"Request submitted!","Your privacy request has been received. We'll respond within 30 days.");else{let T=await x.json();d.textContent=T.error||"Something went wrong.",d.style.display="block",s.disabled=!1,s.textContent="Submit request"}}catch(x){d.textContent="Network error. Please try again.",d.style.display="block",s.disabled=!1,s.textContent="Submit request"}},t?e.append(c,m,d,s):e.append(n,l,o,r,c,m,d,s)}async function re(e){var t;if(!y){e.innerHTML="";let n=a("p",{style:"color:#71717a;text-align:center;margin:8px 0;font-size:13px;line-height:1.5"},["Send a message below to view your message history."]),l=a("div",{class:"llp-new-msg"}),o=a("button",{},["+ Send a message"]);o.onclick=()=>{h="contact",$("contact"),k()},l.appendChild(o),e.append(n,l);return}e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';try{let{threads:n}=await Z(b);if(e.innerHTML="",n.length===0){let r=a("p",{style:"color:#71717a;text-align:center;margin:8px 0"},["No open messages yet."]);e.appendChild(r)}else for(let r of n){let c=a("span",{class:`llp-badge llp-badge-${r.status}`},[r.status]),m=a("div",{class:"llp-thread-label"},[r.type==="privacy"?"Privacy request":"Message"," \u2022 "]);m.appendChild(c);let d=a("div",{class:"llp-thread-text"},[(t=r.preview)!=null?t:""]),s=new Date(r.createdAt).toLocaleDateString(),i=a("div",{class:"llp-thread-meta"},[s]),g=a("div",{class:"llp-thread-item"});g.append(m,d,i),g.onclick=()=>se(r.id),e.appendChild(g)}let l=a("div",{class:"llp-new-msg"}),o=a("button",{},["+ Send a new message"]);o.onclick=()=>{h="contact",$("contact"),k()},l.appendChild(o),e.appendChild(l)}catch(n){e.innerHTML='<p style="color:#ef4444;text-align:center">Failed to load messages.</p>'}}function se(e){A=e,h="thread-detail",k()}async function ce(e){e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';let t=a("button",{class:"llp-chat-back"},["\u2190 Back to messages"]);t.onclick=()=>{h="threads",$("threads"),k()};try{let l=(await ee(A)).messages||[];e.innerHTML="",e.style.padding="12px",e.appendChild(t);let o=a("div",{class:"llp-chat-messages"});for(let i of l){let g=i.direction==="inbound",f=a("div",{style:`display:flex;flex-direction:column;${g?"align-items:flex-start":"align-items:flex-end"}`}),x=a("div",{class:`llp-chat-bubble ${g?"llp-chat-inbound":"llp-chat-outbound"}`},[de(i.body)]),T=a("div",{class:`llp-chat-time ${g?"":"llp-chat-time-right"}`},[pe(i.createdAt)]);f.append(x,T),o.appendChild(f)}e.appendChild(o),requestAnimationFrame(()=>{o.scrollTop=o.scrollHeight});let r=a("div",{class:"llp-chat-reply"}),c=document.createElement("textarea");c.className="llp-chat-reply-input",c.placeholder="Type a reply\u2026",c.rows=1,c.addEventListener("input",()=>{c.style.height="auto",c.style.height=Math.min(c.scrollHeight,80)+"px"});let m=a("button",{class:"llp-chat-send"},["Send"]),d=a("div",{class:"llp-error",style:"display:none;margin-top:4px"});async function s(){let i=c.value.trim();if(i){m.disabled=!0,m.textContent="\u2026",d.style.display="none";try{let g=await te(A,i);if(g.ok){let f=a("div",{style:"display:flex;flex-direction:column;align-items:flex-start"}),x=a("div",{class:"llp-chat-bubble llp-chat-inbound"},[i]),T=a("div",{class:"llp-chat-time"},["Just now"]);f.append(x,T),o.appendChild(f),o.scrollTop=o.scrollHeight,c.value="",c.style.height="auto"}else{let f=await g.json();d.textContent=f.error||"Failed to send.",d.style.display="block"}}catch(g){d.textContent="Network error. Please try again.",d.style.display="block"}m.disabled=!1,m.textContent="Send"}}m.onclick=s,c.addEventListener("keydown",i=>{i.key==="Enter"&&!i.shiftKey&&(i.preventDefault(),s())}),r.append(c,m),e.append(r,d),requestAnimationFrame(()=>c.focus())}catch(n){e.innerHTML="",e.appendChild(t),e.appendChild(a("p",{style:"color:#ef4444;text-align:center"},["Failed to load conversation."]))}}function de(e){let t=e.split(`
151
+ `),n=[];for(let l of t){let o=l.trim();if(/^(On|Em|El|Le|Am|Il giorno) .+(<[^>]+@[^>]+>).*(wrote|escreveu|escribi|crit|schrieb|scritto)\s?:$/i.test(o)||/<[^>]+@[^>]+>/.test(o)&&o.endsWith(":")||/^-{3,}$/.test(o))break;/^>{1,}\s/.test(o)||n.push(l)}return n.join(`
152
+ `).trim()}function pe(e){let t=new Date(e),l=new Date().getTime()-t.getTime(),o=Math.floor(l/6e4);if(o<1)return"Just now";if(o<60)return`${o}m ago`;let r=Math.floor(o/60);return r<24?`${r}h ago`:t.toLocaleDateString()}function q(e,t,n){e.innerHTML="";let l=a("div",{class:"llp-success"});l.innerHTML=`
139
153
  <div class="llp-success-icon">\u2705</div>
140
154
  <h3>${t}</h3>
141
155
  <p>${n}</p>
142
- `,e.appendChild(o)}let M=null,z=null;function $(e){b=e,M&&M.querySelectorAll(".llp-tab").forEach(t=>{t.classList.toggle("active",t.dataset.mode===e)})}function I(){z&&(z.style.display=f&&x?"":"none")}let B=null;function ge(){m=q(),B&&(B.textContent=R())}async function F(){p=await ne(),m=q(),B=document.createElement("style"),B.textContent=R(),document.head.appendChild(B),p.mode==="system"&&window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{ge(),C&&y&&v()});let e=p.triggerIcon?p.triggerIcon:p.triggerEmoji||"\u{1F4AC}",t=p.triggerText||"";if(H=a("button",{class:"llp-btn",title:"Contact us","aria-label":"Open contact widget"}),p.triggerIcon){let r=a("span",{class:"llp-btn-icon"});r.innerHTML=p.triggerIcon,H.appendChild(r)}else H.appendChild(document.createTextNode(p.triggerEmoji||"\u{1F4AC}"));if(t&&H.appendChild(a("span",{class:"llp-btn-label"},[t])),H.onclick=D,document.body.appendChild(H),p.triggerMode==="embedded"&&p.triggerSelector){let r=document.querySelector(p.triggerSelector);r&&r.addEventListener("click",g=>{g.preventDefault(),D()})}y=a("div",{class:"llp-panel",style:"display:none"});let n=a("div",{class:"llp-header"}),o=a("h2",{},[p.headerTitle||"Contact us"]),l=a("button",{class:"llp-close","aria-label":"Close"},["\u2715"]);l.onclick=D,n.append(o,l),M=a("div",{class:"llp-tabs"});let s=a("button",{class:"llp-tab active","data-mode":"contact"},["Message"]),d=a("button",{class:"llp-tab","data-mode":"privacy"},["Privacy"]);z=a("button",{class:"llp-tab","data-mode":"threads"},["Messages"]),z.style.display=f&&x?"":"none",s.onclick=()=>{$("contact"),v()},d.onclick=()=>{$("privacy"),v()},z.onclick=()=>{$("threads"),v()},M.append(s,d,z);let u=a("div",{class:"llp-body"}),i=a("div",{class:"llp-footer"}),c=a("a",{href:"https://heedb.com",target:"_blank",rel:"noopener noreferrer"},["Powered by Heedb"]);i.appendChild(c),y.append(n,M,u,i),document.body.appendChild(y)}function D(){C=!C,y&&(y.style.display=C?"flex":"none",C&&(f&&x&&b!=="privacy"&&b!=="thread-detail"&&(b="threads",$("threads")),v()))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",F):F()})();})();
156
+ `,e.appendChild(l)}let M=null,_=null;function $(e){h=e,M&&M.querySelectorAll(".llp-tab").forEach(t=>{t.classList.toggle("active",t.dataset.mode===e)})}function z(){_&&(_.style.display=b&&y?"":"none")}let B=null;function ge(){u=R(),B&&(B.textContent=O())}async function F(){p=await ne(),u=R(),B=document.createElement("style"),B.textContent=O(),document.head.appendChild(B),p.mode==="system"&&window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{ge(),L&&v&&k()});let e=p.triggerIcon?p.triggerIcon:p.triggerEmoji||"\u{1F4AC}",t=p.triggerText||"";if(H=a("button",{class:"llp-btn",title:"Contact us","aria-label":"Open contact widget"}),p.triggerIcon){let i=a("span",{class:"llp-btn-icon"});i.innerHTML=p.triggerIcon,H.appendChild(i)}else H.appendChild(document.createTextNode(p.triggerEmoji||"\u{1F4AC}"));if(t&&H.appendChild(a("span",{class:"llp-btn-label"},[t])),H.onclick=j,document.body.appendChild(H),p.triggerMode==="embedded"&&p.triggerSelector){let i=document.querySelector(p.triggerSelector);i&&i.addEventListener("click",g=>{g.preventDefault(),j()})}if(p.triggerMode==="tag"){let i=a("button",{class:"llp-tag","aria-label":"Open contact widget"}),g=a("span",{class:"llp-tag-icon"},[p.triggerEmoji||"\u{1F4AC}"]);i.appendChild(g),i.appendChild(document.createTextNode(p.triggerText||"Feedback")),i.onclick=j,document.body.appendChild(i)}v=a("div",{class:"llp-panel",style:"display:none"});let n=a("div",{class:"llp-header"}),l=a("h2",{},[p.headerTitle||"Contact us"]),o=a("button",{class:"llp-close","aria-label":"Close"},["\u2715"]);o.onclick=j,n.append(l,o),M=a("div",{class:"llp-tabs"});let r=a("button",{class:"llp-tab active","data-mode":"contact"},["Message"]),c=a("button",{class:"llp-tab","data-mode":"privacy"},["Privacy"]);_=a("button",{class:"llp-tab","data-mode":"threads"},["Messages"]),_.style.display=b&&y?"":"none",r.onclick=()=>{$("contact"),k()},c.onclick=()=>{$("privacy"),k()},_.onclick=()=>{$("threads"),k()},M.append(r,c,_);let m=a("div",{class:"llp-body"}),d=a("div",{class:"llp-footer"}),s=a("a",{href:"https://heedb.com",target:"_blank",rel:"noopener noreferrer"},["Powered by Heedb"]);d.appendChild(s),v.append(n,M,m,d),document.body.appendChild(v)}function j(){L=!L,v&&(v.style.display=L?"flex":"none",L&&(b&&y&&h!=="privacy"&&h!=="thread-detail"&&(h="threads",$("threads")),k()))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",F):F()})();})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heedb/web-sdk",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Drop-in feedback widget with email conversations for any website",
5
5
  "license": "MIT",
6
6
  "repository": {
package/widget.js CHANGED
@@ -1,11 +1,11 @@
1
- /* Heedb Widget — https://heedb.com */
2
- "use strict";(()=>{(function(){var W,U,K,J,G;let k=document.currentScript||document.querySelector("script[data-api-key]"),L=(W=k==null?void 0:k.getAttribute("data-api-key"))!=null?W:"",N=(U=k==null?void 0:k.src)!=null?U:"",_=(k==null?void 0:k.getAttribute("data-host"))||(N?new URL(N).origin:"");if(!L){console.warn("[Heedb] Missing data-api-key on <script> tag.");return}let p={},m=!1,Y={primary:"#18181b",text:"#18181b",bg:"#ffffff"},Q={primary:"#e4e4e7",text:"#e4e4e7",bg:"#1a1a1a"};function q(){return p.mode==="dark"?!0:p.mode==="light"?!1:p.mode==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches:!1}function V(){return m?Q:Y}function S(e,t){let n=p[e];return n!=null?String(n):t}let C=!1,b="contact",A="",E=(K=localStorage.getItem("heedb_name"))!=null?K:"",f=(J=localStorage.getItem("heedb_email"))!=null?J:"",x=(G=localStorage.getItem("heedb_token"))!=null?G:"",y=null,H=null;async function X(e,t){try{let n=await P("/api/threads/token",{api_key:L,email:e,userHash:t});if(n.ok){let o=await n.json();if(o.widgetToken){x=o.widgetToken,localStorage.setItem("heedb_token",o.widgetToken);return}}x="",localStorage.removeItem("heedb_token")}catch(n){x="",localStorage.removeItem("heedb_token")}}window.Heedb={init(e={}){e.name&&(E=e.name,localStorage.setItem("heedb_name",e.name)),e.email&&(f=e.email,localStorage.setItem("heedb_email",e.email),e.userHash?X(e.email,e.userHash).then(()=>{I(),C&&y&&v()}):(I(),C&&y&&v()))},reset(){E="",f="",x="",localStorage.removeItem("heedb_name"),localStorage.removeItem("heedb_email"),localStorage.removeItem("heedb_token"),b="contact",C=!1,y&&(y.style.display="none"),I()}};function P(e,t){return fetch(`${_}${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function Z(e){let t=new URL(`${_}/api/threads`);return t.searchParams.set("api_key",L),t.searchParams.set("email",e),x&&t.searchParams.set("token",x),fetch(t.toString()).then(n=>n.json())}function ee(e){let t=new URL(`${_}/api/threads/${e}`);return t.searchParams.set("api_key",L),t.searchParams.set("email",f),t.searchParams.set("token",x),fetch(t.toString()).then(n=>n.json())}function te(e,t){return P(`/api/threads/${e}/reply`,{api_key:L,email:f,token:x,message:t})}async function ne(){var e;try{let t=new URL(`${_}/api/widget-config`);t.searchParams.set("api_key",L);let n=await fetch(t.toString());if(n.ok)return(e=(await n.json()).config)!=null?e:{}}catch(t){}return{}}function R(){var c;let e=V(),t=S(m?"darkPrimaryColor":"primaryColor",e.primary),n=S(m?"darkTextColor":"textColor",e.text),o=S(m?"darkBgColor":"bgColor",e.bg),l=(c=p.borderRadius)!=null?c:16,s=p.fontFamily||"system-ui, -apple-system, sans-serif",d=p.position==="bottom-left",u=l>=20?"50%":`${l}px`,i=Math.round(l*.5);return`
1
+ /* Heedb Widget v0.1.6 — https://heedb.com */
2
+ "use strict";(()=>{(function(){var W,U,K,J,V;let w=document.currentScript||document.querySelector("script[data-api-key]"),E=(W=w==null?void 0:w.getAttribute("data-api-key"))!=null?W:"",N=(U=w==null?void 0:w.src)!=null?U:"",I=(w==null?void 0:w.getAttribute("data-host"))||(N?new URL(N).origin:"");if(!E){console.warn("[Heedb] Missing data-api-key on <script> tag.");return}let p={},u=!1,X={primary:"#18181b",text:"#18181b",bg:"#ffffff"},G={primary:"#e4e4e7",text:"#e4e4e7",bg:"#1a1a1a"};function R(){return p.mode==="dark"?!0:p.mode==="light"?!1:p.mode==="system"?window.matchMedia("(prefers-color-scheme: dark)").matches:!1}function Y(){return u?G:X}function S(e,t){let n=p[e];return n!=null?String(n):t}let L=!1,h="contact",A="",C=(K=localStorage.getItem("heedb_name"))!=null?K:"",b=(J=localStorage.getItem("heedb_email"))!=null?J:"",y=(V=localStorage.getItem("heedb_token"))!=null?V:"",v=null,H=null;async function Q(e,t){try{let n=await D("/api/threads/token",{api_key:E,email:e,userHash:t});if(n.ok){let l=await n.json();if(l.widgetToken){y=l.widgetToken,localStorage.setItem("heedb_token",l.widgetToken);return}}y="",localStorage.removeItem("heedb_token")}catch(n){y="",localStorage.removeItem("heedb_token")}}window.Heedb={version:"0.1.6",init(e={}){e.name&&(C=e.name,localStorage.setItem("heedb_name",e.name)),e.email&&(b=e.email,localStorage.setItem("heedb_email",e.email),e.userHash?Q(e.email,e.userHash).then(()=>{z(),L&&v&&k()}):(z(),L&&v&&k()))},reset(){C="",b="",y="",localStorage.removeItem("heedb_name"),localStorage.removeItem("heedb_email"),localStorage.removeItem("heedb_token"),h="contact",L=!1,v&&(v.style.display="none"),z()}};function D(e,t){return fetch(`${I}${e}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)})}function Z(e){let t=new URL(`${I}/api/threads`);return t.searchParams.set("api_key",E),t.searchParams.set("email",e),y&&t.searchParams.set("token",y),fetch(t.toString()).then(n=>n.json())}function ee(e){let t=new URL(`${I}/api/threads/${e}`);return t.searchParams.set("api_key",E),t.searchParams.set("email",b),t.searchParams.set("token",y),fetch(t.toString()).then(n=>n.json())}function te(e,t){return D(`/api/threads/${e}/reply`,{api_key:E,email:b,token:y,message:t})}async function ne(){var e;try{let t=new URL(`${I}/api/widget-config`);t.searchParams.set("api_key",E);let n=await fetch(t.toString());if(n.ok)return(e=(await n.json()).config)!=null?e:{}}catch(t){}return{}}function O(){var f,x;let e=Y(),t=S(u?"darkPrimaryColor":"primaryColor",e.primary),n=S(u?"darkTextColor":"textColor",e.text),l=S(u?"darkBgColor":"bgColor",e.bg),o=(f=p.borderRadius)!=null?f:16,r=(x=p.buttonRadius)!=null?x:50,c=p.fontFamily||"system-ui, -apple-system, sans-serif",m=p.position==="bottom-left",d=r>=50?"50%":`${r}px`,s=Math.round(o*.5),i=p.triggerMode==="tag",g=p.triggerMode==="embedded"||i;return`
3
3
  .llp-btn {
4
- position: fixed; bottom: 24px; ${d?"left: 24px":"right: 24px"}; z-index: 999998;
5
- width: 52px; height: 52px; border-radius: ${u}; border: none;
4
+ position: fixed; bottom: 24px; ${m?"left: 24px":"right: 24px"}; z-index: 999998;
5
+ width: 52px; height: 52px; border-radius: ${d}; border: none;
6
6
  background: ${t}; color: #fff; font-size: 22px; cursor: pointer;
7
7
  box-shadow: 0 4px 16px rgba(0,0,0,.25);
8
- display: ${p.triggerMode==="embedded"?"none":"flex"}; align-items: center; justify-content: center;
8
+ display: ${g?"none":"flex"}; align-items: center; justify-content: center;
9
9
  transition: transform .15s;
10
10
  }
11
11
  .llp-btn:hover { transform: scale(1.08); }
@@ -13,12 +13,26 @@
13
13
  .llp-btn-icon { display: flex; align-items: center; justify-content: center; }
14
14
  .llp-btn-icon svg { width: 22px; height: 22px; fill: currentColor; }
15
15
  .llp-btn:has(.llp-btn-label) { width: auto; padding: 0 18px; gap: 4px; }
16
+ .llp-tag {
17
+ position: fixed; ${m?"left: 0":"right: 0"}; top: 50%; z-index: 999998;
18
+ transform: ${m?"rotate(90deg) translateX(-50%)":"rotate(-90deg) translateX(50%)"};
19
+ transform-origin: ${m?"left top":"right top"};
20
+ background: ${t}; color: #fff; border: none; cursor: pointer;
21
+ padding: 8px 18px; font-size: 13px; font-weight: 600;
22
+ font-family: ${c};
23
+ border-radius: ${Math.min(r,12)}px ${Math.min(r,12)}px 0 0;
24
+ box-shadow: 0 2px 12px rgba(0,0,0,.2);
25
+ display: flex; align-items: center; gap: 6px;
26
+ transition: opacity .15s;
27
+ }
28
+ .llp-tag:hover { opacity: .9; }
29
+ .llp-tag-icon { font-size: 16px; }
16
30
  .llp-panel {
17
- position: fixed; bottom: 88px; ${d?"left: 24px":"right: 24px"}; z-index: 999999;
18
- width: 370px; max-height: 560px; border-radius: ${l}px;
19
- background: ${o}; box-shadow: 0 8px 32px rgba(0,0,0,.18);
31
+ position: fixed; bottom: 88px; ${m?"left: 24px":"right: 24px"}; z-index: 999999;
32
+ width: 370px; max-height: 560px; border-radius: ${o}px;
33
+ background: ${l}; box-shadow: 0 8px 32px rgba(0,0,0,.18);
20
34
  display: flex; flex-direction: column; overflow: hidden;
21
- font-family: ${s}; font-size: 14px; color: ${n};
35
+ font-family: ${c}; font-size: 14px; color: ${n};
22
36
  transition: opacity .15s, transform .15s;
23
37
  }
24
38
  .llp-header {
@@ -31,7 +45,7 @@
31
45
  font-size: 18px; line-height: 1; padding: 0;
32
46
  }
33
47
  .llp-tabs {
34
- display: flex; border-bottom: 1px solid ${m?"#333":"#e4e4e7"};
48
+ display: flex; border-bottom: 1px solid ${u?"#333":"#e4e4e7"};
35
49
  }
36
50
  .llp-tab {
37
51
  flex: 1; padding: 10px 0; border: none; background: none;
@@ -43,9 +57,9 @@
43
57
  .llp-label { display: block; font-size: 12px; font-weight: 600; color: #52525b; margin-bottom: 4px; }
44
58
  .llp-input, .llp-textarea, .llp-select {
45
59
  width: 100%; box-sizing: border-box; padding: 8px 10px;
46
- border: 1px solid ${m?"#444":"#d4d4d8"}; border-radius: ${i}px;
60
+ border: 1px solid ${u?"#444":"#d4d4d8"}; border-radius: ${s}px;
47
61
  font-size: 13px; color: ${n}; margin-bottom: 10px;
48
- font-family: inherit; background: ${m?"#222":o};
62
+ font-family: inherit; background: ${u?"#222":l};
49
63
  }
50
64
  .llp-textarea { min-height: 80px; resize: vertical; }
51
65
  .llp-input:focus, .llp-textarea:focus, .llp-select:focus {
@@ -53,7 +67,7 @@
53
67
  }
54
68
  .llp-btn-submit {
55
69
  width: 100%; padding: 10px; background: ${t}; color: #fff;
56
- border: none; border-radius: ${i}px; font-size: 14px; font-weight: 600;
70
+ border: none; border-radius: ${s}px; font-size: 14px; font-weight: 600;
57
71
  cursor: pointer; transition: opacity .15s;
58
72
  }
59
73
  .llp-btn-submit:hover { opacity: .85; }
@@ -64,25 +78,25 @@
64
78
  .llp-success h3 { margin: 12px 0 6px; font-size: 15px; color: ${n}; }
65
79
  .llp-success p { margin: 0; color: #71717a; font-size: 13px; line-height: 1.5; }
66
80
  .llp-thread-item {
67
- padding: 10px 12px; border: 1px solid ${m?"#333":"#e4e4e7"}; border-radius: ${i}px;
81
+ padding: 10px 12px; border: 1px solid ${u?"#333":"#e4e4e7"}; border-radius: ${s}px;
68
82
  margin-bottom: 8px; cursor: pointer; display: block; color: inherit;
69
83
  transition: background .1s; background: none;
70
84
  }
71
- .llp-thread-item:hover { background: ${m?"#252525":"#f4f4f5"}; }
85
+ .llp-thread-item:hover { background: ${u?"#252525":"#f4f4f5"}; }
72
86
  .llp-thread-label { font-size: 12px; color: #71717a; margin-bottom: 2px; }
73
87
  .llp-thread-text { font-size: 13px; color: ${n}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
74
88
  .llp-thread-meta { font-size: 11px; color: #a1a1aa; margin-top: 3px; }
75
89
  .llp-badge { display: inline-block; padding: 1px 6px; border-radius: 9999px; font-size: 10px; font-weight: 600; }
76
90
  .llp-badge-open { background: #d1fae5; color: #065f46; }
77
91
  .llp-badge-replied { background: #dbeafe; color: #1e40af; }
78
- .llp-new-msg { margin-top: 12px; padding-top: 12px; border-top: 1px solid ${m?"#333":"#e4e4e7"}; }
92
+ .llp-new-msg { margin-top: 12px; padding-top: 12px; border-top: 1px solid ${u?"#333":"#e4e4e7"}; }
79
93
  .llp-new-msg button {
80
- width: 100%; padding: 8px; background: none; border: 1px solid ${m?"#444":"#d4d4d8"};
81
- border-radius: ${i}px; font-size: 13px; cursor: pointer; color: ${m?"#999":"#52525b"};
94
+ width: 100%; padding: 8px; background: none; border: 1px solid ${u?"#444":"#d4d4d8"};
95
+ border-radius: ${s}px; font-size: 13px; cursor: pointer; color: ${u?"#999":"#52525b"};
82
96
  }
83
- .llp-new-msg button:hover { background: ${m?"#252525":"#f4f4f5"}; }
97
+ .llp-new-msg button:hover { background: ${u?"#252525":"#f4f4f5"}; }
84
98
  .llp-footer {
85
- padding: 6px 16px; text-align: center; border-top: 1px solid ${m?"#333":"#f0f0f0"};
99
+ padding: 6px 16px; text-align: center; border-top: 1px solid ${u?"#333":"#f0f0f0"};
86
100
  }
87
101
  .llp-footer a {
88
102
  font-size: 10px; color: #a1a1aa; text-decoration: none; font-weight: 500;
@@ -101,12 +115,12 @@
101
115
  max-height: 320px; overflow-y: auto;
102
116
  }
103
117
  .llp-chat-bubble {
104
- padding: 8px 12px; border-radius: ${Math.max(i,8)}px; font-size: 13px;
118
+ padding: 8px 12px; border-radius: ${Math.max(s,8)}px; font-size: 13px;
105
119
  line-height: 1.45; max-width: 85%; word-wrap: break-word;
106
120
  white-space: pre-wrap;
107
121
  }
108
122
  .llp-chat-inbound {
109
- background: ${m?"#252525":"#f4f4f5"}; color: ${n}; align-self: flex-start;
123
+ background: ${u?"#252525":"#f4f4f5"}; color: ${n}; align-self: flex-start;
110
124
  border-bottom-left-radius: 4px;
111
125
  }
112
126
  .llp-chat-outbound {
@@ -118,25 +132,25 @@
118
132
  }
119
133
  .llp-chat-time-right { text-align: right; }
120
134
  .llp-chat-reply {
121
- display: flex; gap: 8px; border-top: 1px solid ${m?"#333":"#e4e4e7"}; padding-top: 12px;
135
+ display: flex; gap: 8px; border-top: 1px solid ${u?"#333":"#e4e4e7"}; padding-top: 12px;
122
136
  }
123
137
  .llp-chat-reply-input {
124
- flex: 1; padding: 8px 10px; border: 1px solid ${m?"#444":"#d4d4d8"}; border-radius: ${i}px;
125
- font-size: 13px; font-family: inherit; color: ${n}; background: ${m?"#222":o};
138
+ flex: 1; padding: 8px 10px; border: 1px solid ${u?"#444":"#d4d4d8"}; border-radius: ${s}px;
139
+ font-size: 13px; font-family: inherit; color: ${n}; background: ${u?"#222":l};
126
140
  resize: none; min-height: 36px; max-height: 80px; box-sizing: border-box;
127
141
  }
128
142
  .llp-chat-reply-input:focus { outline: none; border-color: ${t}; }
129
143
  .llp-chat-send {
130
144
  padding: 8px 14px; background: ${t}; color: #fff; border: none;
131
- border-radius: ${i}px; font-size: 13px; font-weight: 600; cursor: pointer;
145
+ border-radius: ${s}px; font-size: 13px; font-weight: 600; cursor: pointer;
132
146
  transition: opacity .15s; white-space: nowrap; align-self: flex-end;
133
147
  }
134
148
  .llp-chat-send:hover { opacity: .85; }
135
149
  .llp-chat-send:disabled { opacity: .5; cursor: not-allowed; }
136
- `}function a(e,t={},n=[]){let o=document.createElement(e);for(let[l,s]of Object.entries(t))l==="class"?o.className=s:l==="style"?o.setAttribute("style",s):l.startsWith("on")&&typeof s=="function"?o.addEventListener(l.slice(2),s):o.setAttribute(l,String(s));for(let l of n)o.appendChild(typeof l=="string"?document.createTextNode(l):l);return o}function j(e,t,n=""){let o=document.createElement("input");return o.type=e,o.id=t,o.placeholder=n,o.className="llp-input",o}function le(e,t=""){let n=document.createElement("textarea");return n.id=e,n.placeholder=t,n.className="llp-textarea",n}function ae(e,t){let n=document.createElement("select");n.id=e,n.className="llp-select";for(let o of t){let l=document.createElement("option");l.value=o.value,l.textContent=o.label,n.appendChild(l)}return n}function v(){if(!y)return;let e=y.querySelector(".llp-body");e.innerHTML="",b==="contact"?oe(e):b==="privacy"?ie(e):b==="threads"?re(e):b==="thread-detail"&&ce(e),M&&(M.style.display=b==="thread-detail"?"none":"flex")}function oe(e,t=""){let n=!!(E&&f),o=a("label",{class:"llp-label"},["Name"]),l=j("text","llp-name","Jane Smith");E&&(l.value=E);let s=a("label",{class:"llp-label"},["Email"]),d=j("email","llp-email","jane@example.com");(t||f)&&(d.value=t||f);let u=a("label",{class:"llp-label"},["Message"]),i=le("llp-message","How can we help?"),c=a("div",{class:"llp-error",style:"display:none"}),r=a("button",{class:"llp-btn-submit"},["Send message"]);r.onclick=async()=>{let g=l.value.trim(),h=d.value.trim(),w=i.value.trim();if(c.style.display="none",!g||!h||!w){c.textContent="Please fill in all fields.",c.style.display="block";return}r.disabled=!0,r.textContent="Sending\u2026";try{let T=await P("/api/contact",{api_key:L,name:g,email:h,message:w});if(T.ok)f=h,localStorage.setItem("heedb_email",h),I(),O(e,"Message sent!","We'll get back to you soon. Check your inbox for a confirmation email.");else{let me=await T.json();c.textContent=me.error||"Something went wrong.",c.style.display="block",r.disabled=!1,r.textContent="Send message"}}catch(T){c.textContent="Network error. Please try again.",c.style.display="block",r.disabled=!1,r.textContent="Send message"}},n?e.append(u,i,c,r):e.append(o,l,s,d,u,i,c,r)}function ie(e){let t=!!(E&&f),n=a("label",{class:"llp-label"},["Name"]),o=j("text","llp-priv-name","Jane Smith");E&&(o.value=E);let l=a("label",{class:"llp-label"},["Email"]),s=j("email","llp-priv-email","jane@example.com");f&&(s.value=f);let d=a("label",{class:"llp-label"},["Request type"]),u=ae("llp-priv-type",[{value:"deletion",label:"Delete my data"},{value:"access",label:"Access my data"},{value:"portability",label:"Export my data"},{value:"correction",label:"Correct my data"},{value:"restriction",label:"Restrict processing"},{value:"objection",label:"Object to processing"},{value:"other",label:"Other"}]),i=a("div",{class:"llp-error",style:"display:none"}),c=a("button",{class:"llp-btn-submit"},["Submit request"]);c.onclick=async()=>{let r=o.value.trim(),g=s.value.trim(),h=u.value;if(i.style.display="none",!r||!g){i.textContent="Please fill in all fields.",i.style.display="block";return}c.disabled=!0,c.textContent="Submitting\u2026";try{let w=await P("/api/privacy-request",{api_key:L,name:r,email:g,request_type:h});if(w.ok)f=g,localStorage.setItem("heedb_email",g),I(),O(e,"Request submitted!","Your privacy request has been received. We'll respond within 30 days.");else{let T=await w.json();i.textContent=T.error||"Something went wrong.",i.style.display="block",c.disabled=!1,c.textContent="Submit request"}}catch(w){i.textContent="Network error. Please try again.",i.style.display="block",c.disabled=!1,c.textContent="Submit request"}},t?e.append(d,u,i,c):e.append(n,o,l,s,d,u,i,c)}async function re(e){var t;if(!x){e.innerHTML="";let n=a("p",{style:"color:#71717a;text-align:center;margin:8px 0;font-size:13px;line-height:1.5"},["Send a message below to view your message history."]),o=a("div",{class:"llp-new-msg"}),l=a("button",{},["+ Send a message"]);l.onclick=()=>{b="contact",$("contact"),v()},o.appendChild(l),e.append(n,o);return}e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';try{let{threads:n}=await Z(f);if(e.innerHTML="",n.length===0){let s=a("p",{style:"color:#71717a;text-align:center;margin:8px 0"},["No open messages yet."]);e.appendChild(s)}else for(let s of n){let d=a("span",{class:`llp-badge llp-badge-${s.status}`},[s.status]),u=a("div",{class:"llp-thread-label"},[s.type==="privacy"?"Privacy request":"Message"," \u2022 "]);u.appendChild(d);let i=a("div",{class:"llp-thread-text"},[(t=s.preview)!=null?t:""]),c=new Date(s.createdAt).toLocaleDateString(),r=a("div",{class:"llp-thread-meta"},[c]),g=a("div",{class:"llp-thread-item"});g.append(u,i,r),g.onclick=()=>se(s.id),e.appendChild(g)}let o=a("div",{class:"llp-new-msg"}),l=a("button",{},["+ Send a new message"]);l.onclick=()=>{b="contact",$("contact"),v()},o.appendChild(l),e.appendChild(o)}catch(n){e.innerHTML='<p style="color:#ef4444;text-align:center">Failed to load messages.</p>'}}function se(e){A=e,b="thread-detail",v()}async function ce(e){e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';let t=a("button",{class:"llp-chat-back"},["\u2190 Back to messages"]);t.onclick=()=>{b="threads",$("threads"),v()};try{let o=(await ee(A)).messages||[];e.innerHTML="",e.style.padding="12px",e.appendChild(t);let l=a("div",{class:"llp-chat-messages"});for(let r of o){let g=r.direction==="inbound",h=a("div",{style:`display:flex;flex-direction:column;${g?"align-items:flex-start":"align-items:flex-end"}`}),w=a("div",{class:`llp-chat-bubble ${g?"llp-chat-inbound":"llp-chat-outbound"}`},[de(r.body)]),T=a("div",{class:`llp-chat-time ${g?"":"llp-chat-time-right"}`},[pe(r.createdAt)]);h.append(w,T),l.appendChild(h)}e.appendChild(l),requestAnimationFrame(()=>{l.scrollTop=l.scrollHeight});let s=a("div",{class:"llp-chat-reply"}),d=document.createElement("textarea");d.className="llp-chat-reply-input",d.placeholder="Type a reply\u2026",d.rows=1,d.addEventListener("input",()=>{d.style.height="auto",d.style.height=Math.min(d.scrollHeight,80)+"px"});let u=a("button",{class:"llp-chat-send"},["Send"]),i=a("div",{class:"llp-error",style:"display:none;margin-top:4px"});async function c(){let r=d.value.trim();if(r){u.disabled=!0,u.textContent="\u2026",i.style.display="none";try{let g=await te(A,r);if(g.ok){let h=a("div",{style:"display:flex;flex-direction:column;align-items:flex-start"}),w=a("div",{class:"llp-chat-bubble llp-chat-inbound"},[r]),T=a("div",{class:"llp-chat-time"},["Just now"]);h.append(w,T),l.appendChild(h),l.scrollTop=l.scrollHeight,d.value="",d.style.height="auto"}else{let h=await g.json();i.textContent=h.error||"Failed to send.",i.style.display="block"}}catch(g){i.textContent="Network error. Please try again.",i.style.display="block"}u.disabled=!1,u.textContent="Send"}}u.onclick=c,d.addEventListener("keydown",r=>{r.key==="Enter"&&!r.shiftKey&&(r.preventDefault(),c())}),s.append(d,u),e.append(s,i),requestAnimationFrame(()=>d.focus())}catch(n){e.innerHTML="",e.appendChild(t),e.appendChild(a("p",{style:"color:#ef4444;text-align:center"},["Failed to load conversation."]))}}function de(e){let t=e.split(`
137
- `),n=[];for(let o of t){let l=o.trim();if(/^(On|Em|El|Le|Am|Il giorno) .+(<[^>]+@[^>]+>).*(wrote|escreveu|escribi|crit|schrieb|scritto)\s?:$/i.test(l)||/<[^>]+@[^>]+>/.test(l)&&l.endsWith(":")||/^-{3,}$/.test(l))break;/^>{1,}\s/.test(l)||n.push(o)}return n.join(`
138
- `).trim()}function pe(e){let t=new Date(e),o=new Date().getTime()-t.getTime(),l=Math.floor(o/6e4);if(l<1)return"Just now";if(l<60)return`${l}m ago`;let s=Math.floor(l/60);return s<24?`${s}h ago`:t.toLocaleDateString()}function O(e,t,n){e.innerHTML="";let o=a("div",{class:"llp-success"});o.innerHTML=`
150
+ `}function a(e,t={},n=[]){let l=document.createElement(e);for(let[o,r]of Object.entries(t))o==="class"?l.className=r:o==="style"?l.setAttribute("style",r):o.startsWith("on")&&typeof r=="function"?l.addEventListener(o.slice(2),r):l.setAttribute(o,String(r));for(let o of n)l.appendChild(typeof o=="string"?document.createTextNode(o):o);return l}function P(e,t,n=""){let l=document.createElement("input");return l.type=e,l.id=t,l.placeholder=n,l.className="llp-input",l}function ae(e,t=""){let n=document.createElement("textarea");return n.id=e,n.placeholder=t,n.className="llp-textarea",n}function oe(e,t){let n=document.createElement("select");n.id=e,n.className="llp-select";for(let l of t){let o=document.createElement("option");o.value=l.value,o.textContent=l.label,n.appendChild(o)}return n}function k(){if(!v)return;let e=v.querySelector(".llp-body");e.innerHTML="",h==="contact"?le(e):h==="privacy"?ie(e):h==="threads"?re(e):h==="thread-detail"&&ce(e),M&&(M.style.display=h==="thread-detail"?"none":"flex")}function le(e,t=""){let n=!!(C&&b),l=a("label",{class:"llp-label"},["Name"]),o=P("text","llp-name","Jane Smith");C&&(o.value=C);let r=a("label",{class:"llp-label"},["Email"]),c=P("email","llp-email","jane@example.com");(t||b)&&(c.value=t||b);let m=a("label",{class:"llp-label"},["Message"]),d=ae("llp-message","How can we help?"),s=a("div",{class:"llp-error",style:"display:none"}),i=a("button",{class:"llp-btn-submit"},["Send message"]);i.onclick=async()=>{let g=o.value.trim(),f=c.value.trim(),x=d.value.trim();if(s.style.display="none",!g||!f||!x){s.textContent="Please fill in all fields.",s.style.display="block";return}i.disabled=!0,i.textContent="Sending\u2026";try{let T=await D("/api/contact",{api_key:E,name:g,email:f,message:x});if(T.ok)b=f,localStorage.setItem("heedb_email",f),z(),q(e,"Message sent!","We'll get back to you soon. Check your inbox for a confirmation email.");else{let me=await T.json();s.textContent=me.error||"Something went wrong.",s.style.display="block",i.disabled=!1,i.textContent="Send message"}}catch(T){s.textContent="Network error. Please try again.",s.style.display="block",i.disabled=!1,i.textContent="Send message"}},n?e.append(m,d,s,i):e.append(l,o,r,c,m,d,s,i)}function ie(e){let t=!!(C&&b),n=a("label",{class:"llp-label"},["Name"]),l=P("text","llp-priv-name","Jane Smith");C&&(l.value=C);let o=a("label",{class:"llp-label"},["Email"]),r=P("email","llp-priv-email","jane@example.com");b&&(r.value=b);let c=a("label",{class:"llp-label"},["Request type"]),m=oe("llp-priv-type",[{value:"deletion",label:"Delete my data"},{value:"access",label:"Access my data"},{value:"portability",label:"Export my data"},{value:"correction",label:"Correct my data"},{value:"restriction",label:"Restrict processing"},{value:"objection",label:"Object to processing"},{value:"other",label:"Other"}]),d=a("div",{class:"llp-error",style:"display:none"}),s=a("button",{class:"llp-btn-submit"},["Submit request"]);s.onclick=async()=>{let i=l.value.trim(),g=r.value.trim(),f=m.value;if(d.style.display="none",!i||!g){d.textContent="Please fill in all fields.",d.style.display="block";return}s.disabled=!0,s.textContent="Submitting\u2026";try{let x=await D("/api/privacy-request",{api_key:E,name:i,email:g,request_type:f});if(x.ok)b=g,localStorage.setItem("heedb_email",g),z(),q(e,"Request submitted!","Your privacy request has been received. We'll respond within 30 days.");else{let T=await x.json();d.textContent=T.error||"Something went wrong.",d.style.display="block",s.disabled=!1,s.textContent="Submit request"}}catch(x){d.textContent="Network error. Please try again.",d.style.display="block",s.disabled=!1,s.textContent="Submit request"}},t?e.append(c,m,d,s):e.append(n,l,o,r,c,m,d,s)}async function re(e){var t;if(!y){e.innerHTML="";let n=a("p",{style:"color:#71717a;text-align:center;margin:8px 0;font-size:13px;line-height:1.5"},["Send a message below to view your message history."]),l=a("div",{class:"llp-new-msg"}),o=a("button",{},["+ Send a message"]);o.onclick=()=>{h="contact",$("contact"),k()},l.appendChild(o),e.append(n,l);return}e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';try{let{threads:n}=await Z(b);if(e.innerHTML="",n.length===0){let r=a("p",{style:"color:#71717a;text-align:center;margin:8px 0"},["No open messages yet."]);e.appendChild(r)}else for(let r of n){let c=a("span",{class:`llp-badge llp-badge-${r.status}`},[r.status]),m=a("div",{class:"llp-thread-label"},[r.type==="privacy"?"Privacy request":"Message"," \u2022 "]);m.appendChild(c);let d=a("div",{class:"llp-thread-text"},[(t=r.preview)!=null?t:""]),s=new Date(r.createdAt).toLocaleDateString(),i=a("div",{class:"llp-thread-meta"},[s]),g=a("div",{class:"llp-thread-item"});g.append(m,d,i),g.onclick=()=>se(r.id),e.appendChild(g)}let l=a("div",{class:"llp-new-msg"}),o=a("button",{},["+ Send a new message"]);o.onclick=()=>{h="contact",$("contact"),k()},l.appendChild(o),e.appendChild(l)}catch(n){e.innerHTML='<p style="color:#ef4444;text-align:center">Failed to load messages.</p>'}}function se(e){A=e,h="thread-detail",k()}async function ce(e){e.innerHTML='<p style="color:#71717a;text-align:center">Loading\u2026</p>';let t=a("button",{class:"llp-chat-back"},["\u2190 Back to messages"]);t.onclick=()=>{h="threads",$("threads"),k()};try{let l=(await ee(A)).messages||[];e.innerHTML="",e.style.padding="12px",e.appendChild(t);let o=a("div",{class:"llp-chat-messages"});for(let i of l){let g=i.direction==="inbound",f=a("div",{style:`display:flex;flex-direction:column;${g?"align-items:flex-start":"align-items:flex-end"}`}),x=a("div",{class:`llp-chat-bubble ${g?"llp-chat-inbound":"llp-chat-outbound"}`},[de(i.body)]),T=a("div",{class:`llp-chat-time ${g?"":"llp-chat-time-right"}`},[pe(i.createdAt)]);f.append(x,T),o.appendChild(f)}e.appendChild(o),requestAnimationFrame(()=>{o.scrollTop=o.scrollHeight});let r=a("div",{class:"llp-chat-reply"}),c=document.createElement("textarea");c.className="llp-chat-reply-input",c.placeholder="Type a reply\u2026",c.rows=1,c.addEventListener("input",()=>{c.style.height="auto",c.style.height=Math.min(c.scrollHeight,80)+"px"});let m=a("button",{class:"llp-chat-send"},["Send"]),d=a("div",{class:"llp-error",style:"display:none;margin-top:4px"});async function s(){let i=c.value.trim();if(i){m.disabled=!0,m.textContent="\u2026",d.style.display="none";try{let g=await te(A,i);if(g.ok){let f=a("div",{style:"display:flex;flex-direction:column;align-items:flex-start"}),x=a("div",{class:"llp-chat-bubble llp-chat-inbound"},[i]),T=a("div",{class:"llp-chat-time"},["Just now"]);f.append(x,T),o.appendChild(f),o.scrollTop=o.scrollHeight,c.value="",c.style.height="auto"}else{let f=await g.json();d.textContent=f.error||"Failed to send.",d.style.display="block"}}catch(g){d.textContent="Network error. Please try again.",d.style.display="block"}m.disabled=!1,m.textContent="Send"}}m.onclick=s,c.addEventListener("keydown",i=>{i.key==="Enter"&&!i.shiftKey&&(i.preventDefault(),s())}),r.append(c,m),e.append(r,d),requestAnimationFrame(()=>c.focus())}catch(n){e.innerHTML="",e.appendChild(t),e.appendChild(a("p",{style:"color:#ef4444;text-align:center"},["Failed to load conversation."]))}}function de(e){let t=e.split(`
151
+ `),n=[];for(let l of t){let o=l.trim();if(/^(On|Em|El|Le|Am|Il giorno) .+(<[^>]+@[^>]+>).*(wrote|escreveu|escribi|crit|schrieb|scritto)\s?:$/i.test(o)||/<[^>]+@[^>]+>/.test(o)&&o.endsWith(":")||/^-{3,}$/.test(o))break;/^>{1,}\s/.test(o)||n.push(l)}return n.join(`
152
+ `).trim()}function pe(e){let t=new Date(e),l=new Date().getTime()-t.getTime(),o=Math.floor(l/6e4);if(o<1)return"Just now";if(o<60)return`${o}m ago`;let r=Math.floor(o/60);return r<24?`${r}h ago`:t.toLocaleDateString()}function q(e,t,n){e.innerHTML="";let l=a("div",{class:"llp-success"});l.innerHTML=`
139
153
  <div class="llp-success-icon">\u2705</div>
140
154
  <h3>${t}</h3>
141
155
  <p>${n}</p>
142
- `,e.appendChild(o)}let M=null,z=null;function $(e){b=e,M&&M.querySelectorAll(".llp-tab").forEach(t=>{t.classList.toggle("active",t.dataset.mode===e)})}function I(){z&&(z.style.display=f&&x?"":"none")}let B=null;function ge(){m=q(),B&&(B.textContent=R())}async function F(){p=await ne(),m=q(),B=document.createElement("style"),B.textContent=R(),document.head.appendChild(B),p.mode==="system"&&window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{ge(),C&&y&&v()});let e=p.triggerIcon?p.triggerIcon:p.triggerEmoji||"\u{1F4AC}",t=p.triggerText||"";if(H=a("button",{class:"llp-btn",title:"Contact us","aria-label":"Open contact widget"}),p.triggerIcon){let r=a("span",{class:"llp-btn-icon"});r.innerHTML=p.triggerIcon,H.appendChild(r)}else H.appendChild(document.createTextNode(p.triggerEmoji||"\u{1F4AC}"));if(t&&H.appendChild(a("span",{class:"llp-btn-label"},[t])),H.onclick=D,document.body.appendChild(H),p.triggerMode==="embedded"&&p.triggerSelector){let r=document.querySelector(p.triggerSelector);r&&r.addEventListener("click",g=>{g.preventDefault(),D()})}y=a("div",{class:"llp-panel",style:"display:none"});let n=a("div",{class:"llp-header"}),o=a("h2",{},[p.headerTitle||"Contact us"]),l=a("button",{class:"llp-close","aria-label":"Close"},["\u2715"]);l.onclick=D,n.append(o,l),M=a("div",{class:"llp-tabs"});let s=a("button",{class:"llp-tab active","data-mode":"contact"},["Message"]),d=a("button",{class:"llp-tab","data-mode":"privacy"},["Privacy"]);z=a("button",{class:"llp-tab","data-mode":"threads"},["Messages"]),z.style.display=f&&x?"":"none",s.onclick=()=>{$("contact"),v()},d.onclick=()=>{$("privacy"),v()},z.onclick=()=>{$("threads"),v()},M.append(s,d,z);let u=a("div",{class:"llp-body"}),i=a("div",{class:"llp-footer"}),c=a("a",{href:"https://heedb.com",target:"_blank",rel:"noopener noreferrer"},["Powered by Heedb"]);i.appendChild(c),y.append(n,M,u,i),document.body.appendChild(y)}function D(){C=!C,y&&(y.style.display=C?"flex":"none",C&&(f&&x&&b!=="privacy"&&b!=="thread-detail"&&(b="threads",$("threads")),v()))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",F):F()})();})();
156
+ `,e.appendChild(l)}let M=null,_=null;function $(e){h=e,M&&M.querySelectorAll(".llp-tab").forEach(t=>{t.classList.toggle("active",t.dataset.mode===e)})}function z(){_&&(_.style.display=b&&y?"":"none")}let B=null;function ge(){u=R(),B&&(B.textContent=O())}async function F(){p=await ne(),u=R(),B=document.createElement("style"),B.textContent=O(),document.head.appendChild(B),p.mode==="system"&&window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{ge(),L&&v&&k()});let e=p.triggerIcon?p.triggerIcon:p.triggerEmoji||"\u{1F4AC}",t=p.triggerText||"";if(H=a("button",{class:"llp-btn",title:"Contact us","aria-label":"Open contact widget"}),p.triggerIcon){let i=a("span",{class:"llp-btn-icon"});i.innerHTML=p.triggerIcon,H.appendChild(i)}else H.appendChild(document.createTextNode(p.triggerEmoji||"\u{1F4AC}"));if(t&&H.appendChild(a("span",{class:"llp-btn-label"},[t])),H.onclick=j,document.body.appendChild(H),p.triggerMode==="embedded"&&p.triggerSelector){let i=document.querySelector(p.triggerSelector);i&&i.addEventListener("click",g=>{g.preventDefault(),j()})}if(p.triggerMode==="tag"){let i=a("button",{class:"llp-tag","aria-label":"Open contact widget"}),g=a("span",{class:"llp-tag-icon"},[p.triggerEmoji||"\u{1F4AC}"]);i.appendChild(g),i.appendChild(document.createTextNode(p.triggerText||"Feedback")),i.onclick=j,document.body.appendChild(i)}v=a("div",{class:"llp-panel",style:"display:none"});let n=a("div",{class:"llp-header"}),l=a("h2",{},[p.headerTitle||"Contact us"]),o=a("button",{class:"llp-close","aria-label":"Close"},["\u2715"]);o.onclick=j,n.append(l,o),M=a("div",{class:"llp-tabs"});let r=a("button",{class:"llp-tab active","data-mode":"contact"},["Message"]),c=a("button",{class:"llp-tab","data-mode":"privacy"},["Privacy"]);_=a("button",{class:"llp-tab","data-mode":"threads"},["Messages"]),_.style.display=b&&y?"":"none",r.onclick=()=>{$("contact"),k()},c.onclick=()=>{$("privacy"),k()},_.onclick=()=>{$("threads"),k()},M.append(r,c,_);let m=a("div",{class:"llp-body"}),d=a("div",{class:"llp-footer"}),s=a("a",{href:"https://heedb.com",target:"_blank",rel:"noopener noreferrer"},["Powered by Heedb"]);d.appendChild(s),v.append(n,M,m,d),document.body.appendChild(v)}function j(){L=!L,v&&(v.style.display=L?"flex":"none",L&&(b&&y&&h!=="privacy"&&h!=="thread-detail"&&(h="threads",$("threads")),k()))}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",F):F()})();})();