claudius-chat-widget 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/claudius.js CHANGED
@@ -1,9 +1,9 @@
1
- var Ce = Object.defineProperty;
2
- var Ne = (e, t, r) => t in e ? Ce(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
3
- var X = (e, t, r) => Ne(e, typeof t != "symbol" ? t + "" : t, r);
4
- import { jsx as a, jsxs as g, Fragment as xe } from "react/jsx-runtime";
5
- import { useMemo as se, useState as L, useRef as I, useCallback as O, useEffect as z, forwardRef as ke, memo as de, useId as Le } from "react";
6
- class j extends Error {
1
+ var Ke = Object.defineProperty;
2
+ var Ye = (e, t, n) => t in e ? Ke(e, t, { enumerable: !0, configurable: !0, writable: !0, value: n }) : e[t] = n;
3
+ var oe = (e, t, n) => Ye(e, typeof t != "symbol" ? t + "" : t, n);
4
+ import { jsx as i, jsxs as p, Fragment as we } from "react/jsx-runtime";
5
+ import { useMemo as ae, useState as O, useRef as L, useCallback as M, useEffect as K, forwardRef as qe, memo as ge, useId as Qe } from "react";
6
+ class V extends Error {
7
7
  /**
8
8
  * Create a {@link ChatApiError}.
9
9
  *
@@ -12,31 +12,36 @@ class j extends Error {
12
12
  * @param code - Optional machine-readable error code (e.g. `"TIMEOUT"`, `"NETWORK_ERROR"`).
13
13
  * @param retryAfter - Seconds to wait before retrying, from the `Retry-After` header.
14
14
  */
15
- constructor(t, r, n, s) {
16
- super(t), this.status = r, this.code = n, this.retryAfter = s, this.name = "ChatApiError";
15
+ constructor(t, n, r, s) {
16
+ super(t), this.status = n, this.code = r, this.retryAfter = s, this.name = "ChatApiError";
17
17
  }
18
18
  }
19
- class le extends Error {
19
+ class ye extends Error {
20
20
  /** Creates a `DebounceError` with a fixed message. */
21
21
  constructor() {
22
22
  super("Request debounced"), this.name = "DebounceError";
23
23
  }
24
24
  }
25
- const Ae = 3e4;
26
- class Oe {
25
+ const Ze = 3e4;
26
+ function Je(e, t) {
27
+ const n = atob(e), r = new Uint8Array(n.length);
28
+ for (let s = 0; s < n.length; s++) r[s] = n.charCodeAt(s);
29
+ return new Blob([r], { type: t });
30
+ }
31
+ class Xe {
27
32
  /**
28
33
  * Create a chat client for the given Worker base URL.
29
34
  *
30
35
  * @param baseUrl - Base URL of the Worker. Requests post to `${baseUrl}/api/chat`.
31
36
  * @param options - Optional retry, debounce, and timeout settings.
32
37
  */
33
- constructor(t, r) {
34
- X(this, "baseUrl");
35
- X(this, "maxRetries");
36
- X(this, "debounceMs");
37
- X(this, "timeoutMs");
38
- X(this, "lastSendTime", 0);
39
- this.baseUrl = t, this.maxRetries = (r == null ? void 0 : r.maxRetries) ?? 2, this.debounceMs = (r == null ? void 0 : r.debounceMs) ?? 300, this.timeoutMs = (r == null ? void 0 : r.timeoutMs) ?? Ae;
38
+ constructor(t, n) {
39
+ oe(this, "baseUrl");
40
+ oe(this, "maxRetries");
41
+ oe(this, "debounceMs");
42
+ oe(this, "timeoutMs");
43
+ oe(this, "lastSendTime", 0);
44
+ this.baseUrl = t, this.maxRetries = (n == null ? void 0 : n.maxRetries) ?? 2, this.debounceMs = (n == null ? void 0 : n.debounceMs) ?? 300, this.timeoutMs = (n == null ? void 0 : n.timeoutMs) ?? Ze;
40
45
  }
41
46
  /**
42
47
  * Send the conversation to the chat endpoint and return the assistant's
@@ -50,44 +55,73 @@ class Oe {
50
55
  */
51
56
  async sendMessage(t) {
52
57
  if (this.debounceMs > 0 && Date.now() - this.lastSendTime < this.debounceMs)
53
- throw new le();
58
+ throw new ye();
54
59
  this.lastSendTime = Date.now();
55
- let r;
56
- for (let n = 0; n <= this.maxRetries; n++)
60
+ let n;
61
+ for (let r = 0; r <= this.maxRetries; r++)
57
62
  try {
58
63
  const s = await this.fetchWithTimeout(t);
59
64
  if (s.ok)
60
65
  return await s.json();
61
- const o = await s.json().catch(() => ({})), i = s.headers.get("Retry-After"), l = i ? Number(i) : void 0;
62
- if (r = new j(
66
+ const o = await s.json().catch(() => ({})), a = s.headers.get("Retry-After"), c = a ? Number(a) : void 0;
67
+ if (n = new V(
63
68
  o.error ?? `Request failed with status ${s.status}`,
64
69
  s.status,
65
70
  o.code,
66
- l
71
+ c
67
72
  ), !this.isRetryable(s.status))
68
- throw r;
69
- if (n < this.maxRetries) {
70
- const c = this.getRetryDelay(s, n);
71
- await this.delay(c);
73
+ throw n;
74
+ if (r < this.maxRetries) {
75
+ const u = this.getRetryDelay(s, r);
76
+ await this.delay(u);
72
77
  }
73
78
  } catch (s) {
74
- if (s instanceof j) {
79
+ if (s instanceof V) {
75
80
  if (!this.isRetryable(s.status, s.code))
76
81
  throw s;
77
- if (r = s, n < this.maxRetries) {
78
- const o = this.getRetryDelay(null, n);
82
+ if (n = s, r < this.maxRetries) {
83
+ const o = this.getRetryDelay(null, r);
79
84
  await this.delay(o);
80
85
  }
81
- } else if (r = new j(
86
+ } else if (n = new V(
82
87
  "Failed to connect. Please try again.",
83
88
  0,
84
89
  "NETWORK_ERROR"
85
- ), n < this.maxRetries) {
86
- const o = this.getRetryDelay(null, n);
90
+ ), r < this.maxRetries) {
91
+ const o = this.getRetryDelay(null, r);
87
92
  await this.delay(o);
88
93
  }
89
94
  }
90
- throw r;
95
+ throw n;
96
+ }
97
+ /**
98
+ * Build the request body: JSON by default, multipart when any attachment
99
+ * still carries inline bytes. A fresh body is built per attempt so retries
100
+ * never reuse a consumed stream.
101
+ */
102
+ buildRequest(t) {
103
+ if (!t.some(
104
+ (o) => {
105
+ var a;
106
+ return (a = o.attachments) == null ? void 0 : a.some((c) => !!c.data);
107
+ }
108
+ ))
109
+ return {
110
+ headers: { "Content-Type": "application/json" },
111
+ body: JSON.stringify({ messages: t })
112
+ };
113
+ const r = new FormData(), s = t.map((o) => o.attachments ? {
114
+ ...o,
115
+ attachments: o.attachments.map((a) => {
116
+ const c = { ...a };
117
+ return delete c.data, c;
118
+ })
119
+ } : o);
120
+ r.append("payload", JSON.stringify({ messages: s }));
121
+ for (const o of t)
122
+ for (const a of o.attachments ?? [])
123
+ a.data && r.append(a.id, Je(a.data, a.mediaType), a.name);
124
+ return { body: r };
91
125
  }
92
126
  /**
93
127
  * Send the conversation to the streaming chat endpoint and resolve with the
@@ -109,107 +143,110 @@ class Oe {
109
143
  * @throws {@link ChatApiError} when the request fails after all retries, or
110
144
  * the stream errors or is interrupted mid-reply (code `"STREAM_ERROR"`).
111
145
  */
112
- async streamMessage(t, r = {}) {
146
+ async streamMessage(t, n = {}) {
113
147
  var s;
114
148
  if (typeof ReadableStream > "u")
115
149
  return this.sendMessage(t);
116
150
  if (this.debounceMs > 0 && Date.now() - this.lastSendTime < this.debounceMs)
117
- throw new le();
151
+ throw new ye();
118
152
  this.lastSendTime = Date.now();
119
- let n;
153
+ let r;
120
154
  for (let o = 0; o <= this.maxRetries; o++) {
121
- let i;
155
+ let a;
122
156
  try {
123
- i = await this.fetchStream(t, r.signal);
124
- } catch (c) {
125
- if ((s = r.signal) != null && s.aborted)
157
+ a = await this.fetchStream(t, n.signal);
158
+ } catch (u) {
159
+ if ((s = n.signal) != null && s.aborted)
126
160
  return { reply: "", aborted: !0 };
127
- if (n = c instanceof j ? c : new j(
161
+ if (r = u instanceof V ? u : new V(
128
162
  "Failed to connect. Please try again.",
129
163
  0,
130
164
  "NETWORK_ERROR"
131
- ), !this.isRetryable(n.status, n.code))
132
- throw n;
165
+ ), !this.isRetryable(r.status, r.code))
166
+ throw r;
133
167
  o < this.maxRetries && await this.delay(this.getRetryDelay(null, o));
134
168
  continue;
135
169
  }
136
- if (i.status === 404 || i.status === 405)
170
+ if (a.status === 404 || a.status === 405)
137
171
  return this.lastSendTime = 0, this.sendMessage(t);
138
- if (!i.ok) {
139
- const c = await i.json().catch(() => ({})), u = i.headers.get("Retry-After");
140
- if (n = new j(
141
- c.error ?? `Request failed with status ${i.status}`,
142
- i.status,
143
- c.code,
144
- u ? Number(u) : void 0
145
- ), !this.isRetryable(i.status))
146
- throw n;
147
- o < this.maxRetries && await this.delay(this.getRetryDelay(i, o));
172
+ if (!a.ok) {
173
+ const u = await a.json().catch(() => ({})), l = a.headers.get("Retry-After");
174
+ if (r = new V(
175
+ u.error ?? `Request failed with status ${a.status}`,
176
+ a.status,
177
+ u.code,
178
+ l ? Number(l) : void 0
179
+ ), !this.isRetryable(a.status))
180
+ throw r;
181
+ o < this.maxRetries && await this.delay(this.getRetryDelay(a, o));
148
182
  continue;
149
183
  }
150
- if (!(i.headers.get("Content-Type") ?? "").includes("text/event-stream"))
184
+ if (!(a.headers.get("Content-Type") ?? "").includes("text/event-stream"))
151
185
  try {
152
- return await i.json();
186
+ return await a.json();
153
187
  } catch {
154
188
  return this.lastSendTime = 0, this.sendMessage(t);
155
189
  }
156
- return i.body ? this.readSseStream(i.body, r) : (this.lastSendTime = 0, this.sendMessage(t));
190
+ return a.body ? this.readSseStream(a.body, n) : (this.lastSendTime = 0, this.sendMessage(t));
157
191
  }
158
- throw n;
192
+ throw r;
159
193
  }
160
194
  /**
161
195
  * Consumes an SSE body, invoking `onChunk` per `chunk` event, resolving on
162
196
  * `done`, throwing on `error` events or an interrupted connection, and
163
197
  * resolving with the partial text when the caller aborts.
164
198
  */
165
- async readSseStream(t, r) {
166
- var d, x, N, R, T, p, v;
167
- const n = t.getReader(), s = new TextDecoder();
168
- let o = "", i = "";
169
- const l = [];
170
- let c;
171
- const u = () => {
172
- n.cancel().catch(() => {
199
+ async readSseStream(t, n) {
200
+ var m, E, N, g, d, f, v;
201
+ const r = t.getReader(), s = new TextDecoder();
202
+ let o = "", a = "";
203
+ const c = [];
204
+ let u;
205
+ const l = () => {
206
+ r.cancel().catch(() => {
173
207
  });
174
208
  };
175
- (d = r.signal) == null || d.addEventListener("abort", u, { once: !0 });
209
+ (m = n.signal) == null || m.addEventListener("abort", l, { once: !0 });
176
210
  try {
177
211
  for (; ; ) {
178
- let k;
212
+ let D;
179
213
  try {
180
- k = await n.read();
181
- } catch (w) {
182
- if ((x = r.signal) != null && x.aborted) break;
183
- throw w;
214
+ D = await r.read();
215
+ } catch (T) {
216
+ if ((E = n.signal) != null && E.aborted) break;
217
+ throw T;
184
218
  }
185
- if ((N = r.signal) != null && N.aborted || k.done) break;
186
- o += s.decode(k.value, { stream: !0 });
187
- let H;
188
- for (; (H = o.indexOf(`
219
+ if ((N = n.signal) != null && N.aborted || D.done) break;
220
+ o += s.decode(D.value, { stream: !0 });
221
+ let C;
222
+ for (; (C = o.indexOf(`
189
223
 
190
224
  `)) !== -1; ) {
191
- const w = o.slice(0, H);
192
- o = o.slice(H + 2);
193
- const f = Ie(w);
194
- if (f) {
195
- if (f.event === "chunk") {
196
- const E = typeof f.data.text == "string" ? f.data.text : "";
197
- E && (i += E, (R = r.onChunk) == null || R.call(r, E, i));
198
- } else if (f.event === "tool") {
199
- if (typeof f.data.name == "string") {
200
- const E = f.data;
201
- l.push(E), (T = r.onToolUse) == null || T.call(r, E, l);
225
+ const T = o.slice(0, C);
226
+ o = o.slice(C + 2);
227
+ const b = et(T);
228
+ if (b) {
229
+ if (b.event === "chunk") {
230
+ const k = typeof b.data.text == "string" ? b.data.text : "";
231
+ k && (a += k, (g = n.onChunk) == null || g.call(n, k, a));
232
+ } else if (b.event === "tool") {
233
+ if (typeof b.data.name == "string") {
234
+ const k = b.data;
235
+ c.push(k), (d = n.onToolUse) == null || d.call(n, k, c);
202
236
  }
203
- } else if (f.event === "done") {
204
- const E = Array.isArray(f.data.toolUses) ? f.data.toolUses : l;
205
- c = {
206
- reply: typeof f.data.reply == "string" ? f.data.reply : i,
207
- sources: f.data.sources,
208
- ...E.length > 0 ? { toolUses: E } : {}
237
+ } else if (b.event === "done") {
238
+ const k = Array.isArray(b.data.toolUses) ? b.data.toolUses : c;
239
+ u = {
240
+ reply: typeof b.data.reply == "string" ? b.data.reply : a,
241
+ sources: b.data.sources,
242
+ ...k.length > 0 ? { toolUses: k } : {},
243
+ ...Array.isArray(b.data.attachments) ? {
244
+ attachments: b.data.attachments
245
+ } : {}
209
246
  };
210
- } else if (f.event === "error")
211
- throw new j(
212
- typeof f.data.error == "string" ? f.data.error : "Something went wrong. Please try again.",
247
+ } else if (b.event === "error")
248
+ throw new V(
249
+ typeof b.data.error == "string" ? b.data.error : "Something went wrong. Please try again.",
213
250
  0,
214
251
  "STREAM_ERROR"
215
252
  );
@@ -217,492 +254,630 @@ class Oe {
217
254
  }
218
255
  }
219
256
  } finally {
220
- (p = r.signal) == null || p.removeEventListener("abort", u), n.releaseLock();
257
+ (f = n.signal) == null || f.removeEventListener("abort", l), r.releaseLock();
221
258
  }
222
- if ((v = r.signal) != null && v.aborted)
259
+ if ((v = n.signal) != null && v.aborted)
223
260
  return {
224
- reply: i,
261
+ reply: a,
225
262
  aborted: !0,
226
- ...l.length > 0 ? { toolUses: l } : {}
263
+ ...c.length > 0 ? { toolUses: c } : {}
227
264
  };
228
- if (c) return c;
229
- throw new j(
265
+ if (u) return u;
266
+ throw new V(
230
267
  "Connection interrupted. Please try again.",
231
268
  0,
232
269
  "STREAM_ERROR"
233
270
  );
234
271
  }
235
- async fetchStream(t, r) {
236
- const n = new AbortController(), s = () => n.abort();
237
- r == null || r.addEventListener("abort", s, { once: !0 });
272
+ async fetchStream(t, n) {
273
+ const r = new AbortController(), s = () => r.abort();
274
+ n == null || n.addEventListener("abort", s, { once: !0 });
238
275
  let o = !1;
239
- const i = this.timeoutMs > 0 ? setTimeout(() => {
240
- o = !0, n.abort();
241
- }, this.timeoutMs) : void 0;
276
+ const a = this.timeoutMs > 0 ? setTimeout(() => {
277
+ o = !0, r.abort();
278
+ }, this.timeoutMs) : void 0, { headers: c, body: u } = this.buildRequest(t);
242
279
  try {
243
280
  return await fetch(`${this.baseUrl}/api/chat/stream`, {
244
281
  method: "POST",
245
- headers: { "Content-Type": "application/json" },
246
- body: JSON.stringify({ messages: t }),
247
- signal: n.signal
282
+ headers: c,
283
+ body: u,
284
+ signal: r.signal
248
285
  });
249
286
  } catch (l) {
250
- throw o ? new j(
287
+ throw o ? new V(
251
288
  "Request timed out. Please try again.",
252
289
  0,
253
290
  "TIMEOUT"
254
291
  ) : l;
255
292
  } finally {
256
- i !== void 0 && clearTimeout(i), r == null || r.removeEventListener("abort", s);
293
+ a !== void 0 && clearTimeout(a), n == null || n.removeEventListener("abort", s);
257
294
  }
258
295
  }
259
296
  async fetchWithTimeout(t) {
297
+ const { headers: n, body: r } = this.buildRequest(t);
260
298
  if (this.timeoutMs <= 0)
261
299
  return fetch(`${this.baseUrl}/api/chat`, {
262
300
  method: "POST",
263
- headers: { "Content-Type": "application/json" },
264
- body: JSON.stringify({ messages: t })
301
+ headers: n,
302
+ body: r
265
303
  });
266
- const r = new AbortController(), n = setTimeout(() => r.abort(), this.timeoutMs);
304
+ const s = new AbortController(), o = setTimeout(() => s.abort(), this.timeoutMs);
267
305
  try {
268
306
  return await fetch(`${this.baseUrl}/api/chat`, {
269
307
  method: "POST",
270
- headers: { "Content-Type": "application/json" },
271
- body: JSON.stringify({ messages: t }),
272
- signal: r.signal
308
+ headers: n,
309
+ body: r,
310
+ signal: s.signal
273
311
  });
274
- } catch (s) {
275
- throw r.signal.aborted ? new j(
312
+ } catch (a) {
313
+ throw s.signal.aborted ? new V(
276
314
  "Request timed out. Please try again.",
277
315
  0,
278
316
  "TIMEOUT"
279
- ) : s;
317
+ ) : a;
280
318
  } finally {
281
- clearTimeout(n);
319
+ clearTimeout(o);
282
320
  }
283
321
  }
284
- isRetryable(t, r) {
285
- return r === "TIMEOUT" || r === "NETWORK_ERROR" ? !0 : t === 429 || t === 503;
322
+ isRetryable(t, n) {
323
+ return n === "TIMEOUT" || n === "NETWORK_ERROR" ? !0 : t === 429 || t === 503;
286
324
  }
287
- getRetryDelay(t, r) {
325
+ getRetryDelay(t, n) {
288
326
  if (t && t.status === 429) {
289
- const n = t.headers.get("Retry-After");
290
- if (n) {
291
- const s = Number(n);
327
+ const r = t.headers.get("Retry-After");
328
+ if (r) {
329
+ const s = Number(r);
292
330
  return Math.min(s * 1e3, 6e4);
293
331
  }
294
332
  }
295
- return r === 0 ? 1e3 : 3e3;
333
+ return n === 0 ? 1e3 : 3e3;
296
334
  }
297
335
  delay(t) {
298
- return new Promise((r) => setTimeout(r, t));
336
+ return new Promise((n) => setTimeout(n, t));
299
337
  }
300
338
  }
301
- function Ie(e) {
339
+ function et(e) {
302
340
  let t = "message";
303
- const r = [];
304
- for (const n of e.split(`
341
+ const n = [];
342
+ for (const r of e.split(`
305
343
  `))
306
- n.startsWith("event:") ? t = n.slice(6).trim() : n.startsWith("data:") && r.push(n.slice(5).trimStart());
307
- if (r.length === 0) return null;
344
+ r.startsWith("event:") ? t = r.slice(6).trim() : r.startsWith("data:") && n.push(r.slice(5).trimStart());
345
+ if (n.length === 0) return null;
308
346
  try {
309
- const n = JSON.parse(r.join(`
347
+ const r = JSON.parse(n.join(`
310
348
  `));
311
- return typeof n != "object" || n === null ? null : { event: t, data: n };
349
+ return typeof r != "object" || r === null ? null : { event: t, data: r };
312
350
  } catch {
313
351
  return null;
314
352
  }
315
353
  }
316
- function we(e) {
354
+ function Be(e) {
317
355
  return typeof e == "string" ? { content: e } : e;
318
356
  }
319
- function fe(e, t, r) {
320
- console.error(`[claudius] plugin "${e.name}" failed in ${t}:`, r);
357
+ function Re(e, t, n) {
358
+ console.error(`[claudius] plugin "${e.name}" failed in ${t}:`, n);
321
359
  }
322
- async function De(e, t, r) {
323
- let n = t;
360
+ async function tt(e, t, n) {
361
+ let r = t;
324
362
  for (const s of e) {
325
363
  if (!s.onBeforeSend) continue;
326
364
  let o = null;
327
- const i = {
328
- ...r,
329
- respondWith(l) {
365
+ const a = {
366
+ ...n,
367
+ respondWith(c) {
330
368
  o = {
331
369
  type: "respond",
332
- message: n,
333
- reply: we(l)
370
+ message: r,
371
+ reply: Be(c)
334
372
  };
335
373
  },
336
- abort(l) {
337
- o = { type: "abort", reason: l };
374
+ abort(c) {
375
+ o = { type: "abort", reason: c };
338
376
  }
339
377
  };
340
378
  try {
341
- const l = await s.onBeforeSend(n, i);
379
+ const c = await s.onBeforeSend(r, a);
342
380
  if (o) return o;
343
- l && (n = l);
344
- } catch (l) {
345
- fe(s, "onBeforeSend", l);
381
+ c && (r = c);
382
+ } catch (c) {
383
+ Re(s, "onBeforeSend", c);
346
384
  }
347
385
  }
348
- return { type: "send", message: n };
386
+ return { type: "send", message: r };
349
387
  }
350
- async function _e(e, t, r) {
351
- let n = t;
388
+ async function nt(e, t, n) {
389
+ let r = t;
352
390
  for (const s of e)
353
391
  if (s.onAfterReceive)
354
392
  try {
355
- const o = await s.onAfterReceive(n, r);
356
- o && (n = o);
393
+ const o = await s.onAfterReceive(r, n);
394
+ o && (r = o);
357
395
  } catch (o) {
358
- fe(s, "onAfterReceive", o);
396
+ Re(s, "onAfterReceive", o);
359
397
  }
360
- return n;
398
+ return r;
361
399
  }
362
- async function je(e, t, r) {
363
- for (const n of e) {
364
- if (!n.onError) continue;
400
+ async function rt(e, t, n) {
401
+ for (const r of e) {
402
+ if (!r.onError) continue;
365
403
  let s = null;
366
404
  const o = {
367
- ...r,
368
- respondWith(i) {
369
- s = we(i);
405
+ ...n,
406
+ respondWith(a) {
407
+ s = Be(a);
370
408
  }
371
409
  };
372
410
  try {
373
- if (await n.onError(t, o), s) return s;
374
- } catch (i) {
375
- fe(n, "onError", i);
411
+ if (await r.onError(t, o), s) return s;
412
+ } catch (a) {
413
+ Re(r, "onError", a);
376
414
  }
377
415
  }
378
416
  return null;
379
417
  }
380
- const He = 200, Be = "claudius:messages";
381
- function $e(e, t) {
382
- let r;
418
+ const fe = {
419
+ maxSizeBytes: 5 * 1024 * 1024,
420
+ maxCount: 5,
421
+ allowedTypes: [
422
+ "image/jpeg",
423
+ "image/png",
424
+ "image/gif",
425
+ "image/webp",
426
+ "application/pdf"
427
+ ]
428
+ };
429
+ function st(e) {
430
+ return e ? e === !0 ? fe : {
431
+ maxSizeBytes: e.maxSizeBytes ?? fe.maxSizeBytes,
432
+ maxCount: e.maxCount ?? fe.maxCount,
433
+ allowedTypes: (e.allowedTypes ?? fe.allowedTypes).map((t) => t.trim().toLowerCase()).filter(Boolean)
434
+ } : null;
435
+ }
436
+ function xe(e) {
437
+ if (!Number.isFinite(e) || e < 0) return "0 B";
438
+ if (e < 1024) return `${e} B`;
439
+ const t = e / 1024;
440
+ if (t < 1024) return `${Math.round(t)} KB`;
441
+ const n = t / 1024;
442
+ return `${Number.isInteger(n) ? n : n.toFixed(1)} MB`;
443
+ }
444
+ const ot = {
445
+ png: "image/png",
446
+ jpg: "image/jpeg",
447
+ jpeg: "image/jpeg",
448
+ gif: "image/gif",
449
+ webp: "image/webp",
450
+ pdf: "application/pdf"
451
+ };
452
+ function He(e) {
453
+ var r;
454
+ const t = (e.type || "").trim().toLowerCase();
455
+ if (t) return t;
456
+ const n = ((r = e.name.split(".").pop()) == null ? void 0 : r.toLowerCase()) ?? "";
457
+ return ot[n] ?? "";
458
+ }
459
+ function at(e) {
460
+ return e.startsWith("image/");
461
+ }
462
+ function it(e) {
463
+ if (at(e.mediaType)) {
464
+ if (e.url)
465
+ try {
466
+ const t = new URL(e.url);
467
+ if (t.protocol === "http:" || t.protocol === "https:")
468
+ return e.url;
469
+ } catch {
470
+ }
471
+ if (e.data) return `data:${e.mediaType};base64,${e.data}`;
472
+ }
473
+ }
474
+ function ct(e, t, n) {
475
+ const r = [], s = [];
476
+ let o = Math.max(0, n.maxCount - t);
477
+ for (const a of e) {
478
+ const c = He(a);
479
+ !c || !n.allowedTypes.includes(c) ? s.push({ file: a, reason: "type" }) : a.size > n.maxSizeBytes || a.size === 0 ? s.push({ file: a, reason: "size" }) : o <= 0 ? s.push({ file: a, reason: "count" }) : (r.push(a), o -= 1);
480
+ }
481
+ return { accepted: r, rejected: s };
482
+ }
483
+ function lt(e) {
484
+ return new Promise((t, n) => {
485
+ const r = new FileReader();
486
+ r.onerror = () => n(r.error ?? new Error("Failed to read file")), r.onload = () => {
487
+ const s = String(r.result ?? ""), o = s.indexOf(",");
488
+ t(o >= 0 ? s.slice(o + 1) : s);
489
+ }, r.readAsDataURL(e);
490
+ });
491
+ }
492
+ let Se = 0;
493
+ function ut() {
494
+ return Se += 1, `att-${Date.now().toString(36)}-${Se}`;
495
+ }
496
+ async function dt(e) {
497
+ const t = await lt(e);
498
+ return {
499
+ id: ut(),
500
+ name: e.name || "attachment",
501
+ mediaType: He(e),
502
+ size: e.size,
503
+ data: t
504
+ };
505
+ }
506
+ function ht(e) {
507
+ return e.map((t) => {
508
+ var n;
509
+ return (n = t.attachments) != null && n.some((r) => r.data) ? {
510
+ ...t,
511
+ attachments: t.attachments.map((r) => {
512
+ if (!r.data) return r;
513
+ const s = { ...r };
514
+ return delete s.data, s;
515
+ })
516
+ } : t;
517
+ });
518
+ }
519
+ function ft(e, t) {
520
+ if (!t || t.length === 0) return e;
521
+ const n = new Map(t.map((r) => [r.id, r]));
522
+ return e.map((r) => {
523
+ var s;
524
+ return (s = r.attachments) != null && s.some((o) => n.has(o.id)) ? {
525
+ ...r,
526
+ attachments: r.attachments.map((o) => {
527
+ const a = n.get(o.id);
528
+ if (!a) return o;
529
+ const c = {
530
+ ...o,
531
+ key: a.key,
532
+ url: a.url,
533
+ expiresAt: a.expiresAt
534
+ };
535
+ return delete c.data, c;
536
+ })
537
+ } : r;
538
+ });
539
+ }
540
+ const mt = 200, pt = "claudius:messages";
541
+ function gt(e, t) {
542
+ let n;
383
543
  try {
384
- r = new URL(t).host;
544
+ n = new URL(t).host;
385
545
  } catch {
386
- r = t;
546
+ n = t;
387
547
  }
388
- return `${e}:${r}`;
548
+ return `${e}:${n}`;
389
549
  }
390
- function ue() {
550
+ function ve() {
391
551
  try {
392
552
  return typeof sessionStorage < "u" ? sessionStorage : null;
393
553
  } catch {
394
554
  return null;
395
555
  }
396
556
  }
397
- function Pe(e) {
398
- const t = ue();
557
+ function bt(e) {
558
+ const t = ve();
399
559
  if (!t) return [];
400
560
  try {
401
- const r = t.getItem(e);
402
- if (!r) return [];
403
- const n = JSON.parse(r);
404
- return Array.isArray(n) ? n : [];
561
+ const n = t.getItem(e);
562
+ if (!n) return [];
563
+ const r = JSON.parse(n);
564
+ return Array.isArray(r) ? r : [];
405
565
  } catch {
406
566
  return [];
407
567
  }
408
568
  }
409
- function Ue({
569
+ function yt({
410
570
  apiUrl: e,
411
571
  persistMessages: t = !0,
412
- storageKeyPrefix: r = Be,
413
- timeoutMs: n,
572
+ storageKeyPrefix: n = pt,
573
+ timeoutMs: r,
414
574
  translations: s,
415
575
  plugins: o,
416
- streaming: i = !0
576
+ streaming: a = !0
417
577
  }) {
418
- const l = se(
419
- () => new Oe(e, { debounceMs: 0, timeoutMs: n }),
420
- [e, n]
421
- ), c = $e(r, e), u = t ? Pe(c) : [], [d, x] = L(u), [N, R] = L(!1), [T, p] = L(!1), [v, k] = L(
578
+ const c = ae(
579
+ () => new Xe(e, { debounceMs: 0, timeoutMs: r }),
580
+ [e, r]
581
+ ), u = gt(n, e), l = t ? bt(u) : [], [m, E] = O(l), [N, g] = O(!1), [d, f] = O(!1), [v, D] = O(
422
582
  null
423
- ), [H, w] = L(null), [f, E] = L(!1), F = I(u.length), W = I(!1), y = I(u), K = I(null), B = I(o ?? []);
424
- B.current = o ?? [];
425
- const _ = O(
426
- (h) => {
583
+ ), [C, T] = O(null), [b, k] = O(!1), A = L(l.length), B = L(!1), y = L(l), W = L(null), U = L(o ?? []);
584
+ U.current = o ?? [];
585
+ const H = M(
586
+ (x) => {
427
587
  if (!t) return;
428
- const A = ue();
429
- if (A)
588
+ const z = ve();
589
+ if (z)
430
590
  try {
431
- const S = h.slice(-He);
432
- A.setItem(c, JSON.stringify(S));
591
+ const I = ht(x.slice(-mt));
592
+ z.setItem(u, JSON.stringify(I));
433
593
  } catch {
434
594
  }
435
595
  },
436
- [t, c]
437
- ), m = () => (F.current += 1, `msg-${F.current}`), V = O(
438
- (h, A) => {
596
+ [t, u]
597
+ ), _ = () => (A.current += 1, `msg-${A.current}`), J = M(
598
+ (x, z) => {
439
599
  if (!s)
440
- return A ?? "Something went wrong. Please try again.";
441
- switch (h) {
600
+ return z ?? "Something went wrong. Please try again.";
601
+ switch (x) {
442
602
  case "TIMEOUT":
443
603
  return s.errorTimeout;
444
604
  case "NETWORK_ERROR":
445
605
  return s.errorConnection;
446
606
  case "RATE_LIMITED":
447
- return A != null && A.includes("minute") ? s.errorRateLimitMinute : s.errorRateLimitHour;
607
+ return z != null && z.includes("minute") ? s.errorRateLimitMinute : s.errorRateLimitHour;
608
+ case "ATTACHMENT_QUOTA_EXCEEDED":
609
+ return s.errorAttachmentQuota;
610
+ case "ATTACHMENTS_DISABLED":
611
+ case "ATTACHMENT_INVALID":
612
+ case "ATTACHMENT_TOO_LARGE":
613
+ return s.errorAttachmentRejected;
448
614
  case "VALIDATION_ERROR":
449
615
  case "CONFIG_ERROR":
450
616
  case "SERVICE_ERROR":
451
617
  case "UNKNOWN_ERROR":
452
618
  default:
453
- return A ?? s.errorGeneric;
619
+ return z ?? s.errorGeneric;
454
620
  }
455
621
  },
456
622
  [s]
457
- ), ee = O((h) => !(h instanceof j) || h.code === "TIMEOUT" || h.code === "NETWORK_ERROR" || h.code === "RATE_LIMITED" || h.code === "SERVICE_ERROR" || h.code === "UNKNOWN_ERROR" || h.status >= 500 || h.status === 0, []), J = O(
458
- async (h) => {
459
- R(!0), W.current = !0, w(null), E(!1);
460
- const A = i && typeof l.streamMessage == "function";
461
- let S = null;
462
- const Y = (b) => {
463
- if (S === null) {
464
- S = m(), k(S);
465
- const C = [
623
+ ), re = M((x) => !(x instanceof V) || x.code === "TIMEOUT" || x.code === "NETWORK_ERROR" || x.code === "RATE_LIMITED" || x.code === "SERVICE_ERROR" || x.code === "UNKNOWN_ERROR" || x.status >= 500 || x.status === 0, []), X = M(
624
+ async (x) => {
625
+ var ne, Z;
626
+ g(!0), B.current = !0, T(null), k(!1);
627
+ const z = a && typeof c.streamMessage == "function";
628
+ let I = null;
629
+ const Q = (R) => {
630
+ if (I === null) {
631
+ I = _(), D(I);
632
+ const j = [
466
633
  ...y.current,
467
- { id: S, role: "assistant", content: "", ...b }
634
+ { id: I, role: "assistant", content: "", ...R }
468
635
  ];
469
- y.current = C, x(C);
636
+ y.current = j, E(j);
470
637
  } else {
471
- const C = S, M = y.current.map(
472
- (P) => P.id === C ? { ...P, ...b } : P
638
+ const j = I, P = y.current.map(
639
+ (Y) => Y.id === j ? { ...Y, ...R } : Y
473
640
  );
474
- y.current = M, x(M);
641
+ y.current = P, E(P);
475
642
  }
476
643
  }, $ = () => {
477
- if (S === null) return;
478
- const b = S, C = y.current.filter((M) => M.id !== b);
479
- y.current = C, x(C);
644
+ if (I === null) return;
645
+ const R = I, j = y.current.filter((P) => P.id !== R);
646
+ y.current = j, E(j);
480
647
  };
481
648
  try {
482
- let b, C, M, P = !1;
483
- if (A) {
484
- const G = new AbortController();
485
- K.current = G, p(!0);
486
- const q = await l.streamMessage(h, {
487
- signal: G.signal,
488
- onChunk: (ae, D) => Y({ content: D }),
489
- onToolUse: (ae, D) => Y({ toolUses: [...D] })
649
+ let R, j, P, Y, q = !1;
650
+ if (z) {
651
+ const S = new AbortController();
652
+ W.current = S, f(!0);
653
+ const F = await c.streamMessage(x, {
654
+ signal: S.signal,
655
+ onChunk: (ce, G) => Q({ content: G }),
656
+ onToolUse: (ce, G) => Q({ toolUses: [...G] })
490
657
  });
491
- b = q.reply, C = q.sources, M = q.toolUses, P = q.aborted ?? !1;
658
+ R = F.reply, j = F.sources, P = F.toolUses, Y = F.attachments, q = F.aborted ?? !1;
492
659
  } else {
493
- const G = await l.sendMessage(h);
494
- b = G.reply, C = G.sources, M = G.toolUses;
660
+ const S = await c.sendMessage(x);
661
+ R = S.reply, j = S.sources, P = S.toolUses, Y = S.attachments;
495
662
  }
496
- if (P && !b) {
663
+ if (q && !R) {
497
664
  $();
498
665
  return;
499
666
  }
500
- let U = {
501
- id: S ?? m(),
667
+ let se = {
668
+ id: I ?? _(),
502
669
  role: "assistant",
503
- content: b,
504
- sources: C,
505
- toolUses: M
670
+ content: R,
671
+ sources: j,
672
+ toolUses: P
506
673
  };
507
- B.current.length > 0 && !P && (U = await _e(
508
- B.current,
509
- U,
510
- { messages: h, apiUrl: e }
674
+ U.current.length > 0 && !q && (se = await nt(
675
+ U.current,
676
+ se,
677
+ { messages: x, apiUrl: e }
511
678
  ));
512
- const Z = S !== null ? y.current.map(
513
- (G) => G.id === U.id ? U : G
514
- ) : [...h, U];
515
- y.current = Z, x(Z), _(Z);
516
- } catch (b) {
517
- if (b instanceof le) return;
518
- if (S !== null) {
519
- _(y.current), b instanceof j ? w(V(b.code, b.message)) : w(
679
+ const he = I !== null ? y.current.map(
680
+ (S) => S.id === se.id ? se : S
681
+ ) : [...x, se], h = ft(he, Y);
682
+ y.current = h, E(h), H(h);
683
+ } catch (R) {
684
+ if (R instanceof ye) return;
685
+ if (R instanceof V && ((ne = R.code) != null && ne.startsWith("ATTACHMENT")) && x.length > 0) {
686
+ const j = x[x.length - 1];
687
+ if (j.role === "user" && ((Z = j.attachments) != null && Z.length)) {
688
+ const P = x.slice(0, -1);
689
+ y.current = P, E(P), H(P);
690
+ }
691
+ }
692
+ if (I !== null) {
693
+ H(y.current), R instanceof V ? T(J(R.code, R.message)) : T(
520
694
  (s == null ? void 0 : s.errorConnection) ?? "Failed to connect. Please try again."
521
- ), E(!1);
695
+ ), k(!1);
522
696
  return;
523
697
  }
524
- if (B.current.length > 0) {
525
- const C = b instanceof Error ? b : new Error(String(b)), M = await je(B.current, C, {
526
- messages: h,
698
+ if (U.current.length > 0) {
699
+ const j = R instanceof Error ? R : new Error(String(R)), P = await rt(U.current, j, {
700
+ messages: x,
527
701
  apiUrl: e
528
702
  });
529
- if (M) {
530
- const P = {
531
- id: m(),
703
+ if (P) {
704
+ const Y = {
705
+ id: _(),
532
706
  role: "assistant",
533
- content: M.content,
534
- sources: M.sources
535
- }, U = [...h, P];
536
- y.current = U, x(U), _(U), w(null), E(!1);
707
+ content: P.content,
708
+ sources: P.sources
709
+ }, q = [...x, Y];
710
+ y.current = q, E(q), H(q), T(null), k(!1);
537
711
  return;
538
712
  }
539
713
  }
540
- b instanceof j ? w(V(b.code, b.message)) : w(
714
+ R instanceof V ? T(J(R.code, R.message)) : T(
541
715
  (s == null ? void 0 : s.errorConnection) ?? "Failed to connect. Please try again."
542
- ), E(ee(b));
716
+ ), k(re(R));
543
717
  } finally {
544
- R(!1), W.current = !1, p(!1), k(null), K.current = null;
718
+ g(!1), B.current = !1, f(!1), D(null), W.current = null;
545
719
  }
546
720
  },
547
721
  [
548
722
  e,
549
- l,
550
- V,
551
- ee,
552
- _,
553
- i,
723
+ c,
724
+ J,
725
+ re,
726
+ H,
727
+ a,
554
728
  s
555
729
  ]
556
- ), oe = O(() => {
557
- var h;
558
- (h = K.current) == null || h.abort();
559
- }, []), ie = O(
560
- async (h) => {
561
- const A = h.trim();
562
- if (!A || W.current) return;
563
- const S = {
564
- id: m(),
730
+ ), te = M(() => {
731
+ var x;
732
+ (x = W.current) == null || x.abort();
733
+ }, []), w = M(
734
+ async (x, z) => {
735
+ const I = x.trim(), Q = (z == null ? void 0 : z.filter((R) => R && R.id)) ?? [];
736
+ if (!I && Q.length === 0 || B.current) return;
737
+ const $ = {
738
+ id: _(),
565
739
  role: "user",
566
- content: A
740
+ content: I,
741
+ ...Q.length > 0 ? { attachments: Q } : {}
567
742
  };
568
- let Y = S;
569
- if (B.current.length > 0) {
570
- const b = await De(B.current, S, {
743
+ let ne = $;
744
+ if (U.current.length > 0) {
745
+ const R = await tt(U.current, $, {
571
746
  messages: y.current,
572
747
  apiUrl: e
573
748
  });
574
- if (b.type === "abort") return;
575
- if (b.type === "respond") {
576
- const C = {
577
- id: m(),
749
+ if (R.type === "abort") return;
750
+ if (R.type === "respond") {
751
+ const j = {
752
+ id: _(),
578
753
  role: "assistant",
579
- content: b.reply.content,
580
- sources: b.reply.sources
581
- }, M = [
754
+ content: R.reply.content,
755
+ sources: R.reply.sources
756
+ }, P = [
582
757
  ...y.current,
583
- b.message,
584
- C
758
+ R.message,
759
+ j
585
760
  ];
586
- y.current = M, x(M), _(M), w(null), E(!1);
761
+ y.current = P, E(P), H(P), T(null), k(!1);
587
762
  return;
588
763
  }
589
- Y = b.message;
764
+ ne = R.message;
590
765
  }
591
- const $ = [...y.current, Y];
592
- y.current = $, x($), _($), await J($);
766
+ const Z = [...y.current, ne];
767
+ y.current = Z, E(Z), H(Z), await X(Z);
593
768
  },
594
- [e, _, J]
595
- ), te = O(async () => {
596
- if (W.current) return;
597
- const h = y.current[y.current.length - 1];
598
- !h || h.role !== "user" || await J(y.current);
599
- }, [J]), re = O(() => {
600
- if (y.current = [], x([]), w(null), E(!1), t) {
601
- const h = ue();
602
- if (!h) return;
769
+ [e, H, X]
770
+ ), ee = M(async () => {
771
+ if (B.current) return;
772
+ const x = y.current[y.current.length - 1];
773
+ !x || x.role !== "user" || await X(y.current);
774
+ }, [X]), ie = M(() => {
775
+ if (y.current = [], E([]), T(null), k(!1), t) {
776
+ const x = ve();
777
+ if (!x) return;
603
778
  try {
604
- h.removeItem(c);
779
+ x.removeItem(u);
605
780
  } catch {
606
781
  }
607
782
  }
608
- }, [t, c]);
783
+ }, [t, u]);
609
784
  return {
610
- messages: d,
785
+ messages: m,
611
786
  isLoading: N,
612
- isStreaming: T,
787
+ isStreaming: d,
613
788
  streamingMessageId: v,
614
- error: H,
615
- canRetry: f,
616
- sendMessage: ie,
617
- stop: oe,
618
- retry: te,
619
- clearMessages: re
789
+ error: C,
790
+ canRetry: b,
791
+ sendMessage: w,
792
+ stop: te,
793
+ retry: ee,
794
+ clearMessages: ie
620
795
  };
621
796
  }
622
- function Ge(e) {
623
- const [t, r] = L(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
624
- return z(() => {
625
- const n = window.matchMedia(e);
626
- r(n.matches);
627
- const s = (o) => r(o.matches);
628
- return n.addEventListener("change", s), () => n.removeEventListener("change", s);
797
+ function xt(e) {
798
+ const [t, n] = O(() => typeof window > "u" ? !1 : window.matchMedia(e).matches);
799
+ return K(() => {
800
+ const r = window.matchMedia(e);
801
+ n(r.matches);
802
+ const s = (o) => n(o.matches);
803
+ return r.addEventListener("change", s), () => r.removeEventListener("change", s);
629
804
  }, [e]), t;
630
805
  }
631
- function ne(e, t) {
806
+ function me(e, t) {
632
807
  return e instanceof RegExp ? e.test(t) : t.toLowerCase().includes(e.toLowerCase());
633
808
  }
634
- function We() {
635
- const e = document.documentElement, t = document.body, r = e.scrollTop || t.scrollTop || 0, n = Math.max(e.scrollHeight, t.scrollHeight), s = e.clientHeight || window.innerHeight, o = n - s;
636
- return o <= 0 ? 100 : r / o * 100;
809
+ function vt() {
810
+ const e = document.documentElement, t = document.body, n = e.scrollTop || t.scrollTop || 0, r = Math.max(e.scrollHeight, t.scrollHeight), s = e.clientHeight || window.innerHeight, o = r - s;
811
+ return o <= 0 ? 100 : n / o * 100;
637
812
  }
638
- function ze({
813
+ function wt({
639
814
  triggers: e,
640
815
  enabled: t,
641
- onOpen: r,
642
- onGreeting: n
816
+ onOpen: n,
817
+ onGreeting: r
643
818
  }) {
644
- z(() => {
819
+ K(() => {
645
820
  if (!t || !e || e.length === 0) return;
646
- const s = /* @__PURE__ */ new Set(), o = [], i = typeof window < "u" ? window.location.href : "", l = (c, u) => {
647
- s.has(c) || (s.add(c), u === "open" ? r() : n(u.greeting));
821
+ const s = /* @__PURE__ */ new Set(), o = [], a = typeof window < "u" ? window.location.href : "", c = (u, l) => {
822
+ s.has(u) || (s.add(u), l === "open" ? n() : r(l.greeting));
648
823
  };
649
- return e.forEach((c, u) => {
650
- switch (c.on) {
824
+ return e.forEach((u, l) => {
825
+ switch (u.on) {
651
826
  case "url": {
652
- ne(c.pattern, i) && l(u, c.action);
827
+ me(u.pattern, a) && c(l, u.action);
653
828
  break;
654
829
  }
655
830
  case "time": {
656
- if (c.matchUrl && !ne(c.matchUrl, i))
831
+ if (u.matchUrl && !me(u.matchUrl, a))
657
832
  return;
658
- const d = window.setTimeout(
659
- () => l(u, c.action),
660
- Math.max(0, c.seconds * 1e3)
833
+ const m = window.setTimeout(
834
+ () => c(l, u.action),
835
+ Math.max(0, u.seconds * 1e3)
661
836
  );
662
- o.push(() => window.clearTimeout(d));
837
+ o.push(() => window.clearTimeout(m));
663
838
  break;
664
839
  }
665
840
  case "scroll": {
666
- if (c.matchUrl && !ne(c.matchUrl, i))
841
+ if (u.matchUrl && !me(u.matchUrl, a))
667
842
  return;
668
- const d = () => {
669
- We() >= c.percent && l(u, c.action);
843
+ const m = () => {
844
+ vt() >= u.percent && c(l, u.action);
670
845
  };
671
- d(), window.addEventListener("scroll", d, { passive: !0 }), o.push(() => window.removeEventListener("scroll", d));
846
+ m(), window.addEventListener("scroll", m, { passive: !0 }), o.push(() => window.removeEventListener("scroll", m));
672
847
  break;
673
848
  }
674
849
  case "exit-intent": {
675
- if (c.matchUrl && !ne(c.matchUrl, i))
850
+ if (u.matchUrl && !me(u.matchUrl, a))
676
851
  return;
677
- const d = (x) => {
678
- x.clientY <= 0 && l(u, c.action);
852
+ const m = (E) => {
853
+ E.clientY <= 0 && c(l, u.action);
679
854
  };
680
- document.addEventListener("mouseleave", d), o.push(
681
- () => document.removeEventListener("mouseleave", d)
855
+ document.addEventListener("mouseleave", m), o.push(
856
+ () => document.removeEventListener("mouseleave", m)
682
857
  );
683
858
  break;
684
859
  }
685
860
  }
686
861
  }), () => {
687
- o.forEach((c) => c());
862
+ o.forEach((u) => u());
688
863
  };
689
- }, [e, t, r, n]);
864
+ }, [e, t, n, r]);
690
865
  }
691
- const Fe = {
866
+ const Rt = {
692
867
  "bottom-right": "bottom-6 right-6",
693
868
  "bottom-left": "bottom-6 left-6",
694
869
  "top-right": "top-6 right-6",
695
870
  "top-left": "top-6 left-6"
696
- }, Ve = ke(function({ isOpen: t, onClick: r, position: n = "bottom-right", translations: s }, o) {
697
- const i = t ? (s == null ? void 0 : s.closeChat) ?? "Close chat" : (s == null ? void 0 : s.openChat) ?? "Open chat";
698
- return /* @__PURE__ */ a(
871
+ }, Et = qe(function({ isOpen: t, onClick: n, position: r = "bottom-right", translations: s }, o) {
872
+ const a = t ? (s == null ? void 0 : s.closeChat) ?? "Close chat" : (s == null ? void 0 : s.openChat) ?? "Open chat";
873
+ return /* @__PURE__ */ i(
699
874
  "button",
700
875
  {
701
876
  ref: o,
702
- onClick: r,
703
- "aria-label": i,
704
- className: `fixed ${Fe[n]} z-50 flex h-14 w-14 items-center justify-center rounded-claudius-full bg-claudius-accent text-claudius-accent-text shadow-claudius-floating transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-claudius-accent focus:ring-offset-2`,
705
- children: t ? /* @__PURE__ */ g(
877
+ onClick: n,
878
+ "aria-label": a,
879
+ className: `fixed ${Rt[r]} z-50 flex h-14 w-14 items-center justify-center rounded-claudius-full bg-claudius-accent text-claudius-accent-text shadow-claudius-floating transition-transform hover:scale-105 focus:outline-none focus:ring-2 focus:ring-claudius-accent focus:ring-offset-2`,
880
+ children: t ? /* @__PURE__ */ p(
706
881
  "svg",
707
882
  {
708
883
  width: "24",
@@ -715,11 +890,11 @@ const Fe = {
715
890
  strokeLinejoin: "round",
716
891
  "aria-hidden": "true",
717
892
  children: [
718
- /* @__PURE__ */ a("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
719
- /* @__PURE__ */ a("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
893
+ /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
894
+ /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
720
895
  ]
721
896
  }
722
- ) : /* @__PURE__ */ a(
897
+ ) : /* @__PURE__ */ i(
723
898
  "svg",
724
899
  {
725
900
  width: "24",
@@ -731,25 +906,25 @@ const Fe = {
731
906
  strokeLinecap: "round",
732
907
  strokeLinejoin: "round",
733
908
  "aria-hidden": "true",
734
- children: /* @__PURE__ */ a("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
909
+ children: /* @__PURE__ */ i("path", { d: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" })
735
910
  }
736
911
  )
737
912
  }
738
913
  );
739
- }), Ye = de(function({
914
+ }), Tt = ge(function({
740
915
  count: t,
741
- isActive: r,
742
- onClick: n
916
+ isActive: n,
917
+ onClick: r
743
918
  }) {
744
- return /* @__PURE__ */ g(
919
+ return /* @__PURE__ */ p(
745
920
  "button",
746
921
  {
747
- onClick: n,
922
+ onClick: r,
748
923
  "aria-label": "View sources",
749
924
  title: "View sources",
750
- className: `group relative flex h-7 w-7 items-center justify-center rounded-claudius-full transition-colors ${r ? "bg-claudius-accent text-claudius-accent-text" : "text-claudius-text-muted hover:bg-claudius-surface-muted hover:text-claudius-text"}`,
925
+ className: `group relative flex h-7 w-7 items-center justify-center rounded-claudius-full transition-colors ${n ? "bg-claudius-accent text-claudius-accent-text" : "text-claudius-text-muted hover:bg-claudius-surface-muted hover:text-claudius-text"}`,
751
926
  children: [
752
- /* @__PURE__ */ g(
927
+ /* @__PURE__ */ p(
753
928
  "svg",
754
929
  {
755
930
  width: "14",
@@ -762,84 +937,244 @@ const Fe = {
762
937
  strokeLinejoin: "round",
763
938
  "aria-hidden": "true",
764
939
  children: [
765
- /* @__PURE__ */ a("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
766
- /* @__PURE__ */ a("polyline", { points: "14 2 14 8 20 8" }),
767
- /* @__PURE__ */ a("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
768
- /* @__PURE__ */ a("line", { x1: "16", y1: "17", x2: "8", y2: "17" })
940
+ /* @__PURE__ */ i("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
941
+ /* @__PURE__ */ i("polyline", { points: "14 2 14 8 20 8" }),
942
+ /* @__PURE__ */ i("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
943
+ /* @__PURE__ */ i("line", { x1: "16", y1: "17", x2: "8", y2: "17" })
769
944
  ]
770
945
  }
771
946
  ),
772
- /* @__PURE__ */ a("span", { className: "absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-claudius-full bg-claudius-accent px-1 text-[10px] font-bold text-claudius-accent-text", children: t })
947
+ /* @__PURE__ */ i("span", { className: "absolute -right-1 -top-1 flex h-4 min-w-4 items-center justify-center rounded-claudius-full bg-claudius-accent px-1 text-[10px] font-bold text-claudius-accent-text", children: t })
773
948
  ]
774
949
  }
775
950
  );
776
- }), Ke = ["http:", "https:"];
777
- function ve(e) {
951
+ }), St = ["http:", "https:"];
952
+ function Ee(e) {
778
953
  if (!e || typeof e != "string")
779
954
  return null;
780
955
  const t = e.trim();
781
956
  if (!t)
782
957
  return null;
783
958
  try {
784
- const r = new URL(t);
785
- return Ke.includes(r.protocol) ? t : null;
959
+ const n = new URL(t);
960
+ return St.includes(n.protocol) ? t : null;
786
961
  } catch {
787
962
  return null;
788
963
  }
789
964
  }
790
- function qe(e) {
965
+ function kt() {
966
+ return /* @__PURE__ */ p(
967
+ "svg",
968
+ {
969
+ width: "14",
970
+ height: "14",
971
+ viewBox: "0 0 24 24",
972
+ fill: "none",
973
+ stroke: "currentColor",
974
+ strokeWidth: "2",
975
+ strokeLinecap: "round",
976
+ strokeLinejoin: "round",
977
+ "aria-hidden": "true",
978
+ children: [
979
+ /* @__PURE__ */ i("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
980
+ /* @__PURE__ */ i("polyline", { points: "14 2 14 8 20 8" })
981
+ ]
982
+ }
983
+ );
984
+ }
985
+ function ke({
986
+ label: e,
987
+ onClick: t
988
+ }) {
989
+ return /* @__PURE__ */ i(
990
+ "button",
991
+ {
992
+ type: "button",
993
+ onClick: t,
994
+ "aria-label": e,
995
+ className: "absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-claudius-full bg-claudius-text text-claudius-surface shadow-claudius-floating hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-claudius-accent",
996
+ children: /* @__PURE__ */ p(
997
+ "svg",
998
+ {
999
+ width: "10",
1000
+ height: "10",
1001
+ viewBox: "0 0 24 24",
1002
+ fill: "none",
1003
+ stroke: "currentColor",
1004
+ strokeWidth: "3",
1005
+ strokeLinecap: "round",
1006
+ "aria-hidden": "true",
1007
+ children: [
1008
+ /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1009
+ /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1010
+ ]
1011
+ }
1012
+ )
1013
+ }
1014
+ );
1015
+ }
1016
+ const _e = ge(function({
1017
+ attachment: t,
1018
+ variant: n,
1019
+ onRemove: r,
1020
+ removeLabel: s
1021
+ }) {
1022
+ const o = it(t), a = n === "composer", c = `${t.name} (${xe(t.size)})`, u = t.url ? Ee(t.url) : null;
1023
+ if (o) {
1024
+ const m = /* @__PURE__ */ i(
1025
+ "img",
1026
+ {
1027
+ src: o,
1028
+ alt: t.name,
1029
+ title: c,
1030
+ loading: "lazy",
1031
+ className: a ? "h-12 w-12 rounded-claudius-sm border border-claudius-border object-cover" : "max-h-48 max-w-full rounded-claudius-sm object-contain"
1032
+ }
1033
+ );
1034
+ return /* @__PURE__ */ p("div", { className: "relative inline-block", children: [
1035
+ !a && u ? /* @__PURE__ */ p("a", { href: u, target: "_blank", rel: "noopener noreferrer", children: [
1036
+ m,
1037
+ /* @__PURE__ */ p("span", { className: "sr-only", children: [
1038
+ c,
1039
+ " (opens in a new tab)"
1040
+ ] })
1041
+ ] }) : m,
1042
+ r && s && /* @__PURE__ */ i(ke, { label: s, onClick: r })
1043
+ ] });
1044
+ }
1045
+ const l = /* @__PURE__ */ p(
1046
+ "span",
1047
+ {
1048
+ title: c,
1049
+ className: `inline-flex max-w-[220px] items-center gap-1.5 rounded-claudius-sm border px-2 py-1 text-xs ${a ? "border-claudius-border bg-claudius-field text-claudius-text" : "border-current/30 bg-transparent"}`,
1050
+ children: [
1051
+ /* @__PURE__ */ i(kt, {}),
1052
+ /* @__PURE__ */ i("span", { className: "truncate", children: t.name }),
1053
+ /* @__PURE__ */ i("span", { className: "shrink-0 opacity-70", children: xe(t.size) })
1054
+ ]
1055
+ }
1056
+ );
1057
+ return /* @__PURE__ */ p("div", { className: "relative inline-block", children: [
1058
+ !a && u ? /* @__PURE__ */ p(
1059
+ "a",
1060
+ {
1061
+ href: u,
1062
+ target: "_blank",
1063
+ rel: "noopener noreferrer",
1064
+ className: "underline-offset-2 hover:underline",
1065
+ children: [
1066
+ l,
1067
+ /* @__PURE__ */ i("span", { className: "sr-only", children: " (opens in a new tab)" })
1068
+ ]
1069
+ }
1070
+ ) : l,
1071
+ r && s && /* @__PURE__ */ i(ke, { label: s, onClick: r })
1072
+ ] });
1073
+ });
1074
+ function pe({
1075
+ label: e,
1076
+ onClick: t,
1077
+ children: n
1078
+ }) {
1079
+ return /* @__PURE__ */ i(
1080
+ "button",
1081
+ {
1082
+ type: "button",
1083
+ onClick: t,
1084
+ "aria-label": e,
1085
+ title: e,
1086
+ className: "flex h-7 w-7 items-center justify-center rounded-claudius-full text-claudius-text-muted transition-colors hover:bg-claudius-surface-muted hover:text-claudius-text",
1087
+ children: /* @__PURE__ */ i(
1088
+ "svg",
1089
+ {
1090
+ width: "14",
1091
+ height: "14",
1092
+ viewBox: "0 0 24 24",
1093
+ fill: "currentColor",
1094
+ stroke: "currentColor",
1095
+ strokeWidth: "2",
1096
+ strokeLinecap: "round",
1097
+ strokeLinejoin: "round",
1098
+ "aria-hidden": "true",
1099
+ children: n
1100
+ }
1101
+ )
1102
+ }
1103
+ );
1104
+ }
1105
+ function Ct({
1106
+ state: e,
1107
+ labels: t,
1108
+ onPlay: n,
1109
+ onPause: r,
1110
+ onResume: s,
1111
+ onStop: o
1112
+ }) {
1113
+ return e === "idle" ? /* @__PURE__ */ p(pe, { label: t.play, onClick: n, children: [
1114
+ /* @__PURE__ */ i("polygon", { points: "11 5 6 9 2 9 2 15 6 15 11 19 11 5" }),
1115
+ /* @__PURE__ */ i("path", { d: "M15.54 8.46a5 5 0 0 1 0 7.07", fill: "none" }),
1116
+ /* @__PURE__ */ i("path", { d: "M19.07 4.93a10 10 0 0 1 0 14.14", fill: "none" })
1117
+ ] }) : /* @__PURE__ */ p("div", { className: "flex items-center gap-1", children: [
1118
+ e === "paused" ? /* @__PURE__ */ i(pe, { label: t.resume, onClick: s, children: /* @__PURE__ */ i("polygon", { points: "6 3 20 12 6 21 6 3" }) }) : /* @__PURE__ */ p(pe, { label: t.pause, onClick: r, children: [
1119
+ /* @__PURE__ */ i("rect", { x: "6", y: "4", width: "4", height: "16", rx: "1" }),
1120
+ /* @__PURE__ */ i("rect", { x: "14", y: "4", width: "4", height: "16", rx: "1" })
1121
+ ] }),
1122
+ /* @__PURE__ */ i(pe, { label: t.stop, onClick: o, children: /* @__PURE__ */ i("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" }) })
1123
+ ] });
1124
+ }
1125
+ function At(e) {
791
1126
  const t = e.lastIndexOf(`
792
- `), r = t === -1 ? "" : e.slice(0, t + 1);
793
- let n = t === -1 ? e : e.slice(t + 1);
794
- return n = Ze(n), n = Qe(n), r + n;
1127
+ `), n = t === -1 ? "" : e.slice(0, t + 1);
1128
+ let r = t === -1 ? e : e.slice(t + 1);
1129
+ return r = Lt(r), r = Dt(r), n + r;
795
1130
  }
796
- function Je(e) {
1131
+ function Nt(e) {
797
1132
  const t = [];
798
- for (let r = 0; r < e.length - 1; r++)
799
- e[r] === "*" && e[r + 1] === "*" && (t.push(r), r++);
1133
+ for (let n = 0; n < e.length - 1; n++)
1134
+ e[n] === "*" && e[n + 1] === "*" && (t.push(n), n++);
800
1135
  return t;
801
1136
  }
802
- function Xe(e) {
1137
+ function Mt(e) {
803
1138
  const t = [];
804
- for (let r = 0; r < e.length; r++)
805
- if (e[r] === "*") {
806
- if (e[r + 1] === "*") {
807
- r++;
1139
+ for (let n = 0; n < e.length; n++)
1140
+ if (e[n] === "*") {
1141
+ if (e[n + 1] === "*") {
1142
+ n++;
808
1143
  continue;
809
1144
  }
810
- t.push(r);
1145
+ t.push(n);
811
1146
  }
812
1147
  return t;
813
1148
  }
814
- function Ze(e) {
815
- const t = Je(e);
1149
+ function Lt(e) {
1150
+ const t = Nt(e);
816
1151
  if (t.length % 2 === 0) return e;
817
- const r = t[t.length - 1], n = e.slice(r + 2);
818
- return n.trim() === "" ? e.slice(0, r) + n : e + "**";
1152
+ const n = t[t.length - 1], r = e.slice(n + 2);
1153
+ return r.trim() === "" ? e.slice(0, n) + r : e + "**";
819
1154
  }
820
- function Qe(e) {
821
- const t = Xe(e);
1155
+ function Dt(e) {
1156
+ const t = Mt(e);
822
1157
  if (t.length % 2 === 0) return e;
823
- const r = t[t.length - 1], n = e.slice(r + 1);
824
- return n.trim() === "" ? e.slice(0, r) + n : e + "*";
1158
+ const n = t[t.length - 1], r = e.slice(n + 1);
1159
+ return r.trim() === "" ? e.slice(0, n) + r : e + "*";
825
1160
  }
826
- function et({
1161
+ function It({
827
1162
  toolUse: e,
828
1163
  usedLabel: t,
829
- detailsLabel: r
1164
+ detailsLabel: n
830
1165
  }) {
831
- const [n, s] = L(!1), o = e.input !== void 0 || e.result !== void 0;
832
- return /* @__PURE__ */ g("div", { className: "text-xs text-claudius-text-muted", children: [
833
- /* @__PURE__ */ g(
1166
+ const [r, s] = O(!1), o = e.input !== void 0 || e.result !== void 0;
1167
+ return /* @__PURE__ */ p("div", { className: "text-xs text-claudius-text-muted", children: [
1168
+ /* @__PURE__ */ p(
834
1169
  "button",
835
1170
  {
836
1171
  type: "button",
837
1172
  disabled: !o,
838
- onClick: () => s((i) => !i),
839
- "aria-expanded": o ? n : void 0,
1173
+ onClick: () => s((a) => !a),
1174
+ "aria-expanded": o ? r : void 0,
840
1175
  className: "flex items-center gap-1.5 rounded-claudius-full border border-claudius-border bg-claudius-surface px-2 py-0.5 hover:opacity-80 disabled:cursor-default disabled:hover:opacity-100",
841
1176
  children: [
842
- /* @__PURE__ */ a(
1177
+ /* @__PURE__ */ i(
843
1178
  "svg",
844
1179
  {
845
1180
  width: "11",
@@ -851,18 +1186,18 @@ function et({
851
1186
  strokeLinecap: "round",
852
1187
  strokeLinejoin: "round",
853
1188
  "aria-hidden": "true",
854
- children: /* @__PURE__ */ a("path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" })
1189
+ children: /* @__PURE__ */ i("path", { d: "M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" })
855
1190
  }
856
1191
  ),
857
- /* @__PURE__ */ g("span", { children: [
1192
+ /* @__PURE__ */ p("span", { children: [
858
1193
  t,
859
1194
  " ",
860
- /* @__PURE__ */ a("span", { className: "font-mono text-claudius-text", children: e.name }),
861
- e.isError && /* @__PURE__ */ a("span", { className: "text-claudius-error", children: " ✕" })
1195
+ /* @__PURE__ */ i("span", { className: "font-mono text-claudius-text", children: e.name }),
1196
+ e.isError && /* @__PURE__ */ i("span", { className: "text-claudius-error", children: " ✕" })
862
1197
  ] }),
863
- o && /* @__PURE__ */ g(xe, { children: [
864
- /* @__PURE__ */ a("span", { className: "sr-only", children: r }),
865
- /* @__PURE__ */ a(
1198
+ o && /* @__PURE__ */ p(we, { children: [
1199
+ /* @__PURE__ */ i("span", { className: "sr-only", children: n }),
1200
+ /* @__PURE__ */ i(
866
1201
  "svg",
867
1202
  {
868
1203
  width: "10",
@@ -874,25 +1209,25 @@ function et({
874
1209
  strokeLinecap: "round",
875
1210
  strokeLinejoin: "round",
876
1211
  "aria-hidden": "true",
877
- className: n ? "rotate-180" : void 0,
878
- children: /* @__PURE__ */ a("polyline", { points: "6 9 12 15 18 9" })
1212
+ className: r ? "rotate-180" : void 0,
1213
+ children: /* @__PURE__ */ i("polyline", { points: "6 9 12 15 18 9" })
879
1214
  }
880
1215
  )
881
1216
  ] })
882
1217
  ]
883
1218
  }
884
1219
  ),
885
- n && o && /* @__PURE__ */ g("div", { className: "mt-1 overflow-x-auto rounded-claudius-sm border border-claudius-border bg-claudius-field p-2 font-mono", children: [
886
- e.input !== void 0 && /* @__PURE__ */ a("pre", { className: "whitespace-pre-wrap break-all", children: JSON.stringify(e.input, null, 2) }),
887
- e.result !== void 0 && /* @__PURE__ */ a("pre", { className: "mt-1 whitespace-pre-wrap break-all border-t border-claudius-border pt-1", children: e.result })
1220
+ r && o && /* @__PURE__ */ p("div", { className: "mt-1 overflow-x-auto rounded-claudius-sm border border-claudius-border bg-claudius-field p-2 font-mono", children: [
1221
+ e.input !== void 0 && /* @__PURE__ */ i("pre", { className: "whitespace-pre-wrap break-all", children: JSON.stringify(e.input, null, 2) }),
1222
+ e.result !== void 0 && /* @__PURE__ */ i("pre", { className: "mt-1 whitespace-pre-wrap break-all border-t border-claudius-border pt-1", children: e.result })
888
1223
  ] })
889
1224
  ] });
890
1225
  }
891
- const me = /(https?:\/\/[^\s)]+)/, ge = /(\*\*[^*]+\*\*)/, pe = /(\*[^*]+\*)/;
892
- function tt(e, t) {
893
- const r = e.match(/[.,;:!?'"]+$/), n = r ? e.slice(0, -r[0].length) : e, s = r ? r[0] : "", o = ve(n);
894
- return o ? /* @__PURE__ */ g(xe, { children: [
895
- /* @__PURE__ */ g(
1226
+ const Ce = /(https?:\/\/[^\s)]+)/, Ae = /(\*\*[^*]+\*\*)/, Ne = /(\*[^*]+\*)/;
1227
+ function Ot(e, t) {
1228
+ const n = e.match(/[.,;:!?'"]+$/), r = n ? e.slice(0, -n[0].length) : e, s = n ? n[0] : "", o = Ee(r);
1229
+ return o ? /* @__PURE__ */ p(we, { children: [
1230
+ /* @__PURE__ */ p(
896
1231
  "a",
897
1232
  {
898
1233
  href: o,
@@ -901,7 +1236,7 @@ function tt(e, t) {
901
1236
  className: "underline font-medium hover:opacity-80 text-claudius-link",
902
1237
  children: [
903
1238
  o.replace(/^https?:\/\//, ""),
904
- /* @__PURE__ */ a("span", { className: "sr-only", children: " (opens in a new tab)" })
1239
+ /* @__PURE__ */ i("span", { className: "sr-only", children: " (opens in a new tab)" })
905
1240
  ]
906
1241
  },
907
1242
  t
@@ -909,121 +1244,605 @@ function tt(e, t) {
909
1244
  s
910
1245
  ] }) : e;
911
1246
  }
912
- function rt(e, t) {
913
- const r = e.split(ge), n = [];
914
- return r.forEach((s, o) => {
915
- if (ge.test(s)) {
916
- const i = s.slice(2, -2);
917
- n.push(/* @__PURE__ */ a("strong", { children: i }, `${t}-b${o}`));
1247
+ function jt(e, t) {
1248
+ const n = e.split(Ae), r = [];
1249
+ return n.forEach((s, o) => {
1250
+ if (Ae.test(s)) {
1251
+ const a = s.slice(2, -2);
1252
+ r.push(/* @__PURE__ */ i("strong", { children: a }, `${t}-b${o}`));
918
1253
  } else
919
- s.split(pe).forEach((l, c) => {
920
- if (pe.test(l)) {
921
- const u = l.slice(1, -1);
922
- n.push(/* @__PURE__ */ a("em", { children: u }, `${t}-b${o}-i${c}`));
1254
+ s.split(Ne).forEach((c, u) => {
1255
+ if (Ne.test(c)) {
1256
+ const l = c.slice(1, -1);
1257
+ r.push(/* @__PURE__ */ i("em", { children: l }, `${t}-b${o}-i${u}`));
923
1258
  } else
924
- l.split(me).forEach((d, x) => {
925
- me.test(d) ? n.push(
926
- tt(d, `${t}-b${o}-i${c}-u${x}`)
927
- ) : d && n.push(d);
1259
+ c.split(Ce).forEach((m, E) => {
1260
+ Ce.test(m) ? r.push(
1261
+ Ot(m, `${t}-b${o}-i${u}-u${E}`)
1262
+ ) : m && r.push(m);
928
1263
  });
929
1264
  });
930
- }), n;
1265
+ }), r;
931
1266
  }
932
- function nt(e) {
1267
+ function Pt(e) {
933
1268
  const t = e.split(`
934
1269
  `);
935
- return t.map((r, n) => /* @__PURE__ */ g("span", { children: [
936
- rt(r, `l${n}`),
937
- n < t.length - 1 && /* @__PURE__ */ a("br", {})
938
- ] }, n));
1270
+ return t.map((n, r) => /* @__PURE__ */ p("span", { children: [
1271
+ jt(n, `l${r}`),
1272
+ r < t.length - 1 && /* @__PURE__ */ i("br", {})
1273
+ ] }, r));
939
1274
  }
940
- const st = de(function({
1275
+ const Bt = ge(function({
941
1276
  role: t,
942
- content: r,
943
- isStreaming: n = !1,
1277
+ content: n,
1278
+ isStreaming: r = !1,
944
1279
  sources: s,
945
- toolUses: o,
946
- toolUsedLabel: i = "Used tool:",
947
- toolDetailsLabel: l = "Tool details",
948
- onSourceClick: c,
949
- isSourceActive: u
1280
+ attachments: o,
1281
+ toolUses: a,
1282
+ toolUsedLabel: c = "Used tool:",
1283
+ toolDetailsLabel: u = "Tool details",
1284
+ onSourceClick: l,
1285
+ isSourceActive: m,
1286
+ speech: E
950
1287
  }) {
951
- const d = t === "user", x = n ? qe(r) : r, N = d || r !== "" || !(o != null && o.length);
952
- return /* @__PURE__ */ g("div", { className: `${d ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
953
- N && /* @__PURE__ */ a(
1288
+ const N = t === "user", g = !!o && o.length > 0, d = r ? At(n) : n, f = N || n !== "" || !(a != null && a.length);
1289
+ return /* @__PURE__ */ p("div", { className: `${N ? "ml-auto" : "mr-auto"} max-w-[85%]`, children: [
1290
+ f && /* @__PURE__ */ p(
954
1291
  "div",
955
1292
  {
956
- className: `rounded-claudius-bubble px-4 py-2.5 text-sm leading-relaxed font-body ${d ? "bg-claudius-user-bubble text-claudius-user-bubble-text rounded-br-claudius-tail" : "bg-claudius-assistant-bubble text-claudius-assistant-bubble-text rounded-bl-claudius-tail"}`,
957
- children: nt(x)
1293
+ className: `rounded-claudius-bubble px-4 py-2.5 text-sm leading-relaxed font-body ${N ? "bg-claudius-user-bubble text-claudius-user-bubble-text rounded-br-claudius-tail" : "bg-claudius-assistant-bubble text-claudius-assistant-bubble-text rounded-bl-claudius-tail"}`,
1294
+ children: [
1295
+ g && /* @__PURE__ */ i(
1296
+ "ul",
1297
+ {
1298
+ className: `flex flex-wrap gap-2 ${n ? "mb-2" : ""}`,
1299
+ "aria-label": "Attachments",
1300
+ children: o.map((v) => /* @__PURE__ */ i("li", { children: /* @__PURE__ */ i(_e, { attachment: v, variant: "message" }) }, v.id))
1301
+ }
1302
+ ),
1303
+ (n !== "" || !g) && Pt(d)
1304
+ ]
958
1305
  }
959
1306
  ),
960
- !d && o && o.length > 0 && /* @__PURE__ */ a("div", { className: "mt-1 space-y-1", children: o.map((R, T) => /* @__PURE__ */ a(
961
- et,
1307
+ !N && a && a.length > 0 && /* @__PURE__ */ i("div", { className: "mt-1 space-y-1", children: a.map((v, D) => /* @__PURE__ */ i(
1308
+ It,
962
1309
  {
963
- toolUse: R,
964
- usedLabel: i,
965
- detailsLabel: l
1310
+ toolUse: v,
1311
+ usedLabel: c,
1312
+ detailsLabel: u
966
1313
  },
967
- `${R.name}-${T}`
1314
+ `${v.name}-${D}`
968
1315
  )) }),
969
- !d && s && s.length > 0 && c && /* @__PURE__ */ a("div", { className: "mt-1", children: /* @__PURE__ */ a(
970
- Ye,
1316
+ !N && s && s.length > 0 && l && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(
1317
+ Tt,
971
1318
  {
972
1319
  count: s.length,
973
- isActive: u ?? !1,
974
- onClick: c
1320
+ isActive: m ?? !1,
1321
+ onClick: l
975
1322
  }
976
- ) })
1323
+ ) }),
1324
+ !N && E && /* @__PURE__ */ i("div", { className: "mt-1", children: /* @__PURE__ */ i(Ct, { ...E }) })
977
1325
  ] });
978
- }), ce = 2e3, ot = 1800;
979
- function it({
1326
+ }), ze = {
1327
+ // ChatWindow
1328
+ title: "Chat",
1329
+ subtitle: "Ask me anything",
1330
+ welcomeMessage: "Hi! How can I help you today?",
1331
+ closeChat: "Close chat",
1332
+ chatMessages: "Chat messages",
1333
+ typingIndicator: "Assistant is typing",
1334
+ // ChatInput
1335
+ placeholder: "Type your message...",
1336
+ sendMessage: "Send message",
1337
+ stopGenerating: "Stop generating",
1338
+ toolUsed: "Used tool:",
1339
+ toolDetails: "Tool details",
1340
+ typeYourMessage: "Type your message",
1341
+ // ChatToggleButton
1342
+ openChat: "Open chat",
1343
+ // GreetingBubble
1344
+ dismissGreeting: "Dismiss greeting",
1345
+ // Attachments
1346
+ attachFile: "Attach a file",
1347
+ removeAttachment: "Remove attachment",
1348
+ attachmentsLabel: "Attachments",
1349
+ dropFilesHint: "Drop files to attach",
1350
+ attachmentTooLarge: "{name} is too large. The maximum size is {max}.",
1351
+ attachmentTypeNotAllowed: "{name} is not a supported file type.",
1352
+ attachmentTooMany: "You can attach up to {max} files per message.",
1353
+ // Voice
1354
+ voiceInput: "Voice input",
1355
+ voiceInputHold: "Hold to talk",
1356
+ voiceListening: "Listening...",
1357
+ voicePermissionDenied: "Microphone access is blocked. Allow it in your browser settings to use voice input.",
1358
+ voiceNoSpeech: "No speech was detected. Please try again.",
1359
+ voiceNoMicrophone: "No microphone was found.",
1360
+ voiceUnavailable: "Voice input is not available right now.",
1361
+ readAloud: "Read aloud",
1362
+ pauseReading: "Pause reading",
1363
+ resumeReading: "Resume reading",
1364
+ stopReading: "Stop reading",
1365
+ // Errors
1366
+ errorGeneric: "Something went wrong. Please try again.",
1367
+ errorConnection: "Failed to connect. Please try again.",
1368
+ errorTimeout: "Request timed out. Please try again.",
1369
+ errorRateLimitMinute: "Too many requests. Please wait a minute.",
1370
+ errorRateLimitHour: "Hourly limit reached. Please try again later.",
1371
+ errorAttachmentRejected: "An attachment was rejected. Please remove it and try again.",
1372
+ errorAttachmentQuota: "Upload limit reached. Please try again later.",
1373
+ errorRetry: "Retry"
1374
+ }, Ue = ze;
1375
+ function Hn(e) {
1376
+ return { ...Ue, ...e };
1377
+ }
1378
+ function Me(e) {
1379
+ return e.key === " " || e.key === "Enter";
1380
+ }
1381
+ function Ht({
1382
+ mode: e,
1383
+ isListening: t,
1384
+ disabled: n = !1,
1385
+ onStart: r,
1386
+ onStop: s,
1387
+ label: o
1388
+ }) {
1389
+ const a = e === "hold", c = L(!1), u = () => {
1390
+ n || c.current || (c.current = !0, r());
1391
+ }, l = () => {
1392
+ c.current && (c.current = !1, s());
1393
+ };
1394
+ return /* @__PURE__ */ i(
1395
+ "button",
1396
+ {
1397
+ type: "button",
1398
+ disabled: n,
1399
+ "aria-label": o,
1400
+ "aria-pressed": t,
1401
+ title: o,
1402
+ onClick: (d) => {
1403
+ a && d.detail !== 0 || (t ? s() : r());
1404
+ },
1405
+ onPointerDown: (d) => {
1406
+ var f, v;
1407
+ !a || d.button !== 0 || ((v = (f = d.currentTarget).setPointerCapture) == null || v.call(f, d.pointerId), u());
1408
+ },
1409
+ onPointerUp: l,
1410
+ onPointerCancel: l,
1411
+ onLostPointerCapture: l,
1412
+ onKeyDown: (d) => {
1413
+ !a || !Me(d) || (d.preventDefault(), d.repeat || u());
1414
+ },
1415
+ onKeyUp: (d) => {
1416
+ !a || !Me(d) || (d.preventDefault(), l());
1417
+ },
1418
+ onBlur: l,
1419
+ onContextMenu: a ? (d) => d.preventDefault() : void 0,
1420
+ style: a ? { WebkitTouchCallout: "none" } : void 0,
1421
+ className: `flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm border transition-colors focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50 ${t ? "border-claudius-accent bg-claudius-accent text-claudius-accent-text" : "border-claudius-border bg-claudius-field text-claudius-text-muted hover:text-claudius-text focus:border-claudius-accent"} ${a ? "touch-none select-none" : ""}`,
1422
+ children: t && !a ? (
1423
+ // Same stop square the send button turns into while a reply streams:
1424
+ // it says what a click will do, and keeps this button from looking
1425
+ // like a second send button.
1426
+ /* @__PURE__ */ i(
1427
+ "svg",
1428
+ {
1429
+ width: "16",
1430
+ height: "16",
1431
+ viewBox: "0 0 24 24",
1432
+ fill: "currentColor",
1433
+ "aria-hidden": "true",
1434
+ children: /* @__PURE__ */ i("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" })
1435
+ }
1436
+ )
1437
+ ) : /* @__PURE__ */ p(
1438
+ "svg",
1439
+ {
1440
+ width: "16",
1441
+ height: "16",
1442
+ viewBox: "0 0 24 24",
1443
+ fill: "none",
1444
+ stroke: "currentColor",
1445
+ strokeWidth: "2",
1446
+ strokeLinecap: "round",
1447
+ strokeLinejoin: "round",
1448
+ "aria-hidden": "true",
1449
+ children: [
1450
+ /* @__PURE__ */ i("path", { d: "M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" }),
1451
+ /* @__PURE__ */ i("path", { d: "M19 10v2a7 7 0 0 1-14 0v-2" }),
1452
+ /* @__PURE__ */ i("line", { x1: "12", y1: "19", x2: "12", y2: "22" })
1453
+ ]
1454
+ }
1455
+ )
1456
+ }
1457
+ );
1458
+ }
1459
+ function _t({ active: e }) {
1460
+ return /* @__PURE__ */ p(
1461
+ "span",
1462
+ {
1463
+ "aria-hidden": "true",
1464
+ "data-claudius-voice-level": e ? "active" : "idle",
1465
+ className: "claudius-voice-level pointer-events-none absolute right-3 top-1/2 flex h-4 -translate-y-1/2 items-center gap-0.5 text-claudius-accent",
1466
+ children: [
1467
+ /* @__PURE__ */ i("span", {}),
1468
+ /* @__PURE__ */ i("span", {}),
1469
+ /* @__PURE__ */ i("span", {}),
1470
+ /* @__PURE__ */ i("span", {})
1471
+ ]
1472
+ }
1473
+ );
1474
+ }
1475
+ function be(e, t) {
1476
+ return e.replace(
1477
+ /\{(\w+)\}/g,
1478
+ (n, r) => r in t ? String(t[r]) : n
1479
+ );
1480
+ }
1481
+ const zt = {
1482
+ en: "en-US",
1483
+ es: "es-ES",
1484
+ fr: "fr-FR",
1485
+ de: "de-DE"
1486
+ }, Ut = ["toggle", "hold"];
1487
+ function Le(e, t) {
1488
+ if (!(!e || !e.includes("-")))
1489
+ return e.toLowerCase().split("-")[0] === t ? e : void 0;
1490
+ }
1491
+ function $t(e, t) {
1492
+ const n = t == null ? void 0 : t.trim();
1493
+ if (n) return n;
1494
+ const r = typeof document < "u" ? Le(document.documentElement.lang, e) : void 0;
1495
+ if (r) return r;
1496
+ const s = typeof navigator < "u" ? Le(navigator.language, e) : void 0;
1497
+ return s || zt[e];
1498
+ }
1499
+ function Ft(e, t) {
1500
+ if (!e) return null;
1501
+ const n = e === !0 ? {} : e, r = {
1502
+ input: n.input ?? !0,
1503
+ output: n.output ?? !0,
1504
+ // `mode` can arrive from an HTML attribute, so tolerate junk.
1505
+ mode: Ut.includes(n.mode) ? n.mode : "toggle",
1506
+ autoSubmit: n.autoSubmit ?? !1,
1507
+ lang: $t(t, n.lang)
1508
+ };
1509
+ return r.input || r.output ? r : null;
1510
+ }
1511
+ function Wt(e, t, n) {
1512
+ const r = t.trim();
1513
+ if (!r) return e;
1514
+ const s = e.trimEnd();
1515
+ return (s ? `${s} ${r}` : r).slice(0, n);
1516
+ }
1517
+ function Gt(e) {
1518
+ const t = [];
1519
+ let n = 0;
1520
+ for (let r = 0; r < e.length; r++) {
1521
+ const s = e[r];
1522
+ (s === `
1523
+ ` || (s === "." || s === "!" || s === "?") && (r + 1 === e.length || /\s/.test(e[r + 1]))) && (t.push(e.slice(n, r + 1)), n = r + 1);
1524
+ }
1525
+ return n < e.length && t.push(e.slice(n)), t;
1526
+ }
1527
+ function Vt(e, t = 200) {
1528
+ const n = [];
1529
+ let r = "";
1530
+ const s = () => {
1531
+ const o = r.trim();
1532
+ o && n.push(o), r = "";
1533
+ };
1534
+ for (const o of Gt(e)) {
1535
+ if ((r + o).trim().length <= t) {
1536
+ r += o;
1537
+ continue;
1538
+ }
1539
+ if (s(), o.trim().length <= t) {
1540
+ r = o;
1541
+ continue;
1542
+ }
1543
+ for (const a of o.trim().split(/\s+/))
1544
+ r && `${r} ${a}`.length > t && s(), r = r ? `${r} ${a}` : a;
1545
+ }
1546
+ return s(), n;
1547
+ }
1548
+ function De() {
1549
+ if (typeof window > "u") return;
1550
+ const e = window;
1551
+ return e.SpeechRecognition ?? e.webkitSpeechRecognition;
1552
+ }
1553
+ function Kt(e) {
1554
+ switch (e) {
1555
+ case "not-allowed":
1556
+ case "service-not-allowed":
1557
+ return "permission";
1558
+ case "no-speech":
1559
+ return "no-speech";
1560
+ case "audio-capture":
1561
+ return "no-microphone";
1562
+ default:
1563
+ return "unavailable";
1564
+ }
1565
+ }
1566
+ function Yt(e) {
1567
+ const [t] = O(() => De() !== void 0), [n, r] = O(!1), [s, o] = O(!1), a = L(null), c = L(!1), u = L(e);
1568
+ K(() => {
1569
+ u.current = e;
1570
+ });
1571
+ const l = M((g) => {
1572
+ g.onstart = null, g.onend = null, g.onerror = null, g.onresult = null, g.onspeechstart = null, g.onspeechend = null, a.current === g && (a.current = null), r(!1), o(!1);
1573
+ }, []), m = M(() => {
1574
+ const g = a.current;
1575
+ g && (l(g), g.abort());
1576
+ }, [l]), E = M(() => {
1577
+ const g = a.current;
1578
+ if (g) {
1579
+ if (!c.current) {
1580
+ m();
1581
+ return;
1582
+ }
1583
+ g.stop();
1584
+ }
1585
+ }, [m]), N = M(() => {
1586
+ var D, C;
1587
+ const g = De();
1588
+ if (!g || a.current) return;
1589
+ const d = new g();
1590
+ d.lang = u.current.lang, d.interimResults = !0, d.continuous = !1;
1591
+ let f = "", v = !1;
1592
+ d.onstart = () => {
1593
+ c.current = !0;
1594
+ }, d.onspeechstart = () => o(!0), d.onspeechend = () => o(!1), d.onresult = (T) => {
1595
+ var A, B;
1596
+ let b = "", k = "";
1597
+ for (let y = 0; y < T.results.length; y++) {
1598
+ const W = T.results[y];
1599
+ W.isFinal ? b += W[0].transcript : k += W[0].transcript;
1600
+ }
1601
+ f = b, o(!0), (B = (A = u.current).onTranscript) == null || B.call(A, b + k);
1602
+ }, d.onerror = (T) => {
1603
+ var b, k;
1604
+ T.error !== "aborted" && (v = !0, (k = (b = u.current).onError) == null || k.call(b, Kt(T.error)));
1605
+ }, d.onend = () => {
1606
+ var T, b;
1607
+ l(d), v || (b = (T = u.current).onEnd) == null || b.call(T, f);
1608
+ }, a.current = d, c.current = !1, r(!0);
1609
+ try {
1610
+ d.start();
1611
+ } catch {
1612
+ l(d), (C = (D = u.current).onError) == null || C.call(D, "unavailable");
1613
+ }
1614
+ }, [l]);
1615
+ return K(() => m, [m]), { isSupported: t, isListening: n, isSpeechDetected: s, start: N, stop: E, abort: m };
1616
+ }
1617
+ const le = 2e3, qt = 1800;
1618
+ function Ie(e) {
1619
+ var n;
1620
+ const t = (n = e.dataTransfer) == null ? void 0 : n.types;
1621
+ return !!t && Array.from(t).includes("Files");
1622
+ }
1623
+ function Qt({
980
1624
  onSend: e,
981
1625
  isLoading: t,
982
- isStreaming: r = !1,
983
- onStop: n,
1626
+ isStreaming: n = !1,
1627
+ onStop: r,
984
1628
  placeholder: s,
985
- translations: o
1629
+ translations: o,
1630
+ attachments: a = null,
1631
+ voice: c = null,
1632
+ onVoiceStart: u
986
1633
  }) {
987
- const [i, l] = L(""), c = I(null), u = i.length, d = u >= ot, x = u >= ce, N = s ?? (o == null ? void 0 : o.placeholder) ?? "Type your message...", R = (o == null ? void 0 : o.sendMessage) ?? "Send message", T = (o == null ? void 0 : o.stopGenerating) ?? "Stop generating", p = (o == null ? void 0 : o.typeYourMessage) ?? "Type your message", v = r && !!n;
988
- return z(() => {
989
- var w;
990
- t || (w = c.current) == null || w.focus();
991
- }, [t]), /* @__PURE__ */ g(
1634
+ const l = o ?? Ue, [m, E] = O(""), [N, g] = O([]), [d, f] = O(null), [v, D] = O(!1), [C, T] = O(null), b = L(null), k = L(null), A = L([]), B = L(0), y = L(""), W = L(""), U = (h) => {
1635
+ y.current = h, E(h);
1636
+ }, H = m.length, _ = H >= qt, J = H >= le, re = s ?? l.placeholder, X = !!a && N.length < a.maxCount, te = n && !!r;
1637
+ K(() => {
1638
+ var h;
1639
+ t || (h = b.current) == null || h.focus();
1640
+ }, [t]);
1641
+ const w = M(
1642
+ (h, S) => {
1643
+ if (!a) return "";
1644
+ switch (S) {
1645
+ case "size":
1646
+ return be(l.attachmentTooLarge, {
1647
+ name: h,
1648
+ max: xe(a.maxSizeBytes)
1649
+ });
1650
+ case "type":
1651
+ return be(l.attachmentTypeNotAllowed, { name: h });
1652
+ case "count":
1653
+ return be(l.attachmentTooMany, {
1654
+ max: a.maxCount
1655
+ });
1656
+ }
1657
+ },
1658
+ [a, l]
1659
+ ), ee = M(
1660
+ async (h) => {
1661
+ if (!a || h.length === 0) return;
1662
+ const { accepted: S, rejected: F } = ct(
1663
+ h,
1664
+ A.current.length,
1665
+ a
1666
+ );
1667
+ if (f(
1668
+ F.length > 0 ? w(F[0].file.name, F[0].reason) : null
1669
+ ), S.length === 0) return;
1670
+ const ce = await Promise.all(S.map(dt));
1671
+ A.current = [...A.current, ...ce], g(A.current);
1672
+ },
1673
+ [a, w]
1674
+ ), ie = M((h) => {
1675
+ A.current = A.current.filter((S) => S.id !== h), g(A.current), f(null);
1676
+ }, []), x = () => {
1677
+ const h = y.current.trim(), S = A.current;
1678
+ !h && S.length === 0 || y.current.length >= le || (S.length > 0 ? e(h, S) : e(h), U(""), A.current = [], g([]), f(null));
1679
+ }, z = (h) => {
1680
+ switch (h) {
1681
+ case "permission":
1682
+ return l.voicePermissionDenied;
1683
+ case "no-speech":
1684
+ return l.voiceNoSpeech;
1685
+ case "no-microphone":
1686
+ return l.voiceNoMicrophone;
1687
+ case "unavailable":
1688
+ return l.voiceUnavailable;
1689
+ }
1690
+ }, I = Yt({
1691
+ lang: (c == null ? void 0 : c.lang) ?? "en-US",
1692
+ onTranscript: (h) => U(
1693
+ Wt(W.current, h, le)
1694
+ ),
1695
+ onEnd: (h) => {
1696
+ c != null && c.autoSubmit && h.trim() && x();
1697
+ },
1698
+ onError: (h) => T(z(h))
1699
+ }), Q = !!(c != null && c.input) && I.isSupported, $ = I.isListening;
1700
+ K(() => {
1701
+ const h = b.current;
1702
+ $ && h && (h.scrollLeft = h.scrollWidth);
1703
+ }, [$, m]);
1704
+ const ne = () => {
1705
+ T(null), W.current = y.current, u == null || u(), I.start();
1706
+ }, Z = (h) => {
1707
+ h.preventDefault(), I.abort(), x();
1708
+ }, R = (h) => {
1709
+ const S = h.target.value;
1710
+ S.length <= le && (I.abort(), T(null), U(S));
1711
+ }, j = (h) => {
1712
+ const S = Array.from(h.target.files ?? []);
1713
+ h.target.value = "", ee(S);
1714
+ }, P = (h) => {
1715
+ var F;
1716
+ if (!a) return;
1717
+ const S = Array.from(((F = h.clipboardData) == null ? void 0 : F.files) ?? []);
1718
+ S.length !== 0 && (h.preventDefault(), ee(S));
1719
+ };
1720
+ return /* @__PURE__ */ p(
992
1721
  "form",
993
1722
  {
994
- onSubmit: (w) => {
995
- w.preventDefault();
996
- const f = i.trim();
997
- !f || x || (e(f), l(""));
1723
+ onSubmit: Z,
1724
+ onDragEnter: (h) => {
1725
+ !a || !Ie(h) || (h.preventDefault(), B.current += 1, D(!0));
1726
+ },
1727
+ onDragOver: (h) => {
1728
+ !a || !Ie(h) || h.preventDefault();
1729
+ },
1730
+ onDragLeave: () => {
1731
+ a && (B.current = Math.max(0, B.current - 1), B.current === 0 && D(!1));
998
1732
  },
999
- className: "border-t border-claudius-border bg-claudius-surface p-3",
1733
+ onDrop: (h) => {
1734
+ var S;
1735
+ a && (h.preventDefault(), B.current = 0, D(!1), ee(Array.from(((S = h.dataTransfer) == null ? void 0 : S.files) ?? [])));
1736
+ },
1737
+ "data-drag-over": v || void 0,
1738
+ className: `relative border-t border-claudius-border bg-claudius-surface p-3 ${v ? "ring-2 ring-inset ring-claudius-accent" : ""}`,
1000
1739
  children: [
1001
- /* @__PURE__ */ g("div", { className: "flex gap-2", children: [
1002
- /* @__PURE__ */ a(
1003
- "input",
1740
+ v && /* @__PURE__ */ i(
1741
+ "div",
1742
+ {
1743
+ "aria-hidden": "true",
1744
+ className: "pointer-events-none absolute inset-0 z-10 flex items-center justify-center bg-claudius-surface text-sm font-medium text-claudius-accent",
1745
+ children: l.dropFilesHint
1746
+ }
1747
+ ),
1748
+ a && N.length > 0 && /* @__PURE__ */ i(
1749
+ "ul",
1750
+ {
1751
+ "aria-label": l.attachmentsLabel,
1752
+ className: "mb-2 flex flex-wrap gap-3 pt-1",
1753
+ children: N.map((h) => /* @__PURE__ */ i("li", { children: /* @__PURE__ */ i(
1754
+ _e,
1755
+ {
1756
+ attachment: h,
1757
+ variant: "composer",
1758
+ onRemove: () => ie(h.id),
1759
+ removeLabel: `${l.removeAttachment}: ${h.name}`
1760
+ }
1761
+ ) }, h.id))
1762
+ }
1763
+ ),
1764
+ /* @__PURE__ */ p("div", { className: "flex gap-2", children: [
1765
+ a && /* @__PURE__ */ p(we, { children: [
1766
+ /* @__PURE__ */ i(
1767
+ "input",
1768
+ {
1769
+ ref: k,
1770
+ type: "file",
1771
+ multiple: !0,
1772
+ hidden: !0,
1773
+ tabIndex: -1,
1774
+ accept: a.allowedTypes.join(","),
1775
+ onChange: j,
1776
+ "aria-label": l.attachFile
1777
+ }
1778
+ ),
1779
+ /* @__PURE__ */ i(
1780
+ "button",
1781
+ {
1782
+ type: "button",
1783
+ onClick: () => {
1784
+ var h;
1785
+ return (h = k.current) == null ? void 0 : h.click();
1786
+ },
1787
+ disabled: t || !X,
1788
+ "aria-label": l.attachFile,
1789
+ title: l.attachFile,
1790
+ className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm border border-claudius-border bg-claudius-field text-claudius-text-muted transition-colors hover:text-claudius-text focus:border-claudius-accent focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50",
1791
+ children: /* @__PURE__ */ i(
1792
+ "svg",
1793
+ {
1794
+ width: "16",
1795
+ height: "16",
1796
+ viewBox: "0 0 24 24",
1797
+ fill: "none",
1798
+ stroke: "currentColor",
1799
+ strokeWidth: "2",
1800
+ strokeLinecap: "round",
1801
+ strokeLinejoin: "round",
1802
+ "aria-hidden": "true",
1803
+ children: /* @__PURE__ */ i("path", { d: "m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l8.57-8.57A4 4 0 1 1 18 8.84l-8.59 8.57a2 2 0 0 1-2.83-2.83l8.49-8.48" })
1804
+ }
1805
+ )
1806
+ }
1807
+ )
1808
+ ] }),
1809
+ /* @__PURE__ */ p("div", { className: "relative min-w-0 flex-1", children: [
1810
+ /* @__PURE__ */ i(
1811
+ "input",
1812
+ {
1813
+ ref: b,
1814
+ type: "text",
1815
+ value: m,
1816
+ onChange: R,
1817
+ onPaste: P,
1818
+ placeholder: $ ? l.voiceListening : re,
1819
+ disabled: t,
1820
+ "aria-label": l.typeYourMessage,
1821
+ "aria-describedby": _ ? "char-count" : void 0,
1822
+ className: `h-full w-full rounded-claudius-sm border border-claudius-border bg-claudius-field py-2 pl-3 text-sm font-body text-claudius-text placeholder:text-claudius-text-muted focus:border-claudius-accent focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50 ${$ ? "pr-10" : "pr-3"}`
1823
+ }
1824
+ ),
1825
+ $ && /* @__PURE__ */ i(_t, { active: I.isSpeechDetected })
1826
+ ] }),
1827
+ Q && c && /* @__PURE__ */ i(
1828
+ Ht,
1004
1829
  {
1005
- ref: c,
1006
- type: "text",
1007
- value: i,
1008
- onChange: (w) => {
1009
- const f = w.target.value;
1010
- f.length <= ce && l(f);
1011
- },
1012
- placeholder: N,
1830
+ mode: c.mode,
1831
+ isListening: $,
1013
1832
  disabled: t,
1014
- "aria-label": p,
1015
- "aria-describedby": d ? "char-count" : void 0,
1016
- className: "flex-1 rounded-claudius-sm border border-claudius-border bg-claudius-field px-3 py-2 text-sm font-body text-claudius-text placeholder:text-claudius-text-muted focus:border-claudius-accent focus:outline-none focus:ring-1 focus:ring-claudius-accent disabled:opacity-50"
1833
+ onStart: ne,
1834
+ onStop: I.stop,
1835
+ label: c.mode === "hold" ? l.voiceInputHold : l.voiceInput
1017
1836
  }
1018
1837
  ),
1019
- v ? /* @__PURE__ */ a(
1838
+ te ? /* @__PURE__ */ i(
1020
1839
  "button",
1021
1840
  {
1022
1841
  type: "button",
1023
- onClick: n,
1024
- "aria-label": T,
1842
+ onClick: r,
1843
+ "aria-label": l.stopGenerating,
1025
1844
  className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm bg-claudius-accent text-claudius-accent-text transition-colors hover:opacity-90",
1026
- children: /* @__PURE__ */ a(
1845
+ children: /* @__PURE__ */ i(
1027
1846
  "svg",
1028
1847
  {
1029
1848
  width: "16",
@@ -1031,18 +1850,18 @@ function it({
1031
1850
  viewBox: "0 0 24 24",
1032
1851
  fill: "currentColor",
1033
1852
  "aria-hidden": "true",
1034
- children: /* @__PURE__ */ a("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" })
1853
+ children: /* @__PURE__ */ i("rect", { x: "6", y: "6", width: "12", height: "12", rx: "1.5" })
1035
1854
  }
1036
1855
  )
1037
1856
  }
1038
- ) : /* @__PURE__ */ a(
1857
+ ) : /* @__PURE__ */ i(
1039
1858
  "button",
1040
1859
  {
1041
1860
  type: "submit",
1042
- disabled: t || x,
1043
- "aria-label": R,
1861
+ disabled: t || J,
1862
+ "aria-label": l.sendMessage,
1044
1863
  className: "flex h-11 w-11 shrink-0 items-center justify-center rounded-claudius-sm bg-claudius-accent text-claudius-accent-text transition-colors hover:opacity-90 disabled:opacity-50",
1045
- children: /* @__PURE__ */ g(
1864
+ children: /* @__PURE__ */ p(
1046
1865
  "svg",
1047
1866
  {
1048
1867
  width: "16",
@@ -1055,24 +1874,25 @@ function it({
1055
1874
  strokeLinejoin: "round",
1056
1875
  "aria-hidden": "true",
1057
1876
  children: [
1058
- /* @__PURE__ */ a("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
1059
- /* @__PURE__ */ a("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
1877
+ /* @__PURE__ */ i("line", { x1: "22", y1: "2", x2: "11", y2: "13" }),
1878
+ /* @__PURE__ */ i("polygon", { points: "22 2 15 22 11 13 2 9 22 2" })
1060
1879
  ]
1061
1880
  }
1062
1881
  )
1063
1882
  }
1064
1883
  )
1065
1884
  ] }),
1066
- d && /* @__PURE__ */ g(
1885
+ (d ?? C) && /* @__PURE__ */ i("div", { role: "alert", className: "mt-1 text-xs text-claudius-error", children: d ?? C }),
1886
+ _ && /* @__PURE__ */ p(
1067
1887
  "div",
1068
1888
  {
1069
1889
  id: "char-count",
1070
- className: `mt-1 text-xs text-right ${x ? "text-claudius-error" : "text-claudius-text-muted"}`,
1890
+ className: `mt-1 text-xs text-right ${J ? "text-claudius-error" : "text-claudius-text-muted"}`,
1071
1891
  "aria-live": "polite",
1072
1892
  children: [
1073
- u,
1893
+ H,
1074
1894
  "/",
1075
- ce
1895
+ le
1076
1896
  ]
1077
1897
  }
1078
1898
  )
@@ -1080,40 +1900,40 @@ function it({
1080
1900
  }
1081
1901
  );
1082
1902
  }
1083
- const at = ["blog", "page", "external"], ct = {
1903
+ const Zt = ["blog", "page", "external"], Jt = {
1084
1904
  blog: "Blog",
1085
1905
  page: "Page",
1086
1906
  external: "External"
1087
1907
  };
1088
- function lt(e) {
1908
+ function Xt(e) {
1089
1909
  try {
1090
1910
  return new URL(e).hostname;
1091
1911
  } catch {
1092
1912
  return e;
1093
1913
  }
1094
1914
  }
1095
- const ut = de(function({
1915
+ const en = ge(function({
1096
1916
  sources: t,
1097
- onClose: r
1917
+ onClose: n
1098
1918
  }) {
1099
- const n = at.map((o) => ({
1919
+ const r = Zt.map((o) => ({
1100
1920
  type: o,
1101
- label: ct[o],
1102
- items: t.filter((i) => i.type === o)
1921
+ label: Jt[o],
1922
+ items: t.filter((a) => a.type === o)
1103
1923
  })).filter((o) => o.items.length > 0), s = t.length === 1 ? "1 source found" : `${t.length} sources found`;
1104
- return /* @__PURE__ */ g("div", { className: "absolute inset-y-0 left-0 z-10 flex w-[280px] flex-col border-r-2 border-claudius-border bg-claudius-surface rounded-r-claudius-lg transition-transform duration-200 ease-out", children: [
1105
- /* @__PURE__ */ g("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
1106
- /* @__PURE__ */ g("div", { children: [
1107
- /* @__PURE__ */ a("h3", { className: "text-sm font-heading font-semibold text-claudius-text", children: "Sources" }),
1108
- /* @__PURE__ */ a("p", { className: "text-xs text-claudius-text-muted", children: s })
1924
+ return /* @__PURE__ */ p("div", { className: "absolute inset-y-0 left-0 z-10 flex w-[280px] flex-col border-r-2 border-claudius-border bg-claudius-surface rounded-r-claudius-lg transition-transform duration-200 ease-out", children: [
1925
+ /* @__PURE__ */ p("div", { className: "flex items-center justify-between border-b border-claudius-border px-4 py-3", children: [
1926
+ /* @__PURE__ */ p("div", { children: [
1927
+ /* @__PURE__ */ i("h3", { className: "text-sm font-heading font-semibold text-claudius-text", children: "Sources" }),
1928
+ /* @__PURE__ */ i("p", { className: "text-xs text-claudius-text-muted", children: s })
1109
1929
  ] }),
1110
- /* @__PURE__ */ a(
1930
+ /* @__PURE__ */ i(
1111
1931
  "button",
1112
1932
  {
1113
- onClick: r,
1933
+ onClick: n,
1114
1934
  "aria-label": "Close sources",
1115
1935
  className: "flex h-7 w-7 items-center justify-center rounded-claudius-full text-claudius-text-muted transition-colors hover:bg-claudius-surface-muted hover:text-claudius-text",
1116
- children: /* @__PURE__ */ g(
1936
+ children: /* @__PURE__ */ p(
1117
1937
  "svg",
1118
1938
  {
1119
1939
  width: "14",
@@ -1126,45 +1946,45 @@ const ut = de(function({
1126
1946
  strokeLinejoin: "round",
1127
1947
  "aria-hidden": "true",
1128
1948
  children: [
1129
- /* @__PURE__ */ a("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1130
- /* @__PURE__ */ a("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1949
+ /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1950
+ /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1131
1951
  ]
1132
1952
  }
1133
1953
  )
1134
1954
  }
1135
1955
  )
1136
1956
  ] }),
1137
- /* @__PURE__ */ a("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: n.map((o) => /* @__PURE__ */ g("div", { children: [
1138
- /* @__PURE__ */ a("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-claudius-text-muted", children: o.label }),
1139
- /* @__PURE__ */ a("div", { className: "space-y-2", children: o.items.map((i) => {
1140
- const l = ve(i.url);
1141
- return l ? /* @__PURE__ */ g(
1957
+ /* @__PURE__ */ i("div", { className: "flex-1 overflow-y-auto px-3 py-3 space-y-4", children: r.map((o) => /* @__PURE__ */ p("div", { children: [
1958
+ /* @__PURE__ */ i("h4", { className: "mb-2 text-xs font-semibold uppercase tracking-wide text-claudius-text-muted", children: o.label }),
1959
+ /* @__PURE__ */ i("div", { className: "space-y-2", children: o.items.map((a) => {
1960
+ const c = Ee(a.url);
1961
+ return c ? /* @__PURE__ */ p(
1142
1962
  "a",
1143
1963
  {
1144
- href: l,
1964
+ href: c,
1145
1965
  target: "_blank",
1146
1966
  rel: "noopener noreferrer",
1147
1967
  className: "block rounded-claudius-md border-2 border-claudius-border bg-claudius-surface-muted p-3 transition-colors hover:bg-claudius-border",
1148
1968
  children: [
1149
- /* @__PURE__ */ a("p", { className: "truncate text-sm font-medium text-claudius-text", children: i.title }),
1150
- /* @__PURE__ */ a("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: lt(l) })
1969
+ /* @__PURE__ */ i("p", { className: "truncate text-sm font-medium text-claudius-text", children: a.title }),
1970
+ /* @__PURE__ */ i("p", { className: "mt-0.5 text-xs text-claudius-text-muted", children: Xt(c) })
1151
1971
  ]
1152
1972
  },
1153
- l
1973
+ c
1154
1974
  ) : null;
1155
1975
  }) })
1156
1976
  ] }, o.type)) })
1157
1977
  ] });
1158
1978
  });
1159
- function dt({
1979
+ function tn({
1160
1980
  title: e,
1161
1981
  subtitle: t,
1162
- titleId: r,
1163
- closeLabel: n,
1982
+ titleId: n,
1983
+ closeLabel: r,
1164
1984
  onClose: s
1165
1985
  }) {
1166
- return /* @__PURE__ */ g("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
1167
- /* @__PURE__ */ a(
1986
+ return /* @__PURE__ */ p("div", { className: "flex items-center gap-3 bg-claudius-accent px-5 py-4", children: [
1987
+ /* @__PURE__ */ i(
1168
1988
  "div",
1169
1989
  {
1170
1990
  "aria-hidden": "true",
@@ -1172,24 +1992,24 @@ function dt({
1172
1992
  children: e.charAt(0).toUpperCase()
1173
1993
  }
1174
1994
  ),
1175
- /* @__PURE__ */ g("div", { className: "flex-1", children: [
1176
- /* @__PURE__ */ a(
1995
+ /* @__PURE__ */ p("div", { className: "flex-1", children: [
1996
+ /* @__PURE__ */ i(
1177
1997
  "h2",
1178
1998
  {
1179
- id: r,
1999
+ id: n,
1180
2000
  className: "text-sm font-heading font-semibold text-claudius-accent-text",
1181
2001
  children: e
1182
2002
  }
1183
2003
  ),
1184
- /* @__PURE__ */ a("p", { className: "text-xs text-claudius-accent-text", children: t })
2004
+ /* @__PURE__ */ i("p", { className: "text-xs text-claudius-accent-text", children: t })
1185
2005
  ] }),
1186
- /* @__PURE__ */ a(
2006
+ /* @__PURE__ */ i(
1187
2007
  "button",
1188
2008
  {
1189
2009
  onClick: s,
1190
- "aria-label": n,
2010
+ "aria-label": r,
1191
2011
  className: "flex h-10 w-10 items-center justify-center rounded-claudius-full text-claudius-accent-text-muted transition-colors hover:bg-claudius-accent-soft hover:text-claudius-accent-text",
1192
- children: /* @__PURE__ */ g(
2012
+ children: /* @__PURE__ */ p(
1193
2013
  "svg",
1194
2014
  {
1195
2015
  width: "18",
@@ -1202,8 +2022,8 @@ function dt({
1202
2022
  strokeLinejoin: "round",
1203
2023
  "aria-hidden": "true",
1204
2024
  children: [
1205
- /* @__PURE__ */ a("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1206
- /* @__PURE__ */ a("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
2025
+ /* @__PURE__ */ i("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
2026
+ /* @__PURE__ */ i("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1207
2027
  ]
1208
2028
  }
1209
2029
  )
@@ -1211,23 +2031,23 @@ function dt({
1211
2031
  )
1212
2032
  ] });
1213
2033
  }
1214
- function ft({
2034
+ function nn({
1215
2035
  message: e,
1216
2036
  retryLabel: t,
1217
- onRetry: r
2037
+ onRetry: n
1218
2038
  }) {
1219
- return /* @__PURE__ */ g(
2039
+ return /* @__PURE__ */ p(
1220
2040
  "div",
1221
2041
  {
1222
2042
  role: "alert",
1223
2043
  className: "mx-auto flex max-w-[90%] flex-col items-center gap-2 rounded-claudius-sm bg-claudius-error-surface px-3 py-2 text-center text-xs text-claudius-error",
1224
2044
  children: [
1225
- /* @__PURE__ */ a("span", { children: e }),
1226
- r && /* @__PURE__ */ a(
2045
+ /* @__PURE__ */ i("span", { children: e }),
2046
+ n && /* @__PURE__ */ i(
1227
2047
  "button",
1228
2048
  {
1229
2049
  type: "button",
1230
- onClick: r,
2050
+ onClick: n,
1231
2051
  className: "rounded-claudius-md bg-claudius-error px-3 py-1 text-xs font-semibold text-claudius-error-text transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-claudius-error focus-visible:ring-offset-1",
1232
2052
  children: t
1233
2053
  }
@@ -1236,68 +2056,106 @@ function ft({
1236
2056
  }
1237
2057
  );
1238
2058
  }
1239
- function ht({ label: e }) {
1240
- return /* @__PURE__ */ a(
2059
+ function rn({ label: e }) {
2060
+ return /* @__PURE__ */ i(
1241
2061
  "div",
1242
2062
  {
1243
2063
  role: "status",
1244
2064
  "aria-live": "polite",
1245
2065
  "aria-label": e,
1246
2066
  className: "mr-auto flex max-w-[85%]",
1247
- children: /* @__PURE__ */ g("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
1248
- /* @__PURE__ */ a("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:0ms]" }),
1249
- /* @__PURE__ */ a("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:150ms]" }),
1250
- /* @__PURE__ */ a("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:300ms]" })
2067
+ children: /* @__PURE__ */ p("div", { className: "flex gap-1 rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-3", children: [
2068
+ /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:0ms]" }),
2069
+ /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:150ms]" }),
2070
+ /* @__PURE__ */ i("span", { className: "h-2 w-2 motion-safe:animate-bounce rounded-claudius-full bg-claudius-text-muted [animation-delay:300ms]" })
1251
2071
  ] })
1252
2072
  }
1253
2073
  );
1254
2074
  }
1255
- function mt(e, t, r) {
1256
- const [n, s] = L(0), o = I(0), i = I(0), l = I(0), c = I(!1);
1257
- return z(() => {
1258
- const u = e.current;
1259
- if (!r || !u) return;
1260
- const d = (R) => {
1261
- if (u.scrollTop > 0) {
1262
- c.current = !1;
2075
+ function sn(e, t, n) {
2076
+ const [r, s] = O(0), o = L(0), a = L(0), c = L(0), u = L(!1);
2077
+ return K(() => {
2078
+ const l = e.current;
2079
+ if (!n || !l) return;
2080
+ const m = (g) => {
2081
+ if (l.scrollTop > 0) {
2082
+ u.current = !1;
1263
2083
  return;
1264
2084
  }
1265
- c.current = !0, i.current = R.touches[0].clientY, l.current = Date.now();
1266
- }, x = (R) => {
1267
- if (!c.current) return;
1268
- let T = R.touches[0].clientY - i.current;
1269
- T < 0 && (T = T * 0.3), o.current = T, s(T);
2085
+ u.current = !0, a.current = g.touches[0].clientY, c.current = Date.now();
2086
+ }, E = (g) => {
2087
+ if (!u.current) return;
2088
+ let d = g.touches[0].clientY - a.current;
2089
+ d < 0 && (d = d * 0.3), o.current = d, s(d);
1270
2090
  }, N = () => {
1271
- if (!c.current) return;
1272
- c.current = !1;
1273
- const R = o.current, T = (Date.now() - l.current) / 1e3, p = u.getBoundingClientRect().height, v = T > 0.05 && R > 0 && R / T > 500, k = R > p * 0.3;
1274
- v || k ? t() : (o.current = 0, s(0));
2091
+ if (!u.current) return;
2092
+ u.current = !1;
2093
+ const g = o.current, d = (Date.now() - c.current) / 1e3, f = l.getBoundingClientRect().height, v = d > 0.05 && g > 0 && g / d > 500, D = g > f * 0.3;
2094
+ v || D ? t() : (o.current = 0, s(0));
1275
2095
  };
1276
- return u.addEventListener("touchstart", d, { passive: !0 }), u.addEventListener("touchmove", x, { passive: !0 }), u.addEventListener("touchend", N), () => {
1277
- u.removeEventListener("touchstart", d), u.removeEventListener("touchmove", x), u.removeEventListener("touchend", N);
2096
+ return l.addEventListener("touchstart", m, { passive: !0 }), l.addEventListener("touchmove", E, { passive: !0 }), l.addEventListener("touchend", N), () => {
2097
+ l.removeEventListener("touchstart", m), l.removeEventListener("touchmove", E), l.removeEventListener("touchend", N);
1278
2098
  };
1279
- }, [e, t, r]), { offsetY: n };
1280
- }
1281
- const gt = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
1282
- function pt(e, t) {
1283
- z(() => {
1284
- const r = e.current;
1285
- if (!r) return;
1286
- const n = (s) => {
2099
+ }, [e, t, n]), { offsetY: r };
2100
+ }
2101
+ const on = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
2102
+ function an(e, t) {
2103
+ K(() => {
2104
+ const n = e.current;
2105
+ if (!n) return;
2106
+ const r = (s) => {
1287
2107
  if (s.key !== "Tab") return;
1288
2108
  const o = Array.from(
1289
- r.querySelectorAll(gt)
1290
- ).filter((u) => !u.hasAttribute("aria-hidden"));
2109
+ n.querySelectorAll(on)
2110
+ ).filter((l) => !l.hasAttribute("aria-hidden"));
1291
2111
  if (o.length === 0) return;
1292
- const i = o[0], l = o[o.length - 1], c = document.activeElement;
1293
- s.shiftKey && c === i ? (s.preventDefault(), l.focus()) : !s.shiftKey && c === l && (s.preventDefault(), i.focus());
2112
+ const a = o[0], c = o[o.length - 1], u = document.activeElement;
2113
+ s.shiftKey && u === a ? (s.preventDefault(), c.focus()) : !s.shiftKey && u === c && (s.preventDefault(), a.focus());
1294
2114
  };
1295
- return r.addEventListener("keydown", n), () => r.removeEventListener("keydown", n);
2115
+ return n.addEventListener("keydown", r), () => n.removeEventListener("keydown", r);
1296
2116
  }, [e, t]);
1297
2117
  }
1298
- const bt = /\*\*([^*]+)\*\*/g, yt = /\*([^*]+)\*/g, xt = /https?:\/\/[^\s)]+/g;
1299
- function wt(e) {
1300
- return e.replace(bt, "$1").replace(yt, "$1").replace(xt, (t) => {
2118
+ function ue() {
2119
+ if (!(typeof window > "u") && !(typeof window.SpeechSynthesisUtterance > "u"))
2120
+ return window.speechSynthesis ?? void 0;
2121
+ }
2122
+ function cn(e) {
2123
+ const [t] = O(() => ue() !== void 0), [n, r] = O(null), [s, o] = O(!1), a = L(0), c = L(!1), u = L([]), l = M(() => {
2124
+ a.current += 1, c.current = !1, u.current = [], r(null), o(!1);
2125
+ }, []), m = M(() => {
2126
+ var d;
2127
+ l(), (d = ue()) == null || d.cancel();
2128
+ }, [l]), E = M(
2129
+ (d, f) => {
2130
+ const v = ue();
2131
+ if (!v) return;
2132
+ l(), (v.speaking || v.pending) && v.cancel();
2133
+ const D = Vt(f);
2134
+ if (D.length === 0) return;
2135
+ const C = a.current, T = () => a.current === C;
2136
+ u.current = D.map((b, k) => {
2137
+ const A = new SpeechSynthesisUtterance(b);
2138
+ return A.lang = e, A.onerror = () => {
2139
+ T() && m();
2140
+ }, A.onend = () => {
2141
+ T() && (c.current && !v.paused ? m() : k === D.length - 1 && l());
2142
+ }, A;
2143
+ }), r(d);
2144
+ for (const b of u.current) v.speak(b);
2145
+ },
2146
+ [e, m, l]
2147
+ ), N = M(() => {
2148
+ const d = ue();
2149
+ d && (c.current = !0, d.pause(), o(d.paused));
2150
+ }, []), g = M(() => {
2151
+ const d = ue();
2152
+ d && (c.current = !1, d.resume(), o(!1));
2153
+ }, []);
2154
+ return K(() => m, [m]), { isSupported: t, activeId: n, isPaused: s, speak: E, pause: N, resume: g, cancel: m };
2155
+ }
2156
+ const ln = /\*\*([^*]+)\*\*/g, un = /\*([^*]+)\*/g, dn = /https?:\/\/[^\s)]+/g;
2157
+ function Oe(e) {
2158
+ return e.replace(ln, "$1").replace(un, "$1").replace(dn, (t) => {
1301
2159
  try {
1302
2160
  return new URL(t).hostname;
1303
2161
  } catch {
@@ -1305,220 +2163,218 @@ function wt(e) {
1305
2163
  }
1306
2164
  });
1307
2165
  }
1308
- const vt = {
2166
+ const hn = {
1309
2167
  "bottom-right": "bottom-24 right-3 sm:right-6",
1310
2168
  "bottom-left": "bottom-24 left-3 sm:left-6",
1311
2169
  "top-right": "top-24 right-3 sm:right-6",
1312
2170
  "top-left": "top-24 left-3 sm:left-6"
1313
2171
  };
1314
- function Rt({
2172
+ function fn({
1315
2173
  messages: e,
1316
2174
  isLoading: t,
1317
- isStreaming: r = !1,
1318
- streamingMessageId: n = null,
2175
+ isStreaming: n = !1,
2176
+ streamingMessageId: r = null,
1319
2177
  error: s,
1320
2178
  canRetry: o = !1,
1321
- onSend: i,
1322
- onStop: l,
1323
- onRetry: c,
1324
- onClose: u,
1325
- title: d = "Chat",
1326
- subtitle: x = "Ask me anything",
2179
+ onSend: a,
2180
+ onStop: c,
2181
+ onRetry: u,
2182
+ onClose: l,
2183
+ title: m = "Chat",
2184
+ subtitle: E = "Ask me anything",
1327
2185
  welcomeMessage: N = "Hi! How can I help you today?",
1328
- placeholder: R,
1329
- position: T = "bottom-right",
1330
- translations: p,
1331
- isMobile: v = !1
2186
+ placeholder: g,
2187
+ position: d = "bottom-right",
2188
+ translations: f,
2189
+ isMobile: v = !1,
2190
+ attachments: D = null,
2191
+ voice: C = null
1332
2192
  }) {
1333
- const k = Le(), H = I(null), w = I(null), [f, E] = L(null);
1334
- pt(H, !0);
1335
- const { offsetY: F } = mt(
1336
- w,
1337
- u,
2193
+ const T = Qe(), b = L(null), k = L(null), [A, B] = O(null);
2194
+ an(b, !0);
2195
+ const y = cn((C == null ? void 0 : C.lang) ?? "en-US"), W = !!(C != null && C.output) && y.isSupported, U = {
2196
+ play: (f == null ? void 0 : f.readAloud) ?? "Read aloud",
2197
+ pause: (f == null ? void 0 : f.pauseReading) ?? "Pause reading",
2198
+ resume: (f == null ? void 0 : f.resumeReading) ?? "Resume reading",
2199
+ stop: (f == null ? void 0 : f.stopReading) ?? "Stop reading"
2200
+ }, { offsetY: H } = sn(
2201
+ k,
2202
+ l,
1338
2203
  v
1339
- ), W = F !== 0, y = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
1340
- z(() => {
1341
- const m = w.current;
1342
- m && (m.scrollTop = m.scrollHeight);
1343
- }, [e, t]), z(() => {
1344
- const m = (V) => {
1345
- V.key === "Escape" && !V.isComposing && u();
2204
+ ), _ = H !== 0, J = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(prefers-reduced-motion: reduce)").matches : !1;
2205
+ K(() => {
2206
+ const w = k.current;
2207
+ w && (w.scrollTop = w.scrollHeight);
2208
+ }, [e, t]), K(() => {
2209
+ const w = (ee) => {
2210
+ ee.key === "Escape" && !ee.isComposing && l();
1346
2211
  };
1347
- return document.addEventListener("keydown", m), () => document.removeEventListener("keydown", m);
1348
- }, [u]);
1349
- const K = (p == null ? void 0 : p.closeChat) ?? "Close chat", B = (p == null ? void 0 : p.chatMessages) ?? "Chat messages", _ = [...e].reverse().find((m) => m.role === "assistant");
1350
- return /* @__PURE__ */ g(
2212
+ return document.addEventListener("keydown", w), () => document.removeEventListener("keydown", w);
2213
+ }, [l]);
2214
+ const re = (f == null ? void 0 : f.closeChat) ?? "Close chat", X = (f == null ? void 0 : f.chatMessages) ?? "Chat messages", te = [...e].reverse().find((w) => w.role === "assistant");
2215
+ return /* @__PURE__ */ p(
1351
2216
  "div",
1352
2217
  {
1353
- ref: H,
2218
+ ref: b,
1354
2219
  role: "dialog",
1355
2220
  "aria-modal": v ? "true" : void 0,
1356
- "aria-labelledby": k,
1357
- className: v ? "claudius-bottom-sheet fixed inset-x-0 bottom-0 z-50 flex h-[90vh] w-full flex-col overflow-hidden rounded-t-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body" : `fixed ${vt[T]} z-50 flex h-[min(500px,calc(100vh-7rem))] w-[calc(100vw-1.5rem)] max-w-[380px] sm:max-w-[400px] md:max-w-[440px] flex-col overflow-hidden rounded-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body`,
1358
- style: v && !y ? { transform: `translateY(${Math.max(0, F)}px)` } : void 0,
1359
- "data-dragging": W || void 0,
2221
+ "aria-labelledby": T,
2222
+ className: v ? "claudius-bottom-sheet fixed inset-x-0 bottom-0 z-50 flex h-[90vh] w-full flex-col overflow-hidden rounded-t-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body" : `fixed ${hn[d]} z-50 flex h-[min(500px,calc(100vh-7rem))] w-[calc(100vw-1.5rem)] max-w-[380px] sm:max-w-[400px] md:max-w-[440px] flex-col overflow-hidden rounded-claudius-lg bg-claudius-surface shadow-claudius-elevated font-body`,
2223
+ style: v && !J ? { transform: `translateY(${Math.max(0, H)}px)` } : void 0,
2224
+ "data-dragging": _ || void 0,
1360
2225
  children: [
1361
- v && /* @__PURE__ */ a("div", { className: "flex justify-center py-2", "aria-hidden": "true", children: /* @__PURE__ */ a("div", { className: "h-1 w-8 rounded-claudius-full bg-claudius-border" }) }),
1362
- /* @__PURE__ */ a(
1363
- dt,
2226
+ v && /* @__PURE__ */ i("div", { className: "flex justify-center py-2", "aria-hidden": "true", children: /* @__PURE__ */ i("div", { className: "h-1 w-8 rounded-claudius-full bg-claudius-border" }) }),
2227
+ /* @__PURE__ */ i(
2228
+ tn,
1364
2229
  {
1365
- title: d,
1366
- subtitle: x,
1367
- titleId: k,
1368
- closeLabel: K,
1369
- onClose: u
2230
+ title: m,
2231
+ subtitle: E,
2232
+ titleId: T,
2233
+ closeLabel: re,
2234
+ onClose: l
1370
2235
  }
1371
2236
  ),
1372
- /* @__PURE__ */ g("div", { className: "relative flex-1 overflow-hidden", children: [
1373
- f && /* @__PURE__ */ a(
1374
- ut,
2237
+ /* @__PURE__ */ p("div", { className: "relative flex-1 overflow-hidden", children: [
2238
+ A && /* @__PURE__ */ i(
2239
+ en,
1375
2240
  {
1376
- sources: f.sources,
1377
- onClose: () => E(null)
2241
+ sources: A.sources,
2242
+ onClose: () => B(null)
1378
2243
  }
1379
2244
  ),
1380
- /* @__PURE__ */ g(
2245
+ /* @__PURE__ */ p(
1381
2246
  "div",
1382
2247
  {
1383
- ref: w,
2248
+ ref: k,
1384
2249
  role: "log",
1385
- "aria-label": B,
2250
+ "aria-label": X,
1386
2251
  className: "h-full space-y-3 overflow-y-auto px-4 py-4",
1387
2252
  children: [
1388
- e.length === 0 && !s && /* @__PURE__ */ a("div", { className: "mr-auto flex max-w-[85%]", children: /* @__PURE__ */ a("div", { className: "rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-2.5 text-sm leading-relaxed text-claudius-assistant-bubble-text", children: N }) }),
1389
- e.map((m) => /* @__PURE__ */ a(
1390
- st,
2253
+ e.length === 0 && !s && /* @__PURE__ */ i("div", { className: "mr-auto flex max-w-[85%]", children: /* @__PURE__ */ i("div", { className: "rounded-claudius-bubble rounded-bl-claudius-tail bg-claudius-assistant-bubble px-4 py-2.5 text-sm leading-relaxed text-claudius-assistant-bubble-text", children: N }) }),
2254
+ e.map((w) => /* @__PURE__ */ i(
2255
+ Bt,
1391
2256
  {
1392
- role: m.role,
1393
- content: m.content,
1394
- isStreaming: m.id === n,
1395
- sources: m.sources,
1396
- toolUses: m.toolUses,
1397
- toolUsedLabel: p == null ? void 0 : p.toolUsed,
1398
- toolDetailsLabel: p == null ? void 0 : p.toolDetails,
1399
- isSourceActive: (f == null ? void 0 : f.messageId) === m.id,
2257
+ role: w.role,
2258
+ content: w.content,
2259
+ isStreaming: w.id === r,
2260
+ sources: w.sources,
2261
+ attachments: w.attachments,
2262
+ toolUses: w.toolUses,
2263
+ toolUsedLabel: f == null ? void 0 : f.toolUsed,
2264
+ toolDetailsLabel: f == null ? void 0 : f.toolDetails,
2265
+ isSourceActive: (A == null ? void 0 : A.messageId) === w.id,
1400
2266
  onSourceClick: () => {
1401
- (f == null ? void 0 : f.messageId) === m.id ? E(null) : m.sources && m.sources.length > 0 && E({ messageId: m.id, sources: m.sources });
1402
- }
2267
+ (A == null ? void 0 : A.messageId) === w.id ? B(null) : w.sources && w.sources.length > 0 && B({ messageId: w.id, sources: w.sources });
2268
+ },
2269
+ speech: (
2270
+ // Only settled replies with something to say: reading a
2271
+ // message that is still streaming would stop mid-sentence.
2272
+ W && w.role === "assistant" && w.id !== r && w.content.trim() !== "" ? {
2273
+ state: y.activeId !== w.id ? "idle" : y.isPaused ? "paused" : "speaking",
2274
+ labels: U,
2275
+ // Same cleanup as the screen-reader announcement:
2276
+ // no literal asterisks, URLs shortened to hostnames.
2277
+ onPlay: () => y.speak(
2278
+ w.id,
2279
+ Oe(w.content)
2280
+ ),
2281
+ onPause: y.pause,
2282
+ onResume: y.resume,
2283
+ onStop: y.cancel
2284
+ } : void 0
2285
+ )
1403
2286
  },
1404
- m.id
2287
+ w.id
1405
2288
  )),
1406
2289
  t && /* Once streamed tokens are rendering in a bubble, the typing
1407
2290
  indicator is redundant — show it only until the first token.
1408
2291
  A tool-only placeholder (no text yet) keeps the indicator. */
1409
- !(n !== null && e.some(
1410
- (m) => m.id === n && m.content.length > 0
1411
- )) && /* @__PURE__ */ a(
1412
- ht,
2292
+ !(r !== null && e.some(
2293
+ (w) => w.id === r && w.content.length > 0
2294
+ )) && /* @__PURE__ */ i(
2295
+ rn,
1413
2296
  {
1414
- label: (p == null ? void 0 : p.typingIndicator) ?? "Assistant is typing"
2297
+ label: (f == null ? void 0 : f.typingIndicator) ?? "Assistant is typing"
1415
2298
  }
1416
2299
  ),
1417
- s && /* @__PURE__ */ a(
1418
- ft,
2300
+ s && /* @__PURE__ */ i(
2301
+ nn,
1419
2302
  {
1420
2303
  message: s,
1421
- retryLabel: (p == null ? void 0 : p.errorRetry) ?? "Retry",
1422
- onRetry: o && c && !t ? c : void 0
2304
+ retryLabel: (f == null ? void 0 : f.errorRetry) ?? "Retry",
2305
+ onRetry: o && u && !t ? u : void 0
1423
2306
  }
1424
2307
  )
1425
2308
  ]
1426
2309
  }
1427
2310
  )
1428
2311
  ] }),
1429
- /* @__PURE__ */ a(
2312
+ /* @__PURE__ */ i(
1430
2313
  "div",
1431
2314
  {
1432
2315
  "data-claudius-live": "assistant",
1433
2316
  "aria-live": "polite",
1434
2317
  "aria-atomic": "true",
1435
2318
  className: "sr-only",
1436
- children: _ && _.id !== n ? wt(_.content) : ""
2319
+ children: te && te.id !== r ? Oe(te.content) : ""
1437
2320
  }
1438
2321
  ),
1439
- /* @__PURE__ */ a(
1440
- it,
2322
+ /* @__PURE__ */ i(
2323
+ Qt,
1441
2324
  {
1442
- onSend: i,
2325
+ onSend: a,
1443
2326
  isLoading: t,
1444
- isStreaming: r,
1445
- onStop: l,
1446
- placeholder: R,
1447
- translations: p
2327
+ isStreaming: n,
2328
+ onStop: c,
2329
+ placeholder: g,
2330
+ translations: f,
2331
+ attachments: D,
2332
+ voice: C,
2333
+ onVoiceStart: y.cancel
1448
2334
  }
1449
2335
  )
1450
2336
  ]
1451
2337
  }
1452
2338
  );
1453
2339
  }
1454
- function Et({
2340
+ function mn({
1455
2341
  message: e,
1456
2342
  position: t,
1457
- onOpen: r,
1458
- onDismiss: n,
2343
+ onOpen: n,
2344
+ onDismiss: r,
1459
2345
  dismissLabel: s
1460
2346
  }) {
1461
- const o = t.startsWith("bottom"), i = t.endsWith("right"), l = [
2347
+ const o = t.startsWith("bottom"), a = t.endsWith("right"), c = [
1462
2348
  "claudius-greeting-bubble",
1463
2349
  "fixed z-40 max-w-xs",
1464
2350
  o ? "bottom-20" : "top-20",
1465
- i ? "right-4" : "left-4"
2351
+ a ? "right-4" : "left-4"
1466
2352
  ].join(" ");
1467
- return /* @__PURE__ */ g("div", { className: l, role: "status", "aria-live": "polite", children: [
1468
- /* @__PURE__ */ a(
2353
+ return /* @__PURE__ */ p("div", { className: c, role: "status", "aria-live": "polite", children: [
2354
+ /* @__PURE__ */ i(
1469
2355
  "button",
1470
2356
  {
1471
2357
  type: "button",
1472
- onClick: r,
2358
+ onClick: n,
1473
2359
  className: "block w-full rounded-claudius-lg bg-claudius-surface p-4 pr-8 text-left text-sm font-body text-claudius-text shadow-claudius-floating ring-1 ring-claudius-border transition hover:shadow-claudius-floating-hover focus:outline-none focus:ring-2 focus:ring-claudius-accent",
1474
2360
  children: e
1475
2361
  }
1476
2362
  ),
1477
- /* @__PURE__ */ a(
2363
+ /* @__PURE__ */ i(
1478
2364
  "button",
1479
2365
  {
1480
2366
  type: "button",
1481
- onClick: (c) => {
1482
- c.stopPropagation(), n();
2367
+ onClick: (u) => {
2368
+ u.stopPropagation(), r();
1483
2369
  },
1484
2370
  "aria-label": s,
1485
2371
  className: "absolute right-1 top-1 flex h-6 w-6 items-center justify-center rounded-claudius-full text-claudius-text-muted hover:bg-claudius-surface-muted focus:outline-none focus:ring-2 focus:ring-claudius-accent",
1486
- children: /* @__PURE__ */ a("span", { "aria-hidden": "true", children: "×" })
2372
+ children: /* @__PURE__ */ i("span", { "aria-hidden": "true", children: "×" })
1487
2373
  }
1488
2374
  )
1489
2375
  ] });
1490
2376
  }
1491
- const Re = {
1492
- // ChatWindow
1493
- title: "Chat",
1494
- subtitle: "Ask me anything",
1495
- welcomeMessage: "Hi! How can I help you today?",
1496
- closeChat: "Close chat",
1497
- chatMessages: "Chat messages",
1498
- typingIndicator: "Assistant is typing",
1499
- // ChatInput
1500
- placeholder: "Type your message...",
1501
- sendMessage: "Send message",
1502
- stopGenerating: "Stop generating",
1503
- toolUsed: "Used tool:",
1504
- toolDetails: "Tool details",
1505
- typeYourMessage: "Type your message",
1506
- // ChatToggleButton
1507
- openChat: "Open chat",
1508
- // GreetingBubble
1509
- dismissGreeting: "Dismiss greeting",
1510
- // Errors
1511
- errorGeneric: "Something went wrong. Please try again.",
1512
- errorConnection: "Failed to connect. Please try again.",
1513
- errorTimeout: "Request timed out. Please try again.",
1514
- errorRateLimitMinute: "Too many requests. Please wait a minute.",
1515
- errorRateLimitHour: "Hourly limit reached. Please try again later.",
1516
- errorRetry: "Retry"
1517
- }, Tt = Re;
1518
- function qt(e) {
1519
- return { ...Tt, ...e };
1520
- }
1521
- const Mt = {
2377
+ const pn = {
1522
2378
  // ChatWindow
1523
2379
  title: "Chat",
1524
2380
  subtitle: "Pregúntame lo que quieras",
@@ -1537,14 +2393,36 @@ const Mt = {
1537
2393
  openChat: "Abrir chat",
1538
2394
  // GreetingBubble
1539
2395
  dismissGreeting: "Descartar saludo",
2396
+ // Attachments
2397
+ attachFile: "Adjuntar un archivo",
2398
+ removeAttachment: "Quitar adjunto",
2399
+ attachmentsLabel: "Adjuntos",
2400
+ dropFilesHint: "Suelta los archivos para adjuntarlos",
2401
+ attachmentTooLarge: "{name} es demasiado grande. El tamaño máximo es {max}.",
2402
+ attachmentTypeNotAllowed: "{name} no es un tipo de archivo compatible.",
2403
+ attachmentTooMany: "Puedes adjuntar hasta {max} archivos por mensaje.",
2404
+ // Voice
2405
+ voiceInput: "Entrada de voz",
2406
+ voiceInputHold: "Mantén pulsado para hablar",
2407
+ voiceListening: "Escuchando...",
2408
+ voicePermissionDenied: "El acceso al micrófono está bloqueado. Permítelo en la configuración de tu navegador para usar la entrada de voz.",
2409
+ voiceNoSpeech: "No se detectó ninguna voz. Inténtalo de nuevo.",
2410
+ voiceNoMicrophone: "No se encontró ningún micrófono.",
2411
+ voiceUnavailable: "La entrada de voz no está disponible en este momento.",
2412
+ readAloud: "Leer en voz alta",
2413
+ pauseReading: "Pausar la lectura",
2414
+ resumeReading: "Reanudar la lectura",
2415
+ stopReading: "Detener la lectura",
1540
2416
  // Errors
1541
2417
  errorGeneric: "Algo salió mal. Inténtalo de nuevo.",
1542
2418
  errorConnection: "No se pudo conectar. Inténtalo de nuevo.",
1543
2419
  errorTimeout: "La solicitud tardó demasiado. Inténtalo de nuevo.",
1544
2420
  errorRateLimitMinute: "Demasiadas solicitudes. Espera un minuto.",
1545
2421
  errorRateLimitHour: "Has alcanzado el límite por hora. Inténtalo más tarde.",
2422
+ errorAttachmentRejected: "Se rechazó un adjunto. Quítalo e inténtalo de nuevo.",
2423
+ errorAttachmentQuota: "Límite de subida alcanzado. Inténtalo más tarde.",
1546
2424
  errorRetry: "Reintentar"
1547
- }, St = {
2425
+ }, gn = {
1548
2426
  // ChatWindow
1549
2427
  title: "Chat",
1550
2428
  subtitle: "Posez-moi vos questions",
@@ -1563,14 +2441,36 @@ const Mt = {
1563
2441
  openChat: "Ouvrir le chat",
1564
2442
  // GreetingBubble
1565
2443
  dismissGreeting: "Ignorer le message d'accueil",
2444
+ // Attachments
2445
+ attachFile: "Joindre un fichier",
2446
+ removeAttachment: "Retirer la pièce jointe",
2447
+ attachmentsLabel: "Pièces jointes",
2448
+ dropFilesHint: "Déposez les fichiers pour les joindre",
2449
+ attachmentTooLarge: "{name} est trop volumineux. La taille maximale est de {max}.",
2450
+ attachmentTypeNotAllowed: "{name} n'est pas un type de fichier pris en charge.",
2451
+ attachmentTooMany: "Vous pouvez joindre jusqu'à {max} fichiers par message.",
2452
+ // Voice
2453
+ voiceInput: "Saisie vocale",
2454
+ voiceInputHold: "Maintenez pour parler",
2455
+ voiceListening: "Écoute en cours...",
2456
+ voicePermissionDenied: "L'accès au microphone est bloqué. Autorisez-le dans les paramètres de votre navigateur pour utiliser la saisie vocale.",
2457
+ voiceNoSpeech: "Aucune voix n'a été détectée. Veuillez réessayer.",
2458
+ voiceNoMicrophone: "Aucun microphone n'a été trouvé.",
2459
+ voiceUnavailable: "La saisie vocale n'est pas disponible pour le moment.",
2460
+ readAloud: "Lire à voix haute",
2461
+ pauseReading: "Mettre la lecture en pause",
2462
+ resumeReading: "Reprendre la lecture",
2463
+ stopReading: "Arrêter la lecture",
1566
2464
  // Errors
1567
2465
  errorGeneric: "Une erreur s'est produite. Veuillez réessayer.",
1568
2466
  errorConnection: "Échec de la connexion. Veuillez réessayer.",
1569
2467
  errorTimeout: "La requête a expiré. Veuillez réessayer.",
1570
2468
  errorRateLimitMinute: "Trop de requêtes. Veuillez patienter une minute.",
1571
2469
  errorRateLimitHour: "Limite horaire atteinte. Veuillez réessayer plus tard.",
2470
+ errorAttachmentRejected: "Une pièce jointe a été refusée. Retirez-la et réessayez.",
2471
+ errorAttachmentQuota: "Limite d'envoi atteinte. Veuillez réessayer plus tard.",
1572
2472
  errorRetry: "Réessayer"
1573
- }, Ct = {
2473
+ }, bn = {
1574
2474
  // ChatWindow
1575
2475
  title: "Chat",
1576
2476
  subtitle: "Fragen Sie mich alles",
@@ -1589,35 +2489,57 @@ const Mt = {
1589
2489
  openChat: "Chat öffnen",
1590
2490
  // GreetingBubble
1591
2491
  dismissGreeting: "Begrüßung schließen",
2492
+ // Attachments
2493
+ attachFile: "Datei anhängen",
2494
+ removeAttachment: "Anhang entfernen",
2495
+ attachmentsLabel: "Anhänge",
2496
+ dropFilesHint: "Dateien hier ablegen, um sie anzuhängen",
2497
+ attachmentTooLarge: "{name} ist zu groß. Die maximale Größe beträgt {max}.",
2498
+ attachmentTypeNotAllowed: "{name} ist kein unterstützter Dateityp.",
2499
+ attachmentTooMany: "Sie können bis zu {max} Dateien pro Nachricht anhängen.",
2500
+ // Voice
2501
+ voiceInput: "Spracheingabe",
2502
+ voiceInputHold: "Zum Sprechen gedrückt halten",
2503
+ voiceListening: "Ich höre zu...",
2504
+ voicePermissionDenied: "Der Zugriff auf das Mikrofon ist blockiert. Erlauben Sie ihn in den Einstellungen Ihres Browsers, um die Spracheingabe zu nutzen.",
2505
+ voiceNoSpeech: "Es wurde keine Sprache erkannt. Bitte versuchen Sie es erneut.",
2506
+ voiceNoMicrophone: "Es wurde kein Mikrofon gefunden.",
2507
+ voiceUnavailable: "Die Spracheingabe ist momentan nicht verfügbar.",
2508
+ readAloud: "Vorlesen",
2509
+ pauseReading: "Vorlesen pausieren",
2510
+ resumeReading: "Vorlesen fortsetzen",
2511
+ stopReading: "Vorlesen beenden",
1592
2512
  // Errors
1593
2513
  errorGeneric: "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.",
1594
2514
  errorConnection: "Verbindung fehlgeschlagen. Bitte versuchen Sie es erneut.",
1595
2515
  errorTimeout: "Zeitüberschreitung der Anfrage. Bitte versuchen Sie es erneut.",
1596
2516
  errorRateLimitMinute: "Zu viele Anfragen. Bitte warten Sie eine Minute.",
1597
2517
  errorRateLimitHour: "Stündliches Limit erreicht. Bitte versuchen Sie es später erneut.",
2518
+ errorAttachmentRejected: "Ein Anhang wurde abgelehnt. Bitte entfernen Sie ihn und versuchen Sie es erneut.",
2519
+ errorAttachmentQuota: "Upload-Limit erreicht. Bitte versuchen Sie es später erneut.",
1598
2520
  errorRetry: "Erneut versuchen"
1599
- }, Ee = {
1600
- en: Re,
1601
- es: Mt,
1602
- fr: St,
1603
- de: Ct
2521
+ }, $e = {
2522
+ en: ze,
2523
+ es: pn,
2524
+ fr: gn,
2525
+ de: bn
1604
2526
  };
1605
- function be(e) {
2527
+ function je(e) {
1606
2528
  if (!e) return;
1607
2529
  const t = e.toLowerCase().split("-")[0];
1608
- return Object.prototype.hasOwnProperty.call(Ee, t) ? t : void 0;
2530
+ return Object.prototype.hasOwnProperty.call($e, t) ? t : void 0;
1609
2531
  }
1610
- function Nt() {
1611
- const e = typeof document < "u" ? be(document.documentElement.lang) : void 0;
2532
+ function Fe() {
2533
+ const e = typeof document < "u" ? je(document.documentElement.lang) : void 0;
1612
2534
  if (e) return e;
1613
- const t = typeof navigator < "u" ? be(navigator.language) : void 0;
2535
+ const t = typeof navigator < "u" ? je(navigator.language) : void 0;
1614
2536
  return t || "en";
1615
2537
  }
1616
- function kt(e = {}) {
1617
- const { locale: t, translations: r } = e, n = Ee[t ?? Nt()];
1618
- return r ? { ...n, ...r } : { ...n };
2538
+ function yn(e = {}) {
2539
+ const { locale: t, translations: n } = e, r = $e[t ?? Fe()];
2540
+ return n ? { ...r, ...n } : { ...r };
1619
2541
  }
1620
- const ye = [
2542
+ const Pe = [
1621
2543
  "accent",
1622
2544
  "accentText",
1623
2545
  "accentSoft",
@@ -1637,11 +2559,11 @@ const ye = [
1637
2559
  "errorText",
1638
2560
  "link",
1639
2561
  "scrim"
1640
- ], Lt = ["sm", "md", "lg", "full", "tail"], At = [
2562
+ ], xn = ["sm", "md", "lg", "full", "tail"], vn = [
1641
2563
  "elevated",
1642
2564
  "floating",
1643
2565
  "floatingHover"
1644
- ], Ot = ["heading", "body"], Te = {
2566
+ ], wn = ["heading", "body"], We = {
1645
2567
  default: {
1646
2568
  name: "default"
1647
2569
  },
@@ -1726,243 +2648,253 @@ const ye = [
1726
2648
  }
1727
2649
  }
1728
2650
  };
1729
- function It(e) {
1730
- return Object.prototype.hasOwnProperty.call(Te, e);
2651
+ function Rn(e) {
2652
+ return Object.prototype.hasOwnProperty.call(We, e);
1731
2653
  }
1732
- const Dt = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
1733
- function _t(e) {
2654
+ const En = /* @__PURE__ */ new Set(["light", "dark", "auto"]);
2655
+ function Tn(e) {
1734
2656
  if (e === void 0)
1735
2657
  return { mode: "light" };
1736
2658
  if (typeof e == "string") {
1737
- if (Dt.has(e))
2659
+ if (En.has(e))
1738
2660
  return { mode: e };
1739
- if (It(e)) {
1740
- const t = Te[e];
2661
+ if (Rn(e)) {
2662
+ const t = We[e];
1741
2663
  return { mode: t.colorScheme ?? "light", theme: t };
1742
2664
  }
1743
2665
  return { mode: "light", url: e };
1744
2666
  }
1745
2667
  return { mode: e.colorScheme ?? "light", theme: e };
1746
2668
  }
1747
- function jt(e) {
2669
+ function Sn(e) {
1748
2670
  return e.replace(/[A-Z]/g, (t) => `-${t.toLowerCase()}`);
1749
2671
  }
1750
- function Ht(e, t) {
2672
+ function kn(e, t) {
1751
2673
  console.warn(
1752
2674
  `[Claudius] Ignoring unknown theme token "${t}" in "${e}"`
1753
2675
  );
1754
2676
  }
1755
- function Q(e, t, r, n, s, o = "") {
2677
+ function de(e, t, n, r, s, o = "") {
1756
2678
  if (s)
1757
- for (const [i, l] of Object.entries(s)) {
1758
- if (!n.includes(i)) {
1759
- Ht(t, i);
2679
+ for (const [a, c] of Object.entries(s)) {
2680
+ if (!r.includes(a)) {
2681
+ kn(t, a);
1760
2682
  continue;
1761
2683
  }
1762
- typeof l == "string" && (e[`${r}${jt(i)}${o}`] = l);
2684
+ typeof c == "string" && (e[`${n}${Sn(a)}${o}`] = c);
1763
2685
  }
1764
2686
  }
1765
- function Bt(e) {
2687
+ function Cn(e) {
1766
2688
  const t = {};
1767
- Q(t, "colors", "--cl-color-", ye, e.colors);
1768
- for (const [r, n] of Object.entries({ ...t }))
1769
- t[`${r}-dark`] = n;
1770
- return Q(
2689
+ de(t, "colors", "--cl-color-", Pe, e.colors);
2690
+ for (const [n, r] of Object.entries({ ...t }))
2691
+ t[`${n}-dark`] = r;
2692
+ return de(
1771
2693
  t,
1772
2694
  "colorsDark",
1773
2695
  "--cl-color-",
1774
- ye,
2696
+ Pe,
1775
2697
  e.colorsDark,
1776
2698
  "-dark"
1777
- ), Q(t, "radii", "--cl-radius-", Lt, e.radii), Q(t, "shadows", "--cl-shadow-", At, e.shadows), Q(t, "fonts", "--cl-font-", Ot, e.fonts), t;
2699
+ ), de(t, "radii", "--cl-radius-", xn, e.radii), de(t, "shadows", "--cl-shadow-", vn, e.shadows), de(t, "fonts", "--cl-font-", wn, e.fonts), t;
1778
2700
  }
1779
- function $t(e) {
2701
+ function An(e) {
1780
2702
  return typeof e == "object" && e !== null && !Array.isArray(e);
1781
2703
  }
1782
- function Pt(e) {
1783
- const t = se(() => _t(e), [e]), [r, n] = L(null), s = t.url;
1784
- z(() => {
1785
- if (n(null), !s) return;
1786
- const c = new AbortController();
1787
- return fetch(s, { signal: c.signal }).then((u) => {
1788
- if (!u.ok)
1789
- throw new Error(`HTTP ${u.status}`);
1790
- return u.json();
1791
- }).then((u) => {
1792
- if (!$t(u))
2704
+ function Nn(e) {
2705
+ const t = ae(() => Tn(e), [e]), [n, r] = O(null), s = t.url;
2706
+ K(() => {
2707
+ if (r(null), !s) return;
2708
+ const u = new AbortController();
2709
+ return fetch(s, { signal: u.signal }).then((l) => {
2710
+ if (!l.ok)
2711
+ throw new Error(`HTTP ${l.status}`);
2712
+ return l.json();
2713
+ }).then((l) => {
2714
+ if (!An(l))
1793
2715
  throw new Error("theme JSON must be an object");
1794
- n(u);
1795
- }).catch((u) => {
1796
- c.signal.aborted || console.error(`[Claudius] Failed to load theme from ${s}:`, u);
1797
- }), () => c.abort();
2716
+ r(l);
2717
+ }).catch((l) => {
2718
+ u.signal.aborted || console.error(`[Claudius] Failed to load theme from ${s}:`, l);
2719
+ }), () => u.abort();
1798
2720
  }, [s]);
1799
- const o = t.theme ?? r ?? null, i = (r == null ? void 0 : r.colorScheme) ?? t.mode, l = se(
1800
- () => o ? Bt(o) : {},
2721
+ const o = t.theme ?? n ?? null, a = (n == null ? void 0 : n.colorScheme) ?? t.mode, c = ae(
2722
+ () => o ? Cn(o) : {},
1801
2723
  [o]
1802
2724
  );
1803
- return { mode: i, cssVars: l };
2725
+ return { mode: a, cssVars: c };
1804
2726
  }
1805
- const Me = "claudius:triggers:dismissed";
1806
- function Ut() {
2727
+ const Ge = "claudius:triggers:dismissed";
2728
+ function Mn() {
1807
2729
  if (typeof window > "u") return !1;
1808
2730
  try {
1809
- return window.sessionStorage.getItem(Me) === "1";
2731
+ return window.sessionStorage.getItem(Ge) === "1";
1810
2732
  } catch {
1811
2733
  return !1;
1812
2734
  }
1813
2735
  }
1814
- function Gt() {
2736
+ function Ln() {
1815
2737
  if (!(typeof window > "u"))
1816
2738
  try {
1817
- window.sessionStorage.setItem(Me, "1");
2739
+ window.sessionStorage.setItem(Ge, "1");
1818
2740
  } catch {
1819
2741
  }
1820
2742
  }
1821
- function Jt({
2743
+ function _n({
1822
2744
  apiUrl: e,
1823
2745
  title: t,
1824
- subtitle: r,
1825
- welcomeMessage: n,
2746
+ subtitle: n,
2747
+ welcomeMessage: r,
1826
2748
  placeholder: s,
1827
2749
  persistMessages: o,
1828
- storageKeyPrefix: i,
1829
- requestTimeoutMs: l,
1830
- theme: c = "light",
1831
- accentColor: u,
1832
- position: d = "bottom-right",
1833
- locale: x,
2750
+ storageKeyPrefix: a,
2751
+ requestTimeoutMs: c,
2752
+ theme: u = "light",
2753
+ accentColor: l,
2754
+ position: m = "bottom-right",
2755
+ locale: E,
1834
2756
  translations: N,
1835
- triggers: R,
1836
- plugins: T,
1837
- streaming: p = !0
2757
+ triggers: g,
2758
+ plugins: d,
2759
+ streaming: f = !0,
2760
+ attachments: v = !1,
2761
+ voice: D = !1
1838
2762
  }) {
1839
- const [v, k] = L(!1), [H, w] = L(null), [f, E] = L(Ut), F = I(!1), W = Ge("(max-width: 639px)"), y = se(
1840
- () => kt({ locale: x, translations: N }),
1841
- [x, N]
2763
+ const [C, T] = O(!1), b = ae(
2764
+ () => st(v),
2765
+ [v]
2766
+ ), k = ae(
2767
+ () => Ft(D, E ?? Fe()),
2768
+ [D, E]
2769
+ ), [A, B] = O(null), [y, W] = O(Mn), U = L(!1), H = xt("(max-width: 639px)"), _ = ae(
2770
+ () => yn({ locale: E, translations: N }),
2771
+ [E, N]
1842
2772
  ), {
1843
- messages: K,
1844
- isLoading: B,
1845
- isStreaming: _,
1846
- streamingMessageId: m,
1847
- error: V,
2773
+ messages: J,
2774
+ isLoading: re,
2775
+ isStreaming: X,
2776
+ streamingMessageId: te,
2777
+ error: w,
1848
2778
  canRetry: ee,
1849
- sendMessage: J,
1850
- stop: oe,
1851
- retry: ie
1852
- } = Ue({
2779
+ sendMessage: ie,
2780
+ stop: x,
2781
+ retry: z
2782
+ } = yt({
1853
2783
  apiUrl: e,
1854
2784
  persistMessages: o,
1855
- storageKeyPrefix: i,
1856
- timeoutMs: l,
1857
- translations: y,
1858
- plugins: T,
1859
- streaming: p
1860
- }), te = I(null), re = I(v), { mode: h, cssVars: A } = Pt(c), [S, Y] = L(!1);
1861
- z(() => {
1862
- if (h !== "auto") return;
1863
- const D = window.matchMedia("(prefers-color-scheme: dark)");
1864
- Y(D.matches);
1865
- const he = (Se) => Y(Se.matches);
1866
- return D.addEventListener("change", he), () => D.removeEventListener("change", he);
1867
- }, [h]), z(() => {
1868
- var D;
1869
- re.current && !v && ((D = te.current) == null || D.focus()), re.current = v;
1870
- }, [v]);
1871
- const $ = O(() => {
1872
- E(!0), Gt();
1873
- }, []), b = O(() => {
1874
- k(!1), F.current && (F.current = !1, $());
1875
- }, [$]), C = O(() => {
1876
- k((D) => !D);
1877
- }, []), M = O(() => {
1878
- F.current = !0, w(null), k(!0);
1879
- }, []), P = O((D) => {
1880
- w(D);
1881
- }, []), U = O(() => {
1882
- w(null), M();
1883
- }, [M]), Z = O(() => {
1884
- w(null), $();
1885
- }, [$]);
1886
- ze({
1887
- triggers: R,
1888
- enabled: !f && !v,
1889
- onOpen: M,
1890
- onGreeting: P
2785
+ storageKeyPrefix: a,
2786
+ timeoutMs: c,
2787
+ translations: _,
2788
+ plugins: d,
2789
+ streaming: f
2790
+ }), I = L(null), Q = L(C), { mode: $, cssVars: ne } = Nn(u), [Z, R] = O(!1);
2791
+ K(() => {
2792
+ if ($ !== "auto") return;
2793
+ const G = window.matchMedia("(prefers-color-scheme: dark)");
2794
+ R(G.matches);
2795
+ const Te = (Ve) => R(Ve.matches);
2796
+ return G.addEventListener("change", Te), () => G.removeEventListener("change", Te);
2797
+ }, [$]), K(() => {
2798
+ var G;
2799
+ Q.current && !C && ((G = I.current) == null || G.focus()), Q.current = C;
2800
+ }, [C]);
2801
+ const j = M(() => {
2802
+ W(!0), Ln();
2803
+ }, []), P = M(() => {
2804
+ T(!1), U.current && (U.current = !1, j());
2805
+ }, [j]), Y = M(() => {
2806
+ T((G) => !G);
2807
+ }, []), q = M(() => {
2808
+ U.current = !0, B(null), T(!0);
2809
+ }, []), se = M((G) => {
2810
+ B(G);
2811
+ }, []), he = M(() => {
2812
+ B(null), q();
2813
+ }, [q]), h = M(() => {
2814
+ B(null), j();
2815
+ }, [j]);
2816
+ wt({
2817
+ triggers: g,
2818
+ enabled: !y && !C,
2819
+ onOpen: q,
2820
+ onGreeting: se
1891
2821
  });
1892
- const G = h === "dark" || h === "auto" && S, q = {
1893
- ...A,
1894
- ...u ? {
1895
- "--cl-color-accent": u,
1896
- "--cl-color-accent-dark": u
2822
+ const S = $ === "dark" || $ === "auto" && Z, F = {
2823
+ ...ne,
2824
+ ...l ? {
2825
+ "--cl-color-accent": l,
2826
+ "--cl-color-accent-dark": l
1897
2827
  } : {}
1898
- }, ae = Object.keys(q).length > 0 ? q : void 0;
2828
+ }, ce = Object.keys(F).length > 0 ? F : void 0;
1899
2829
  return (
1900
2830
  // Outer div carries theme token vars; the inner div carries the dark-mode
1901
2831
  // attribute so the [data-claudius-dark] token reassignments in styles.css
1902
2832
  // beat inherited (inline) light values.
1903
- /* @__PURE__ */ a("div", { className: "claudius-root", style: ae, children: /* @__PURE__ */ g("div", { "data-claudius-dark": G ? "true" : "false", children: [
1904
- v && W && /* @__PURE__ */ a(
2833
+ /* @__PURE__ */ i("div", { className: "claudius-root", style: ce, children: /* @__PURE__ */ p("div", { "data-claudius-dark": S ? "true" : "false", children: [
2834
+ C && H && /* @__PURE__ */ i(
1905
2835
  "div",
1906
2836
  {
1907
2837
  className: "claudius-scrim fixed inset-0 z-40 bg-claudius-scrim",
1908
- onClick: b,
2838
+ onClick: P,
1909
2839
  "aria-hidden": "true"
1910
2840
  }
1911
2841
  ),
1912
- v && /* @__PURE__ */ a(
1913
- Rt,
2842
+ C && /* @__PURE__ */ i(
2843
+ fn,
1914
2844
  {
1915
- messages: K,
1916
- isLoading: B,
1917
- isStreaming: _,
1918
- streamingMessageId: m,
1919
- error: V,
2845
+ messages: J,
2846
+ isLoading: re,
2847
+ isStreaming: X,
2848
+ streamingMessageId: te,
2849
+ error: w,
1920
2850
  canRetry: ee,
1921
- onSend: J,
1922
- onStop: oe,
1923
- onRetry: ie,
1924
- onClose: b,
1925
- title: t ?? y.title,
1926
- subtitle: r ?? y.subtitle,
1927
- welcomeMessage: n ?? y.welcomeMessage,
1928
- placeholder: s ?? y.placeholder,
1929
- position: d,
1930
- translations: y,
1931
- isMobile: W
2851
+ onSend: ie,
2852
+ onStop: x,
2853
+ onRetry: z,
2854
+ onClose: P,
2855
+ title: t ?? _.title,
2856
+ subtitle: n ?? _.subtitle,
2857
+ welcomeMessage: r ?? _.welcomeMessage,
2858
+ placeholder: s ?? _.placeholder,
2859
+ position: m,
2860
+ translations: _,
2861
+ isMobile: H,
2862
+ attachments: b,
2863
+ voice: k
1932
2864
  }
1933
2865
  ),
1934
- !(v && W) && /* @__PURE__ */ a(
1935
- Ve,
2866
+ !(C && H) && /* @__PURE__ */ i(
2867
+ Et,
1936
2868
  {
1937
- ref: te,
1938
- isOpen: v,
1939
- onClick: C,
1940
- position: d,
1941
- translations: y
2869
+ ref: I,
2870
+ isOpen: C,
2871
+ onClick: Y,
2872
+ position: m,
2873
+ translations: _
1942
2874
  }
1943
2875
  ),
1944
- !v && H && /* @__PURE__ */ a(
1945
- Et,
2876
+ !C && A && /* @__PURE__ */ i(
2877
+ mn,
1946
2878
  {
1947
- message: H,
1948
- position: d,
1949
- onOpen: U,
1950
- onDismiss: Z,
1951
- dismissLabel: y.dismissGreeting
2879
+ message: A,
2880
+ position: m,
2881
+ onOpen: he,
2882
+ onDismiss: h,
2883
+ dismissLabel: _.dismissGreeting
1952
2884
  }
1953
2885
  )
1954
2886
  ] }) })
1955
2887
  );
1956
2888
  }
1957
- function Xt(e) {
1958
- const { onEvent: t, includeContent: r = !0 } = e, n = (s) => r ? s : "";
2889
+ function zn(e) {
2890
+ const { onEvent: t, includeContent: n = !0 } = e, r = (s) => n ? s : "";
1959
2891
  return {
1960
2892
  name: "analytics",
1961
2893
  onBeforeSend(s) {
1962
2894
  t({
1963
2895
  type: "message_sent",
1964
2896
  role: "user",
1965
- content: n(s.content),
2897
+ content: r(s.content),
1966
2898
  chars: s.content.length
1967
2899
  });
1968
2900
  },
@@ -1970,7 +2902,7 @@ function Xt(e) {
1970
2902
  t({
1971
2903
  type: "message_received",
1972
2904
  role: "assistant",
1973
- content: n(s.content),
2905
+ content: r(s.content),
1974
2906
  chars: s.content.length
1975
2907
  });
1976
2908
  },
@@ -1983,7 +2915,7 @@ function Xt(e) {
1983
2915
  }
1984
2916
  };
1985
2917
  }
1986
- const Wt = [
2918
+ const Dn = [
1987
2919
  // Email
1988
2920
  /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
1989
2921
  // US SSN (before the looser card pattern so it wins on 9-digit groups)
@@ -1993,39 +2925,39 @@ const Wt = [
1993
2925
  // Phone: optional +1, area code, 7 digits with common separators
1994
2926
  /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
1995
2927
  ];
1996
- function zt(e, t, r) {
2928
+ function In(e, t, n) {
1997
2929
  return t.reduce(
1998
2930
  // Reset lastIndex defensively: a shared global regex is stateful.
1999
- (n, s) => (s.lastIndex = 0, n.replace(s, r)),
2931
+ (r, s) => (s.lastIndex = 0, r.replace(s, n)),
2000
2932
  e
2001
2933
  );
2002
2934
  }
2003
- function Zt(e = {}) {
2935
+ function Un(e = {}) {
2004
2936
  const {
2005
- patterns: t = Wt,
2006
- replacement: r = "[redacted]",
2007
- redactReplies: n = !1
2937
+ patterns: t = Dn,
2938
+ replacement: n = "[redacted]",
2939
+ redactReplies: r = !1
2008
2940
  } = e, s = (o) => {
2009
- const i = zt(o.content, t, r);
2010
- if (i !== o.content)
2011
- return { ...o, content: i };
2941
+ const a = In(o.content, t, n);
2942
+ if (a !== o.content)
2943
+ return { ...o, content: a };
2012
2944
  };
2013
2945
  return {
2014
2946
  name: "redact-pii",
2015
2947
  onBeforeSend: s,
2016
- onAfterReceive: n ? s : void 0
2948
+ onAfterReceive: r ? s : void 0
2017
2949
  };
2018
2950
  }
2019
- function Ft(e, t, r) {
2020
- return typeof e == "function" ? e(t) : e instanceof RegExp ? e.test(t) : r ? t.includes(e) : t.toLowerCase().includes(e.toLowerCase());
2951
+ function On(e, t, n) {
2952
+ return typeof e == "function" ? e(t) : e instanceof RegExp ? e.test(t) : n ? t.includes(e) : t.toLowerCase().includes(e.toLowerCase());
2021
2953
  }
2022
- function Qt(e) {
2023
- const { rules: t, caseSensitive: r = !1 } = e;
2954
+ function $n(e) {
2955
+ const { rules: t, caseSensitive: n = !1 } = e;
2024
2956
  return {
2025
2957
  name: "canned-responses",
2026
- onBeforeSend(n, s) {
2958
+ onBeforeSend(r, s) {
2027
2959
  for (const o of t)
2028
- if (Ft(o.match, n.content, r)) {
2960
+ if (On(o.match, r.content, n)) {
2029
2961
  s.respondWith(o.reply);
2030
2962
  return;
2031
2963
  }
@@ -2033,19 +2965,20 @@ function Qt(e) {
2033
2965
  };
2034
2966
  }
2035
2967
  export {
2036
- Oe as ChatApiClient,
2037
- j as ChatApiError,
2038
- Jt as ChatWidget,
2039
- Wt as DEFAULT_PII_PATTERNS,
2040
- le as DebounceError,
2041
- Te as builtinThemes,
2042
- qt as createTranslations,
2043
- Tt as defaultTranslations,
2044
- Nt as detectLocale,
2045
- Ee as locales,
2046
- Xt as pluginAnalytics,
2047
- Qt as pluginCannedResponses,
2048
- Zt as pluginRedactPII,
2049
- zt as redactText,
2050
- kt as resolveTranslations
2968
+ Xe as ChatApiClient,
2969
+ V as ChatApiError,
2970
+ _n as ChatWidget,
2971
+ fe as DEFAULT_ATTACHMENT_OPTIONS,
2972
+ Dn as DEFAULT_PII_PATTERNS,
2973
+ ye as DebounceError,
2974
+ We as builtinThemes,
2975
+ Hn as createTranslations,
2976
+ Ue as defaultTranslations,
2977
+ Fe as detectLocale,
2978
+ $e as locales,
2979
+ zn as pluginAnalytics,
2980
+ $n as pluginCannedResponses,
2981
+ Un as pluginRedactPII,
2982
+ In as redactText,
2983
+ yn as resolveTranslations
2051
2984
  };