@spilki/widget 1.0.35 → 1.0.36

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/widget.es.js CHANGED
@@ -1,4 +1,4 @@
1
- const F = `
1
+ const Y = `
2
2
  <style>
3
3
  :host {
4
4
  all: initial;
@@ -12,6 +12,9 @@ const F = `
12
12
  :host([data-position="bottom-left"]) {
13
13
  left: 24px;
14
14
  }
15
+ :host([data-dimmed]) button {
16
+ opacity: 0.4;
17
+ }
15
18
  button {
16
19
  all: unset;
17
20
  position: relative;
@@ -25,7 +28,7 @@ const F = `
25
28
  background: var(--spilki-accent);
26
29
  color: #fff;
27
30
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
28
- transition: transform 0.18s ease, box-shadow 0.18s ease;
31
+ transition: transform 0.18s ease, box-shadow 0.18s ease, opacity 0.2s ease;
29
32
  }
30
33
  button:focus-visible {
31
34
  outline: 2px solid #fff;
@@ -71,13 +74,13 @@ const F = `
71
74
  <span class="badge" hidden aria-hidden="true">0</span>
72
75
  </button>
73
76
  `;
74
- function R(r) {
77
+ function G(o) {
75
78
  const e = document.createElement("div");
76
- e.setAttribute("part", "bubble-root"), e.setAttribute("data-position", r.position), e.style.setProperty("--spilki-accent", r.color);
79
+ e.setAttribute("part", "bubble-root"), e.setAttribute("data-position", o.position), e.style.setProperty("--spilki-accent", o.color);
77
80
  const t = e.attachShadow({ mode: "open" });
78
- t.innerHTML = F;
81
+ t.innerHTML = Y;
79
82
  const s = t.querySelector("button"), i = t.querySelector(".badge");
80
- return s.addEventListener("click", () => r.onClick()), {
83
+ return s.addEventListener("click", () => o.onClick()), {
81
84
  element: e,
82
85
  mount() {
83
86
  document.body.appendChild(e);
@@ -85,20 +88,29 @@ function R(r) {
85
88
  destroy() {
86
89
  e.remove();
87
90
  },
88
- setOpen(l) {
89
- s.setAttribute("aria-expanded", String(l)), s.setAttribute("aria-label", l ? "Close chat" : "Open chat");
91
+ setOpen(a) {
92
+ s.setAttribute("aria-expanded", String(a)), s.setAttribute("aria-label", a ? "Close chat" : "Open chat");
90
93
  },
91
- setBadge(l) {
92
- const n = Math.max(0, l), a = s.getAttribute("aria-expanded") === "true";
93
- if (n === 0) {
94
- i.toggleAttribute("hidden", !0), i.textContent = "0", a || s.setAttribute("aria-label", "Open chat");
94
+ setBadge(a) {
95
+ const r = Math.max(0, a), l = s.getAttribute("aria-expanded") === "true";
96
+ if (r === 0) {
97
+ i.toggleAttribute("hidden", !0), i.textContent = "0", l || s.setAttribute("aria-label", "Open chat");
95
98
  return;
96
99
  }
97
- i.toggleAttribute("hidden", !1), i.textContent = n > 99 ? "99+" : String(n), a || s.setAttribute("aria-label", `Open chat, ${n} unread`);
100
+ i.toggleAttribute("hidden", !1), i.textContent = r > 99 ? "99+" : String(r), l || s.setAttribute("aria-label", `Open chat, ${r} unread`);
101
+ },
102
+ setDimmed(a) {
103
+ e.toggleAttribute("data-dimmed", a);
104
+ },
105
+ setPassthrough(a) {
106
+ e.style.pointerEvents = a ? "none" : "";
107
+ },
108
+ setPosition(a) {
109
+ e.setAttribute("data-position", a);
98
110
  }
99
111
  };
100
112
  }
101
- const K = "https://api.spilki.app", I = {
113
+ const V = "https://api.spilki.app", M = {
102
114
  welcome: "Hi! I'm your assistant.",
103
115
  placeholder: "Type a message…",
104
116
  sendLabel: "Send",
@@ -109,57 +121,57 @@ const K = "https://api.spilki.app", I = {
109
121
  offline: "Unable to connect. Please try again later.",
110
122
  title: "Spilki Assistant"
111
123
  }, w = {
112
- apiBase: K,
124
+ apiBase: V,
113
125
  position: "bottom-right",
114
126
  theme: "auto",
115
127
  color: "#6366f1",
116
- welcome: I.welcome,
128
+ welcome: M.welcome,
117
129
  persist: !0,
118
130
  sound: !0,
119
- i18n: I
131
+ i18n: M
120
132
  };
121
- function H(r) {
122
- var t, s, i, o, l, n, a, g;
123
- const e = { ...I, ...(t = r.i18n) != null ? t : {} };
133
+ function J(o) {
134
+ var t, s, i, n, a, r, l, p;
135
+ const e = { ...M, ...(t = o.i18n) != null ? t : {} };
124
136
  return {
125
137
  ...w,
126
- ...r,
127
- apiBase: (s = r.apiBase) != null ? s : w.apiBase,
138
+ ...o,
139
+ apiBase: (s = o.apiBase) != null ? s : w.apiBase,
128
140
  i18n: e,
129
- welcome: (i = r.welcome) != null ? i : e.welcome,
130
- position: (o = r.position) != null ? o : w.position,
131
- theme: (l = r.theme) != null ? l : w.theme,
132
- color: (n = r.color) != null ? n : w.color,
133
- persist: (a = r.persist) != null ? a : w.persist,
134
- sound: (g = r.sound) != null ? g : w.sound
141
+ welcome: (i = o.welcome) != null ? i : e.welcome,
142
+ position: (n = o.position) != null ? n : w.position,
143
+ theme: (a = o.theme) != null ? a : w.theme,
144
+ color: (r = o.color) != null ? r : w.color,
145
+ persist: (l = o.persist) != null ? l : w.persist,
146
+ sound: (p = o.sound) != null ? p : w.sound
135
147
  };
136
148
  }
137
- function z(r = "msg") {
138
- return typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${r}-${Math.random().toString(16).slice(2)}`;
149
+ function X(o = "msg") {
150
+ return typeof crypto != "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${o}-${Math.random().toString(16).slice(2)}`;
139
151
  }
140
- function _() {
141
- var r, e;
142
- return (e = (r = window.matchMedia) == null ? void 0 : r.call(window, "(prefers-color-scheme: dark)").matches) != null ? e : !1;
152
+ function Z() {
153
+ var o, e;
154
+ return (e = (o = window.matchMedia) == null ? void 0 : o.call(window, "(prefers-color-scheme: dark)").matches) != null ? e : !1;
143
155
  }
144
- function P(r) {
145
- return r === "light" || r === "dark" ? r : _() ? "dark" : "light";
156
+ function R(o) {
157
+ return o === "light" || o === "dark" ? o : Z() ? "dark" : "light";
146
158
  }
147
- function S(r, e = 30) {
148
- return r.slice(-e);
159
+ function A(o, e = 30) {
160
+ return o.slice(-e);
149
161
  }
150
- function q(r) {
151
- if (!r || r.length === 0) return;
162
+ function Q(o) {
163
+ if (!o || o.length === 0) return;
152
164
  const e = window.location.origin;
153
- r.includes(e) || console.warn(
154
- `SpilkiWidget: current origin ${e} not in allowedOriginsHint: ${r.join(", ")}`
165
+ o.includes(e) || console.warn(
166
+ `SpilkiWidget: current origin ${e} not in allowedOriginsHint: ${o.join(", ")}`
155
167
  );
156
168
  }
157
- const G = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
158
- function V(r) {
159
- const e = new Date(r), t = /* @__PURE__ */ new Date(), s = (a) => String(a).padStart(2, "0"), i = `${s(e.getHours())}:${s(e.getMinutes())}`, o = new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime(), l = o - 864e5, n = new Date(e.getFullYear(), e.getMonth(), e.getDate()).getTime();
160
- return n === o ? `Today at ${i}` : n === l ? `Yesterday at ${i}` : `${G[e.getMonth()]} ${e.getDate()}, ${i}`;
169
+ const ee = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
170
+ function te(o) {
171
+ const e = new Date(o), t = /* @__PURE__ */ new Date(), s = (l) => String(l).padStart(2, "0"), i = `${s(e.getHours())}:${s(e.getMinutes())}`, n = new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime(), a = n - 864e5, r = new Date(e.getFullYear(), e.getMonth(), e.getDate()).getTime();
172
+ return r === n ? `Today at ${i}` : r === a ? `Yesterday at ${i}` : `${ee[e.getMonth()]} ${e.getDate()}, ${i}`;
161
173
  }
162
- const Y = ':host{--spilki-bg-light: #ffffff;--spilki-bg-dark: #0f172a;--spilki-text-light: #0f172a;--spilki-text-dark: #f8fafc;--spilki-border-light: rgba(15, 23, 42, .1);--spilki-border-dark: rgba(148, 163, 184, .25);--spilki-muted-light: #64748b;--spilki-muted-dark: #94a3b8;--spilki-shadow: 0 10px 40px rgba(15, 23, 42, .2);--spilki-radius: 16px;--spilki-font: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;color:inherit;font-family:var(--spilki-font)}.wrapper{position:relative;width:100%;height:100%;display:flex;flex-direction:column;background:var(--spilki-surface);color:var(--spilki-text);border-radius:var(--spilki-radius);box-shadow:var(--spilki-shadow);border:1px solid var(--spilki-border);overflow:hidden}header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--spilki-surface);border-bottom:1px solid var(--spilki-border)}header h1{font-size:1rem;margin:0;display:flex;align-items:center;gap:.5rem}header button.close{border:none;background:transparent;color:inherit;font-size:1.25rem;cursor:pointer}header button.close:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}header .status-dot{width:10px;height:10px;border-radius:999px;background:var(--spilki-accent)}.messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.75rem;scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent;scroll-behavior:smooth}.message{display:flex;flex-direction:column;gap:.15rem;max-width:85%;width:fit-content;line-height:1.4;word-wrap:break-word;overflow-wrap:anywhere;white-space:pre-wrap}.message.user{align-self:flex-end;align-items:flex-end}.message .bubble{padding:.6rem .8rem;border-radius:1rem;background:#6366f126}.message.user .bubble{background:var(--spilki-accent);color:#fff}.message.bot .bubble{background:#94a3b826}.msg-time{font-size:.7rem;color:var(--spilki-muted);margin-top:2px}.date-separator{display:flex;align-items:center;gap:.5rem;padding:.4rem 0;font-size:.72rem;color:var(--spilki-muted);white-space:nowrap}.date-separator:before,.date-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.scroll-bottom{position:absolute;right:1rem;bottom:88px;width:38px;height:38px;border:none;border-radius:999px;background:var(--spilki-accent);color:#fff;box-shadow:0 8px 20px #0f172a40;cursor:pointer;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .18s ease,transform .18s ease;z-index:3}.scroll-bottom.visible{opacity:1;pointer-events:auto;transform:translateY(0)}.scroll-arrow{font-size:.8rem;line-height:1}.scroll-count{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;border-radius:999px;background:#ef4444;color:#fff;font-size:10px;line-height:16px;text-align:center;padding:0 4px}.suggested-replies{display:flex;flex-wrap:wrap;gap:.4rem;padding:.5rem 1rem;border-top:1px solid var(--spilki-border)}.suggested-chip{border:1px solid var(--spilki-accent);background:transparent;color:var(--spilki-accent);border-radius:999px;padding:.35rem .75rem;font-size:.8rem;font-family:inherit;cursor:pointer;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:background .15s,color .15s}.suggested-chip:hover{background:var(--spilki-accent);color:#fff}.suggested-chip:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.input-area{padding:.5rem .75rem}.input-wrap{display:flex;align-items:center;border:1px solid var(--spilki-border);border-radius:1.5rem;background:transparent;padding-left:0}.input-area textarea{flex:1;resize:none;min-height:2.4rem;max-height:6rem;border:0;border-radius:0;outline:0;background:transparent;box-shadow:none;-webkit-box-shadow:none;-webkit-appearance:none;appearance:none;padding:.55rem 0 .55rem 1rem;font-family:inherit;font-size:.95rem;color:var(--spilki-text);scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent}.input-actions{display:flex;align-items:center;gap:.25rem;padding:.25rem .35rem;flex-shrink:0}.input-actions button{width:32px;height:32px;display:grid;place-items:center;border:none;border-radius:50%;cursor:pointer;padding:0;transition:opacity .15s}.emoji-btn{background:#6366f126;color:var(--spilki-accent)}.emoji-btn:hover{background:#6366f140}.emoji-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:1px}.send-btn{background:var(--spilki-accent);color:#fff}.send-btn:hover{opacity:.85}.send-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.emoji-picker{position:absolute;right:1rem;bottom:80px;width:240px;max-height:180px;overflow-y:auto;display:none;grid-template-columns:repeat(10,minmax(0,1fr));gap:.25rem;padding:.5rem;background:var(--spilki-surface);border:1px solid var(--spilki-border);border-radius:12px;box-shadow:0 14px 30px #0f172a40;z-index:4}.emoji-option{width:100%;aspect-ratio:1;border:none;border-radius:8px;background:transparent;font-size:1rem;cursor:pointer}.emoji-option:hover,.emoji-option:focus-visible{background:#94a3b833}.typing{font-size:.75rem;color:var(--spilki-muted);padding:0 1rem .75rem}.typing:after{content:"";animation:dots 1.2s steps(4,end) infinite}@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}.offline{font-size:.8rem;padding:0 1rem;color:#f97316}:host([data-theme="dark"]){--spilki-surface: var(--spilki-bg-dark);--spilki-text: var(--spilki-text-dark);--spilki-border: var(--spilki-border-dark);--spilki-muted: var(--spilki-muted-dark)}:host([data-theme="dark"]) .messages,:host([data-theme="dark"]) .input-area textarea,:host([data-theme="dark"]) .emoji-picker{scrollbar-color:rgba(255,255,255,.2) transparent}:host([data-theme="light"]){--spilki-surface: var(--spilki-bg-light);--spilki-text: var(--spilki-text-light);--spilki-border: var(--spilki-border-light);--spilki-muted: var(--spilki-muted-light)}:host([data-theme="dark"]) .message .bubble{background:#94a3b81f}:host([data-theme="dark"]) .message.bot .bubble{background:#6366f126}:host([data-theme="dark"]) .input-area textarea{background:transparent}.messages::-webkit-scrollbar,.input-area textarea::-webkit-scrollbar,.emoji-picker::-webkit-scrollbar{width:6px}.messages::-webkit-scrollbar-track,.input-area textarea::-webkit-scrollbar-track,.emoji-picker::-webkit-scrollbar-track{background:transparent}.messages::-webkit-scrollbar-thumb,.input-area textarea::-webkit-scrollbar-thumb,.emoji-picker::-webkit-scrollbar-thumb{background:#94a3b84d;border-radius:999px}.messages::-webkit-scrollbar-thumb:hover,.input-area textarea::-webkit-scrollbar-thumb:hover,.emoji-picker::-webkit-scrollbar-thumb:hover{background:#94a3b880}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .emoji-picker::-webkit-scrollbar-thumb{background:#fff3}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb:hover,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb:hover,:host([data-theme="dark"]) .emoji-picker::-webkit-scrollbar-thumb:hover{background:#ffffff59}.conversation-separator{display:flex;align-items:center;gap:.5rem;padding:.5rem 0;cursor:pointer;user-select:none;font-size:.7rem;color:var(--spilki-muted);white-space:nowrap}.conversation-separator:before,.conversation-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.conversation-separator:hover{color:var(--spilki-text)}.conversation-separator:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}.conversation-history{display:none;flex-direction:column;gap:.5rem}.conversation-history.expanded{display:flex}', D = 24 * 60 * 60 * 1e3, J = 2 * 60 * 1e3, X = 200, Z = [
174
+ const se = ':host{--spilki-bg-light: #ffffff;--spilki-bg-dark: #0f172a;--spilki-text-light: #0f172a;--spilki-text-dark: #f8fafc;--spilki-border-light: rgba(15, 23, 42, .1);--spilki-border-dark: rgba(148, 163, 184, .25);--spilki-muted-light: #64748b;--spilki-muted-dark: #94a3b8;--spilki-shadow: 0 10px 40px rgba(15, 23, 42, .2);--spilki-radius: 16px;--spilki-font: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;color:inherit;font-family:var(--spilki-font)}.wrapper{position:relative;width:100%;height:100%;display:flex;flex-direction:column;background:var(--spilki-surface);color:var(--spilki-text);border-radius:var(--spilki-radius);box-shadow:var(--spilki-shadow);border:1px solid var(--spilki-border);overflow:hidden}header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:var(--spilki-surface);border-bottom:1px solid var(--spilki-border)}header h1{font-size:1rem;margin:0;display:flex;align-items:center;gap:.5rem}header button.close{border:none;background:transparent;color:inherit;font-size:1.25rem;cursor:pointer}header button.close:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}header .status-dot{width:10px;height:10px;border-radius:999px;background:var(--spilki-accent)}.messages{flex:1;overflow-y:auto;padding:1rem;display:flex;flex-direction:column;gap:.75rem;scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent;scroll-behavior:smooth}.message{display:flex;flex-direction:column;gap:.15rem;max-width:85%;width:fit-content;line-height:1.4;word-wrap:break-word;overflow-wrap:anywhere;white-space:pre-wrap}.message.user{align-self:flex-end;align-items:flex-end}.message .bubble{padding:.6rem .8rem;border-radius:1rem;background:#6366f126}.message.user .bubble{background:var(--spilki-accent);color:#fff}.message.bot .bubble{background:#94a3b826}.msg-time{font-size:.7rem;color:var(--spilki-muted);margin-top:2px}.date-separator{display:flex;align-items:center;gap:.5rem;padding:.4rem 0;font-size:.72rem;color:var(--spilki-muted);white-space:nowrap}.date-separator:before,.date-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.scroll-bottom{position:absolute;right:1rem;bottom:88px;width:38px;height:38px;border:none;border-radius:999px;background:var(--spilki-accent);color:#fff;box-shadow:0 8px 20px #0f172a40;cursor:pointer;opacity:0;pointer-events:none;transform:translateY(4px);transition:opacity .18s ease,transform .18s ease;z-index:3}.scroll-bottom.visible{opacity:1;pointer-events:auto;transform:translateY(0)}.scroll-arrow{font-size:.8rem;line-height:1}.scroll-count{position:absolute;top:-5px;right:-5px;min-width:16px;height:16px;border-radius:999px;background:#ef4444;color:#fff;font-size:10px;line-height:16px;text-align:center;padding:0 4px}.suggested-replies{display:flex;flex-wrap:wrap;gap:.4rem;padding:.5rem 1rem;border-top:1px solid var(--spilki-border)}.suggested-chip{border:1px solid var(--spilki-accent);background:transparent;color:var(--spilki-accent);border-radius:999px;padding:.35rem .75rem;font-size:.8rem;font-family:inherit;cursor:pointer;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;transition:background .15s,color .15s}.suggested-chip:hover{background:var(--spilki-accent);color:#fff}.suggested-chip:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.input-area{padding:.5rem .75rem}.input-wrap{display:flex;align-items:center;border:1px solid var(--spilki-border);border-radius:1.5rem;background:transparent;padding-left:0}.input-area textarea{flex:1;resize:none;min-height:2.4rem;max-height:6rem;border:0;border-radius:0;outline:0;background:transparent;box-shadow:none;-webkit-box-shadow:none;-webkit-appearance:none;appearance:none;padding:.55rem 0 .55rem 1rem;font-family:inherit;font-size:.95rem;color:var(--spilki-text);scrollbar-width:thin;scrollbar-color:rgba(148,163,184,.3) transparent}.input-actions{display:flex;align-items:center;gap:.25rem;padding:.25rem .35rem;flex-shrink:0}.input-actions button{width:32px;height:32px;display:grid;place-items:center;border:none;border-radius:50%;cursor:pointer;padding:0;transition:opacity .15s}.emoji-btn{background:#6366f126;color:var(--spilki-accent)}.emoji-btn:hover{background:#6366f140}.emoji-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:1px}.send-btn{background:var(--spilki-accent);color:#fff}.send-btn:hover{opacity:.85}.send-btn:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px}.emoji-picker{position:absolute;right:1rem;bottom:80px;width:240px;max-height:180px;overflow-y:auto;display:none;grid-template-columns:repeat(10,minmax(0,1fr));gap:.25rem;padding:.5rem;background:var(--spilki-surface);border:1px solid var(--spilki-border);border-radius:12px;box-shadow:0 14px 30px #0f172a40;z-index:4}.emoji-option{width:100%;aspect-ratio:1;border:none;border-radius:8px;background:transparent;font-size:1rem;cursor:pointer}.emoji-option:hover,.emoji-option:focus-visible{background:#94a3b833}.typing{font-size:.75rem;color:var(--spilki-muted);padding:0 1rem .75rem}.typing:after{content:"";animation:dots 1.2s steps(4,end) infinite}@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}.offline{font-size:.8rem;padding:0 1rem;color:#f97316}:host([data-theme="dark"]){--spilki-surface: var(--spilki-bg-dark);--spilki-text: var(--spilki-text-dark);--spilki-border: var(--spilki-border-dark);--spilki-muted: var(--spilki-muted-dark)}:host([data-theme="dark"]) .messages,:host([data-theme="dark"]) .input-area textarea,:host([data-theme="dark"]) .emoji-picker{scrollbar-color:rgba(255,255,255,.2) transparent}:host([data-theme="light"]){--spilki-surface: var(--spilki-bg-light);--spilki-text: var(--spilki-text-light);--spilki-border: var(--spilki-border-light);--spilki-muted: var(--spilki-muted-light)}:host([data-theme="dark"]) .message .bubble{background:#94a3b81f}:host([data-theme="dark"]) .message.bot .bubble{background:#6366f126}:host([data-theme="dark"]) .input-area textarea{background:transparent}.messages::-webkit-scrollbar,.input-area textarea::-webkit-scrollbar,.emoji-picker::-webkit-scrollbar{width:6px}.messages::-webkit-scrollbar-track,.input-area textarea::-webkit-scrollbar-track,.emoji-picker::-webkit-scrollbar-track{background:transparent}.messages::-webkit-scrollbar-thumb,.input-area textarea::-webkit-scrollbar-thumb,.emoji-picker::-webkit-scrollbar-thumb{background:#94a3b84d;border-radius:999px}.messages::-webkit-scrollbar-thumb:hover,.input-area textarea::-webkit-scrollbar-thumb:hover,.emoji-picker::-webkit-scrollbar-thumb:hover{background:#94a3b880}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb,:host([data-theme="dark"]) .emoji-picker::-webkit-scrollbar-thumb{background:#fff3}:host([data-theme="dark"]) .messages::-webkit-scrollbar-thumb:hover,:host([data-theme="dark"]) .input-area textarea::-webkit-scrollbar-thumb:hover,:host([data-theme="dark"]) .emoji-picker::-webkit-scrollbar-thumb:hover{background:#ffffff59}.conversation-separator{display:flex;align-items:center;gap:.5rem;padding:.5rem 0;cursor:pointer;user-select:none;font-size:.7rem;color:var(--spilki-muted);white-space:nowrap}.conversation-separator:before,.conversation-separator:after{content:"";flex:1;height:1px;background:var(--spilki-border)}.conversation-separator:hover{color:var(--spilki-text)}.conversation-separator:focus-visible{outline:2px solid var(--spilki-accent);outline-offset:2px;border-radius:4px}.conversation-history{display:none;flex-direction:column;gap:.5rem}.conversation-history.expanded{display:flex}', $ = 24 * 60 * 60 * 1e3, ie = 2 * 60 * 1e3, oe = 200, ne = [
163
175
  "😀",
164
176
  "😂",
165
177
  "🤣",
@@ -211,10 +223,10 @@ const Y = ':host{--spilki-bg-light: #ffffff;--spilki-bg-dark: #0f172a;--spilki-t
211
223
  "☕",
212
224
  "🍕"
213
225
  ];
214
- function E(r) {
215
- return r.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
226
+ function S(o) {
227
+ return o.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
216
228
  }
217
- class Q {
229
+ class re {
218
230
  constructor(e) {
219
231
  this.options = e, this.relativeTimeFormat = new Intl.RelativeTimeFormat(void 0, {
220
232
  numeric: "auto"
@@ -229,9 +241,9 @@ class Q {
229
241
  day: "numeric",
230
242
  year: "numeric"
231
243
  }), this.renderedMessages = [], this.focusable = [], this.seenIds = /* @__PURE__ */ new Set(), this.lastTimelineMessage = null, this.scrollUnreadCount = 0, this.emojiPickerOpen = !1, this.open = !1, this.host = document.createElement("div"), this.host.setAttribute("part", "panel-root"), this.host.style.position = "fixed", this.host.style.bottom = "96px", this.host.style[e.position === "bottom-right" ? "right" : "left"] = "24px", this.host.style.width = "360px", this.host.style.maxWidth = "calc(100vw - 32px)", this.host.style.height = "520px", this.host.style.display = "none", this.host.style.zIndex = "2147483001", this.shadow = this.host.attachShadow({ mode: "open" });
232
- const t = E(e.i18n.title), s = E(e.i18n.typing), i = E(e.i18n.offline), o = E(e.i18n.placeholder), l = E(e.i18n.sendLabel);
244
+ const t = S(e.i18n.title), s = S(e.i18n.typing), i = S(e.i18n.offline), n = S(e.i18n.placeholder), a = S(e.i18n.sendLabel);
233
245
  this.shadow.innerHTML = `
234
- <style>${Y}</style>
246
+ <style>${se}</style>
235
247
  <div class="wrapper" role="dialog" aria-modal="true" aria-label="${t}">
236
248
  <header>
237
249
  <h1><span class="status-dot" aria-hidden="true"></span>${t}</h1>
@@ -248,7 +260,7 @@ class Q {
248
260
  <div class="emoji-picker" aria-label="Emoji picker"></div>
249
261
  <div class="input-area">
250
262
  <div class="input-wrap">
251
- <textarea rows="1" placeholder="${o}" aria-label="${o}"></textarea>
263
+ <textarea rows="1" placeholder="${n}" aria-label="${n}"></textarea>
252
264
  <div class="input-actions">
253
265
  <button class="emoji-btn" type="button" aria-label="Insert emoji">
254
266
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
@@ -258,7 +270,7 @@ class Q {
258
270
  <circle cx="15" cy="10" r="1" fill="currentColor"/>
259
271
  </svg>
260
272
  </button>
261
- <button type="button" class="send-btn" aria-label="${l}">
273
+ <button type="button" class="send-btn" aria-label="${a}">
262
274
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true">
263
275
  <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z" fill="currentColor"/>
264
276
  </svg>
@@ -267,36 +279,39 @@ class Q {
267
279
  </div>
268
280
  </div>
269
281
  </div>
270
- `, this.host.dataset.theme = e.theme, this.host.style.setProperty("--spilki-accent", e.color), this.messagesEl = this.shadow.querySelector(".messages"), this.typingEl = this.shadow.querySelector(".typing"), this.input = this.shadow.querySelector("textarea"), this.offlineEl = this.shadow.querySelector(".offline"), this.sendButton = this.shadow.querySelector(".send-btn"), this.emojiButton = this.shadow.querySelector(".emoji-btn"), this.emojiPickerEl = this.shadow.querySelector(".emoji-picker"), this.scrollBottomButton = this.shadow.querySelector(".scroll-bottom"), this.scrollBottomCountEl = this.shadow.querySelector(".scroll-count"), this.closeButton = this.shadow.querySelector("header .close"), this.suggestedRepliesEl = this.shadow.querySelector(".suggested-replies"), this.handleCloseClick = () => this.options.onClose(), this.handleSendClick = () => this.send(), this.handleInputKeydown = (n) => {
271
- if (n.key === "Enter" && !n.shiftKey)
272
- n.preventDefault(), this.send();
273
- else if (n.key === "Escape") {
282
+ `, this.host.dataset.theme = e.theme, this.host.style.setProperty("--spilki-accent", e.color), this.messagesEl = this.shadow.querySelector(".messages"), this.typingEl = this.shadow.querySelector(".typing"), this.input = this.shadow.querySelector("textarea"), this.offlineEl = this.shadow.querySelector(".offline"), this.sendButton = this.shadow.querySelector(".send-btn"), this.emojiButton = this.shadow.querySelector(".emoji-btn"), this.emojiPickerEl = this.shadow.querySelector(".emoji-picker"), this.scrollBottomButton = this.shadow.querySelector(".scroll-bottom"), this.scrollBottomCountEl = this.shadow.querySelector(".scroll-count"), this.closeButton = this.shadow.querySelector("header .close"), this.suggestedRepliesEl = this.shadow.querySelector(".suggested-replies"), this.handleCloseClick = () => this.options.onClose(), this.handleSendClick = () => this.send(), this.handleInputKeydown = (r) => {
283
+ if (r.key === "Enter" && !r.shiftKey)
284
+ r.preventDefault(), this.send();
285
+ else if (r.key === "Escape") {
274
286
  if (this.emojiPickerOpen) {
275
- n.stopPropagation(), this.closeEmojiPicker();
287
+ r.stopPropagation(), this.closeEmojiPicker();
276
288
  return;
277
289
  }
278
290
  this.options.onClose();
279
291
  }
280
- }, this.handleShadowKeydown = (n) => {
281
- const a = n;
282
- if (a.key === "Escape") {
292
+ }, this.handleShadowKeydown = (r) => {
293
+ const l = r;
294
+ if (l.key === "Escape") {
283
295
  if (this.emojiPickerOpen) {
284
- a.preventDefault(), this.closeEmojiPicker();
296
+ l.preventDefault(), this.closeEmojiPicker();
285
297
  return;
286
298
  }
287
299
  this.options.onClose();
288
300
  }
289
- a.key === "Tab" && this.trapFocus(a);
301
+ l.key === "Tab" && this.trapFocus(l);
290
302
  }, this.handleFocusin = () => this.collectFocusable(), this.handleMessagesScroll = () => this.updateScrollBottomState(), this.handleScrollBottomClick = () => {
291
303
  this.scrollToBottom(), this.resetScrollUnreadCount();
292
304
  }, this.handleEmojiClick = () => {
293
305
  this.toggleEmojiPicker();
294
- }, this.handleDocumentPointerDown = (n) => {
306
+ }, this.handleDocumentPointerDown = (r) => {
295
307
  if (!this.emojiPickerOpen) return;
296
- const a = n.composedPath();
297
- a.includes(this.emojiPickerEl) || a.includes(this.emojiButton) || this.closeEmojiPicker();
308
+ const l = r.composedPath();
309
+ l.includes(this.emojiPickerEl) || l.includes(this.emojiButton) || this.closeEmojiPicker();
298
310
  }, this.closeButton.addEventListener("click", this.handleCloseClick), this.sendButton.addEventListener("click", this.handleSendClick), this.emojiButton.addEventListener("click", this.handleEmojiClick), this.scrollBottomButton.addEventListener("click", this.handleScrollBottomClick), this.input.addEventListener("keydown", this.handleInputKeydown), this.messagesEl.addEventListener("scroll", this.handleMessagesScroll), this.shadow.addEventListener("keydown", this.handleShadowKeydown), this.shadow.addEventListener("focusin", this.handleFocusin), document.addEventListener("pointerdown", this.handleDocumentPointerDown, !0), this.renderEmojiPicker(), this.updateScrollBottomState(), this.collectFocusable();
299
311
  }
312
+ get element() {
313
+ return this.host;
314
+ }
300
315
  mount() {
301
316
  document.body.appendChild(this.host);
302
317
  }
@@ -328,9 +343,9 @@ class Q {
328
343
  renderWithConversations(e, t) {
329
344
  this.messagesEl.innerHTML = "", this.seenIds.clear(), this.renderedMessages.length = 0, this.lastTimelineMessage = null;
330
345
  for (const s of e) {
331
- s.messages.forEach((n) => this.seenIds.add(n.id));
332
- const i = this.createHistoryContainer(s.messages), o = s.messages[s.messages.length - 1].ts, l = this.createSeparatorElement(o, i);
333
- this.messagesEl.appendChild(i), this.messagesEl.appendChild(l);
346
+ s.messages.forEach((r) => this.seenIds.add(r.id));
347
+ const i = this.createHistoryContainer(s.messages), n = s.messages[s.messages.length - 1].ts, a = this.createSeparatorElement(n, i);
348
+ this.messagesEl.appendChild(i), this.messagesEl.appendChild(a);
334
349
  }
335
350
  t.forEach((s) => {
336
351
  this.seenIds.add(s.id), this.appendTimelineMessage(s);
@@ -395,17 +410,17 @@ class Q {
395
410
  }
396
411
  createSeparatorElement(e, t) {
397
412
  const s = document.createElement("div");
398
- s.className = "conversation-separator", s.setAttribute("role", "button"), s.setAttribute("tabindex", "0"), s.setAttribute("aria-expanded", "false"), s.setAttribute("aria-label", "Show previous conversation"), s.textContent = V(e);
413
+ s.className = "conversation-separator", s.setAttribute("role", "button"), s.setAttribute("tabindex", "0"), s.setAttribute("aria-expanded", "false"), s.setAttribute("aria-label", "Show previous conversation"), s.textContent = te(e);
399
414
  const i = () => {
400
- const o = t.classList.toggle("expanded");
401
- s.setAttribute("aria-expanded", String(o)), s.setAttribute(
415
+ const n = t.classList.toggle("expanded");
416
+ s.setAttribute("aria-expanded", String(n)), s.setAttribute(
402
417
  "aria-label",
403
- o ? "Hide previous conversation" : "Show previous conversation"
418
+ n ? "Hide previous conversation" : "Show previous conversation"
404
419
  );
405
420
  };
406
- return s.addEventListener("click", i), s.addEventListener("keydown", (o) => {
407
- const l = o;
408
- (l.key === "Enter" || l.key === " ") && (l.preventDefault(), i());
421
+ return s.addEventListener("click", i), s.addEventListener("keydown", (n) => {
422
+ const a = n;
423
+ (a.key === "Enter" || a.key === " ") && (a.preventDefault(), i());
409
424
  }), s;
410
425
  }
411
426
  createHistoryContainer(e) {
@@ -414,8 +429,8 @@ class Q {
414
429
  let s = null;
415
430
  return e.forEach((i) => {
416
431
  this.appendDateSeparatorIfNeeded(s, i, t);
417
- const { item: o } = this.createMessageElement(i);
418
- t.appendChild(o), s = i;
432
+ const { item: n } = this.createMessageElement(i);
433
+ t.appendChild(n), s = i;
419
434
  }), t;
420
435
  }
421
436
  appendTimelineMessage(e) {
@@ -431,24 +446,24 @@ class Q {
431
446
  }
432
447
  updateTimestampVisibility() {
433
448
  for (let e = 0; e < this.renderedMessages.length; e += 1) {
434
- const t = this.renderedMessages[e], s = this.renderedMessages[e + 1], i = !!s && s.message.author === t.message.author && s.message.ts - t.message.ts <= J && s.message.ts >= t.message.ts;
449
+ const t = this.renderedMessages[e], s = this.renderedMessages[e + 1], i = !!s && s.message.author === t.message.author && s.message.ts - t.message.ts <= ie && s.message.ts >= t.message.ts;
435
450
  t.timeEl.toggleAttribute("hidden", i), t.timeEl.textContent = this.formatMessageTimestamp(t.message.ts);
436
451
  }
437
452
  }
438
453
  formatMessageTimestamp(e) {
439
454
  const s = Date.now() - e;
440
- if (s < D) {
455
+ if (s < $) {
441
456
  const i = Math.max(1, Math.round(s / 6e4));
442
457
  if (i < 60)
443
458
  return this.relativeTimeFormat.format(-i, "minute");
444
- const o = Math.max(1, Math.round(i / 60));
445
- return this.relativeTimeFormat.format(-o, "hour");
459
+ const n = Math.max(1, Math.round(i / 60));
460
+ return this.relativeTimeFormat.format(-n, "hour");
446
461
  }
447
462
  return this.absoluteTimeFormat.format(new Date(e));
448
463
  }
449
464
  formatDateSeparator(e) {
450
465
  const t = new Date(e), s = this.startOfDay(Date.now()), i = this.startOfDay(e);
451
- return i === s ? "Today" : i === s - D ? "Yesterday" : this.dateSeparatorFormat.format(t);
466
+ return i === s ? "Today" : i === s - $ ? "Yesterday" : this.dateSeparatorFormat.format(t);
452
467
  }
453
468
  isSameDay(e, t) {
454
469
  return this.startOfDay(e) === this.startOfDay(t);
@@ -458,7 +473,7 @@ class Q {
458
473
  return new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime();
459
474
  }
460
475
  isScrolledUp() {
461
- return this.distanceFromBottom() > X;
476
+ return this.distanceFromBottom() > oe;
462
477
  }
463
478
  distanceFromBottom() {
464
479
  return this.messagesEl.scrollHeight - this.messagesEl.scrollTop - this.messagesEl.clientHeight;
@@ -505,7 +520,7 @@ class Q {
505
520
  this.emojiPickerOpen && (this.emojiPickerOpen = !1, this.emojiPickerEl.style.display = "none", this.emojiButton.setAttribute("aria-expanded", "false"), this.collectFocusable());
506
521
  }
507
522
  renderEmojiPicker() {
508
- this.emojiPickerEl.replaceChildren(), Z.forEach((e) => {
523
+ this.emojiPickerEl.replaceChildren(), ne.forEach((e) => {
509
524
  const t = document.createElement("button");
510
525
  t.type = "button", t.className = "emoji-option", t.textContent = e, t.setAttribute("aria-label", `Insert ${e}`), t.addEventListener("click", () => {
511
526
  this.insertEmojiAtCursor(e), this.closeEmojiPicker();
@@ -513,11 +528,11 @@ class Q {
513
528
  });
514
529
  }
515
530
  insertEmojiAtCursor(e) {
516
- var l, n;
517
- const t = this.input.value, s = (l = this.input.selectionStart) != null ? l : t.length, i = (n = this.input.selectionEnd) != null ? n : t.length;
531
+ var a, r;
532
+ const t = this.input.value, s = (a = this.input.selectionStart) != null ? a : t.length, i = (r = this.input.selectionEnd) != null ? r : t.length;
518
533
  this.input.value = `${t.slice(0, s)}${e}${t.slice(i)}`;
519
- const o = s + e.length;
520
- this.input.setSelectionRange(o, o), this.input.dispatchEvent(new Event("input", { bubbles: !0 })), this.input.focus();
534
+ const n = s + e.length;
535
+ this.input.setSelectionRange(n, n), this.input.dispatchEvent(new Event("input", { bubbles: !0 })), this.input.focus();
521
536
  }
522
537
  collectFocusable() {
523
538
  const e = this.shadow.querySelectorAll(
@@ -533,8 +548,117 @@ class Q {
533
548
  e.shiftKey && i === t ? (e.preventDefault(), s.focus()) : !e.shiftKey && i === s && (e.preventDefault(), t.focus());
534
549
  }
535
550
  }
536
- const v = 1500, L = 8e3;
537
- class ee {
551
+ function ae(o) {
552
+ if (!(o instanceof HTMLElement) || o.hasAttribute("disabled") || o.getAttribute("aria-disabled") === "true" || o.hasAttribute("inert"))
553
+ return !1;
554
+ const e = getComputedStyle(o);
555
+ if (e.display === "none" || e.visibility === "hidden" || e.pointerEvents === "none")
556
+ return !1;
557
+ const t = o.tagName;
558
+ if (t === "BUTTON" || t === "SELECT" || t === "TEXTAREA" || t === "A" && o.hasAttribute("href") || t === "INPUT" && o.type !== "hidden" || t === "IFRAME") return !0;
559
+ const s = o.getAttribute("role");
560
+ if (s === "button" || s === "link" || o.getAttribute("contenteditable") === "true") return !0;
561
+ const i = o.getAttribute("tabindex");
562
+ return i !== null && i !== "-1";
563
+ }
564
+ function K(o, e, t) {
565
+ const s = document.elementsFromPoint(o, e);
566
+ for (const i of s) {
567
+ if (t.has(i)) continue;
568
+ let n = !1;
569
+ for (const a of t)
570
+ if (a.contains(i)) {
571
+ n = !0;
572
+ break;
573
+ }
574
+ if (!n && ae(i))
575
+ return !0;
576
+ }
577
+ return !1;
578
+ }
579
+ function N(o, e) {
580
+ const t = [
581
+ [o.x + o.width / 2, o.y + o.height / 2],
582
+ [o.x + o.width / 2, o.y + 4],
583
+ [o.x + o.width / 2, o.y + o.height - 4],
584
+ [o.x + 4, o.y + o.height / 2],
585
+ [o.x + o.width - 4, o.y + o.height / 2]
586
+ ];
587
+ for (const [s, i] of t)
588
+ if (K(s, i, e)) return !0;
589
+ return !1;
590
+ }
591
+ function F() {
592
+ var o, e;
593
+ return (e = (o = window.matchMedia) == null ? void 0 : o.call(window, "(pointer: coarse)").matches) != null ? e : !1;
594
+ }
595
+ function le(o) {
596
+ return o === "bottom-right" ? "bottom-left" : "bottom-right";
597
+ }
598
+ class ce {
599
+ constructor(e) {
600
+ this.rafId = 0, this.pendingX = 0, this.pendingY = 0, this.pendingUpdate = !1, this.passthrough = !1, this.cachedRect = null, this.bubble = e.bubble, this.widgetHosts = e.widgetHosts, this.currentPosition = e.position, this.handlePointerMove = (t) => this.onPointerMove(t), this.handlePointerUp = () => this.exitPassthrough(), this.handleScroll = () => this.onLayoutChange(), this.handleResize = () => this.onLayoutChange(), window.addEventListener("scroll", this.handleScroll, { passive: !0 }), window.addEventListener("resize", this.handleResize, { passive: !0 }), F() ? this.scheduleAutoDockCheck() : (document.addEventListener("pointermove", this.handlePointerMove, {
601
+ passive: !0
602
+ }), document.addEventListener("pointerup", this.handlePointerUp, {
603
+ passive: !0
604
+ })), requestAnimationFrame(() => this.onLayoutChange());
605
+ }
606
+ destroy() {
607
+ document.removeEventListener("pointermove", this.handlePointerMove), document.removeEventListener("pointerup", this.handlePointerUp), window.removeEventListener("scroll", this.handleScroll), window.removeEventListener("resize", this.handleResize), this.rafId && cancelAnimationFrame(this.rafId), this.exitPassthrough();
608
+ }
609
+ onPointerMove(e) {
610
+ this.pendingX = e.clientX, this.pendingY = e.clientY, this.pendingUpdate || (this.pendingUpdate = !0, this.rafId = requestAnimationFrame(() => this.tick()));
611
+ }
612
+ tick() {
613
+ this.pendingUpdate = !1;
614
+ const e = this.getBubbleRect(), t = this.pendingX, s = this.pendingY;
615
+ if (!(t >= e.left && t <= e.right && s >= e.top && s <= e.bottom)) {
616
+ this.passthrough && this.exitPassthrough();
617
+ return;
618
+ }
619
+ const n = this.bubble.element, a = n.style.pointerEvents;
620
+ n.style.pointerEvents = "none";
621
+ const r = K(t, s, this.widgetHosts);
622
+ n.style.pointerEvents = a, r && !this.passthrough ? this.enterPassthrough() : !r && this.passthrough && this.exitPassthrough();
623
+ }
624
+ enterPassthrough() {
625
+ this.passthrough = !0, this.bubble.setDimmed(!0), this.bubble.setPassthrough(!0);
626
+ }
627
+ exitPassthrough() {
628
+ this.passthrough && (this.passthrough = !1, this.bubble.setDimmed(!1), this.bubble.setPassthrough(!1));
629
+ }
630
+ scheduleAutoDockCheck() {
631
+ requestAnimationFrame(() => this.autoDockIfNeeded());
632
+ }
633
+ autoDockIfNeeded() {
634
+ this.invalidateRect();
635
+ const e = this.getBubbleRect(), t = this.bubble.element, s = t.style.pointerEvents;
636
+ t.style.pointerEvents = "none";
637
+ const i = N(e, this.widgetHosts);
638
+ if (t.style.pointerEvents = s, !i) return;
639
+ const n = le(this.currentPosition);
640
+ this.currentPosition = n, this.bubble.setPosition(n), this.invalidateRect(), requestAnimationFrame(() => {
641
+ const a = this.getBubbleRect(), r = this.bubble.element, l = r.style.pointerEvents;
642
+ r.style.pointerEvents = "none";
643
+ const p = N(
644
+ a,
645
+ this.widgetHosts
646
+ );
647
+ r.style.pointerEvents = l, p && this.bubble.setDimmed(!0);
648
+ });
649
+ }
650
+ onLayoutChange() {
651
+ this.invalidateRect(), F() && this.autoDockIfNeeded();
652
+ }
653
+ getBubbleRect() {
654
+ return this.cachedRect || (this.cachedRect = this.bubble.element.getBoundingClientRect()), this.cachedRect;
655
+ }
656
+ invalidateRect() {
657
+ this.cachedRect = null;
658
+ }
659
+ }
660
+ const v = 1500, W = 8e3;
661
+ class he {
538
662
  constructor(e, t) {
539
663
  this.sessionId = null, this.currentKind = null, this.stopped = !1, this.backoff = v, this.connectPromise = null, this.options = e, this.handlers = t;
540
664
  }
@@ -545,8 +669,8 @@ class ee {
545
669
  const t = {};
546
670
  for (const [s, i] of Object.entries(e))
547
671
  if (typeof i == "string") {
548
- const o = i.trim();
549
- o && (t[s] = o);
672
+ const n = i.trim();
673
+ n && (t[s] = n);
550
674
  }
551
675
  this.user = t, this.sessionId && this.sendIdentify().catch(
552
676
  (s) => this.handlers.onError(s)
@@ -585,9 +709,9 @@ class ee {
585
709
  }
586
710
  }
587
711
  async doConnect() {
588
- var l, n;
712
+ var a, r;
589
713
  this.stopped = !1;
590
- const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/session`, t = (n = (l = this.sessionId) != null ? l : this.options.sessionId) != null ? n : void 0, s = {
714
+ const e = `${this.options.apiBase.replace(/\/$/, "")}/widget/session`, t = (r = (a = this.sessionId) != null ? a : this.options.sessionId) != null ? r : void 0, s = {
591
715
  organisationId: this.options.org,
592
716
  sessionId: t,
593
717
  userAgent: typeof navigator != "undefined" ? navigator.userAgent : "",
@@ -604,16 +728,16 @@ class ee {
604
728
  });
605
729
  if (!i.ok)
606
730
  throw new Error(`SpilkiWidget: connect failed (${i.status})`);
607
- const o = await i.json();
608
- return this.sessionId = o.sessionId, this.options.sessionId = o.sessionId, this.backoff = v, await this.startTransport(o), o;
731
+ const n = await i.json();
732
+ return this.sessionId = n.sessionId, this.options.sessionId = n.sessionId, this.backoff = v, await this.startTransport(n), n;
609
733
  }
610
734
  async send(e, t) {
611
- var l, n, a;
735
+ var a, r, l;
612
736
  const s = {
613
- sessionId: (n = (l = this.sessionId) != null ? l : this.options.sessionId) != null ? n : "",
737
+ sessionId: (r = (a = this.sessionId) != null ? a : this.options.sessionId) != null ? r : "",
614
738
  text: e,
615
739
  ...t ? { messageId: t } : {},
616
- ...(a = this.user) != null && a.userId ? { userId: this.user.userId } : {}
740
+ ...(l = this.user) != null && l.userId ? { userId: this.user.userId } : {}
617
741
  };
618
742
  if (!s.sessionId)
619
743
  throw new Error("SpilkiWidget: missing session id");
@@ -621,7 +745,7 @@ class ee {
621
745
  this.ws.send(JSON.stringify({ type: "message", payload: s }));
622
746
  return;
623
747
  }
624
- const i = `${this.options.apiBase.replace(/\/$/, "")}/widget/message`, o = await fetch(i, {
748
+ const i = `${this.options.apiBase.replace(/\/$/, "")}/widget/message`, n = await fetch(i, {
625
749
  method: "POST",
626
750
  headers: {
627
751
  "Content-Type": "application/json",
@@ -629,8 +753,8 @@ class ee {
629
753
  },
630
754
  body: JSON.stringify(s)
631
755
  });
632
- if (!o.ok)
633
- throw new Error(`SpilkiWidget: send failed (${o.status})`);
756
+ if (!n.ok)
757
+ throw new Error(`SpilkiWidget: send failed (${n.status})`);
634
758
  }
635
759
  // #1: accept resetBackoff param; #8 #9: clear retryTimer
636
760
  stop(e = !0) {
@@ -660,7 +784,7 @@ class ee {
660
784
  return;
661
785
  }
662
786
  this.currentKind = "ws", this.handlers.onOpen("ws"), this.backoff = v, t();
663
- }, this.wsOnMessage = (o) => this.handleIncoming(o.data), this.wsOnClose = () => {
787
+ }, this.wsOnMessage = (n) => this.handleIncoming(n.data), this.wsOnClose = () => {
664
788
  this.stopped || this.retryFallback("ws");
665
789
  }, this.wsOnError = () => {
666
790
  this.handlers.onError(new Error("SpilkiWidget: websocket error")), i.readyState !== WebSocket.OPEN && s(new Error("WebSocket failed"));
@@ -680,8 +804,8 @@ class ee {
680
804
  "X-Authorization": `Bearer ${this.options.accessToken}`
681
805
  },
682
806
  signal: i.signal
683
- }).then((o) => {
684
- if (!o.ok || !o.body) {
807
+ }).then((n) => {
808
+ if (!n.ok || !n.body) {
685
809
  s(new Error("SSE failed"));
686
810
  return;
687
811
  }
@@ -690,32 +814,32 @@ class ee {
690
814
  return;
691
815
  }
692
816
  this.currentKind = "sse", this.handlers.onOpen("sse"), this.backoff = v, t();
693
- const l = o.body.getReader(), n = new TextDecoder();
694
- let a = "";
695
- const g = () => {
696
- l.read().then(({ done: u, value: h }) => {
697
- var m;
817
+ const a = n.body.getReader(), r = new TextDecoder();
818
+ let l = "";
819
+ const p = () => {
820
+ a.read().then(({ done: u, value: h }) => {
821
+ var y;
698
822
  if (u || this.stopped) {
699
823
  this.stopped || (this.handlers.onError(new Error("SpilkiWidget: SSE stream ended")), this.retryFallback("sse"));
700
824
  return;
701
825
  }
702
- a += n.decode(h, { stream: !0 });
703
- const d = a.split(`
826
+ l += r.decode(h, { stream: !0 });
827
+ const d = l.split(`
704
828
 
705
829
  `);
706
- a = (m = d.pop()) != null ? m : "";
830
+ l = (y = d.pop()) != null ? y : "";
707
831
  for (const f of d)
708
- for (const p of f.split(`
832
+ for (const g of f.split(`
709
833
  `))
710
- p.startsWith("data:") && this.handleIncoming(p.slice(5).trim());
711
- g();
834
+ g.startsWith("data:") && this.handleIncoming(g.slice(5).trim());
835
+ p();
712
836
  }).catch((u) => {
713
837
  i.signal.aborted || (this.handlers.onError(u), this.stopped || this.retryFallback("sse"));
714
838
  });
715
839
  };
716
- g();
717
- }).catch((o) => {
718
- i.signal.aborted || s(o);
840
+ p();
841
+ }).catch((n) => {
842
+ i.signal.aborted || s(n);
719
843
  });
720
844
  });
721
845
  }
@@ -732,9 +856,9 @@ class ee {
732
856
  });
733
857
  if (!s.ok) throw new Error(`Poll failed ${s.status}`);
734
858
  const i = await s.json();
735
- S(i).forEach((o) => this.handlers.onMessage(o)), this.backoff = v;
859
+ A(i).forEach((n) => this.handlers.onMessage(n)), this.backoff = v;
736
860
  } catch (s) {
737
- this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5, L);
861
+ this.handlers.onError(s), this.backoff = Math.min(this.backoff * 1.5, W);
738
862
  } finally {
739
863
  this.stopped || (this.pollTimer = window.setTimeout(t, this.backoff));
740
864
  }
@@ -743,7 +867,7 @@ class ee {
743
867
  }
744
868
  // #1: preserve backoff by calling stop(false); #8: check stopped before reconnect
745
869
  retryFallback(e) {
746
- this.stopped || (this.stop(!1), this.backoff = Math.min(this.backoff * 1.5, L), this.retryTimer = window.setTimeout(() => {
870
+ this.stopped || (this.stop(!1), this.backoff = Math.min(this.backoff * 1.5, W), this.retryTimer = window.setTimeout(() => {
747
871
  this.stopped || (this.handlers.onError(new Error(`SpilkiWidget: retrying after ${e}`)), this.connect().catch((t) => this.handlers.onError(t)));
748
872
  }, this.backoff));
749
873
  }
@@ -763,20 +887,20 @@ class ee {
763
887
  dispatchIncoming(e) {
764
888
  var t;
765
889
  if ("type" in e) {
766
- e.type === "message" ? this.handlers.onMessage(e.payload) : e.type === "typing" ? this.handlers.onTyping(!!((t = e.payload) != null && t.active)) : e.type === "AGENT_EVENT" && se(e.payload) && this.handlers.onAgentEvent(e.payload);
890
+ e.type === "message" ? this.handlers.onMessage(e.payload) : e.type === "typing" ? this.handlers.onTyping(!!((t = e.payload) != null && t.active)) : e.type === "AGENT_EVENT" && ue(e.payload) && this.handlers.onAgentEvent(e.payload);
767
891
  return;
768
892
  }
769
893
  this.handlers.onMessage(e);
770
894
  }
771
895
  }
772
- const te = /* @__PURE__ */ new Set(["TYPING", "THINKING", "SEARCHING", "EXECUTING_TOOL"]);
773
- function se(r) {
774
- if (typeof r != "object" || r === null) return !1;
775
- const e = r;
776
- return te.has(e.eventType);
896
+ const de = /* @__PURE__ */ new Set(["TYPING", "THINKING", "SEARCHING", "EXECUTING_TOOL"]);
897
+ function ue(o) {
898
+ if (typeof o != "object" || o === null) return !1;
899
+ const e = o;
900
+ return de.has(e.eventType);
777
901
  }
778
- const U = 30 * 60 * 1e3, ie = 3e4, A = 30;
779
- class re {
902
+ const H = 30 * 60 * 1e3, pe = 3e4, O = 30;
903
+ class ge {
780
904
  constructor(e, t) {
781
905
  this.org = e, this.listeners = /* @__PURE__ */ new Set(), this.activityTimer = null, this.state = {
782
906
  isOpen: !1,
@@ -805,7 +929,7 @@ class re {
805
929
  handleAgentEvent(e) {
806
930
  this.activityTimer && (clearTimeout(this.activityTimer), this.activityTimer = null), this.activityTimer = setTimeout(() => {
807
931
  this.state.agentActivity = null, this.activityTimer = null, this.emit();
808
- }, ie), this.state.agentActivity !== e && (this.state.agentActivity = e, this.emit());
932
+ }, pe), this.state.agentActivity !== e && (this.state.agentActivity = e, this.emit());
809
933
  }
810
934
  clearAgentActivity() {
811
935
  this.resetAgentActivity() && this.emit();
@@ -819,15 +943,15 @@ class re {
819
943
  addMessage(e) {
820
944
  var s, i;
821
945
  const t = {
822
- id: (s = e.id) != null ? s : z("msg"),
946
+ id: (s = e.id) != null ? s : X("msg"),
823
947
  ts: (i = e.ts) != null ? i : Date.now(),
824
948
  author: e.author,
825
949
  text: e.text
826
950
  };
827
- return this.state.messages.some((o) => o.id === t.id) ? null : (this.state.messages = S([...this.state.messages, t], A), this.resetAgentActivity(), this.persistMessages(), this.touchActivity(), this.emit(), t);
951
+ return this.state.messages.some((n) => n.id === t.id) ? null : (this.state.messages = A([...this.state.messages, t], O), this.resetAgentActivity(), this.persistMessages(), this.touchActivity(), this.emit(), t);
828
952
  }
829
953
  setMessages(e) {
830
- this.state.messages = S(e, A), this.persistMessages(), this.emit();
954
+ this.state.messages = A(e, O), this.persistMessages(), this.emit();
831
955
  }
832
956
  clearMessages() {
833
957
  this.state.messages = [], this.persistMessages(), this.emit();
@@ -919,7 +1043,7 @@ class re {
919
1043
  }
920
1044
  isSessionExpired() {
921
1045
  const e = this.lastActivityTs;
922
- return e === 0 ? !1 : Date.now() - e >= U;
1046
+ return e === 0 ? !1 : Date.now() - e >= H;
923
1047
  }
924
1048
  getConversationGroups() {
925
1049
  const e = this.state.messages;
@@ -927,7 +1051,7 @@ class re {
927
1051
  const t = [];
928
1052
  let s = { startTs: e[0].ts, messages: [e[0]] };
929
1053
  for (let i = 1; i < e.length; i++)
930
- e[i].ts - e[i - 1].ts >= U ? (t.push(s), s = { startTs: e[i].ts, messages: [e[i]] }) : s.messages.push(e[i]);
1054
+ e[i].ts - e[i - 1].ts >= H ? (t.push(s), s = { startTs: e[i].ts, messages: [e[i]] }) : s.messages.push(e[i]);
931
1055
  return t.push(s), t;
932
1056
  }
933
1057
  emit() {
@@ -947,14 +1071,14 @@ class re {
947
1071
  const e = localStorage.getItem(this.historyKey);
948
1072
  if (!e) return [];
949
1073
  const t = JSON.parse(e);
950
- return Array.isArray(t) ? S(t, A) : [];
1074
+ return Array.isArray(t) ? A(t, O) : [];
951
1075
  } catch (e) {
952
1076
  return console.error("SpilkiWidget: unable to load messages", e), [];
953
1077
  }
954
1078
  }
955
1079
  }
956
- function oe(r) {
957
- const e = r.replace(/-/g, "+").replace(/_/g, "/"), t = e.padEnd(e.length + (4 - e.length % 4) % 4, "=");
1080
+ function me(o) {
1081
+ const e = o.replace(/-/g, "+").replace(/_/g, "/"), t = e.padEnd(e.length + (4 - e.length % 4) % 4, "=");
958
1082
  if (typeof atob == "function")
959
1083
  return decodeURIComponent(
960
1084
  Array.prototype.map.call(atob(t), (i) => `%${`00${i.charCodeAt(0).toString(16)}`.slice(-2)}`).join("")
@@ -964,24 +1088,24 @@ function oe(r) {
964
1088
  return s.from(t, "base64").toString("utf8");
965
1089
  throw new Error("SpilkiWidget: no base64 decoder available");
966
1090
  }
967
- function ne(r) {
968
- if (!r) return null;
969
- const e = r.split(".");
1091
+ function fe(o) {
1092
+ if (!o) return null;
1093
+ const e = o.split(".");
970
1094
  if (e.length < 2) return null;
971
1095
  try {
972
- const t = oe(e[1]);
1096
+ const t = me(e[1]);
973
1097
  return JSON.parse(t);
974
1098
  } catch (t) {
975
1099
  return console.error("SpilkiWidget: unable to parse JWT", t), null;
976
1100
  }
977
1101
  }
978
- function ae(r) {
979
- const e = ne(r);
1102
+ function be(o) {
1103
+ const e = fe(o);
980
1104
  if (!(e != null && e.exp) || typeof e.exp != "number") return !0;
981
1105
  const t = Math.floor(Date.now() / 1e3);
982
1106
  return e.exp < t + 60;
983
1107
  }
984
- const le = {
1108
+ const ke = {
985
1109
  onOpen() {
986
1110
  },
987
1111
  onClose() {
@@ -993,8 +1117,8 @@ const le = {
993
1117
  onTransportChange() {
994
1118
  }
995
1119
  };
996
- async function ce(r, e, t) {
997
- const s = `${r.replace(/\/$/, "")}/widget/install`, i = await fetch(s, {
1120
+ async function ye(o, e, t) {
1121
+ const s = `${o.replace(/\/$/, "")}/widget/install`, i = await fetch(s, {
998
1122
  method: "POST",
999
1123
  headers: { "Content-Type": "application/json", Origin: window.location.origin },
1000
1124
  body: JSON.stringify({ token: e, organisationId: t })
@@ -1002,127 +1126,127 @@ async function ce(r, e, t) {
1002
1126
  if (!i.ok) throw new Error(`SpilkiWidget: install failed (${i.status})`);
1003
1127
  return (await i.json()).accessToken;
1004
1128
  }
1005
- async function he(r, e) {
1006
- const t = `${r.replace(/\/$/, "")}/widget/refresh`, s = await fetch(t, {
1129
+ async function we(o, e) {
1130
+ const t = `${o.replace(/\/$/, "")}/widget/refresh`, s = await fetch(t, {
1007
1131
  method: "POST",
1008
1132
  headers: { "X-Authorization": `Bearer ${e}`, Origin: window.location.origin }
1009
1133
  });
1010
1134
  if (!s.ok) throw new Error(`SpilkiWidget: refresh failed (${s.status})`);
1011
1135
  return (await s.json()).accessToken;
1012
1136
  }
1013
- function de(r) {
1137
+ function ve(o) {
1014
1138
  let e = !1, t = null;
1015
1139
  const s = [], i = () => {
1016
- var n;
1017
- if (!r) return null;
1140
+ var r;
1141
+ if (!o) return null;
1018
1142
  if (t) return t;
1019
1143
  try {
1020
- const a = (n = window.AudioContext) != null ? n : window.webkitAudioContext;
1021
- if (!a) return null;
1022
- t = new a();
1144
+ const l = (r = window.AudioContext) != null ? r : window.webkitAudioContext;
1145
+ if (!l) return null;
1146
+ t = new l();
1023
1147
  } catch {
1024
1148
  return null;
1025
1149
  }
1026
1150
  return t;
1027
- }, o = () => {
1151
+ }, n = () => {
1028
1152
  e = !0;
1029
1153
  try {
1030
- const n = i();
1031
- (n == null ? void 0 : n.state) === "suspended" && n.resume().catch(() => {
1154
+ const r = i();
1155
+ (r == null ? void 0 : r.state) === "suspended" && r.resume().catch(() => {
1032
1156
  });
1033
1157
  } catch {
1034
1158
  }
1035
- }, l = (n) => {
1036
- const a = () => {
1037
- o(), window.removeEventListener(n, a, !0);
1159
+ }, a = (r) => {
1160
+ const l = () => {
1161
+ n(), window.removeEventListener(r, l, !0);
1038
1162
  };
1039
- s.push({ type: n, listener: a }), window.addEventListener(n, a, { capture: !0, passive: !0 });
1163
+ s.push({ type: r, listener: l }), window.addEventListener(r, l, { capture: !0, passive: !0 });
1040
1164
  };
1041
- return l("pointerdown"), l("keydown"), {
1042
- markUserInteraction: o,
1165
+ return a("pointerdown"), a("keydown"), {
1166
+ markUserInteraction: n,
1043
1167
  play() {
1044
- if (!r || !e) return;
1045
- const n = i();
1046
- if (!n || n.state !== "running") return;
1047
- const a = n.createGain();
1048
- a.gain.value = 0.15, a.connect(n.destination);
1049
- const g = (h, d, m) => {
1050
- const f = n.createOscillator(), p = n.createGain();
1051
- f.type = "sine", f.frequency.setValueAtTime(h, d), p.gain.setValueAtTime(1e-4, d), p.gain.exponentialRampToValueAtTime(1, d + 0.012), p.gain.exponentialRampToValueAtTime(1e-4, d + m), f.connect(p), p.connect(a), f.start(d), f.stop(d + m + 0.02);
1052
- }, u = n.currentTime;
1053
- g(880, u, 0.08), g(1175, u + 0.09, 0.08);
1168
+ if (!o || !e) return;
1169
+ const r = i();
1170
+ if (!r || r.state !== "running") return;
1171
+ const l = r.createGain();
1172
+ l.gain.value = 0.15, l.connect(r.destination);
1173
+ const p = (h, d, y) => {
1174
+ const f = r.createOscillator(), g = r.createGain();
1175
+ f.type = "sine", f.frequency.setValueAtTime(h, d), g.gain.setValueAtTime(1e-4, d), g.gain.exponentialRampToValueAtTime(1, d + 0.012), g.gain.exponentialRampToValueAtTime(1e-4, d + y), f.connect(g), g.connect(l), f.start(d), f.stop(d + y + 0.02);
1176
+ }, u = r.currentTime;
1177
+ p(880, u, 0.08), p(1175, u + 0.09, 0.08);
1054
1178
  },
1055
1179
  destroy() {
1056
- s.forEach(({ type: n, listener: a }) => {
1057
- window.removeEventListener(n, a, !0);
1180
+ s.forEach(({ type: r, listener: l }) => {
1181
+ window.removeEventListener(r, l, !0);
1058
1182
  }), s.length = 0, t && t.close().catch(() => {
1059
1183
  }), t = null;
1060
1184
  }
1061
1185
  };
1062
1186
  }
1063
- function $(r) {
1064
- var O, M, B, j;
1065
- if (!r.org)
1187
+ function z(o) {
1188
+ var B, L, D, j, U;
1189
+ if (!o.org)
1066
1190
  throw new Error("SpilkiWidget: org is required");
1067
- const e = H(r);
1068
- q(e.allowedOriginsHint);
1069
- const t = { ...le, ...(O = e.hooks) != null ? O : {} }, s = new re(e.org, { persist: e.persist }), i = de(e.sound);
1070
- let o = (M = s.accessToken) != null ? M : void 0, l = null;
1071
- const n = () => {
1191
+ const e = J(o);
1192
+ Q(e.allowedOriginsHint);
1193
+ const t = { ...ke, ...(B = e.hooks) != null ? B : {} }, s = new ge(e.org, { persist: e.persist }), i = ve(e.sound);
1194
+ let n = (L = s.accessToken) != null ? L : void 0, a = null;
1195
+ const r = () => {
1072
1196
  u.setBadge(s.countUnread());
1073
- }, a = () => {
1197
+ }, l = () => {
1074
1198
  s.markRead(), u.setBadge(0);
1075
- }, g = async () => l || (l = (async () => {
1199
+ }, p = async () => a || (a = (async () => {
1076
1200
  try {
1077
- if (o && ae(o))
1201
+ if (n && be(n))
1078
1202
  try {
1079
- o = await he(e.apiBase, o), s.persistAccessToken(o), d.setAccessToken(o);
1203
+ n = await we(e.apiBase, n), s.persistAccessToken(n), d.setAccessToken(n);
1080
1204
  return;
1081
1205
  } catch {
1082
- o = void 0, s.clearAccessToken();
1206
+ n = void 0, s.clearAccessToken();
1083
1207
  }
1084
- if (!o) {
1085
- if (!r.installationToken) throw new Error("SpilkiWidget: missing installationToken");
1086
- if (!r.org) throw new Error("SpilkiWidget: missing org");
1087
- o = await ce(e.apiBase, r.installationToken, r.org), s.persistAccessToken(o), d.setAccessToken(o);
1208
+ if (!n) {
1209
+ if (!o.installationToken) throw new Error("SpilkiWidget: missing installationToken");
1210
+ if (!o.org) throw new Error("SpilkiWidget: missing org");
1211
+ n = await ye(e.apiBase, o.installationToken, o.org), s.persistAccessToken(n), d.setAccessToken(n);
1088
1212
  }
1089
1213
  } finally {
1090
- l = null;
1214
+ a = null;
1091
1215
  }
1092
- })(), l), u = R({
1216
+ })(), a), u = G({
1093
1217
  color: e.color,
1094
- position: (B = e.position) != null ? B : "bottom-right",
1218
+ position: (D = e.position) != null ? D : "bottom-right",
1095
1219
  onClick: () => {
1096
- s.snapshot.isOpen ? (s.close(), t.onClose()) : (i.markUserInteraction(), s.open(), a(), t.onOpen());
1220
+ s.snapshot.isOpen ? (s.close(), t.onClose()) : (i.markUserInteraction(), s.open(), l(), t.onOpen());
1097
1221
  }
1098
- }), h = new Q({
1222
+ }), h = new re({
1099
1223
  color: e.color,
1100
- theme: P(e.theme),
1224
+ theme: R(e.theme),
1101
1225
  position: (j = e.position) != null ? j : "bottom-right",
1102
1226
  i18n: e.i18n,
1103
1227
  onClose: () => {
1104
1228
  s.close(), t.onClose();
1105
1229
  },
1106
1230
  onSend: (c) => {
1107
- const k = s.addMessage({ author: "user", text: c });
1108
- k && (h.appendMessage(k), g().then(() => d.send(c, k.id)).catch((b) => {
1109
- t.onError(b), s.setConnected(!1), h.setOffline(!0);
1231
+ const b = s.addMessage({ author: "user", text: c });
1232
+ b && (h.appendMessage(b), p().then(() => d.send(c, b.id)).catch((m) => {
1233
+ t.onError(m), s.setConnected(!1), h.setOffline(!0);
1110
1234
  }));
1111
1235
  }
1112
- }), d = new ee(
1236
+ }), d = new he(
1113
1237
  {
1114
1238
  apiBase: e.apiBase,
1115
- accessToken: o,
1239
+ accessToken: n,
1116
1240
  org: e.org,
1117
1241
  sessionId: s.sessionId
1118
1242
  },
1119
1243
  {
1120
1244
  onOpen(c) {
1121
- C.transport = c, t.onTransportChange(c), s.setConnected(!0), h.setOffline(!1);
1245
+ I.transport = c, t.onTransportChange(c), s.setConnected(!0), h.setOffline(!1);
1122
1246
  },
1123
1247
  onMessage(c) {
1124
- const b = c.suggestedReplies, y = s.addMessage(c);
1125
- y && (h.appendMessage(y), y.author === "bot" && b && b.length > 0 && h.setSuggestedReplies(b), !s.snapshot.isOpen && y.author === "bot" && (n(), i.play()), t.onMessage(y));
1248
+ const m = c.suggestedReplies, k = s.addMessage(c);
1249
+ k && (h.appendMessage(k), k.author === "bot" && m && m.length > 0 && h.setSuggestedReplies(m), !s.snapshot.isOpen && k.author === "bot" && (r(), i.play()), t.onMessage(k));
1126
1250
  },
1127
1251
  onTyping() {
1128
1252
  s.handleAgentEvent("TYPING");
@@ -1136,8 +1260,12 @@ function $(r) {
1136
1260
  }
1137
1261
  );
1138
1262
  u.mount(), h.mount();
1139
- const m = s.snapshot.messages, f = s.isSessionExpired(), p = s.getConversationGroups();
1140
- if (m.length === 0 && e.welcome) {
1263
+ const y = (U = e.position) != null ? U : "bottom-right", f = /* @__PURE__ */ new Set([u.element, h.element]), g = new ce({
1264
+ bubble: u,
1265
+ widgetHosts: f,
1266
+ position: y
1267
+ }), T = s.snapshot.messages, P = s.isSessionExpired(), x = s.getConversationGroups();
1268
+ if (T.length === 0 && e.welcome) {
1141
1269
  const c = {
1142
1270
  id: "welcome",
1143
1271
  author: "bot",
@@ -1145,33 +1273,33 @@ function $(r) {
1145
1273
  ts: Date.now()
1146
1274
  };
1147
1275
  s.addMessage(c), h.appendMessage(c);
1148
- } else f && m.length > 0 ? h.renderWithConversations(p, []) : p.length > 1 ? h.renderWithConversations(p.slice(0, -1), p[p.length - 1].messages) : h.updateMessages(m);
1149
- let T = !1;
1150
- const N = s.subscribe(() => {
1276
+ } else P && T.length > 0 ? h.renderWithConversations(x, []) : x.length > 1 ? h.renderWithConversations(x.slice(0, -1), x[x.length - 1].messages) : h.updateMessages(T);
1277
+ let C = !1;
1278
+ const _ = s.subscribe(() => {
1151
1279
  const c = s.snapshot;
1152
- if (u.setOpen(c.isOpen), h.setAgentActivity(c.agentActivity, e.i18n), h.setOffline(!c.isConnected), h.updateTheme(P(e.theme)), c.isOpen) {
1153
- if (!T) {
1154
- const k = s.countUnread() > 0, b = s.lastReadTs;
1155
- a(), k && h.scrollToFirstUnread(b);
1280
+ if (u.setOpen(c.isOpen), h.setAgentActivity(c.agentActivity, e.i18n), h.setOffline(!c.isConnected), h.updateTheme(R(e.theme)), c.isOpen) {
1281
+ if (!C) {
1282
+ const b = s.countUnread() > 0, m = s.lastReadTs;
1283
+ l(), b && h.scrollToFirstUnread(m);
1156
1284
  }
1157
- T = !0, h.show();
1285
+ C = !0, h.show();
1158
1286
  } else
1159
- T = !1, h.hide();
1160
- }), W = m.length === 0 || f;
1161
- n(), g().then(
1287
+ C = !1, h.hide();
1288
+ }), q = T.length === 0 || P;
1289
+ r(), p().then(
1162
1290
  () => d.connect().then((c) => {
1163
- var b, y;
1164
- e.persist && s.persistSession(c.sessionId), s.setConnected(!0), t.onTransportChange((b = d.kind) != null ? b : "ws");
1165
- const k = (y = c.suggestedReplies) != null ? y : [];
1166
- k.length > 0 && W && h.setSuggestedReplies(k);
1291
+ var m, k;
1292
+ e.persist && s.persistSession(c.sessionId), s.setConnected(!0), t.onTransportChange((m = d.kind) != null ? m : "ws");
1293
+ const b = (k = c.suggestedReplies) != null ? k : [];
1294
+ b.length > 0 && q && h.setSuggestedReplies(b);
1167
1295
  })
1168
1296
  ).catch((c) => {
1169
1297
  t.onError(c), s.setConnected(!1), h.setOffline(!0);
1170
1298
  });
1171
- const C = {
1299
+ const I = {
1172
1300
  transport: null,
1173
1301
  open() {
1174
- i.markUserInteraction(), s.open(), a(), t.onOpen();
1302
+ i.markUserInteraction(), s.open(), l(), t.onOpen();
1175
1303
  },
1176
1304
  close() {
1177
1305
  s.close(), t.onClose();
@@ -1180,24 +1308,24 @@ function $(r) {
1180
1308
  d.setUser(c);
1181
1309
  },
1182
1310
  destroy() {
1183
- N(), d.stop(), i.destroy(), u.destroy(), h.destroy(), x === C && (x = null);
1311
+ _(), g.destroy(), d.stop(), i.destroy(), u.destroy(), h.destroy(), E === I && (E = null);
1184
1312
  }
1185
1313
  };
1186
- return C;
1314
+ return I;
1187
1315
  }
1188
- function pe() {
1316
+ function Ee() {
1189
1317
  var s, i;
1190
1318
  if (typeof document == "undefined") return;
1191
- const r = document.currentScript;
1192
- if (!r) return;
1193
- const e = r.dataset;
1319
+ const o = document.currentScript;
1320
+ if (!o) return;
1321
+ const e = o.dataset;
1194
1322
  if (e.autoinit === "false") return;
1195
1323
  const t = e.org;
1196
1324
  if (!t) {
1197
1325
  console.error("SpilkiWidget: data-org and is required for auto init");
1198
1326
  return;
1199
1327
  }
1200
- x = $({
1328
+ E = z({
1201
1329
  org: t,
1202
1330
  installationToken: e.installationToken,
1203
1331
  apiBase: e.apiBase,
@@ -1205,13 +1333,13 @@ function pe() {
1205
1333
  theme: (i = e.theme) != null ? i : void 0
1206
1334
  });
1207
1335
  }
1208
- let x = null;
1209
- typeof window != "undefined" && (window.SpilkiWidget = window.SpilkiWidget || {}, window.SpilkiWidget.init = (r) => (x = $(r), x), window.SpilkiWidget.identify = (r) => {
1210
- x ? x.identify(r) : console.warn("SpilkiWidget: call init() before identify()");
1336
+ let E = null;
1337
+ typeof window != "undefined" && (window.SpilkiWidget = window.SpilkiWidget || {}, window.SpilkiWidget.init = (o) => (E = z(o), E), window.SpilkiWidget.identify = (o) => {
1338
+ E ? E.identify(o) : console.warn("SpilkiWidget: call init() before identify()");
1211
1339
  });
1212
- pe();
1340
+ Ee();
1213
1341
  export {
1214
- pe as autoInit,
1215
- $ as initSpilkiWidget
1342
+ Ee as autoInit,
1343
+ z as initSpilkiWidget
1216
1344
  };
1217
1345
  //# sourceMappingURL=widget.es.js.map