@copilotz/chat-adapter 0.1.15 → 0.1.17

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/index.d.ts CHANGED
@@ -107,6 +107,7 @@ type RunErrorInterceptor = (error: unknown) => SpecialChatState | null | undefin
107
107
 
108
108
  interface CopilotzChatProps {
109
109
  userId: string;
110
+ authToken?: string | null;
110
111
  userName?: string;
111
112
  userAvatar?: string;
112
113
  userEmail?: string;
@@ -186,6 +187,7 @@ declare const CopilotzChat: React.FC<CopilotzChatProps>;
186
187
 
187
188
  interface UseCopilotzOptions {
188
189
  userId: string | null;
190
+ authToken?: string | null;
189
191
  initialContext?: ChatUserContext;
190
192
  bootstrap?: {
191
193
  initialMessage?: string;
@@ -217,7 +219,7 @@ interface UseCopilotzOptions {
217
219
  */
218
220
  urlSync?: UrlSyncConfig;
219
221
  }
220
- declare function useCopilotz({ userId, initialContext, bootstrap, defaultThreadName, onToolOutput, preferredAgentName, eventInterceptor, runErrorInterceptor, urlSync, }: UseCopilotzOptions): {
222
+ declare function useCopilotz({ userId, authToken, initialContext, bootstrap, defaultThreadName, onToolOutput, preferredAgentName, eventInterceptor, runErrorInterceptor, urlSync, }: UseCopilotzOptions): {
221
223
  messages: ChatMessage[];
222
224
  isMessagesLoading: boolean;
223
225
  threads: ChatThread[];
@@ -276,6 +278,7 @@ type StreamCallbacks = {
276
278
  signal?: AbortSignal;
277
279
  };
278
280
  type RunOptions = {
281
+ authToken?: string | null;
279
282
  threadId?: string;
280
283
  threadExternalId?: string;
281
284
  content: string;
@@ -311,11 +314,11 @@ declare class CopilotzRequestError extends Error {
311
314
  });
312
315
  }
313
316
  declare function runCopilotzStream(options: RunOptions): Promise<CopilotzStreamResult>;
314
- declare function fetchThreads(userId: string): Promise<RestThread[]>;
315
- declare function fetchThreadMessages(threadId: string): Promise<RestMessage[]>;
316
- declare function updateThread(threadId: string, updates: Partial<RestThread>): Promise<any>;
317
- declare function deleteMessagesByThreadId(threadId: string): Promise<void>;
318
- declare function deleteThread(threadId: string): Promise<boolean>;
317
+ declare function fetchThreads(userId: string, authToken?: string | null): Promise<RestThread[]>;
318
+ declare function fetchThreadMessages(threadId: string, authToken?: string | null): Promise<RestMessage[]>;
319
+ declare function updateThread(threadId: string, updates: Partial<RestThread>, authToken?: string | null): Promise<any>;
320
+ declare function deleteMessagesByThreadId(threadId: string, authToken?: string | null): Promise<void>;
321
+ declare function deleteThread(threadId: string, authToken?: string | null): Promise<boolean>;
319
322
  declare const copilotzService: {
320
323
  runCopilotzStream: typeof runCopilotzStream;
321
324
  fetchThreads: typeof fetchThreads;
package/dist/index.js CHANGED
@@ -118,9 +118,10 @@ var API_KEY = (() => {
118
118
  ];
119
119
  return candidates.find((value) => typeof value === "string" && value.length > 0);
120
120
  })();
121
- var withAuthHeaders = (headers = {}) => {
122
- if (API_KEY) {
123
- return { ...headers, Authorization: `Bearer ${API_KEY}` };
121
+ var withAuthHeaders = (headers = {}, authToken) => {
122
+ const token = authToken || API_KEY;
123
+ if (token) {
124
+ return { ...headers, Authorization: `Bearer ${token}` };
124
125
  }
125
126
  return headers;
126
127
  };
@@ -271,6 +272,7 @@ var convertAudioDataUrlToWavBase64 = async (dataUrl) => {
271
272
  };
272
273
  async function runCopilotzStream(options) {
273
274
  const {
275
+ authToken,
274
276
  threadId,
275
277
  threadExternalId,
276
278
  content,
@@ -377,9 +379,9 @@ async function runCopilotzStream(options) {
377
379
  };
378
380
  const response = await fetch(apiUrl("/v1/providers/web"), {
379
381
  method: "POST",
380
- headers: {
382
+ headers: withAuthHeaders({
381
383
  "Content-Type": "application/json"
382
- },
384
+ }, authToken),
383
385
  body: JSON.stringify(payload),
384
386
  signal: controller.signal
385
387
  });
@@ -489,12 +491,12 @@ async function runCopilotzStream(options) {
489
491
  media: collectedMedia
490
492
  };
491
493
  }
492
- async function fetchThreads(userId) {
494
+ async function fetchThreads(userId, authToken) {
493
495
  const params = new URLSearchParams();
494
496
  params.set("filters", JSON.stringify({ "metadata.userExternalId": userId }));
495
497
  params.set("sort", "-updatedAt");
496
498
  const res = await fetch(apiUrl(`/v1/rest/threads?${params.toString()}`), {
497
- headers: withAuthHeaders({ Accept: "application/json" })
499
+ headers: withAuthHeaders({ Accept: "application/json" }, authToken)
498
500
  });
499
501
  if (!res.ok) {
500
502
  const errorText = await res.text().catch(() => res.statusText);
@@ -506,13 +508,13 @@ async function fetchThreads(userId) {
506
508
  }
507
509
  return data;
508
510
  }
509
- async function fetchThreadMessages(threadId) {
511
+ async function fetchThreadMessages(threadId, authToken) {
510
512
  const graphParams = new URLSearchParams();
511
513
  graphParams.set("threadId", threadId);
512
514
  graphParams.set("limit", "500");
513
515
  try {
514
516
  const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {
515
- headers: withAuthHeaders({ Accept: "application/json" })
517
+ headers: withAuthHeaders({ Accept: "application/json" }, authToken)
516
518
  });
517
519
  if (graphRes.ok) {
518
520
  const graphData = await graphRes.json();
@@ -538,7 +540,7 @@ async function fetchThreadMessages(threadId) {
538
540
  params.set("filters", JSON.stringify({ threadId }));
539
541
  params.set("sort", "createdAt:asc");
540
542
  const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {
541
- headers: withAuthHeaders({ Accept: "application/json" })
543
+ headers: withAuthHeaders({ Accept: "application/json" }, authToken)
542
544
  });
543
545
  if (!res.ok) {
544
546
  const errorText = await res.text().catch(() => res.statusText);
@@ -550,10 +552,10 @@ async function fetchThreadMessages(threadId) {
550
552
  }
551
553
  return data;
552
554
  }
553
- async function updateThread(threadId, updates) {
555
+ async function updateThread(threadId, updates, authToken) {
554
556
  const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {
555
557
  method: "PUT",
556
- headers: withAuthHeaders({ "Content-Type": "application/json", Accept: "application/json" }),
558
+ headers: withAuthHeaders({ "Content-Type": "application/json", Accept: "application/json" }, authToken),
557
559
  body: JSON.stringify(updates)
558
560
  });
559
561
  if (!res.ok) {
@@ -563,13 +565,13 @@ async function updateThread(threadId, updates) {
563
565
  const data = await res.json();
564
566
  return data?.body ?? data;
565
567
  }
566
- async function deleteMessagesByThreadId(threadId) {
568
+ async function deleteMessagesByThreadId(threadId, authToken) {
567
569
  const graphParams = new URLSearchParams();
568
570
  graphParams.set("threadId", threadId);
569
571
  try {
570
572
  const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {
571
573
  method: "DELETE",
572
- headers: withAuthHeaders({ Accept: "application/json" })
574
+ headers: withAuthHeaders({ Accept: "application/json" }, authToken)
573
575
  });
574
576
  if (!graphRes.ok && ![404, 405, 501].includes(graphRes.status)) {
575
577
  const errorText = await graphRes.text().catch(() => graphRes.statusText);
@@ -584,7 +586,7 @@ async function deleteMessagesByThreadId(threadId) {
584
586
  const params = new URLSearchParams();
585
587
  params.set("filters", JSON.stringify({ threadId }));
586
588
  const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {
587
- headers: withAuthHeaders({ Accept: "application/json" })
589
+ headers: withAuthHeaders({ Accept: "application/json" }, authToken)
588
590
  });
589
591
  if (!res.ok) {
590
592
  console.warn("Could not fetch messages for deletion:", res.status);
@@ -599,18 +601,18 @@ async function deleteMessagesByThreadId(threadId) {
599
601
  try {
600
602
  await fetch(apiUrl(`/v1/rest/messages/${msg.id}`), {
601
603
  method: "DELETE",
602
- headers: withAuthHeaders({ Accept: "application/json" })
604
+ headers: withAuthHeaders({ Accept: "application/json" }, authToken)
603
605
  });
604
606
  } catch {
605
607
  }
606
608
  }
607
609
  }
608
610
  }
609
- async function deleteThread(threadId) {
610
- await deleteMessagesByThreadId(threadId);
611
+ async function deleteThread(threadId, authToken) {
612
+ await deleteMessagesByThreadId(threadId, authToken);
611
613
  const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {
612
614
  method: "DELETE",
613
- headers: withAuthHeaders({ Accept: "application/json" })
615
+ headers: withAuthHeaders({ Accept: "application/json" }, authToken)
614
616
  });
615
617
  if (!res.ok) {
616
618
  const errorText = await res.text().catch(() => res.statusText);
@@ -958,6 +960,7 @@ var convertServerMessage = (msg) => {
958
960
  };
959
961
  function useCopilotz({
960
962
  userId,
963
+ authToken,
961
964
  initialContext,
962
965
  bootstrap,
963
966
  defaultThreadName,
@@ -1024,7 +1027,7 @@ function useCopilotz({
1024
1027
  if (!eventInterceptor) return void 0;
1025
1028
  try {
1026
1029
  const result = eventInterceptor(event);
1027
- if (result?.specialState) {
1030
+ if (result && typeof result === "object" && result.specialState) {
1028
1031
  setSpecialState(result.specialState);
1029
1032
  }
1030
1033
  return result;
@@ -1100,10 +1103,6 @@ function useCopilotz({
1100
1103
  if (!trimmedContent) {
1101
1104
  return prev;
1102
1105
  }
1103
- const last = next[next.length - 1];
1104
- if (last?.role === "assistant" && last.content === payload.content) {
1105
- return prev;
1106
- }
1107
1106
  return [
1108
1107
  ...next,
1109
1108
  {
@@ -1163,20 +1162,20 @@ function useCopilotz({
1163
1162
  }, []);
1164
1163
  const fetchAndSetThreadsState = useCallback2(async (uid, preferredExternalId) => {
1165
1164
  try {
1166
- const rawThreads = await fetchThreads(uid);
1165
+ const rawThreads = await fetchThreads(uid, authToken);
1167
1166
  return updateThreadsState(rawThreads, preferredExternalId);
1168
1167
  } catch (error) {
1169
1168
  if (isAbortError(error)) return;
1170
1169
  console.error("Error loading threads", error);
1171
1170
  return null;
1172
1171
  }
1173
- }, [updateThreadsState]);
1172
+ }, [authToken, updateThreadsState]);
1174
1173
  const loadThreadMessages = useCallback2(async (threadId) => {
1175
1174
  const requestId = messagesRequestRef.current + 1;
1176
1175
  messagesRequestRef.current = requestId;
1177
1176
  setIsMessagesLoading(true);
1178
1177
  try {
1179
- const rawMessages = await fetchThreadMessages(threadId);
1178
+ const rawMessages = await fetchThreadMessages(threadId, authToken);
1180
1179
  const resolvedMessages = await resolveAssetsInMessages(rawMessages);
1181
1180
  if (messagesRequestRef.current !== requestId) return;
1182
1181
  resolvedMessages.forEach((msg) => {
@@ -1208,7 +1207,7 @@ function useCopilotz({
1208
1207
  setIsMessagesLoading(false);
1209
1208
  }
1210
1209
  }
1211
- }, [processToolOutput]);
1210
+ }, [authToken, processToolOutput]);
1212
1211
  const handleSelectThread = useCallback2(async (threadId) => {
1213
1212
  setCurrentThreadId(threadId);
1214
1213
  setMessages([]);
@@ -1251,7 +1250,7 @@ function useCopilotz({
1251
1250
  }));
1252
1251
  } else {
1253
1252
  try {
1254
- await updateThread(threadId, { name: trimmedTitle });
1253
+ await updateThread(threadId, { name: trimmedTitle }, authToken);
1255
1254
  } catch (error) {
1256
1255
  console.error("Failed to rename thread:", error);
1257
1256
  if (userId) {
@@ -1259,7 +1258,7 @@ function useCopilotz({
1259
1258
  }
1260
1259
  }
1261
1260
  }
1262
- }, [userId, fetchAndSetThreadsState]);
1261
+ }, [authToken, userId, fetchAndSetThreadsState]);
1263
1262
  const handleArchiveThread = useCallback2(async (threadId) => {
1264
1263
  const thread = threadsRef.current.find((t) => t.id === threadId);
1265
1264
  if (!thread) return;
@@ -1271,7 +1270,7 @@ function useCopilotz({
1271
1270
  const isPlaceholder = extMap[threadId] === threadId;
1272
1271
  if (!isPlaceholder) {
1273
1272
  try {
1274
- await updateThread(threadId, { status: newArchivedStatus ? "archived" : "active" });
1273
+ await updateThread(threadId, { status: newArchivedStatus ? "archived" : "active" }, authToken);
1275
1274
  } catch (error) {
1276
1275
  console.error("Failed to archive thread:", error);
1277
1276
  if (userId) {
@@ -1279,7 +1278,7 @@ function useCopilotz({
1279
1278
  }
1280
1279
  }
1281
1280
  }
1282
- }, [userId, fetchAndSetThreadsState]);
1281
+ }, [authToken, userId, fetchAndSetThreadsState]);
1283
1282
  const handleDeleteThread = useCallback2(async (threadId) => {
1284
1283
  const extMap = threadExternalIdMapRef.current;
1285
1284
  const isPlaceholder = extMap[threadId] === threadId;
@@ -1308,7 +1307,7 @@ function useCopilotz({
1308
1307
  }
1309
1308
  if (!isPlaceholder) {
1310
1309
  try {
1311
- await deleteThread(threadId);
1310
+ await deleteThread(threadId, authToken);
1312
1311
  } catch (error) {
1313
1312
  console.error("Failed to delete thread:", error);
1314
1313
  if (userId) {
@@ -1316,7 +1315,7 @@ function useCopilotz({
1316
1315
  }
1317
1316
  }
1318
1317
  }
1319
- }, [userId, fetchAndSetThreadsState, loadThreadMessages]);
1318
+ }, [authToken, userId, fetchAndSetThreadsState, loadThreadMessages]);
1320
1319
  const handleStop = useCallback2(() => {
1321
1320
  abortControllerRef.current?.abort();
1322
1321
  abortControllerRef.current = null;
@@ -1362,7 +1361,7 @@ function useCopilotz({
1362
1361
  const nextComplete = false;
1363
1362
  setMessages((prev) => {
1364
1363
  const idx = prev.findIndex((m) => m.id === currentAssistantId);
1365
- if (idx >= 0 && prev[idx].role === "assistant") {
1364
+ if (idx >= 0 && prev[idx].role === "assistant" && prev[idx].isStreaming) {
1366
1365
  const msg = prev[idx];
1367
1366
  if (msg.content === partial && msg.isStreaming === nextStreaming && msg.isComplete === nextComplete) {
1368
1367
  return prev;
@@ -1519,6 +1518,7 @@ function useCopilotz({
1519
1518
  };
1520
1519
  const finalMetadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : void 0;
1521
1520
  await runCopilotzStream({
1521
+ authToken,
1522
1522
  threadId: params.threadId ?? void 0,
1523
1523
  threadExternalId: params.threadExternalId ?? void 0,
1524
1524
  content: requestContent,
@@ -1538,7 +1538,7 @@ function useCopilotz({
1538
1538
  onToken: (token) => updateStreamingMessage(token),
1539
1539
  onMessageEvent: async (event) => {
1540
1540
  const intercepted = applyEventInterceptor(event);
1541
- if (intercepted?.handled) {
1541
+ if (intercepted && typeof intercepted === "object" && intercepted.handled) {
1542
1542
  return;
1543
1543
  }
1544
1544
  const type = event?.type || "";
@@ -1594,6 +1594,10 @@ function useCopilotz({
1594
1594
  return;
1595
1595
  }
1596
1596
  handleStreamMessageEvent(event);
1597
+ if (senderType === "agent") {
1598
+ currentAssistantId = generateId();
1599
+ pendingStartNewAssistantBubble = true;
1600
+ }
1597
1601
  return;
1598
1602
  }
1599
1603
  if (type === "TOOL_CALL") {
@@ -1617,21 +1621,34 @@ function useCopilotz({
1617
1621
  }
1618
1622
  ]
1619
1623
  });
1620
- for (let i = prev.length - 1; i >= 0; i--) {
1621
- if (prev[i].role === "assistant") {
1622
- const next = [...prev];
1623
- next[i] = appendToolCall({
1624
- ...next[i],
1625
- isStreaming: true,
1626
- isComplete: false
1627
- });
1628
- return next;
1629
- }
1624
+ const currentIdx = prev.findIndex((message) => message.id === currentAssistantId && message.role === "assistant" && message.isStreaming);
1625
+ if (currentIdx >= 0) {
1626
+ const next = [...prev];
1627
+ next[currentIdx] = appendToolCall({
1628
+ ...next[currentIdx],
1629
+ isStreaming: true,
1630
+ isComplete: false
1631
+ });
1632
+ return next;
1633
+ }
1634
+ const last = prev[prev.length - 1];
1635
+ if (!pendingStartNewAssistantBubble && last?.role === "assistant" && last.isStreaming) {
1636
+ currentAssistantId = last.id;
1637
+ const next = [...prev];
1638
+ next[prev.length - 1] = appendToolCall({
1639
+ ...last,
1640
+ isStreaming: true,
1641
+ isComplete: false
1642
+ });
1643
+ return next;
1630
1644
  }
1645
+ const newId = generateId();
1646
+ currentAssistantId = newId;
1647
+ pendingStartNewAssistantBubble = false;
1631
1648
  return [
1632
1649
  ...prev,
1633
1650
  appendToolCall({
1634
- id: generateId(),
1651
+ id: newId,
1635
1652
  role: "assistant",
1636
1653
  content: "",
1637
1654
  timestamp: nowTs(),
@@ -1657,7 +1674,7 @@ function useCopilotz({
1657
1674
  },
1658
1675
  onAssetEvent: async (payload) => {
1659
1676
  const intercepted = applyEventInterceptor({ type: "ASSET_CREATED", payload });
1660
- if (intercepted?.handled) {
1677
+ if (intercepted && typeof intercepted === "object" && intercepted.handled) {
1661
1678
  return;
1662
1679
  }
1663
1680
  await (async () => {
@@ -1684,7 +1701,7 @@ function useCopilotz({
1684
1701
  abortControllerRef.current = null;
1685
1702
  }
1686
1703
  return currentAssistantId;
1687
- }, [applyEventInterceptor, handleStreamMessageEvent, handleStreamAssetEvent]);
1704
+ }, [authToken, applyEventInterceptor, handleStreamMessageEvent, handleStreamAssetEvent]);
1688
1705
  const handleSendMessage = useCallback2(async (content, attachments = []) => {
1689
1706
  if (!content.trim() && attachments.length === 0) return;
1690
1707
  if (!userId) return;
@@ -1768,7 +1785,7 @@ function useCopilotz({
1768
1785
  content: "Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente."
1769
1786
  } : msg));
1770
1787
  }
1771
- }, [userId, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, getSpecialStateFromError]);
1788
+ }, [userId, authToken, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, getSpecialStateFromError]);
1772
1789
  const bootstrapConversation = useCallback2(async (uid) => {
1773
1790
  if (!bootstrap?.initialToolCalls && !bootstrap?.initialMessage) return;
1774
1791
  const bootstrapThreadExternalId = generateId();
@@ -1811,7 +1828,7 @@ function useCopilotz({
1811
1828
  }
1812
1829
  ]);
1813
1830
  }
1814
- }, [fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName, getSpecialStateFromError]);
1831
+ }, [authToken, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName, getSpecialStateFromError]);
1815
1832
  const reset = useCallback2(() => {
1816
1833
  messagesRequestRef.current += 1;
1817
1834
  setThreads([]);
@@ -1846,7 +1863,7 @@ function useCopilotz({
1846
1863
  initializationRef.current = { userId: null, started: false };
1847
1864
  reset();
1848
1865
  }
1849
- }, [userId, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);
1866
+ }, [userId, authToken, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);
1850
1867
  useEffect2(() => {
1851
1868
  if (!isUrlSyncEnabled) return;
1852
1869
  if (!initializationRef.current.started) return;
@@ -1895,6 +1912,7 @@ function useCopilotz({
1895
1912
  import { jsx } from "react/jsx-runtime";
1896
1913
  var CopilotzChat = ({
1897
1914
  userId,
1915
+ authToken,
1898
1916
  userName,
1899
1917
  userAvatar,
1900
1918
  userEmail,
@@ -1942,6 +1960,7 @@ var CopilotzChat = ({
1942
1960
  setUrlAgentId
1943
1961
  } = useCopilotz({
1944
1962
  userId,
1963
+ authToken,
1945
1964
  initialContext,
1946
1965
  bootstrap,
1947
1966
  defaultThreadName: userConfig?.labels?.defaultThreadName,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/CopilotzChat.tsx","../../node_modules/shared/src/utils.ts","../../node_modules/lucide-react/src/defaultAttributes.ts","../../node_modules/lucide-react/src/Icon.ts","../../node_modules/lucide-react/src/createLucideIcon.ts","../../node_modules/lucide-react/src/icons/user.ts","../src/useCopilotzChat.ts","../src/copilotzService.ts","../src/assetsService.ts","../src/useUrlState.ts"],"sourcesContent":["import React, { useMemo, useEffect, useState } from 'react';\nimport { ChatUI, ChatUserContextProvider } from '@copilotz/chat-ui';\nimport type { AgentOption, ChatConfig, ChatCallbacks, ChatUserContext, MemoryItem } from '@copilotz/chat-ui';\nimport { User } from 'lucide-react';\nimport { useCopilotz } from './useCopilotzChat';\nimport type { UrlSyncConfig } from './useUrlState';\nimport type { EventInterceptor, RenderSpecialState, RunErrorInterceptor } from './specialState';\n\nexport interface CopilotzChatProps {\n userId: string;\n userName?: string;\n userAvatar?: string;\n userEmail?: string;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n config?: ChatConfig;\n callbacks?: Partial<ChatCallbacks>;\n /**\n * Custom component to render in the right sidebar panel (e.g. Profile info).\n * Can be:\n * - A React node (static)\n * - A function receiving context: `(context) => ReactNode`\n * - A render function receiving panel props: `(props: { onClose, isMobile }) => ReactNode`\n * Toggle visibility via the header button.\n */\n customComponent?: \n | React.ReactNode \n | ((context: ChatUserContext) => React.ReactNode)\n | ((props: { onClose: () => void; isMobile: boolean }) => React.ReactNode);\n onToolOutput?: (output: Record<string, unknown>) => void;\n /** Called when user clicks logout in the user menu */\n onLogout?: () => void;\n /** Called when user clicks \"View Profile\" in the user menu */\n onViewProfile?: () => void;\n /** Called when user adds a memory */\n onAddMemory?: (content: string, category?: MemoryItem['category']) => void;\n /** Called when user updates a memory */\n onUpdateMemory?: (memoryId: string, content: string) => void;\n /** Called when user deletes a memory */\n onDeleteMemory?: (memoryId: string) => void;\n /** Empty-state suggestions */\n suggestions?: string[];\n /** Agent selector data (built-in ChatUI) */\n agentOptions?: AgentOption[];\n selectedAgentId?: string | null;\n onSelectAgent?: (agentId: string) => void;\n className?: string;\n eventInterceptor?: EventInterceptor;\n runErrorInterceptor?: RunErrorInterceptor;\n renderSpecialState?: RenderSpecialState;\n /**\n * URL state synchronization configuration.\n * When enabled, syncs thread ID, agent, and prompt to/from URL parameters.\n * \n * Features:\n * - `?thread=abc123` - Opens specific thread\n * - `?agent=support-bot` - Pre-selects agent\n * - `?prompt=Hello` - Pre-fills or auto-sends message\n * \n * @example\n * ```tsx\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{ enabled: true }}\n * />\n * \n * // With custom param names\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{\n * enabled: true,\n * params: { thread: 't', agent: 'a', prompt: 'q' },\n * promptBehavior: 'auto-send'\n * }}\n * />\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport const CopilotzChat: React.FC<CopilotzChatProps> = ({\n userId,\n userName,\n userAvatar,\n userEmail,\n initialContext,\n bootstrap,\n config: userConfig,\n callbacks: userCallbacks,\n customComponent,\n onToolOutput,\n onLogout,\n onViewProfile,\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n suggestions,\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n className,\n eventInterceptor,\n runErrorInterceptor,\n renderSpecialState,\n urlSync,\n}) => {\n const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;\n\n const {\n messages,\n isMessagesLoading,\n threads,\n currentThreadId,\n isStreaming,\n specialState,\n clearSpecialState,\n userContextSeed,\n sendMessage,\n createThread,\n selectThread,\n renameThread,\n archiveThread,\n deleteThread,\n stopGeneration,\n initialPrompt,\n clearInitialPrompt,\n urlAgentId,\n setUrlAgentId,\n } = useCopilotz({ \n userId, \n initialContext, \n bootstrap, \n defaultThreadName: userConfig?.labels?.defaultThreadName,\n onToolOutput,\n preferredAgentName: selectedAgent?.name ?? null,\n eventInterceptor,\n runErrorInterceptor,\n urlSync,\n });\n\n // Track if we've handled the initial prompt\n const [promptHandled, setPromptHandled] = useState(false);\n\n // Handle URL agent ID - call onSelectAgent if URL has agent and it differs from current\n useEffect(() => {\n if (urlAgentId && onSelectAgent && urlAgentId !== selectedAgentId) {\n // Check if the agent exists in options\n const agentExists = agentOptions.some((a) => a.id === urlAgentId);\n if (agentExists) {\n onSelectAgent(urlAgentId);\n }\n }\n }, [urlAgentId, selectedAgentId, onSelectAgent, agentOptions]);\n\n // Sync selected agent to URL when it changes (after initial load)\n useEffect(() => {\n if (selectedAgentId && urlSync?.enabled) {\n setUrlAgentId(selectedAgentId);\n }\n }, [selectedAgentId, urlSync?.enabled, setUrlAgentId]);\n\n // Handle auto-send behavior for initial prompt\n useEffect(() => {\n if (initialPrompt && !promptHandled && urlSync?.promptBehavior === 'auto-send') {\n // Wait for initial load to complete\n const timer = setTimeout(() => {\n void sendMessage(initialPrompt);\n clearInitialPrompt();\n setPromptHandled(true);\n }, 500);\n return () => clearTimeout(timer);\n }\n }, [initialPrompt, promptHandled, urlSync?.promptBehavior, sendMessage, clearInitialPrompt]);\n\n // For prefill behavior, we'll pass initialInput to ChatUI\n\n const chatCallbacks: ChatCallbacks = useMemo(() => ({\n onSendMessage: (content, attachments) => {\n void sendMessage(content, attachments);\n userCallbacks?.onSendMessage?.(content, attachments);\n },\n onStopGeneration: () => {\n stopGeneration();\n userCallbacks?.onStopGeneration?.();\n },\n onCreateThread: (title) => {\n createThread(title);\n userCallbacks?.onCreateThread?.(title);\n },\n onSelectThread: (threadId) => {\n void selectThread(threadId);\n userCallbacks?.onSelectThread?.(threadId);\n },\n onRenameThread: (threadId, newTitle) => {\n void renameThread(threadId, newTitle);\n userCallbacks?.onRenameThread?.(threadId, newTitle);\n },\n onArchiveThread: (threadId) => {\n void archiveThread(threadId);\n userCallbacks?.onArchiveThread?.(threadId);\n },\n onDeleteThread: (threadId) => {\n void deleteThread(threadId);\n userCallbacks?.onDeleteThread?.(threadId);\n },\n onCopyMessage: async (messageId, content) => {\n try {\n await navigator.clipboard.writeText(content);\n userCallbacks?.onCopyMessage?.(messageId, content);\n } catch (error) {\n console.error('Failed to copy message', error);\n }\n },\n // User menu callbacks\n onLogout,\n onViewProfile,\n ...userCallbacks,\n }), [sendMessage, stopGeneration, createThread, selectThread, renameThread, archiveThread, deleteThread, userCallbacks, onLogout, onViewProfile]);\n\n // Merge user config with dynamic values\n // customComponent is passed through - it will be resolved in ChatUI\n // which can provide onClose and isMobile props\n const mergedConfig: ChatConfig = useMemo(() => {\n const base = userConfig || {};\n if (!customComponent) {\n return base;\n }\n return {\n ...base,\n customComponent: {\n ...base.customComponent,\n component: customComponent,\n icon: base.customComponent?.icon || <User className=\"h-6 w-6\" />,\n },\n };\n }, [userConfig, customComponent]);\n\n const effectiveUserName = userName || userId;\n // Don't try to extract avatar from profile automatically unless it's in context\n const effectiveUserAvatar = userAvatar;\n const specialStateContent = specialState ? renderSpecialState?.(specialState, { clear: clearSpecialState }) : null;\n\n return (\n <ChatUserContextProvider initial={userContextSeed}>\n {specialStateContent ?? (\n <ChatUI\n messages={messages}\n isMessagesLoading={isMessagesLoading}\n threads={threads}\n currentThreadId={currentThreadId}\n config={mergedConfig}\n callbacks={chatCallbacks}\n isGenerating={isStreaming}\n suggestions={suggestions}\n agentOptions={agentOptions}\n selectedAgentId={selectedAgentId}\n onSelectAgent={onSelectAgent}\n user={{\n id: userId,\n name: effectiveUserName,\n email: userEmail,\n avatar: effectiveUserAvatar,\n }}\n assistant={{\n name: userConfig?.branding?.title,\n avatar: userConfig?.branding?.avatar,\n description: userConfig?.branding?.subtitle,\n }}\n onAddMemory={onAddMemory}\n onUpdateMemory={onUpdateMemory}\n onDeleteMemory={onDeleteMemory}\n className={className}\n // Pass initial prompt for prefill behavior (not auto-send)\n initialInput={\n initialPrompt && !promptHandled && urlSync?.promptBehavior !== 'auto-send'\n ? initialPrompt\n : undefined\n }\n onInitialInputConsumed={() => {\n clearInitialPrompt();\n setPromptHandled(true);\n }}\n />\n )}\n </ChatUserContextProvider>\n );\n};\n","import { CamelToPascal } from './utility-types';\n\n/**\n * Converts string to kebab case\n *\n * @param {string} string\n * @returns {string} A kebabized string\n */\nexport const toKebabCase = (string: string) =>\n string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Converts string to camel case\n *\n * @param {string} string\n * @returns {string} A camelized string\n */\nexport const toCamelCase = <T extends string>(string: T) =>\n string.replace(/^([A-Z])|[\\s-_]+(\\w)/g, (match, p1, p2) =>\n p2 ? p2.toUpperCase() : p1.toLowerCase(),\n );\n\n/**\n * Converts string to pascal case\n *\n * @param {string} string\n * @returns {string} A pascalized string\n */\nexport const toPascalCase = <T extends string>(string: T): CamelToPascal<T> => {\n const camelCase = toCamelCase(string);\n\n return (camelCase.charAt(0).toUpperCase() + camelCase.slice(1)) as CamelToPascal<T>;\n};\n\n/**\n * Merges classes into a single string\n *\n * @param {array} classes\n * @returns {string} A string of classes\n */\nexport const mergeClasses = <ClassType = string | undefined | null>(...classes: ClassType[]) =>\n classes\n .filter((className, index, array) => {\n return (\n Boolean(className) &&\n (className as string).trim() !== '' &&\n array.indexOf(className) === index\n );\n })\n .join(' ')\n .trim();\n\n/**\n * Is empty string\n *\n * @param {unknown} value\n * @returns {boolean} Whether the value is an empty string\n */\nexport const isEmptyString = (value: unknown): boolean => value === '';\n\n/**\n * Check if a component has an accessibility prop\n *\n * @param {object} props\n * @returns {boolean} Whether the component has an accessibility prop\n */\nexport const hasA11yProp = (props: Record<string, any>) => {\n for (const prop in props) {\n if (prop.startsWith('aria-') || prop === 'role' || prop === 'title') {\n return true;\n }\n }\n};\n","export default {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n};\n","import { createElement, forwardRef } from 'react';\nimport defaultAttributes from './defaultAttributes';\nimport { IconNode, LucideProps } from './types';\nimport { mergeClasses, hasA11yProp } from '@lucide/shared';\n\ninterface IconComponentProps extends LucideProps {\n iconNode: IconNode;\n}\n\n/**\n * Lucide icon component\n *\n * @component Icon\n * @param {object} props\n * @param {string} props.color - The color of the icon\n * @param {number} props.size - The size of the icon\n * @param {number} props.strokeWidth - The stroke width of the icon\n * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width\n * @param {string} props.className - The class name of the icon\n * @param {IconNode} props.children - The children of the icon\n * @param {IconNode} props.iconNode - The icon node of the icon\n *\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst Icon = forwardRef<SVGSVGElement, IconComponentProps>(\n (\n {\n color = 'currentColor',\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = '',\n children,\n iconNode,\n ...rest\n },\n ref,\n ) =>\n createElement(\n 'svg',\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth,\n className: mergeClasses('lucide', className),\n ...(!children && !hasA11yProp(rest) && { 'aria-hidden': 'true' }),\n ...rest,\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...(Array.isArray(children) ? children : [children]),\n ],\n ),\n);\n\nexport default Icon;\n","import { createElement, forwardRef } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';\nimport { IconNode, LucideProps } from './types';\nimport Icon from './Icon';\n\n/**\n * Create a Lucide icon component\n * @param {string} iconName\n * @param {array} iconNode\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst createLucideIcon = (iconName: string, iconNode: IconNode) => {\n const Component = forwardRef<SVGSVGElement, LucideProps>(({ className, ...props }, ref) =>\n createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className,\n ),\n ...props,\n }),\n );\n\n Component.displayName = toPascalCase(iconName);\n\n return Component;\n};\n\nexport default createLucideIcon;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2', key: '975kel' }],\n ['circle', { cx: '12', cy: '7', r: '4', key: '17ys0d' }],\n];\n\n/**\n * @component @name User\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cGF0aCBkPSJNMTkgMjF2LTJhNCA0IDAgMCAwLTQtNEg5YTQgNCAwIDAgMC00IDR2MiIgLz4KICA8Y2lyY2xlIGN4PSIxMiIgY3k9IjciIHI9IjQiIC8+Cjwvc3ZnPgo=) - https://lucide.dev/icons/user\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst User = createLucideIcon('user', __iconNode);\n\nexport default User;\n","// deno-lint-ignore-file no-explicit-any\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { runCopilotzStream, fetchThreads, fetchThreadMessages, updateThread as updateThreadApi, deleteThread as deleteThreadApi } from './copilotzService';\nimport { resolveAssetsInMessages } from './assetsService';\nimport type { ChatMessage as ChatViewMessage, ChatThread, MediaAttachment, ChatUserContext } from '@copilotz/chat-ui';\nimport { useUrlState, type UrlSyncConfig } from './useUrlState';\nimport type { EventInterceptor, RunErrorInterceptor, SpecialChatState } from './specialState';\n\nconst nowTs = () => Date.now();\nconst generateId = () =>\n (globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`) as string;\nconst isAbortError = (error: unknown) => (\n error instanceof DOMException && error.name === 'AbortError'\n) || (typeof error === 'object' && error !== null && 'name' in error && (error as { name?: string }).name === 'AbortError');\nconst getEventPayload = (event: any) => event?.payload ?? event;\nconst getEventSenderType = (payload: any): string | undefined => payload?.senderType || payload?.sender?.type;\n\ntype ServerThread = Awaited<ReturnType<typeof fetchThreads>>[number];\ntype ServerMessage = Awaited<ReturnType<typeof fetchThreadMessages>>[number];\n\ntype ToolCallStatus = 'pending' | 'running' | 'completed' | 'failed';\ntype ParsedToolCall = {\n id?: string;\n name: string;\n arguments: Record<string, unknown>;\n status: ToolCallStatus;\n result?: unknown;\n};\n\ntype ToolResultUpdate = {\n id?: string;\n name?: string;\n status: ToolCallStatus;\n result?: unknown;\n endTime: number;\n};\n\nconst normalizeToolStatus = (status: unknown): ToolCallStatus => {\n if (status === 'pending') return 'pending';\n if (status === 'running' || status === 'processing') return 'running';\n if (status === 'failed') return 'failed';\n return 'completed';\n};\n\nconst parseToolArguments = (value: unknown): Record<string, unknown> => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value);\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // Ignore invalid JSON and fall through to empty args.\n }\n }\n return {};\n};\n\nconst extractToolCallsFromServerMessage = (msg: ServerMessage): ParsedToolCall[] => {\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const topLevelToolCalls = Array.isArray((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls)\n ? ((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls || [])\n : [];\n const metadataToolCalls = Array.isArray(metadata?.toolCalls)\n ? (metadata.toolCalls as Array<Record<string, unknown>>)\n : [];\n\n const usedMetadataIndexes = new Set<number>();\n const parsed: ParsedToolCall[] = [];\n\n const findMatchingMetadataIndex = (toolCall: Record<string, unknown>): number => {\n const id = typeof toolCall.id === 'string' ? toolCall.id : undefined;\n const name = typeof toolCall.name === 'string' ? toolCall.name : undefined;\n\n const byId = id\n ? metadataToolCalls.findIndex((candidate, idx) => !usedMetadataIndexes.has(idx) && candidate?.id === id)\n : -1;\n if (byId >= 0) return byId;\n\n return name\n ? metadataToolCalls.findIndex((candidate, idx) => !usedMetadataIndexes.has(idx) && candidate?.name === name)\n : -1;\n };\n\n const parseToolCall = (\n primary: Record<string, unknown>,\n secondary?: Record<string, unknown>,\n ): ParsedToolCall => {\n const id = typeof primary.id === 'string'\n ? primary.id\n : (typeof secondary?.id === 'string' ? secondary.id : undefined);\n const name = typeof primary.name === 'string'\n ? primary.name\n : (typeof secondary?.name === 'string' ? secondary.name : 'tool');\n const argsRaw =\n primary.args ?? primary.arguments ?? secondary?.args ?? secondary?.arguments;\n const result =\n primary.output !== undefined\n ? primary.output\n : primary.result !== undefined\n ? primary.result\n : secondary?.output !== undefined\n ? secondary.output\n : secondary?.result;\n const status = normalizeToolStatus(primary.status ?? secondary?.status);\n\n return {\n ...(id ? { id } : {}),\n name,\n arguments: parseToolArguments(argsRaw),\n ...(result !== undefined ? { result } : {}),\n status,\n };\n };\n\n topLevelToolCalls.forEach((toolCall) => {\n const metadataIndex = findMatchingMetadataIndex(toolCall);\n const metadataCall = metadataIndex >= 0 ? metadataToolCalls[metadataIndex] : undefined;\n if (metadataIndex >= 0) usedMetadataIndexes.add(metadataIndex);\n parsed.push(parseToolCall(toolCall, metadataCall));\n });\n\n metadataToolCalls.forEach((toolCall, index) => {\n if (usedMetadataIndexes.has(index)) return;\n parsed.push(parseToolCall(toolCall));\n });\n\n return parsed;\n};\n\nconst extractToolResultUpdateFromMessage = (msg: ServerMessage): ToolResultUpdate | null => {\n if (msg.senderType !== 'tool') return null;\n\n const toolCalls = extractToolCallsFromServerMessage(msg);\n if (!Array.isArray(toolCalls) || toolCalls.length === 0) return null;\n\n const firstToolCall = toolCalls[0];\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const fallbackResult = metadata?.output;\n const result = firstToolCall.result !== undefined ? firstToolCall.result : fallbackResult;\n\n return {\n ...(firstToolCall.id ? { id: firstToolCall.id } : {}),\n ...(firstToolCall.name ? { name: firstToolCall.name } : {}),\n ...(result !== undefined ? { result } : {}),\n status: firstToolCall.status,\n endTime: msg.createdAt ? new Date(msg.createdAt).getTime() : nowTs(),\n };\n};\n\nconst mergePersistedToolResults = (\n messages: ChatViewMessage[],\n updates: ToolResultUpdate[],\n): ChatViewMessage[] => {\n if (updates.length === 0) return messages;\n\n const nextMessages = [...messages];\n\n for (const update of updates) {\n for (let i = nextMessages.length - 1; i >= 0; i--) {\n const message = nextMessages[i];\n if (message.role !== 'assistant' || !Array.isArray(message.toolCalls) || message.toolCalls.length === 0) {\n continue;\n }\n\n const toolCalls = message.toolCalls;\n\n let toolCallIndex = update.id\n ? toolCalls.findIndex((toolCall) => toolCall.id === update.id)\n : -1;\n\n if (toolCallIndex === -1 && update.name) {\n toolCallIndex = toolCalls.findIndex((toolCall) => (\n toolCall.name === update.name &&\n (toolCall.status === 'pending' || toolCall.status === 'running' || typeof toolCall.result === 'undefined')\n ));\n }\n\n if (toolCallIndex === -1) continue;\n\n const updatedToolCalls = [...toolCalls];\n const current = updatedToolCalls[toolCallIndex];\n updatedToolCalls[toolCallIndex] = {\n ...current,\n status: update.status,\n ...(update.result !== undefined ? { result: update.result } : {}),\n endTime: update.endTime,\n };\n\n nextMessages[i] = {\n ...message,\n toolCalls: updatedToolCalls,\n };\n break;\n }\n }\n\n return nextMessages;\n};\n\nconst convertServerMessage = (msg: ServerMessage): ChatViewMessage => {\n const timestamp = msg.createdAt ? new Date(msg.createdAt).getTime() : nowTs();\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachmentsMeta = Array.isArray(metadata?.attachments)\n ? (metadata!.attachments as Array<Record<string, unknown>>)\n : [];\n\n const attachments: MediaAttachment[] = attachmentsMeta.flatMap((att) => {\n const kind = typeof att.kind === 'string' ? att.kind : undefined;\n const dataUrl = typeof att.dataUrl === 'string' ? att.dataUrl : undefined;\n const mimeType = typeof att.mimeType === 'string' ? att.mimeType : undefined;\n if (!dataUrl) return [];\n\n if (kind === 'image') {\n return [{ kind: 'image', dataUrl, mimeType: mimeType ?? 'image/jpeg' }] as MediaAttachment[];\n }\n if (kind === 'audio') {\n return [{\n kind: 'audio',\n dataUrl,\n mimeType: mimeType ?? 'audio/webm',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n }] as MediaAttachment[];\n }\n if (kind === 'video') {\n return [{\n kind: 'video',\n dataUrl,\n mimeType: mimeType ?? 'video/mp4',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n poster: typeof att.poster === 'string' ? att.poster : undefined,\n }] as MediaAttachment[];\n }\n return [] as MediaAttachment[];\n });\n\n const role = msg.senderType === 'agent'\n ? 'assistant'\n : msg.senderType === 'user'\n ? 'user'\n : 'assistant';\n\n const parsedToolCalls = extractToolCallsFromServerMessage(msg);\n const mappedToolCalls = parsedToolCalls.map((toolCall) => ({\n id: toolCall.id ?? generateId(),\n name: toolCall.name,\n arguments: toolCall.arguments,\n status: toolCall.status,\n ...(toolCall.result !== undefined ? { result: toolCall.result } : {}),\n }));\n\n const hasToolCalls = mappedToolCalls.length > 0;\n const isToolSender = msg.senderType === 'tool';\n const content =\n isToolSender\n ? '' // Do not render textual content for tool messages; attachments only\n : ((msg.content ?? '') || (hasToolCalls ? '' : ''));\n\n return {\n id: msg.id,\n role,\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isStreaming: false,\n isComplete: true,\n metadata,\n toolCalls: hasToolCalls ? mappedToolCalls : undefined,\n };\n};\n\nexport interface UseCopilotzOptions {\n userId: string | null;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n defaultThreadName?: string;\n onToolOutput?: (output: Record<string, unknown>) => void;\n preferredAgentName?: string | null;\n eventInterceptor?: EventInterceptor;\n runErrorInterceptor?: RunErrorInterceptor;\n /**\n * URL state synchronization configuration.\n * When enabled, thread ID and agent are synced to/from URL parameters.\n * \n * @example\n * ```tsx\n * const chat = useCopilotz({\n * userId: 'user123',\n * urlSync: {\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * }\n * });\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport function useCopilotz({\n userId,\n initialContext,\n bootstrap,\n defaultThreadName,\n onToolOutput,\n preferredAgentName,\n eventInterceptor,\n runErrorInterceptor,\n urlSync,\n}: UseCopilotzOptions) {\n // URL state management\n const {\n state: urlState,\n setThreadId: setUrlThreadId,\n setAgentId: setUrlAgentId,\n clearPrompt: clearUrlPrompt,\n isEnabled: isUrlSyncEnabled,\n } = useUrlState(urlSync);\n\n const [threads, setThreads] = useState<ChatThread[]>([]);\n const [threadMetadataMap, setThreadMetadataMap] = useState<Record<string, Record<string, unknown> | undefined>>({});\n const [threadExternalIdMap, setThreadExternalIdMap] = useState<Record<string, string | null>>({});\n\n const [currentThreadId, setCurrentThreadId] = useState<string | null>(null);\n const [currentThreadExternalId, setCurrentThreadExternalId] = useState<string | null>(null);\n\n const [messages, setMessages] = useState<ChatViewMessage[]>([]);\n const [isMessagesLoading, setIsMessagesLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [specialState, setSpecialState] = useState<SpecialChatState | null>(null);\n\n const [userContextSeed, setUserContextSeed] = useState<Partial<ChatUserContext>>(initialContext || {});\n const preferredAgentRef = useRef<string | null>(preferredAgentName ?? null);\n\n // Refs to hold latest state for callbacks to avoid dependency cycles\n // Using direct assignment pattern instead of useEffect for better performance\n const threadsRef = useRef(threads);\n const threadMetadataMapRef = useRef(threadMetadataMap);\n const threadExternalIdMapRef = useRef(threadExternalIdMap);\n const currentThreadIdRef = useRef(currentThreadId);\n const currentThreadExternalIdRef = useRef(currentThreadExternalId);\n const userContextSeedRef = useRef(userContextSeed);\n\n // Sync refs on every render (more efficient than multiple useEffects)\n threadsRef.current = threads;\n threadMetadataMapRef.current = threadMetadataMap;\n threadExternalIdMapRef.current = threadExternalIdMap;\n currentThreadIdRef.current = currentThreadId;\n currentThreadExternalIdRef.current = currentThreadExternalId;\n userContextSeedRef.current = userContextSeed;\n preferredAgentRef.current = preferredAgentName ?? null;\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const messagesRequestRef = useRef<number>(0);\n // Guard to prevent double initialization in StrictMode\n const initializationRef = useRef<{ userId: string | null; started: boolean }>({ userId: null, started: false });\n\n useEffect(() => {\n if (initialContext) {\n setUserContextSeed((prev) => ({ ...prev, ...initialContext }));\n }\n }, [initialContext]);\n\n const processToolOutput = useCallback((output: Record<string, unknown>) => {\n if (!output) return;\n\n const contextPatch: Partial<ChatUserContext> = {};\n\n // Generic merge of userContext from output if present\n if (output.userContext && typeof output.userContext === 'object') {\n Object.assign(contextPatch, output.userContext as Partial<ChatUserContext>);\n }\n\n if (Object.keys(contextPatch).length > 0) {\n setUserContextSeed((prev) => ({ ...prev, ...contextPatch }));\n }\n\n onToolOutput?.(output);\n }, [onToolOutput]);\n\n const clearSpecialState = useCallback(() => {\n setSpecialState(null);\n }, []);\n\n const applyEventInterceptor = useCallback((event: unknown) => {\n if (!eventInterceptor) return undefined;\n try {\n const result = eventInterceptor(event);\n if (result?.specialState) {\n setSpecialState(result.specialState);\n }\n return result;\n } catch (error) {\n console.error('Error in Copilotz event interceptor', error);\n return undefined;\n }\n }, [eventInterceptor]);\n\n const getSpecialStateFromError = useCallback((error: unknown) => {\n if (!runErrorInterceptor) return null;\n try {\n return runErrorInterceptor(error) ?? null;\n } catch (interceptorError) {\n console.error('Error in Copilotz run error interceptor', interceptorError);\n return null;\n }\n }, [runErrorInterceptor]);\n\n const handleStreamMessageEvent = useCallback((event: any) => {\n const payload = getEventPayload(event);\n if (!payload) return;\n const senderType = getEventSenderType(payload);\n\n if (senderType === 'tool') {\n const metadata = (payload.metadata ?? event.metadata ?? {}) as Record<string, unknown>;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n\n // Attach tool call details to the current assistant bubble (expandable)\n const toolName = (metadata?.toolName as string) || (metadata?.tool as string) || 'tool';\n let argsObj: Record<string, unknown> = {};\n try {\n const argStr = (metadata?.arguments as string) ?? '{}';\n argsObj = typeof argStr === 'string' ? JSON.parse(argStr) : (argStr as Record<string, unknown>);\n } catch (_) { /* ignore parse */ }\n const resultObj = metadata?.output as unknown;\n const callId = (payload.toolCallId as string) || generateId();\n\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant') {\n const existing = Array.isArray(m.toolCalls) ? m.toolCalls : [];\n next[i] = {\n ...m,\n toolCalls: [\n ...existing,\n {\n id: callId,\n name: toolName,\n arguments: argsObj as Record<string, any>,\n result: resultObj,\n status: 'completed' as const,\n endTime: Date.now(),\n },\n ],\n };\n break;\n }\n }\n return next;\n });\n return;\n }\n\n if (senderType === 'agent' && typeof payload.content === 'string') {\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant' && m.isStreaming) {\n next[i] = { ...m, content: payload.content, isStreaming: false, isComplete: true };\n return next;\n }\n }\n\n const trimmedContent = payload.content.trim();\n if (!trimmedContent) {\n return prev;\n }\n\n const last = next[next.length - 1];\n if (last?.role === 'assistant' && last.content === payload.content) {\n return prev;\n }\n\n return [\n ...next,\n {\n id: generateId(),\n role: 'assistant',\n content: payload.content,\n timestamp: nowTs(),\n isStreaming: false,\n isComplete: true,\n metadata: (payload.metadata ?? undefined) as Record<string, unknown> | undefined,\n },\n ];\n });\n }\n }, [processToolOutput]);\n\n const updateThreadsState = useCallback((rawThreads: ServerThread[], preferredExternalId?: string | null) => {\n const metadataMap: Record<string, Record<string, unknown> | undefined> = {};\n const externalMap: Record<string, string | null> = {};\n\n const normalized = rawThreads.map((thread) => {\n metadataMap[thread.id] = thread.metadata ?? undefined;\n externalMap[thread.id] = thread.externalId ?? null;\n const updatedAt = thread.updatedAt ? new Date(thread.updatedAt).getTime() : nowTs();\n const createdAt = thread.createdAt ? new Date(thread.createdAt).getTime() : updatedAt;\n return {\n id: thread.id,\n title: thread.name || 'Chat',\n createdAt,\n updatedAt,\n messageCount: typeof thread.metadata?.messageCount === 'number'\n ? thread.metadata!.messageCount as number\n : 0,\n isArchived: thread.status === 'archived',\n metadata: thread.metadata ?? undefined,\n } as ChatThread;\n });\n\n setThreadMetadataMap(metadataMap);\n setThreadExternalIdMap(externalMap);\n setThreads(normalized);\n\n // Use refs to avoid dependency cycle\n const curExtId = currentThreadExternalIdRef.current;\n const curId = currentThreadIdRef.current;\n\n let nextThreadId: string | null = null;\n\n if (preferredExternalId) {\n const preferred = rawThreads.find((thread) => (thread.externalId ?? thread.id) === preferredExternalId);\n if (preferred) nextThreadId = preferred.id;\n }\n\n if (!nextThreadId && curExtId) {\n const match = rawThreads.find((thread) => (thread.externalId ?? thread.id) === curExtId);\n if (match) nextThreadId = match.id;\n }\n\n if (!nextThreadId && curId && rawThreads.some((thread) => thread.id === curId)) {\n nextThreadId = curId;\n }\n\n if (!nextThreadId && normalized.length > 0) {\n nextThreadId = normalized[0].id;\n }\n\n setCurrentThreadId(nextThreadId ?? null);\n setCurrentThreadExternalId(nextThreadId ? externalMap[nextThreadId] ?? null : null);\n\n return nextThreadId;\n }, []); // No dependencies needed now as we use refs for reading current state\n\n const fetchAndSetThreadsState = useCallback(async (uid: string, preferredExternalId?: string | null) => {\n try {\n const rawThreads = await fetchThreads(uid);\n return updateThreadsState(rawThreads, preferredExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error loading threads', error);\n return null;\n }\n }, [updateThreadsState]);\n\n const loadThreadMessages = useCallback(async (threadId: string) => {\n const requestId = messagesRequestRef.current + 1;\n messagesRequestRef.current = requestId;\n setIsMessagesLoading(true);\n try {\n const rawMessages = await fetchThreadMessages(threadId);\n const resolvedMessages = await resolveAssetsInMessages(rawMessages as unknown as any[]);\n if (messagesRequestRef.current !== requestId) return;\n\n resolvedMessages.forEach((msg: any) => {\n if (msg.senderType === 'tool') {\n const metadata = msg.metadata as Record<string, unknown> | undefined;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n }\n });\n\n const toolResultUpdates = resolvedMessages\n .map((msg) => extractToolResultUpdateFromMessage(msg as unknown as ServerMessage))\n .filter((update): update is ToolResultUpdate => update !== null);\n\n const viewMessages = resolvedMessages\n .filter((msg) => {\n const text = (typeof msg.content === 'string' ? msg.content : '').trim();\n const hasText = text.length > 0;\n const hasToolCalls = extractToolCallsFromServerMessage(msg as unknown as ServerMessage).length > 0;\n const meta = (msg.metadata ?? {}) as Record<string, unknown>;\n const hasAttachments = Array.isArray(meta.attachments) && (meta.attachments as unknown[]).length > 0;\n // Keep tool messages only if they carry attachments (e.g., generated media)\n if (msg.senderType === 'tool') {\n return hasAttachments;\n }\n // For agent/user/system, keep if there is text, tool calls, or attachments\n return hasText || hasToolCalls || hasAttachments;\n })\n .map(convertServerMessage);\n\n const hydratedMessages = mergePersistedToolResults(viewMessages, toolResultUpdates);\n setMessages(hydratedMessages);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error(`Error loading messages for thread ${threadId}`, error);\n } finally {\n if (messagesRequestRef.current === requestId) {\n setIsMessagesLoading(false);\n }\n }\n }, [processToolOutput]);\n\n const handleSelectThread = useCallback(async (threadId: string) => {\n setCurrentThreadId(threadId);\n setMessages([]);\n // Use ref for external map to avoid re-creation\n const extMap = threadExternalIdMapRef.current;\n setCurrentThreadExternalId(extMap[threadId] ?? null);\n await loadThreadMessages(threadId);\n }, [loadThreadMessages]);\n\n const handleCreateThread = useCallback((title?: string) => {\n messagesRequestRef.current += 1;\n setIsMessagesLoading(false);\n const id = generateId();\n const now = nowTs();\n const newThread: ChatThread = {\n id,\n title: title?.trim() || 'New Chat',\n createdAt: now,\n updatedAt: now,\n messageCount: 0,\n metadata: { pendingTitle: title?.trim() || undefined },\n };\n\n setThreads((prev) => [newThread, ...prev]);\n setThreadMetadataMap((prev) => ({ ...prev, [id]: { pendingTitle: title?.trim() || undefined } }));\n setThreadExternalIdMap((prev) => ({ ...prev, [id]: id }));\n setCurrentThreadId(id);\n setCurrentThreadExternalId(id);\n setMessages([]);\n }, []);\n\n const handleRenameThread = useCallback(async (threadId: string, newTitle: string) => {\n const trimmedTitle = newTitle.trim();\n if (!trimmedTitle) return;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title: trimmedTitle, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread (not yet persisted)\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (isPlaceholder) {\n // Store title in metadata for when thread is created\n setThreadMetadataMap((prev) => ({\n ...prev,\n [threadId]: { ...prev[threadId], pendingTitle: trimmedTitle },\n }));\n } else {\n // Persist to backend\n try {\n await updateThreadApi(threadId, { name: trimmedTitle });\n } catch (error) {\n console.error('Failed to rename thread:', error);\n // Revert on error - refetch threads\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState]);\n\n const handleArchiveThread = useCallback(async (threadId: string) => {\n // Find current archive status\n const thread = threadsRef.current.find((t) => t.id === threadId);\n if (!thread) return;\n\n const newArchivedStatus = !thread.isArchived;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, isArchived: newArchivedStatus, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (!isPlaceholder) {\n try {\n await updateThreadApi(threadId, { status: newArchivedStatus ? 'archived' : 'active' });\n } catch (error) {\n console.error('Failed to archive thread:', error);\n // Revert on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState]);\n\n const handleDeleteThread = useCallback(async (threadId: string) => {\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n // Remove from local state immediately\n setThreads((prev) => prev.filter((t) => t.id !== threadId));\n setThreadMetadataMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n setThreadExternalIdMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n\n // If deleting current thread, switch to another\n if (currentThreadIdRef.current === threadId) {\n const remaining = threadsRef.current.filter((t) => t.id !== threadId);\n if (remaining.length > 0) {\n setCurrentThreadId(remaining[0].id);\n setCurrentThreadExternalId(extMap[remaining[0].id] ?? null);\n await loadThreadMessages(remaining[0].id);\n } else {\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n }\n }\n\n if (!isPlaceholder) {\n try {\n await deleteThreadApi(threadId);\n } catch (error) {\n console.error('Failed to delete thread:', error);\n // Refetch to restore state on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages]);\n\n const handleStop = useCallback(() => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n setMessages((prev) => {\n // Check if any message needs updating before creating new array\n const hasStreaming = prev.some((msg) => msg.isStreaming);\n if (!hasStreaming) return prev;\n return prev.map((msg) => (msg.isStreaming ? { ...msg, isStreaming: false, isComplete: true } : msg));\n });\n }, []);\n\n const handleStreamAssetEvent = useCallback((payload: any, assistantMessageId: string) => {\n // Handle ASSET_CREATED event from copilotz\n if (!payload?.dataUrl) return;\n\n const mimeType = payload.mime || 'image/png';\n const dataUrl = payload.dataUrl;\n\n // Determine attachment kind based on mime type\n let kind: 'image' | 'audio' | 'video' = 'image';\n if (mimeType.startsWith('audio/')) {\n kind = 'audio';\n } else if (mimeType.startsWith('video/')) {\n kind = 'video';\n }\n\n const mediaAttachment: MediaAttachment = {\n kind,\n dataUrl,\n mimeType,\n };\n\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId\n ? {\n ...msg,\n attachments: [...(msg.attachments || []), mediaAttachment],\n isStreaming: false,\n isComplete: true\n }\n : msg)));\n }, []);\n\n const sendCopilotzMessage = useCallback(async (\n params: {\n threadId?: string | null;\n threadExternalId?: string | null;\n content: string;\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n userId: string;\n userName?: string;\n userMetadata?: Record<string, unknown>;\n agentName?: string | null;\n onBeforeStart?: (assistantMessageId: string) => void;\n },\n ) => {\n // Track current assistant streaming bubble id so we can split bubbles between events\n let currentAssistantId = generateId();\n params.onBeforeStart?.(currentAssistantId);\n\n let hasStreamProgress = false;\n let pendingStartNewAssistantBubble = false;\n\n // Combined function to ensure bubble exists AND update content in a single setMessages call\n const updateStreamingMessage = (partial: string) => {\n if (partial && partial.length > 0) {\n hasStreamProgress = true;\n }\n\n // Keep feedback visible while the run is active. A token segment can finish\n // before tool calls or subsequent token segments start.\n const nextStreaming = true;\n const nextComplete = false;\n \n setMessages((prev) => {\n // First, check if we need to create a new streaming bubble\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx >= 0 && prev[idx].role === 'assistant') {\n // Found our current bubble - just update it\n const msg = prev[idx];\n if (msg.content === partial && msg.isStreaming === nextStreaming && msg.isComplete === nextComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[idx] = { ...msg, content: partial, isStreaming: nextStreaming, isComplete: nextComplete };\n return updated;\n }\n \n // Check if last message is a streaming assistant we can reuse\n const last = prev[prev.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n currentAssistantId = last.id;\n pendingStartNewAssistantBubble = false;\n if (last.content === partial && last.isStreaming === nextStreaming && last.isComplete === nextComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[prev.length - 1] = { ...last, content: partial, isStreaming: nextStreaming, isComplete: nextComplete };\n return updated;\n }\n \n // Need to create a new bubble\n if (pendingStartNewAssistantBubble || !prev.length || (prev[prev.length - 1].role !== 'assistant' || !prev[prev.length - 1].isStreaming)) {\n const newId = generateId();\n currentAssistantId = newId;\n pendingStartNewAssistantBubble = false;\n return [\n ...prev,\n {\n id: newId,\n role: 'assistant' as const,\n content: partial,\n timestamp: nowTs(),\n isStreaming: nextStreaming,\n isComplete: nextComplete,\n },\n ];\n }\n \n return prev;\n });\n };\n\n const finalizeCurrentAssistantBubble = () => {\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx < 0) return prev;\n const msg = prev[idx];\n // Skip update if already finalized\n if (!msg.isStreaming && msg.isComplete) return prev;\n const updated = [...prev];\n updated[idx] = { ...msg, isStreaming: false, isComplete: true };\n return updated;\n });\n };\n\n // Using Refs for accessing current state inside callback\n const curThreadId = currentThreadIdRef.current;\n\n // Build a ServerMessage-like object from various streaming event payloads\n const toServerMessageFromEvent = async (event: any): Promise<ServerMessage | null> => {\n if (!event) return null;\n const type = (event?.type as string) || '';\n const payload = event?.payload ?? event;\n\n // TOOL_CALL bubble\n if (type === 'TOOL_CALL') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n const call = (payload?.call ?? (metadata as any)?.call) as Record<string, unknown> | undefined;\n const func = (call?.function ?? (payload as any)?.function) as Record<string, unknown> | undefined;\n\n // Extract tool name from various possible locations\n const toolName =\n (func?.name as string) ||\n (payload?.name as string) ||\n (call?.name as string) ||\n (metadata.toolName as string) ||\n (metadata.tool as string) ||\n 'tool';\n\n // Robust args extraction across shapes, including the call.function.arguments pattern\n let argsObj: Record<string, unknown> = {};\n const possibleArgs = [\n func?.arguments, // Try call.function.arguments first (most specific for this event structure)\n payload?.args,\n call?.arguments,\n (metadata as any)?.args,\n (metadata as any)?.arguments,\n ];\n for (const candidate of possibleArgs) {\n if (candidate === undefined || candidate === null) continue;\n try {\n if (typeof candidate === 'string') {\n argsObj = JSON.parse(candidate);\n break;\n }\n if (typeof candidate === 'object') {\n argsObj = candidate as Record<string, unknown>;\n break;\n }\n } catch { /* ignore */ }\n }\n\n const output =\n (metadata as any)?.output !== undefined ? (metadata as any).output\n : payload?.output !== undefined ? payload.output\n : undefined;\n\n // Extract call ID from various locations\n const callId =\n (call?.id as string) ||\n (func?.id as string) ||\n (payload?.id as string) ||\n generateId();\n\n const statusVal =\n (payload?.status as string) ||\n ((event as any)?.status as string) ||\n 'pending';\n\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n toolCalls: [{\n id: callId,\n name: toolName,\n args: argsObj as Record<string, unknown>,\n output,\n status: statusVal,\n }] as Array<Record<string, unknown>>,\n } as unknown as ServerMessage;\n }\n\n // MESSAGE bubble (agent text only - ignore system/tool messages and empty content)\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = payload?.senderType || payload?.sender?.type;\n // Only process agent messages, skip system/tool/user messages\n if (senderType !== 'agent') {\n return null;\n }\n const content = typeof payload?.content === 'string' ? payload.content : '';\n // Skip messages with empty content (especially NEW_MESSAGE events that only have toolCalls)\n if (!content.trim()) {\n return null;\n }\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'agent',\n content,\n metadata: (payload?.metadata ?? {}) as Record<string, unknown>,\n } as unknown as ServerMessage;\n }\n\n // ASSET_CREATED bubble (tool-generated media)\n if (type === 'ASSET_CREATED') {\n // Only render assets created by tools (ignore user uploads)\n const by = (payload?.by as string) || '';\n if (by && by !== 'tool') return null;\n\n const mime = (payload?.mime as string) || 'image/png';\n const ref = (payload?.ref as string) || (payload?.assetRef as string) || '';\n if (!ref) return null;\n const kind = mime.startsWith('audio/') ? 'audio' : (mime.startsWith('video/') ? 'video' : 'image');\n const msgLike = {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n metadata: {\n attachments: [{ kind, assetRef: ref, mimeType: mime }],\n },\n } as unknown as ServerMessage;\n // Resolve assetRef → dataUrl via service\n const [resolved] = await resolveAssetsInMessages([msgLike] as any);\n return resolved as unknown as ServerMessage;\n }\n\n return null;\n };\n\n const abortController = new AbortController();\n abortControllerRef.current?.abort();\n abortControllerRef.current = abortController;\n setIsStreaming(true);\n\n try {\n const normalizedUserMetadata = params.userMetadata\n ? JSON.parse(JSON.stringify(params.userMetadata)) as Record<string, unknown>\n : undefined;\n\n const contextSeed = userContextSeedRef.current;\n const contextMetadata = contextSeed\n ? JSON.parse(JSON.stringify(contextSeed)) as Record<string, unknown>\n : undefined;\n const requestContent = params.content && params.content.length > 0 ? params.content : '';\n\n const metadataKey = params.threadId ?? params.threadExternalId ?? undefined;\n // Read from ref to avoid dependency on threadMetadataMap\n const currentThreadMetadataMap = threadMetadataMapRef.current;\n const messageMetadata = metadataKey ? currentThreadMetadataMap[metadataKey]?.userContext as Record<string, unknown> | undefined : undefined;\n const threadMetadata = metadataKey ? currentThreadMetadataMap[metadataKey] : undefined;\n\n const mergedMetadata = {\n ...(messageMetadata ?? {}),\n ...(params.metadata ?? {}),\n } as Record<string, unknown>;\n\n const finalMetadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : undefined;\n\n await runCopilotzStream({\n threadId: params.threadId ?? undefined,\n threadExternalId: params.threadExternalId ?? undefined,\n content: requestContent,\n user: {\n externalId: params.userId,\n name: params.userName ?? params.userId,\n metadata: {\n ...(contextMetadata ? contextMetadata : {}),\n ...(normalizedUserMetadata ?? {}),\n },\n },\n attachments: params.attachments,\n metadata: finalMetadata,\n threadMetadata: params.threadMetadata ?? threadMetadata,\n toolCalls: params.toolCalls,\n selectedAgent: params.agentName ?? preferredAgentRef.current ?? null,\n onToken: (token) => updateStreamingMessage(token),\n onMessageEvent: async (event: any) => {\n const intercepted = applyEventInterceptor(event);\n if (intercepted?.handled) {\n return;\n }\n\n const type = (event?.type as string) || '';\n const payload = getEventPayload(event);\n\n // Handle MESSAGE/NEW_MESSAGE events for tool responses\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = getEventSenderType(payload);\n \n // Handle tool responses: update the matching tool call status\n if (senderType === 'tool') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n \n // Extract tool call information from metadata.toolCalls array\n const toolCallsArray = metadata?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCallData = toolCallsArray && toolCallsArray.length > 0 ? toolCallsArray[0] : undefined;\n \n if (!toolCallData) {\n return; // No tool call data found\n }\n \n // Notify onToolOutput callback with the full metadata (includes toolCalls array)\n // This allows consumers to react to tool completions in real-time\n processToolOutput(metadata);\n \n // Extract tool call ID and name\n const toolCallId = toolCallData.id as string | undefined;\n const toolCallName = toolCallData.name as string | undefined;\n \n // Extract the tool result/output\n const toolResult = toolCallData.output || payload?.content;\n \n // Check if the tool execution failed\n const toolStatus = (toolCallData.status as string) || 'completed';\n const isFailed = toolStatus === 'failed' || toolCallData?.error;\n \n // Update the tool call status in the assistant message\n setMessages((prev) => {\n const updated = [...prev];\n // Find the assistant message with the matching tool call\n for (let i = updated.length - 1; i >= 0; i--) {\n if (updated[i].role === 'assistant' && updated[i].toolCalls) {\n const toolCalls = updated[i].toolCalls;\n if (toolCalls) {\n // Try to find by ID first, then by name for pending/running tools\n let toolCallIndex = toolCallId \n ? toolCalls.findIndex(tc => tc.id === toolCallId)\n : -1;\n \n // If not found by ID, try to find a pending/running tool with the same name\n if (toolCallIndex === -1 && toolCallName) {\n toolCallIndex = toolCalls.findIndex(\n tc => tc.name === toolCallName && \n (tc.status === 'pending' || tc.status === 'running')\n );\n }\n \n if (toolCallIndex !== -1) {\n const updatedToolCalls = [...toolCalls];\n updatedToolCalls[toolCallIndex] = {\n ...updatedToolCalls[toolCallIndex],\n status: isFailed ? 'failed' : 'completed',\n result: toolResult,\n endTime: Date.now(),\n };\n updated[i] = {\n ...updated[i],\n toolCalls: updatedToolCalls,\n isStreaming: true,\n isComplete: false,\n };\n break;\n }\n }\n }\n }\n return updated;\n });\n return; // Don't create a separate bubble for tool responses\n }\n \n handleStreamMessageEvent(event);\n return;\n }\n\n // TOOL_CALL events: render inside current assistant bubble\n if (type === 'TOOL_CALL') {\n const sm = await toServerMessageFromEvent(event);\n const toolCalls = sm?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCall = toolCalls && toolCalls[0];\n if (!toolCall) return;\n\n setMessages((prev) =>\n (() => {\n const appendToolCall = (msg: ChatViewMessage) => ({\n ...msg,\n toolCalls: [\n ...(Array.isArray(msg.toolCalls) ? msg.toolCalls : []),\n {\n id: (toolCall.id as string) ?? generateId(),\n name: (toolCall.name as string) ?? 'tool',\n arguments:\n (toolCall.args as Record<string, unknown>) ??\n (toolCall.arguments as Record<string, unknown>) ??\n {},\n result: toolCall.output,\n status:\n (toolCall.status as 'pending' | 'running' | 'completed' | 'failed') ??\n 'running',\n startTime: Date.now(),\n },\n ],\n });\n\n // Try to attach to the most recent assistant message\n for (let i = prev.length - 1; i >= 0; i--) {\n if (prev[i].role === 'assistant') {\n const next = [...prev];\n next[i] = appendToolCall({\n ...next[i],\n isStreaming: true,\n isComplete: false,\n });\n return next;\n }\n }\n\n // No assistant message yet – create one to host the tool call\n return [\n ...prev,\n appendToolCall({\n id: generateId(),\n role: 'assistant',\n content: '',\n timestamp: nowTs(),\n isStreaming: true,\n isComplete: false,\n }),\n ];\n })(),\n );\n hasStreamProgress = true;\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Other event types (ASSET_CREATED, etc.) should render as their own bubbles\n const sm = await toServerMessageFromEvent(event);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n finalizeCurrentAssistantBubble();\n setMessages((prev) => [...prev, viewMsg]);\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Fallback for unknown events\n handleStreamMessageEvent(event);\n },\n onAssetEvent: async (payload: any) => {\n const intercepted = applyEventInterceptor({ type: 'ASSET_CREATED', payload });\n if (intercepted?.handled) {\n return;\n }\n\n // Treat as ASSET_CREATED event in unified handler\n await (async () => {\n if (!hasStreamProgress) return;\n finalizeCurrentAssistantBubble();\n const evt = { type: 'ASSET_CREATED', payload };\n const sm = await toServerMessageFromEvent(evt);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n setMessages((prev) => [...prev, viewMsg]);\n }\n // Defer creating a new assistant bubble until next TOKEN arrives\n pendingStartNewAssistantBubble = true;\n })();\n },\n signal: abortController.signal,\n });\n } finally {\n setIsStreaming(false);\n setMessages((prev) => {\n const hasStreaming = prev.some((msg) => msg.isStreaming);\n if (!hasStreaming) return prev;\n return prev.map((msg) => (msg.isStreaming\n ? { ...msg, isStreaming: false, isComplete: true }\n : msg));\n });\n abortControllerRef.current = null;\n }\n\n return currentAssistantId;\n }, [applyEventInterceptor, handleStreamMessageEvent, handleStreamAssetEvent]);\n\n const handleSendMessage = useCallback(async (content: string, attachments: MediaAttachment[] = []) => {\n if (!content.trim() && attachments.length === 0) return;\n if (!userId) return;\n\n const timestamp = nowTs();\n const curThreadId = currentThreadIdRef.current;\n const curThreadExtId = currentThreadExternalIdRef.current;\n\n const existingThreadId = curThreadId ?? undefined;\n // Use Ref to check without adding dependency\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholderThread = existingThreadId\n ? extMap[existingThreadId] === existingThreadId\n : false;\n\n const threadIdForSend = isPlaceholderThread ? undefined : existingThreadId;\n\n let effectiveThreadExternalId = curThreadExtId ?? (isPlaceholderThread ? existingThreadId : undefined);\n\n if (!threadIdForSend) {\n if (!effectiveThreadExternalId) {\n effectiveThreadExternalId = generateId();\n }\n setCurrentThreadExternalId(effectiveThreadExternalId);\n } else if (curThreadExtId !== (effectiveThreadExternalId ?? null)) {\n setCurrentThreadExternalId(effectiveThreadExternalId ?? null);\n }\n\n const conversationKey = threadIdForSend ?? effectiveThreadExternalId!;\n\n // Get pending title for new threads if any\n const currentMetadata = threadMetadataMapRef.current[conversationKey];\n const pendingTitle = currentMetadata?.pendingTitle as string | undefined;\n\n const userMessage: ChatViewMessage = {\n id: generateId(),\n role: 'user',\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isComplete: true,\n };\n\n // Create an assistant message placeholder with streaming state for typewriter effect\n const assistantPlaceholder: ChatViewMessage = {\n id: generateId(),\n role: 'assistant',\n content: '',\n timestamp: timestamp + 1,\n isStreaming: true,\n isComplete: false,\n };\n\n // Add user message and assistant placeholder for typewriter loading effect\n setMessages((prev) => [...prev, userMessage, assistantPlaceholder]);\n setSpecialState(null);\n\n // Use ref for threads check\n if (!threadsRef.current.some(t => t.id === conversationKey)) {\n const newThread: ChatThread = {\n id: conversationKey,\n title: content.slice(0, 40) || 'Nova conversa',\n createdAt: timestamp,\n updatedAt: timestamp,\n messageCount: 0,\n };\n setThreads(prev => [newThread, ...prev]);\n setThreadMetadataMap(prev => ({ ...prev, [conversationKey]: {} }));\n setThreadExternalIdMap(prev => ({ ...prev, [conversationKey]: effectiveThreadExternalId ?? null }));\n }\n\n try {\n await sendCopilotzMessage({\n threadId: threadIdForSend,\n threadExternalId: effectiveThreadExternalId,\n content,\n attachments,\n userId,\n // userName can be anything, but let's try to find it in context or just fallback\n userName: (userContextSeedRef.current?.profile as any)?.full_name ?? userId,\n agentName: preferredAgentRef.current,\n // Include pending title for new threads\n threadMetadata: pendingTitle ? { name: pendingTitle } : undefined,\n });\n\n // Wait to ensure the assistant message is persisted before refreshing\n await new Promise((r) => setTimeout(r, 1000));\n // Refresh threads list to update metadata (message count, timestamps, etc.)\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(userId, effectiveThreadExternalId ?? existingThreadId ?? null);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error sending Copilotz message', error);\n const nextSpecialState = getSpecialStateFromError(error);\n if (nextSpecialState) {\n setSpecialState(nextSpecialState);\n setMessages((prev) => prev.filter((msg) => !msg.isStreaming));\n return;\n }\n setMessages((prev) => prev.map((msg) => (msg.isStreaming\n ? {\n ...msg,\n isStreaming: false,\n isComplete: true,\n content: 'Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente.',\n }\n : msg)));\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, getSpecialStateFromError]);\n\n const bootstrapConversation = useCallback(async (uid: string) => {\n if (!bootstrap?.initialToolCalls && !bootstrap?.initialMessage) return;\n\n const bootstrapThreadExternalId = generateId();\n setCurrentThreadId(bootstrapThreadExternalId);\n setCurrentThreadExternalId(bootstrapThreadExternalId);\n setThreadExternalIdMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: bootstrapThreadExternalId }));\n setThreadMetadataMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: {} }));\n // Clear messages; let streaming create bubbles as needed\n setMessages([]);\n setSpecialState(null);\n\n try {\n await sendCopilotzMessage({\n threadExternalId: bootstrapThreadExternalId,\n content: bootstrap.initialMessage || '',\n toolCalls: bootstrap.initialToolCalls,\n userId: uid,\n agentName: preferredAgentRef.current,\n threadMetadata: {\n name: defaultThreadName || 'Main Thread',\n },\n });\n\n // Give the backend time to persist tool outputs/messages before refresh\n await new Promise((r) => setTimeout(r, 1000));\n\n // Refresh threads list to update metadata\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(uid, bootstrapThreadExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error bootstrapping conversation', error);\n const nextSpecialState = getSpecialStateFromError(error);\n if (nextSpecialState) {\n setSpecialState(nextSpecialState);\n setMessages([]);\n return;\n }\n setMessages([\n {\n id: generateId(),\n role: 'assistant',\n content: 'Não foi possível iniciar a conversa. Tente novamente mais tarde.',\n timestamp: nowTs(),\n isStreaming: false,\n isComplete: true,\n },\n ]);\n }\n }, [fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName, getSpecialStateFromError]);\n\n const reset = useCallback(() => {\n messagesRequestRef.current += 1;\n setThreads([]);\n setThreadMetadataMap({});\n setThreadExternalIdMap({});\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n setUserContextSeed({});\n setIsMessagesLoading(false);\n setIsStreaming(false);\n setSpecialState(null);\n abortControllerRef.current?.abort();\n }, []);\n\n // Initialize when userId changes\n useEffect(() => {\n if (userId) {\n // Guard against double initialization in StrictMode\n if (initializationRef.current.userId === userId && initializationRef.current.started) {\n return;\n }\n initializationRef.current = { userId, started: true };\n\n const init = async () => {\n // Use URL thread ID as preferred if available\n const urlPreferredThread = isUrlSyncEnabled ? urlState.threadId : undefined;\n const preferredThreadId = await fetchAndSetThreadsState(userId, urlPreferredThread);\n if (preferredThreadId) {\n await loadThreadMessages(preferredThreadId);\n } else if (bootstrap) {\n await bootstrapConversation(userId);\n }\n };\n init();\n } else {\n initializationRef.current = { userId: null, started: false };\n reset();\n }\n }, [userId, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);\n\n // Sync currentThreadExternalId to URL when it changes\n useEffect(() => {\n if (!isUrlSyncEnabled) return;\n // Only sync after initial load is complete\n if (!initializationRef.current.started) return;\n \n setUrlThreadId(currentThreadExternalId);\n }, [currentThreadExternalId, isUrlSyncEnabled, setUrlThreadId]);\n\n // Sync metadata map effects\n useEffect(() => {\n if (!currentThreadId) return;\n const metadata = threadMetadataMap[currentThreadId];\n if (!metadata) return;\n\n if (metadata.userContext && typeof metadata.userContext === 'object') {\n setUserContextSeed((prev) => ({ ...prev, ...(metadata.userContext as Partial<ChatUserContext>) }));\n }\n }, [currentThreadId, threadMetadataMap]);\n\n return {\n messages,\n isMessagesLoading,\n threads,\n currentThreadId,\n isStreaming,\n specialState,\n clearSpecialState,\n userContextSeed,\n sendMessage: handleSendMessage,\n createThread: handleCreateThread,\n selectThread: handleSelectThread,\n renameThread: handleRenameThread,\n archiveThread: handleArchiveThread,\n deleteThread: handleDeleteThread,\n stopGeneration: handleStop,\n fetchAndSetThreadsState,\n loadThreadMessages,\n reset,\n // URL state\n /** Initial prompt from URL (if urlSync enabled) - use for pre-filling input */\n initialPrompt: isUrlSyncEnabled ? urlState.prompt : null,\n /** Clear the initial prompt from URL (call after consuming it) */\n clearInitialPrompt: clearUrlPrompt,\n /** URL agent ID (if urlSync enabled) - use for agent pre-selection */\n urlAgentId: isUrlSyncEnabled ? urlState.agentId : null,\n /** Update agent ID in URL */\n setUrlAgentId,\n };\n}\n","import type { MediaAttachment } from '@copilotz/chat-ui';\n\nconst rawBaseValue = import.meta.env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst runtimeProcess: typeof process | undefined = typeof process !== 'undefined' ? process : undefined;\n\nconst API_KEY = (() => {\n const env = (import.meta as { env?: Record<string, string | undefined> }).env ?? {};\n const candidates = [\n env.VITE_API_KEY,\n env.VITE_COPILOTZ_API_KEY,\n runtimeProcess?.env?.COPILOTZ_API_KEY,\n runtimeProcess?.env?.API_KEY,\n ];\n return candidates.find((value) => typeof value === 'string' && value.length > 0);\n})();\n\nconst withAuthHeaders = (headers: Record<string, string> = {}): Record<string, string> => {\n if (API_KEY) {\n return { ...headers, Authorization: `Bearer ${API_KEY}` };\n }\n return headers;\n};\n\ntype RestThread = {\n id: string;\n name?: string | null;\n externalId?: string | null;\n description?: string | null;\n participants?: string[] | null;\n status?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype RestMessage = {\n id: string;\n threadId: string;\n senderId?: string | null;\n senderType: string;\n senderUserId?: string | null;\n content?: string | null;\n metadata?: Record<string, unknown> | null;\n toolCalls?: Array<Record<string, unknown>> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype MessageSenderType = 'agent' | 'user' | 'tool' | 'system';\n\ntype MessageContent =\n | string\n | Array<\n | { type: 'text'; text: string }\n | { type: 'image'; url?: string; dataBase64?: string; mimeType?: string; alt?: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n | { type: 'file'; url?: string; dataBase64?: string; mimeType?: string; name?: string }\n | { type: 'json'; value: unknown }\n >;\n\ntype MessageToolCall = {\n id?: string | null;\n name: string;\n args: Record<string, unknown>;\n};\n\ntype MessageThread = {\n id?: string | null;\n name?: string | null;\n description?: string | null;\n externalId?: string | null;\n participants?: string[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessageSender = {\n id?: string | null;\n externalId?: string | null;\n type: MessageSenderType;\n name?: string | null;\n identifierType?: 'id' | 'name' | 'email' | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessagePayload = {\n content: MessageContent;\n sender: MessageSender;\n thread?: MessageThread | null;\n toolCalls?: MessageToolCall[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype StreamCallbacks = {\n onToken?: (token: string, isComplete: boolean, raw?: any) => void;\n onMessageEvent?: (payload: any) => void;\n onAssetEvent?: (payload: any) => void;\n signal?: AbortSignal;\n};\n\ntype RunOptions = {\n threadId?: string;\n threadExternalId?: string;\n content: string;\n user: {\n externalId: string;\n name?: string;\n email?: string;\n metadata?: Record<string, unknown>;\n };\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown>; id?: string }>;\n selectedAgent?: string | null;\n} & StreamCallbacks;\n\nexport type CopilotzStreamResult = {\n text: string;\n messages: any[];\n media: Record<string, string> | null;\n};\n\nexport class CopilotzRequestError extends Error {\n status: number;\n code?: string;\n details?: unknown;\n\n constructor(message: string, options: { status: number; code?: string; details?: unknown }) {\n super(message);\n this.name = 'CopilotzRequestError';\n this.status = options.status;\n this.code = options.code;\n this.details = options.details;\n }\n}\n\nconst SSE_LINE_BREAK = '\\n\\n';\n\nconst appendChunk = (buffer: string, chunk: string): string => {\n if (!buffer) return chunk;\n if (!chunk) return buffer;\n if (chunk.startsWith(buffer)) return chunk;\n if (buffer.startsWith(chunk)) return buffer;\n const maxOverlap = Math.min(buffer.length, chunk.length);\n for (let i = maxOverlap; i > 0; i--) {\n if (buffer.endsWith(chunk.slice(0, i))) {\n return buffer + chunk.slice(i);\n }\n }\n return buffer + chunk;\n};\n\nconst parseErrorText = (rawText: string): unknown => {\n if (!rawText) return null;\n try {\n return JSON.parse(rawText);\n } catch {\n return null;\n }\n};\n\nconst toAttachmentPayload = (attachments?: MediaAttachment[]) => {\n if (!attachments || attachments.length === 0) return undefined;\n return attachments.map(att => {\n const base = {\n kind: att.kind,\n dataUrl: att.dataUrl,\n mimeType: att.mimeType,\n fileName: att.fileName,\n };\n if (att.kind === 'audio' || att.kind === 'video') {\n return {\n ...base,\n durationMs: att.durationMs,\n ...(att.kind === 'video' && 'poster' in att ? { poster: att.poster } : {}),\n };\n }\n return base;\n });\n};\n\n// --- Audio helpers: convert browser-recorded WebM/Opus to WAV (16-bit PCM) ---\nconst base64FromUint8 = (bytes: Uint8Array): string => {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n const chunk = bytes.subarray(i, i + chunkSize);\n binary += String.fromCharCode.apply(null, Array.from(chunk));\n }\n // btoa is available in browsers\n return btoa(binary);\n};\n\nconst parseDataUrl = (dataUrl: string): { mime: string; base64: string } | null => {\n const match = dataUrl.match(/^data:(.+?);base64,(.+)$/s);\n if (!match) return null;\n return { mime: match[1], base64: match[2] };\n};\n\nconst dataUrlToArrayBuffer = (dataUrl: string): ArrayBuffer => {\n const parsed = parseDataUrl(dataUrl);\n if (!parsed) return new ArrayBuffer(0);\n const binaryString = atob(parsed.base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n};\n\nconst encodeWav16BitPCM = (audioBuffer: AudioBuffer): Uint8Array => {\n const numChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const numFrames = audioBuffer.length;\n const bytesPerSample = 2; // 16-bit\n const dataSize = numFrames * numChannels * bytesPerSample;\n const buffer = new ArrayBuffer(44 + dataSize);\n const view = new DataView(buffer);\n\n // RIFF header\n const writeString = (offset: number, str: string) => {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n };\n\n let offset = 0;\n writeString(offset, \"RIFF\"); offset += 4;\n view.setUint32(offset, 36 + dataSize, true); offset += 4;\n writeString(offset, \"WAVE\"); offset += 4;\n\n // fmt subchunk\n writeString(offset, \"fmt \"); offset += 4;\n view.setUint32(offset, 16, true); offset += 4; // Subchunk1Size (16 for PCM)\n view.setUint16(offset, 1, true); offset += 2; // AudioFormat (1 = PCM)\n view.setUint16(offset, numChannels, true); offset += 2; // NumChannels\n view.setUint32(offset, sampleRate, true); offset += 4; // SampleRate\n view.setUint32(offset, sampleRate * numChannels * bytesPerSample, true); offset += 4; // ByteRate\n view.setUint16(offset, numChannels * bytesPerSample, true); offset += 2; // BlockAlign\n view.setUint16(offset, 16, true); offset += 2; // BitsPerSample\n\n // data subchunk\n writeString(offset, \"data\"); offset += 4;\n view.setUint32(offset, dataSize, true); offset += 4;\n\n // Interleave channels and write PCM samples\n const channelData: Float32Array[] = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channelData.push(audioBuffer.getChannelData(ch));\n }\n\n let idx = 0;\n for (let i = 0; i < numFrames; i++) {\n for (let ch = 0; ch < numChannels; ch++) {\n let sample = channelData[ch][i];\n // Clamp\n sample = Math.max(-1, Math.min(1, sample));\n // Convert to 16-bit PCM\n const s = sample < 0 ? sample * 0x8000 : sample * 0x7FFF;\n view.setInt16(offset + idx, s, true);\n idx += 2;\n }\n }\n\n return new Uint8Array(buffer);\n};\n\nconst convertAudioDataUrlToWavBase64 = async (dataUrl: string): Promise<string | null> => {\n try {\n const ab = dataUrlToArrayBuffer(dataUrl);\n const ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n const audioBuffer = await ctx.decodeAudioData(ab.slice(0)); // ensure detached buffer\n // Optionally downsample here if desired; we'll keep source sampleRate.\n const wavBytes = encodeWav16BitPCM(audioBuffer);\n return base64FromUint8(wavBytes);\n } catch (_err) {\n return null;\n }\n};\n\nexport async function runCopilotzStream(options: RunOptions): Promise<CopilotzStreamResult> {\n const {\n threadId,\n threadExternalId,\n content,\n user,\n attachments,\n metadata,\n threadMetadata,\n toolCalls,\n selectedAgent,\n onToken,\n onMessageEvent,\n onAssetEvent,\n signal,\n } = options;\n\n const controller = new AbortController();\n if (signal) {\n signal.addEventListener('abort', () => controller.abort(signal.reason), { once: true });\n }\n\n // Audio attachments are sent as content parts and also mirrored in metadata\n // so the persisted message can render the same media after reload.\n const audioAttachments = attachments?.filter(att => att.kind === 'audio') ?? [];\n const attachmentPayload = toAttachmentPayload(attachments);\n\n const normalizedToolCalls =\n toolCalls?.map<MessageToolCall>((call) => ({\n id: call.id ?? crypto.randomUUID(),\n name: call.name,\n args: call.args ?? {},\n })) ?? [];\n\n const metadataToolCalls =\n normalizedToolCalls.length > 0\n ? normalizedToolCalls.map((tc) => ({\n id: tc.id ?? undefined,\n name: tc.name,\n args: JSON.stringify(tc.args ?? {}),\n }))\n : undefined;\n\n const baseMetadata = {\n ...(metadata ?? {}),\n ...(attachmentPayload ? { attachments: attachmentPayload } : {}),\n ...(metadataToolCalls ? { toolCalls: metadataToolCalls } : {}),\n userExternalId: user.externalId,\n } as Record<string, unknown>;\n\n const messageMetadata = Object.keys(baseMetadata).length > 0 ? baseMetadata : undefined;\n\n const senderMetadata = {\n ...(user.metadata ?? {}),\n ...(user.email ? { email: user.email } : {}),\n } as Record<string, unknown>;\n\n const mergedThreadMetadata = {\n ...(threadMetadata ?? {}),\n } as Record<string, unknown>;\n\n if (mergedThreadMetadata.userExternalId === undefined) {\n mergedThreadMetadata.userExternalId = user.externalId;\n }\n\n // Extract name from threadMetadata if present\n const threadName = (mergedThreadMetadata.name as string) ?? null;\n // Remove name from metadata since it's a top-level field\n const { name: _threadName, ...restThreadMetadata } = mergedThreadMetadata;\n\n const threadPayload: MessageThread | undefined = (threadId || threadExternalId || threadName || Object.keys(restThreadMetadata).length > 0)\n ? {\n id: threadId ?? null,\n externalId: threadExternalId ?? null,\n name: threadName,\n participants: [selectedAgent || 'assistant'],\n metadata: Object.keys(restThreadMetadata).length > 0 ? restThreadMetadata : null,\n }\n : undefined;\n\n // Prepare audio parts (convert to WAV when needed)\n const preparedAudioParts: Array<{ type: 'audio'; dataBase64?: string; url?: string; mimeType?: string; transcript?: string }> = [];\n for (const audioAtt of audioAttachments) {\n if (!audioAtt.dataUrl) continue;\n const parsed = parseDataUrl(audioAtt.dataUrl);\n if (parsed && (parsed.mime.includes('wav') || parsed.mime.includes('mp3') || parsed.mime.includes('mpeg'))) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: parsed.base64,\n mimeType: parsed.mime.includes('wav') ? 'audio/wav' : 'audio/mp3',\n });\n continue;\n }\n // Convert other formats (e.g., audio/webm) to WAV\n const wavBase64 = await convertAudioDataUrlToWavBase64(audioAtt.dataUrl);\n if (wavBase64) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: wavBase64,\n mimeType: 'audio/wav',\n });\n } else {\n // Fallback: send as URL (may fail at provider side, but do not block)\n preparedAudioParts.push({\n type: 'audio',\n url: audioAtt.dataUrl,\n mimeType: audioAtt.mimeType || 'audio/webm',\n });\n }\n }\n\n // Build content array: include text and prepared audio parts\n const contentParts: MessageContent = (() => {\n const parts: Array<\n | { type: 'text'; text: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n > = [];\n const text = (typeof content === 'string' && content.trim().length > 0) ? content : '';\n parts.push({ type: 'text', text });\n for (const p of preparedAudioParts) parts.push(p);\n if (parts.length === 1 && parts[0].type === 'text') return parts[0].text;\n return parts;\n })();\n\n const payload: MessagePayload = {\n content: contentParts,\n sender: {\n type: normalizedToolCalls.length > 0 ? 'agent' : 'user',\n externalId: user.externalId,\n id: normalizedToolCalls.length > 0 ? 'assistant' : undefined,\n name: normalizedToolCalls.length > 0 ? 'assistant' : (user.name ?? null),\n metadata: Object.keys(senderMetadata).length > 0 ? senderMetadata : null,\n },\n metadata: messageMetadata ?? null,\n thread: threadPayload ?? null,\n toolCalls: normalizedToolCalls.length > 0 ? normalizedToolCalls : null,\n };\n\n const response = await fetch(apiUrl('/v1/providers/web'), {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n\n if (!response.ok || !response.body) {\n const errorText = await response.text().catch(() => response.statusText);\n const parsed = parseErrorText(errorText);\n const details = parsed && typeof parsed === 'object' ? parsed : undefined;\n const detailsRecord = details as Record<string, unknown> | undefined;\n const message =\n (typeof detailsRecord?.message === 'string' && detailsRecord.message) ||\n (typeof detailsRecord?.error === 'string' && detailsRecord.error) ||\n errorText ||\n response.statusText ||\n 'Failed to run Copilotz agent';\n const code =\n typeof detailsRecord?.code === 'string'\n ? detailsRecord.code\n : (typeof detailsRecord?.error === 'string' && detailsRecord.error !== message\n ? detailsRecord.error\n : undefined);\n\n throw new CopilotzRequestError(message, {\n status: response.status,\n code,\n details,\n });\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let aggregatedText = '';\n const collectedMessages: any[] = [];\n let collectedMedia: Record<string, string> | null = null;\n\n const processEvent = (eventChunk: string) => {\n if (!eventChunk.trim()) return;\n const lines = eventChunk.split('\\n');\n let eventType = 'message';\n let dataRaw = '';\n for (const line of lines) {\n if (line.startsWith('event:')) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n dataRaw += line.slice(5).trim();\n }\n }\n\n if (!dataRaw) return;\n\n let payload: any;\n try {\n payload = JSON.parse(dataRaw);\n } catch (error) {\n console.warn('copilotzService: failed to parse SSE payload', error, dataRaw);\n return;\n }\n\n switch (eventType) {\n case 'TOKEN': {\n const chunk =\n typeof payload?.payload?.token === 'string'\n ? payload.payload.token\n : (typeof payload?.token === 'string' ? payload.token : '');\n if (chunk) {\n aggregatedText = appendChunk(aggregatedText, chunk);\n }\n const isComplete = Boolean(\n (payload && payload.payload && payload.payload.isComplete) ?? payload?.isComplete\n );\n if (chunk || isComplete) {\n onToken?.(aggregatedText, isComplete, payload);\n }\n break;\n }\n case 'MESSAGE': {\n collectedMessages.push(payload);\n // Pass the payload with its internal type (e.g., NEW_MESSAGE, MESSAGE, etc.)\n // The hook will use payload.type to determine the actual event type\n onMessageEvent?.(payload);\n const senderType =\n payload?.payload?.senderType ??\n payload?.payload?.sender?.type;\n\n if (senderType === 'agent' && typeof payload?.payload?.content === 'string') {\n aggregatedText = payload.payload.content;\n }\n break;\n }\n case 'TOOL_CALL': {\n // Pass TOOL_CALL events directly to the message event handler\n // The payload already has the full event structure with type: \"TOOL_CALL\"\n onMessageEvent?.(payload);\n break;\n }\n case 'ASSET_CREATED': {\n const assetPayload = (payload && typeof payload === 'object' && 'payload' in payload)\n ? (payload as { payload?: any }).payload\n : payload;\n // Convert ASSET_CREATED to media format for backward compatibility\n if (assetPayload?.dataUrl) {\n collectedMedia = {\n [assetPayload.assetId || '0']: assetPayload.dataUrl\n };\n }\n // Call the asset event handler\n onAssetEvent?.(assetPayload);\n break;\n }\n case 'ERROR':\n throw new Error(payload?.error || 'Copilotz stream error');\n default:\n // For other event types, wrap in a structure with type and payload\n onMessageEvent?.({ type: eventType, payload });\n }\n };\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n if (buffer.includes('\\r')) {\n buffer = buffer.replace(/\\r/g, '');\n }\n\n let eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n while (eventBoundary >= 0) {\n const chunk = buffer.slice(0, eventBoundary);\n buffer = buffer.slice(eventBoundary + SSE_LINE_BREAK.length);\n processEvent(chunk);\n eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n }\n }\n\n if (buffer.length > 0) {\n processEvent(buffer);\n }\n\n return {\n text: aggregatedText,\n messages: collectedMessages,\n media: collectedMedia,\n };\n}\n\nexport async function fetchThreads(userId: string) {\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ \"metadata.userExternalId\": userId } ));\n params.set('sort', '-updatedAt');\n\n const res = await fetch(apiUrl(`/v1/rest/threads?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load threads (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestThread[];\n}\n\nexport async function fetchThreadMessages(threadId: string) {\n const graphParams = new URLSearchParams();\n graphParams.set('threadId', threadId);\n graphParams.set('limit', '500');\n\n try {\n const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (graphRes.ok) {\n const graphData = await graphRes.json();\n if (Array.isArray(graphData)) {\n return graphData as RestMessage[];\n }\n if (Array.isArray(graphData?.data)) {\n return graphData.data as RestMessage[];\n }\n return [];\n }\n\n // Only fall back for endpoint absence or gateway errors. For other failures,\n // preserve the real error instead of silently switching stores.\n if (![404, 405, 501, 502, 503, 504].includes(graphRes.status)) {\n const errorText = await graphRes.text().catch(() => graphRes.statusText);\n throw new Error(errorText || `Failed to load graph thread messages (${graphRes.status})`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : '';\n if (!/Failed to fetch/i.test(message)) {\n throw error;\n }\n }\n\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n params.set('sort', 'createdAt:asc');\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load thread messages (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestMessage[];\n}\n\nexport async function updateThread(threadId: string, updates: Partial<RestThread>) {\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'PUT',\n headers: withAuthHeaders({ 'Content-Type': 'application/json', Accept: 'application/json' }),\n body: JSON.stringify(updates),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to update thread (${res.status})`);\n }\n\n const data = await res.json();\n return data?.body ?? data;\n}\n\nexport async function deleteMessagesByThreadId(threadId: string) {\n const graphParams = new URLSearchParams();\n graphParams.set('threadId', threadId);\n\n try {\n const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!graphRes.ok && ![404, 405, 501].includes(graphRes.status)) {\n const errorText = await graphRes.text().catch(() => graphRes.statusText);\n throw new Error(errorText || `Failed to delete graph messages (${graphRes.status})`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : '';\n if (!/Failed to fetch/i.test(message)) {\n throw error;\n }\n }\n\n // First fetch all messages for the thread (no field selection to avoid issues)\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n // If we can't fetch messages, we can't delete them - but this might be ok if there are none\n console.warn('Could not fetch messages for deletion:', res.status);\n return;\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data) || data.length === 0) {\n return; // No messages to delete\n }\n\n // Delete each message sequentially to avoid overwhelming the server\n for (const msg of data) {\n if (msg?.id) {\n try {\n await fetch(apiUrl(`/v1/rest/messages/${msg.id}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n } catch {\n // Ignore individual message delete errors\n }\n }\n }\n}\n\nexport async function deleteThread(threadId: string) {\n // First delete all messages in the thread to avoid foreign key constraint\n await deleteMessagesByThreadId(threadId);\n\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to delete thread (${res.status})`);\n }\n\n return true;\n}\n\nexport const copilotzService = {\n runCopilotzStream,\n fetchThreads,\n fetchThreadMessages,\n updateThread,\n deleteThread,\n};\n","// Minimal API client for Copilotz assets\n\ntype FetchAssetResult = {\n assetId: string;\n ref: string;\n dataUrl?: string;\n base64?: string;\n mime?: string;\n error?: string;\n};\n\nconst rawBaseValue = (import.meta as { env?: Record<string, string | undefined> }).env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst extractAssetId = (refOrId: string) =>\n refOrId.startsWith('asset://') ? refOrId.slice('asset://'.length) : refOrId;\n\nexport async function getAssetDataUrl(refOrId: string): Promise<{ dataUrl: string; mime?: string; assetId: string }> {\n const id = extractAssetId(refOrId);\n const res = await fetch(apiUrl(`/v1/assets/${encodeURIComponent(id)}?format=dataUrl`), {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => res.statusText);\n throw new Error(text || `Failed to fetch asset ${refOrId}`);\n }\n const data = (await res.json()) as FetchAssetResult;\n if (!data?.dataUrl) {\n throw new Error(data?.error || `Asset ${refOrId} has no dataUrl`);\n }\n return { dataUrl: data.dataUrl, mime: data.mime, assetId: data.assetId };\n}\n\n// Resolve assets in messages by replacing metadata.attachments[].assetRef with dataUrl\ntype WithMetadata = {\n metadata?: Record<string, unknown> | null;\n};\n\nexport async function resolveAssetsInMessages<T extends WithMetadata>(messages: T[]): Promise<T[]> {\n // Deduplicate in-flight fetches so the same assetRef is resolved only once.\n const inFlightByRef = new Map<string, Promise<{ dataUrl: string; mime?: string; assetId: string }>>();\n\n const resolveAssetRef = (assetRef: string) => {\n if (!inFlightByRef.has(assetRef)) {\n inFlightByRef.set(assetRef, getAssetDataUrl(assetRef));\n }\n return inFlightByRef.get(assetRef)!;\n };\n\n return Promise.all(messages.map(async (msg) => {\n const meta = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachments = Array.isArray(meta?.attachments)\n ? (meta!.attachments as Array<Record<string, unknown>>)\n : undefined;\n\n if (!attachments || attachments.length === 0) {\n return msg;\n }\n\n const newAttachments = await Promise.all(attachments.map(async (att) => {\n const assetRef = typeof att?.assetRef === 'string' ? (att.assetRef as string) : undefined;\n if (!assetRef) return att;\n\n try {\n const { dataUrl, mime } = await resolveAssetRef(assetRef);\n const kind = typeof att.kind === 'string' ? (att.kind as string) : 'image';\n return {\n kind,\n dataUrl,\n mimeType: typeof att.mimeType === 'string' ? att.mimeType : (mime ?? undefined),\n } as Record<string, unknown>;\n } catch {\n // If fetching fails, keep original so UI can ignore gracefully\n return att;\n }\n }));\n\n const newMeta = { ...(meta ?? {}), attachments: newAttachments } as Record<string, unknown>;\n return { ...msg, metadata: newMeta };\n }));\n}\n\n","import { useState, useEffect, useCallback, useRef } from 'react';\n\n/**\n * Configuration for URL parameter names\n */\nexport interface UrlParamsConfig {\n /** URL param name for thread ID (default: 'thread') */\n thread?: string;\n /** URL param name for agent ID (default: 'agent') */\n agent?: string;\n /** URL param name for initial prompt (default: 'prompt') */\n prompt?: string;\n}\n\n/**\n * URL sync behavior configuration\n */\nexport interface UrlSyncConfig {\n /** Enable/disable URL sync (default: true) */\n enabled?: boolean;\n /** \n * How to update the URL when state changes:\n * - 'push': Creates browser history entries (back button works)\n * - 'replace': Updates URL without history entries (default)\n * - 'read-only': Only reads from URL, never writes\n */\n mode?: 'push' | 'replace' | 'read-only';\n /** Custom parameter names */\n params?: UrlParamsConfig;\n /**\n * Behavior for the prompt parameter:\n * - 'prefill': Pre-fills the input field (default)\n * - 'auto-send': Automatically sends the message on load\n */\n promptBehavior?: 'prefill' | 'auto-send';\n /**\n * Whether to clear the prompt param from URL after reading\n * Prevents re-sending on refresh (default: true)\n */\n clearPromptAfterRead?: boolean;\n}\n\n/**\n * State values parsed from URL\n */\nexport interface UrlState {\n threadId: string | null;\n agentId: string | null;\n prompt: string | null;\n}\n\n/**\n * Return type of useUrlState hook\n */\nexport interface UseUrlStateReturn {\n /** Current state parsed from URL */\n state: UrlState;\n /** Update thread ID in URL */\n setThreadId: (threadId: string | null) => void;\n /** Update agent ID in URL */\n setAgentId: (agentId: string | null) => void;\n /** Clear prompt from URL (call after consuming it) */\n clearPrompt: () => void;\n /** Whether URL sync is enabled */\n isEnabled: boolean;\n}\n\nconst DEFAULT_PARAMS: Required<UrlParamsConfig> = {\n thread: 'thread',\n agent: 'agent',\n prompt: 'prompt',\n};\n\n/**\n * Check if we're in a browser environment\n */\nconst isBrowser = typeof globalThis !== 'undefined' && typeof globalThis.location !== 'undefined';\n\n/**\n * Get current URL search params (SSR-safe)\n */\nconst getSearchParams = (): URLSearchParams => {\n if (!isBrowser) return new URLSearchParams();\n return new URLSearchParams(globalThis.location.search);\n};\n\n/**\n * Update URL with new search params\n */\nconst updateUrl = (params: URLSearchParams, mode: 'push' | 'replace') => {\n if (!isBrowser) return;\n \n const url = new URL(globalThis.location.href);\n url.search = params.toString();\n \n if (mode === 'push') {\n globalThis.history.pushState({}, '', url.toString());\n } else {\n globalThis.history.replaceState({}, '', url.toString());\n }\n};\n\n/**\n * Hook to manage chat state persistence via URL parameters.\n * \n * Supports:\n * - Thread ID: Navigate to specific conversation\n * - Agent ID: Pre-select an agent\n * - Prompt: Pre-fill or auto-send a message\n * \n * @example\n * ```tsx\n * const { state, setThreadId, setAgentId } = useUrlState({\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * });\n * \n * // Read initial values\n * console.log(state.threadId, state.agentId, state.prompt);\n * \n * // Update URL when thread changes\n * setThreadId('abc123');\n * ```\n */\nexport function useUrlState(config: UrlSyncConfig = {}): UseUrlStateReturn {\n const {\n enabled = true,\n mode = 'replace',\n params: userParams = {},\n clearPromptAfterRead = true,\n } = config;\n\n const params = { ...DEFAULT_PARAMS, ...userParams };\n const isReadOnly = mode === 'read-only';\n const updateMode = mode === 'read-only' ? 'replace' : mode;\n\n // Track if initial read has been done\n const initialReadDone = useRef(false);\n const promptCleared = useRef(false);\n\n // Parse initial state from URL\n const parseUrlState = useCallback((): UrlState => {\n if (!enabled || !isBrowser) {\n return { threadId: null, agentId: null, prompt: null };\n }\n\n const searchParams = getSearchParams();\n \n return {\n threadId: searchParams.get(params.thread) || null,\n agentId: searchParams.get(params.agent) || null,\n prompt: promptCleared.current ? null : (searchParams.get(params.prompt) || null),\n };\n }, [enabled, params.thread, params.agent, params.prompt]);\n\n const [state, setState] = useState<UrlState>(parseUrlState);\n\n // Read URL state on mount and handle popstate (back/forward navigation)\n useEffect(() => {\n if (!enabled || !isBrowser) return;\n\n // Initial read\n if (!initialReadDone.current) {\n const initialState = parseUrlState();\n setState(initialState);\n initialReadDone.current = true;\n\n // Clear prompt from URL after reading if configured\n if (clearPromptAfterRead && initialState.prompt && !isReadOnly) {\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n }\n }\n\n // Listen for popstate (browser back/forward)\n const handlePopState = () => {\n setState(parseUrlState());\n };\n\n globalThis.addEventListener('popstate', handlePopState);\n return () => globalThis.removeEventListener('popstate', handlePopState);\n }, [enabled, parseUrlState, clearPromptAfterRead, params.prompt, isReadOnly]);\n\n // Update thread ID in URL\n const setThreadId = useCallback((threadId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (threadId) {\n searchParams.set(params.thread, threadId);\n } else {\n searchParams.delete(params.thread);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, threadId }));\n }, [enabled, isReadOnly, params.thread, updateMode]);\n\n // Update agent ID in URL\n const setAgentId = useCallback((agentId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (agentId) {\n searchParams.set(params.agent, agentId);\n } else {\n searchParams.delete(params.agent);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, agentId }));\n }, [enabled, isReadOnly, params.agent, updateMode]);\n\n // Clear prompt from URL\n const clearPrompt = useCallback(() => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n setState(prev => ({ ...prev, prompt: null }));\n }, [enabled, isReadOnly, params.prompt]);\n\n return {\n state,\n setThreadId,\n setAgentId,\n clearPrompt,\n isEnabled: enabled,\n };\n}\n"],"mappings":"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","names":["useEffect","useState","forwardRef","createElement","useState","useCallback","useRef","useEffect","offset","payload","rawBaseValue","rawBase","normalizedBase","API_BASE","apiUrl","useState","useRef","useEffect","useCallback","sm","deleteThread","useState","useEffect"]}
1
+ {"version":3,"sources":["../src/CopilotzChat.tsx","../../node_modules/shared/src/utils.ts","../../node_modules/lucide-react/src/defaultAttributes.ts","../../node_modules/lucide-react/src/Icon.ts","../../node_modules/lucide-react/src/createLucideIcon.ts","../../node_modules/lucide-react/src/icons/user.ts","../src/useCopilotzChat.ts","../src/copilotzService.ts","../src/assetsService.ts","../src/useUrlState.ts"],"sourcesContent":["import React, { useMemo, useEffect, useState } from 'react';\nimport { ChatUI, ChatUserContextProvider } from '@copilotz/chat-ui';\nimport type { AgentOption, ChatConfig, ChatCallbacks, ChatUserContext, MemoryItem } from '@copilotz/chat-ui';\nimport { User } from 'lucide-react';\nimport { useCopilotz } from './useCopilotzChat';\nimport type { UrlSyncConfig } from './useUrlState';\nimport type { EventInterceptor, RenderSpecialState, RunErrorInterceptor } from './specialState';\n\nexport interface CopilotzChatProps {\n userId: string;\n authToken?: string | null;\n userName?: string;\n userAvatar?: string;\n userEmail?: string;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n config?: ChatConfig;\n callbacks?: Partial<ChatCallbacks>;\n /**\n * Custom component to render in the right sidebar panel (e.g. Profile info).\n * Can be:\n * - A React node (static)\n * - A function receiving context: `(context) => ReactNode`\n * - A render function receiving panel props: `(props: { onClose, isMobile }) => ReactNode`\n * Toggle visibility via the header button.\n */\n customComponent?: \n | React.ReactNode \n | ((context: ChatUserContext) => React.ReactNode)\n | ((props: { onClose: () => void; isMobile: boolean }) => React.ReactNode);\n onToolOutput?: (output: Record<string, unknown>) => void;\n /** Called when user clicks logout in the user menu */\n onLogout?: () => void;\n /** Called when user clicks \"View Profile\" in the user menu */\n onViewProfile?: () => void;\n /** Called when user adds a memory */\n onAddMemory?: (content: string, category?: MemoryItem['category']) => void;\n /** Called when user updates a memory */\n onUpdateMemory?: (memoryId: string, content: string) => void;\n /** Called when user deletes a memory */\n onDeleteMemory?: (memoryId: string) => void;\n /** Empty-state suggestions */\n suggestions?: string[];\n /** Agent selector data (built-in ChatUI) */\n agentOptions?: AgentOption[];\n selectedAgentId?: string | null;\n onSelectAgent?: (agentId: string) => void;\n className?: string;\n eventInterceptor?: EventInterceptor;\n runErrorInterceptor?: RunErrorInterceptor;\n renderSpecialState?: RenderSpecialState;\n /**\n * URL state synchronization configuration.\n * When enabled, syncs thread ID, agent, and prompt to/from URL parameters.\n * \n * Features:\n * - `?thread=abc123` - Opens specific thread\n * - `?agent=support-bot` - Pre-selects agent\n * - `?prompt=Hello` - Pre-fills or auto-sends message\n * \n * @example\n * ```tsx\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{ enabled: true }}\n * />\n * \n * // With custom param names\n * <CopilotzChat\n * userId=\"user123\"\n * urlSync={{\n * enabled: true,\n * params: { thread: 't', agent: 'a', prompt: 'q' },\n * promptBehavior: 'auto-send'\n * }}\n * />\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport const CopilotzChat: React.FC<CopilotzChatProps> = ({\n userId,\n authToken,\n userName,\n userAvatar,\n userEmail,\n initialContext,\n bootstrap,\n config: userConfig,\n callbacks: userCallbacks,\n customComponent,\n onToolOutput,\n onLogout,\n onViewProfile,\n onAddMemory,\n onUpdateMemory,\n onDeleteMemory,\n suggestions,\n agentOptions = [],\n selectedAgentId = null,\n onSelectAgent,\n className,\n eventInterceptor,\n runErrorInterceptor,\n renderSpecialState,\n urlSync,\n}) => {\n const selectedAgent = agentOptions.find((agent) => agent.id === selectedAgentId) || null;\n\n const {\n messages,\n isMessagesLoading,\n threads,\n currentThreadId,\n isStreaming,\n specialState,\n clearSpecialState,\n userContextSeed,\n sendMessage,\n createThread,\n selectThread,\n renameThread,\n archiveThread,\n deleteThread,\n stopGeneration,\n initialPrompt,\n clearInitialPrompt,\n urlAgentId,\n setUrlAgentId,\n } = useCopilotz({ \n userId, \n authToken,\n initialContext, \n bootstrap, \n defaultThreadName: userConfig?.labels?.defaultThreadName,\n onToolOutput,\n preferredAgentName: selectedAgent?.name ?? null,\n eventInterceptor,\n runErrorInterceptor,\n urlSync,\n });\n\n // Track if we've handled the initial prompt\n const [promptHandled, setPromptHandled] = useState(false);\n\n // Handle URL agent ID - call onSelectAgent if URL has agent and it differs from current\n useEffect(() => {\n if (urlAgentId && onSelectAgent && urlAgentId !== selectedAgentId) {\n // Check if the agent exists in options\n const agentExists = agentOptions.some((a) => a.id === urlAgentId);\n if (agentExists) {\n onSelectAgent(urlAgentId);\n }\n }\n }, [urlAgentId, selectedAgentId, onSelectAgent, agentOptions]);\n\n // Sync selected agent to URL when it changes (after initial load)\n useEffect(() => {\n if (selectedAgentId && urlSync?.enabled) {\n setUrlAgentId(selectedAgentId);\n }\n }, [selectedAgentId, urlSync?.enabled, setUrlAgentId]);\n\n // Handle auto-send behavior for initial prompt\n useEffect(() => {\n if (initialPrompt && !promptHandled && urlSync?.promptBehavior === 'auto-send') {\n // Wait for initial load to complete\n const timer = setTimeout(() => {\n void sendMessage(initialPrompt);\n clearInitialPrompt();\n setPromptHandled(true);\n }, 500);\n return () => clearTimeout(timer);\n }\n }, [initialPrompt, promptHandled, urlSync?.promptBehavior, sendMessage, clearInitialPrompt]);\n\n // For prefill behavior, we'll pass initialInput to ChatUI\n\n const chatCallbacks: ChatCallbacks = useMemo(() => ({\n onSendMessage: (content, attachments) => {\n void sendMessage(content, attachments);\n userCallbacks?.onSendMessage?.(content, attachments);\n },\n onStopGeneration: () => {\n stopGeneration();\n userCallbacks?.onStopGeneration?.();\n },\n onCreateThread: (title) => {\n createThread(title);\n userCallbacks?.onCreateThread?.(title);\n },\n onSelectThread: (threadId) => {\n void selectThread(threadId);\n userCallbacks?.onSelectThread?.(threadId);\n },\n onRenameThread: (threadId, newTitle) => {\n void renameThread(threadId, newTitle);\n userCallbacks?.onRenameThread?.(threadId, newTitle);\n },\n onArchiveThread: (threadId) => {\n void archiveThread(threadId);\n userCallbacks?.onArchiveThread?.(threadId);\n },\n onDeleteThread: (threadId) => {\n void deleteThread(threadId);\n userCallbacks?.onDeleteThread?.(threadId);\n },\n onCopyMessage: async (messageId, content) => {\n try {\n await navigator.clipboard.writeText(content);\n userCallbacks?.onCopyMessage?.(messageId, content);\n } catch (error) {\n console.error('Failed to copy message', error);\n }\n },\n // User menu callbacks\n onLogout,\n onViewProfile,\n ...userCallbacks,\n }), [sendMessage, stopGeneration, createThread, selectThread, renameThread, archiveThread, deleteThread, userCallbacks, onLogout, onViewProfile]);\n\n // Merge user config with dynamic values\n // customComponent is passed through - it will be resolved in ChatUI\n // which can provide onClose and isMobile props\n const mergedConfig: ChatConfig = useMemo(() => {\n const base = userConfig || {};\n if (!customComponent) {\n return base;\n }\n return {\n ...base,\n customComponent: {\n ...base.customComponent,\n component: customComponent,\n icon: base.customComponent?.icon || <User className=\"h-6 w-6\" />,\n },\n };\n }, [userConfig, customComponent]);\n\n const effectiveUserName = userName || userId;\n // Don't try to extract avatar from profile automatically unless it's in context\n const effectiveUserAvatar = userAvatar;\n const specialStateContent = specialState ? renderSpecialState?.(specialState, { clear: clearSpecialState }) : null;\n\n return (\n <ChatUserContextProvider initial={userContextSeed}>\n {specialStateContent ?? (\n <ChatUI\n messages={messages}\n isMessagesLoading={isMessagesLoading}\n threads={threads}\n currentThreadId={currentThreadId}\n config={mergedConfig}\n callbacks={chatCallbacks}\n isGenerating={isStreaming}\n suggestions={suggestions}\n agentOptions={agentOptions}\n selectedAgentId={selectedAgentId}\n onSelectAgent={onSelectAgent}\n user={{\n id: userId,\n name: effectiveUserName,\n email: userEmail,\n avatar: effectiveUserAvatar,\n }}\n assistant={{\n name: userConfig?.branding?.title,\n avatar: userConfig?.branding?.avatar,\n description: userConfig?.branding?.subtitle,\n }}\n onAddMemory={onAddMemory}\n onUpdateMemory={onUpdateMemory}\n onDeleteMemory={onDeleteMemory}\n className={className}\n // Pass initial prompt for prefill behavior (not auto-send)\n initialInput={\n initialPrompt && !promptHandled && urlSync?.promptBehavior !== 'auto-send'\n ? initialPrompt\n : undefined\n }\n onInitialInputConsumed={() => {\n clearInitialPrompt();\n setPromptHandled(true);\n }}\n />\n )}\n </ChatUserContextProvider>\n );\n};\n","import { CamelToPascal } from './utility-types';\n\n/**\n * Converts string to kebab case\n *\n * @param {string} string\n * @returns {string} A kebabized string\n */\nexport const toKebabCase = (string: string) =>\n string.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n\n/**\n * Converts string to camel case\n *\n * @param {string} string\n * @returns {string} A camelized string\n */\nexport const toCamelCase = <T extends string>(string: T) =>\n string.replace(/^([A-Z])|[\\s-_]+(\\w)/g, (match, p1, p2) =>\n p2 ? p2.toUpperCase() : p1.toLowerCase(),\n );\n\n/**\n * Converts string to pascal case\n *\n * @param {string} string\n * @returns {string} A pascalized string\n */\nexport const toPascalCase = <T extends string>(string: T): CamelToPascal<T> => {\n const camelCase = toCamelCase(string);\n\n return (camelCase.charAt(0).toUpperCase() + camelCase.slice(1)) as CamelToPascal<T>;\n};\n\n/**\n * Merges classes into a single string\n *\n * @param {array} classes\n * @returns {string} A string of classes\n */\nexport const mergeClasses = <ClassType = string | undefined | null>(...classes: ClassType[]) =>\n classes\n .filter((className, index, array) => {\n return (\n Boolean(className) &&\n (className as string).trim() !== '' &&\n array.indexOf(className) === index\n );\n })\n .join(' ')\n .trim();\n\n/**\n * Is empty string\n *\n * @param {unknown} value\n * @returns {boolean} Whether the value is an empty string\n */\nexport const isEmptyString = (value: unknown): boolean => value === '';\n\n/**\n * Check if a component has an accessibility prop\n *\n * @param {object} props\n * @returns {boolean} Whether the component has an accessibility prop\n */\nexport const hasA11yProp = (props: Record<string, any>) => {\n for (const prop in props) {\n if (prop.startsWith('aria-') || prop === 'role' || prop === 'title') {\n return true;\n }\n }\n};\n","export default {\n xmlns: 'http://www.w3.org/2000/svg',\n width: 24,\n height: 24,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n};\n","import { createElement, forwardRef } from 'react';\nimport defaultAttributes from './defaultAttributes';\nimport { IconNode, LucideProps } from './types';\nimport { mergeClasses, hasA11yProp } from '@lucide/shared';\n\ninterface IconComponentProps extends LucideProps {\n iconNode: IconNode;\n}\n\n/**\n * Lucide icon component\n *\n * @component Icon\n * @param {object} props\n * @param {string} props.color - The color of the icon\n * @param {number} props.size - The size of the icon\n * @param {number} props.strokeWidth - The stroke width of the icon\n * @param {boolean} props.absoluteStrokeWidth - Whether to use absolute stroke width\n * @param {string} props.className - The class name of the icon\n * @param {IconNode} props.children - The children of the icon\n * @param {IconNode} props.iconNode - The icon node of the icon\n *\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst Icon = forwardRef<SVGSVGElement, IconComponentProps>(\n (\n {\n color = 'currentColor',\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = '',\n children,\n iconNode,\n ...rest\n },\n ref,\n ) =>\n createElement(\n 'svg',\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? (Number(strokeWidth) * 24) / Number(size) : strokeWidth,\n className: mergeClasses('lucide', className),\n ...(!children && !hasA11yProp(rest) && { 'aria-hidden': 'true' }),\n ...rest,\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...(Array.isArray(children) ? children : [children]),\n ],\n ),\n);\n\nexport default Icon;\n","import { createElement, forwardRef } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from '@lucide/shared';\nimport { IconNode, LucideProps } from './types';\nimport Icon from './Icon';\n\n/**\n * Create a Lucide icon component\n * @param {string} iconName\n * @param {array} iconNode\n * @returns {ForwardRefExoticComponent} LucideIcon\n */\nconst createLucideIcon = (iconName: string, iconNode: IconNode) => {\n const Component = forwardRef<SVGSVGElement, LucideProps>(({ className, ...props }, ref) =>\n createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className,\n ),\n ...props,\n }),\n );\n\n Component.displayName = toPascalCase(iconName);\n\n return Component;\n};\n\nexport default createLucideIcon;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2', key: '975kel' }],\n ['circle', { cx: '12', cy: '7', r: '4', key: '17ys0d' }],\n];\n\n/**\n * @component @name User\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cGF0aCBkPSJNMTkgMjF2LTJhNCA0IDAgMCAwLTQtNEg5YTQgNCAwIDAgMC00IDR2MiIgLz4KICA8Y2lyY2xlIGN4PSIxMiIgY3k9IjciIHI9IjQiIC8+Cjwvc3ZnPgo=) - https://lucide.dev/icons/user\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst User = createLucideIcon('user', __iconNode);\n\nexport default User;\n","// deno-lint-ignore-file no-explicit-any\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport { runCopilotzStream, fetchThreads, fetchThreadMessages, updateThread as updateThreadApi, deleteThread as deleteThreadApi } from './copilotzService';\nimport { resolveAssetsInMessages } from './assetsService';\nimport type { ChatMessage as ChatViewMessage, ChatThread, MediaAttachment, ChatUserContext } from '@copilotz/chat-ui';\nimport { useUrlState, type UrlSyncConfig } from './useUrlState';\nimport type { EventInterceptor, RunErrorInterceptor, SpecialChatState } from './specialState';\n\nconst nowTs = () => Date.now();\nconst generateId = () =>\n (globalThis.crypto?.randomUUID?.() ?? `id-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`) as string;\nconst isAbortError = (error: unknown) => (\n error instanceof DOMException && error.name === 'AbortError'\n) || (typeof error === 'object' && error !== null && 'name' in error && (error as { name?: string }).name === 'AbortError');\nconst getEventPayload = (event: any) => event?.payload ?? event;\nconst getEventSenderType = (payload: any): string | undefined => payload?.senderType || payload?.sender?.type;\n\ntype ServerThread = Awaited<ReturnType<typeof fetchThreads>>[number];\ntype ServerMessage = Awaited<ReturnType<typeof fetchThreadMessages>>[number];\n\ntype ToolCallStatus = 'pending' | 'running' | 'completed' | 'failed';\ntype ParsedToolCall = {\n id?: string;\n name: string;\n arguments: Record<string, unknown>;\n status: ToolCallStatus;\n result?: unknown;\n};\n\ntype ToolResultUpdate = {\n id?: string;\n name?: string;\n status: ToolCallStatus;\n result?: unknown;\n endTime: number;\n};\n\nconst normalizeToolStatus = (status: unknown): ToolCallStatus => {\n if (status === 'pending') return 'pending';\n if (status === 'running' || status === 'processing') return 'running';\n if (status === 'failed') return 'failed';\n return 'completed';\n};\n\nconst parseToolArguments = (value: unknown): Record<string, unknown> => {\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n return value as Record<string, unknown>;\n }\n if (typeof value === 'string') {\n try {\n const parsed = JSON.parse(value);\n if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // Ignore invalid JSON and fall through to empty args.\n }\n }\n return {};\n};\n\nconst extractToolCallsFromServerMessage = (msg: ServerMessage): ParsedToolCall[] => {\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const topLevelToolCalls = Array.isArray((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls)\n ? ((msg as unknown as { toolCalls?: Array<Record<string, unknown>> }).toolCalls || [])\n : [];\n const metadataToolCalls = Array.isArray(metadata?.toolCalls)\n ? (metadata.toolCalls as Array<Record<string, unknown>>)\n : [];\n\n const usedMetadataIndexes = new Set<number>();\n const parsed: ParsedToolCall[] = [];\n\n const findMatchingMetadataIndex = (toolCall: Record<string, unknown>): number => {\n const id = typeof toolCall.id === 'string' ? toolCall.id : undefined;\n const name = typeof toolCall.name === 'string' ? toolCall.name : undefined;\n\n const byId = id\n ? metadataToolCalls.findIndex((candidate, idx) => !usedMetadataIndexes.has(idx) && candidate?.id === id)\n : -1;\n if (byId >= 0) return byId;\n\n return name\n ? metadataToolCalls.findIndex((candidate, idx) => !usedMetadataIndexes.has(idx) && candidate?.name === name)\n : -1;\n };\n\n const parseToolCall = (\n primary: Record<string, unknown>,\n secondary?: Record<string, unknown>,\n ): ParsedToolCall => {\n const id = typeof primary.id === 'string'\n ? primary.id\n : (typeof secondary?.id === 'string' ? secondary.id : undefined);\n const name = typeof primary.name === 'string'\n ? primary.name\n : (typeof secondary?.name === 'string' ? secondary.name : 'tool');\n const argsRaw =\n primary.args ?? primary.arguments ?? secondary?.args ?? secondary?.arguments;\n const result =\n primary.output !== undefined\n ? primary.output\n : primary.result !== undefined\n ? primary.result\n : secondary?.output !== undefined\n ? secondary.output\n : secondary?.result;\n const status = normalizeToolStatus(primary.status ?? secondary?.status);\n\n return {\n ...(id ? { id } : {}),\n name,\n arguments: parseToolArguments(argsRaw),\n ...(result !== undefined ? { result } : {}),\n status,\n };\n };\n\n topLevelToolCalls.forEach((toolCall) => {\n const metadataIndex = findMatchingMetadataIndex(toolCall);\n const metadataCall = metadataIndex >= 0 ? metadataToolCalls[metadataIndex] : undefined;\n if (metadataIndex >= 0) usedMetadataIndexes.add(metadataIndex);\n parsed.push(parseToolCall(toolCall, metadataCall));\n });\n\n metadataToolCalls.forEach((toolCall, index) => {\n if (usedMetadataIndexes.has(index)) return;\n parsed.push(parseToolCall(toolCall));\n });\n\n return parsed;\n};\n\nconst extractToolResultUpdateFromMessage = (msg: ServerMessage): ToolResultUpdate | null => {\n if (msg.senderType !== 'tool') return null;\n\n const toolCalls = extractToolCallsFromServerMessage(msg);\n if (!Array.isArray(toolCalls) || toolCalls.length === 0) return null;\n\n const firstToolCall = toolCalls[0];\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const fallbackResult = metadata?.output;\n const result = firstToolCall.result !== undefined ? firstToolCall.result : fallbackResult;\n\n return {\n ...(firstToolCall.id ? { id: firstToolCall.id } : {}),\n ...(firstToolCall.name ? { name: firstToolCall.name } : {}),\n ...(result !== undefined ? { result } : {}),\n status: firstToolCall.status,\n endTime: msg.createdAt ? new Date(msg.createdAt).getTime() : nowTs(),\n };\n};\n\nconst mergePersistedToolResults = (\n messages: ChatViewMessage[],\n updates: ToolResultUpdate[],\n): ChatViewMessage[] => {\n if (updates.length === 0) return messages;\n\n const nextMessages = [...messages];\n\n for (const update of updates) {\n for (let i = nextMessages.length - 1; i >= 0; i--) {\n const message = nextMessages[i];\n if (message.role !== 'assistant' || !Array.isArray(message.toolCalls) || message.toolCalls.length === 0) {\n continue;\n }\n\n const toolCalls = message.toolCalls;\n\n let toolCallIndex = update.id\n ? toolCalls.findIndex((toolCall) => toolCall.id === update.id)\n : -1;\n\n if (toolCallIndex === -1 && update.name) {\n toolCallIndex = toolCalls.findIndex((toolCall) => (\n toolCall.name === update.name &&\n (toolCall.status === 'pending' || toolCall.status === 'running' || typeof toolCall.result === 'undefined')\n ));\n }\n\n if (toolCallIndex === -1) continue;\n\n const updatedToolCalls = [...toolCalls];\n const current = updatedToolCalls[toolCallIndex];\n updatedToolCalls[toolCallIndex] = {\n ...current,\n status: update.status,\n ...(update.result !== undefined ? { result: update.result } : {}),\n endTime: update.endTime,\n };\n\n nextMessages[i] = {\n ...message,\n toolCalls: updatedToolCalls,\n };\n break;\n }\n }\n\n return nextMessages;\n};\n\nconst convertServerMessage = (msg: ServerMessage): ChatViewMessage => {\n const timestamp = msg.createdAt ? new Date(msg.createdAt).getTime() : nowTs();\n const metadata = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachmentsMeta = Array.isArray(metadata?.attachments)\n ? (metadata!.attachments as Array<Record<string, unknown>>)\n : [];\n\n const attachments: MediaAttachment[] = attachmentsMeta.flatMap((att) => {\n const kind = typeof att.kind === 'string' ? att.kind : undefined;\n const dataUrl = typeof att.dataUrl === 'string' ? att.dataUrl : undefined;\n const mimeType = typeof att.mimeType === 'string' ? att.mimeType : undefined;\n if (!dataUrl) return [];\n\n if (kind === 'image') {\n return [{ kind: 'image', dataUrl, mimeType: mimeType ?? 'image/jpeg' }] as MediaAttachment[];\n }\n if (kind === 'audio') {\n return [{\n kind: 'audio',\n dataUrl,\n mimeType: mimeType ?? 'audio/webm',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n }] as MediaAttachment[];\n }\n if (kind === 'video') {\n return [{\n kind: 'video',\n dataUrl,\n mimeType: mimeType ?? 'video/mp4',\n durationMs: typeof att.durationMs === 'number' ? att.durationMs : undefined,\n poster: typeof att.poster === 'string' ? att.poster : undefined,\n }] as MediaAttachment[];\n }\n return [] as MediaAttachment[];\n });\n\n const role = msg.senderType === 'agent'\n ? 'assistant'\n : msg.senderType === 'user'\n ? 'user'\n : 'assistant';\n\n const parsedToolCalls = extractToolCallsFromServerMessage(msg);\n const mappedToolCalls = parsedToolCalls.map((toolCall) => ({\n id: toolCall.id ?? generateId(),\n name: toolCall.name,\n arguments: toolCall.arguments,\n status: toolCall.status,\n ...(toolCall.result !== undefined ? { result: toolCall.result } : {}),\n }));\n\n const hasToolCalls = mappedToolCalls.length > 0;\n const isToolSender = msg.senderType === 'tool';\n const content =\n isToolSender\n ? '' // Do not render textual content for tool messages; attachments only\n : ((msg.content ?? '') || (hasToolCalls ? '' : ''));\n\n return {\n id: msg.id,\n role,\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isStreaming: false,\n isComplete: true,\n metadata,\n toolCalls: hasToolCalls ? mappedToolCalls : undefined,\n };\n};\n\nexport interface UseCopilotzOptions {\n userId: string | null;\n authToken?: string | null;\n initialContext?: ChatUserContext;\n bootstrap?: {\n initialMessage?: string;\n initialToolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n };\n defaultThreadName?: string;\n onToolOutput?: (output: Record<string, unknown>) => void;\n preferredAgentName?: string | null;\n eventInterceptor?: EventInterceptor;\n runErrorInterceptor?: RunErrorInterceptor;\n /**\n * URL state synchronization configuration.\n * When enabled, thread ID and agent are synced to/from URL parameters.\n * \n * @example\n * ```tsx\n * const chat = useCopilotz({\n * userId: 'user123',\n * urlSync: {\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * }\n * });\n * ```\n */\n urlSync?: UrlSyncConfig;\n}\n\nexport function useCopilotz({\n userId,\n authToken,\n initialContext,\n bootstrap,\n defaultThreadName,\n onToolOutput,\n preferredAgentName,\n eventInterceptor,\n runErrorInterceptor,\n urlSync,\n}: UseCopilotzOptions) {\n // URL state management\n const {\n state: urlState,\n setThreadId: setUrlThreadId,\n setAgentId: setUrlAgentId,\n clearPrompt: clearUrlPrompt,\n isEnabled: isUrlSyncEnabled,\n } = useUrlState(urlSync);\n\n const [threads, setThreads] = useState<ChatThread[]>([]);\n const [threadMetadataMap, setThreadMetadataMap] = useState<Record<string, Record<string, unknown> | undefined>>({});\n const [threadExternalIdMap, setThreadExternalIdMap] = useState<Record<string, string | null>>({});\n\n const [currentThreadId, setCurrentThreadId] = useState<string | null>(null);\n const [currentThreadExternalId, setCurrentThreadExternalId] = useState<string | null>(null);\n\n const [messages, setMessages] = useState<ChatViewMessage[]>([]);\n const [isMessagesLoading, setIsMessagesLoading] = useState(false);\n const [isStreaming, setIsStreaming] = useState(false);\n const [specialState, setSpecialState] = useState<SpecialChatState | null>(null);\n\n const [userContextSeed, setUserContextSeed] = useState<Partial<ChatUserContext>>(initialContext || {});\n const preferredAgentRef = useRef<string | null>(preferredAgentName ?? null);\n\n // Refs to hold latest state for callbacks to avoid dependency cycles\n // Using direct assignment pattern instead of useEffect for better performance\n const threadsRef = useRef(threads);\n const threadMetadataMapRef = useRef(threadMetadataMap);\n const threadExternalIdMapRef = useRef(threadExternalIdMap);\n const currentThreadIdRef = useRef(currentThreadId);\n const currentThreadExternalIdRef = useRef(currentThreadExternalId);\n const userContextSeedRef = useRef(userContextSeed);\n\n // Sync refs on every render (more efficient than multiple useEffects)\n threadsRef.current = threads;\n threadMetadataMapRef.current = threadMetadataMap;\n threadExternalIdMapRef.current = threadExternalIdMap;\n currentThreadIdRef.current = currentThreadId;\n currentThreadExternalIdRef.current = currentThreadExternalId;\n userContextSeedRef.current = userContextSeed;\n preferredAgentRef.current = preferredAgentName ?? null;\n\n const abortControllerRef = useRef<AbortController | null>(null);\n const messagesRequestRef = useRef<number>(0);\n // Guard to prevent double initialization in StrictMode\n const initializationRef = useRef<{ userId: string | null; started: boolean }>({ userId: null, started: false });\n\n useEffect(() => {\n if (initialContext) {\n setUserContextSeed((prev) => ({ ...prev, ...initialContext }));\n }\n }, [initialContext]);\n\n const processToolOutput = useCallback((output: Record<string, unknown>) => {\n if (!output) return;\n\n const contextPatch: Partial<ChatUserContext> = {};\n\n // Generic merge of userContext from output if present\n if (output.userContext && typeof output.userContext === 'object') {\n Object.assign(contextPatch, output.userContext as Partial<ChatUserContext>);\n }\n\n if (Object.keys(contextPatch).length > 0) {\n setUserContextSeed((prev) => ({ ...prev, ...contextPatch }));\n }\n\n onToolOutput?.(output);\n }, [onToolOutput]);\n\n const clearSpecialState = useCallback(() => {\n setSpecialState(null);\n }, []);\n\n const applyEventInterceptor = useCallback((event: unknown) => {\n if (!eventInterceptor) return undefined;\n try {\n const result = eventInterceptor(event);\n if (result && typeof result === 'object' && result.specialState) {\n setSpecialState(result.specialState);\n }\n return result;\n } catch (error) {\n console.error('Error in Copilotz event interceptor', error);\n return undefined;\n }\n }, [eventInterceptor]);\n\n const getSpecialStateFromError = useCallback((error: unknown) => {\n if (!runErrorInterceptor) return null;\n try {\n return runErrorInterceptor(error) ?? null;\n } catch (interceptorError) {\n console.error('Error in Copilotz run error interceptor', interceptorError);\n return null;\n }\n }, [runErrorInterceptor]);\n\n const handleStreamMessageEvent = useCallback((event: any) => {\n const payload = getEventPayload(event);\n if (!payload) return;\n const senderType = getEventSenderType(payload);\n\n if (senderType === 'tool') {\n const metadata = (payload.metadata ?? event.metadata ?? {}) as Record<string, unknown>;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n\n // Attach tool call details to the current assistant bubble (expandable)\n const toolName = (metadata?.toolName as string) || (metadata?.tool as string) || 'tool';\n let argsObj: Record<string, unknown> = {};\n try {\n const argStr = (metadata?.arguments as string) ?? '{}';\n argsObj = typeof argStr === 'string' ? JSON.parse(argStr) : (argStr as Record<string, unknown>);\n } catch (_) { /* ignore parse */ }\n const resultObj = metadata?.output as unknown;\n const callId = (payload.toolCallId as string) || generateId();\n\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant') {\n const existing = Array.isArray(m.toolCalls) ? m.toolCalls : [];\n next[i] = {\n ...m,\n toolCalls: [\n ...existing,\n {\n id: callId,\n name: toolName,\n arguments: argsObj as Record<string, any>,\n result: resultObj,\n status: 'completed' as const,\n endTime: Date.now(),\n },\n ],\n };\n break;\n }\n }\n return next;\n });\n return;\n }\n\n if (senderType === 'agent' && typeof payload.content === 'string') {\n setMessages((prev) => {\n const next = [...prev];\n for (let i = next.length - 1; i >= 0; i--) {\n const m = next[i];\n if (m.role === 'assistant' && m.isStreaming) {\n next[i] = { ...m, content: payload.content, isStreaming: false, isComplete: true };\n return next;\n }\n }\n\n const trimmedContent = payload.content.trim();\n if (!trimmedContent) {\n return prev;\n }\n\n return [\n ...next,\n {\n id: generateId(),\n role: 'assistant',\n content: payload.content,\n timestamp: nowTs(),\n isStreaming: false,\n isComplete: true,\n metadata: (payload.metadata ?? undefined) as Record<string, unknown> | undefined,\n },\n ];\n });\n }\n }, [processToolOutput]);\n\n const updateThreadsState = useCallback((rawThreads: ServerThread[], preferredExternalId?: string | null) => {\n const metadataMap: Record<string, Record<string, unknown> | undefined> = {};\n const externalMap: Record<string, string | null> = {};\n\n const normalized = rawThreads.map((thread) => {\n metadataMap[thread.id] = thread.metadata ?? undefined;\n externalMap[thread.id] = thread.externalId ?? null;\n const updatedAt = thread.updatedAt ? new Date(thread.updatedAt).getTime() : nowTs();\n const createdAt = thread.createdAt ? new Date(thread.createdAt).getTime() : updatedAt;\n return {\n id: thread.id,\n title: thread.name || 'Chat',\n createdAt,\n updatedAt,\n messageCount: typeof thread.metadata?.messageCount === 'number'\n ? thread.metadata!.messageCount as number\n : 0,\n isArchived: thread.status === 'archived',\n metadata: thread.metadata ?? undefined,\n } as ChatThread;\n });\n\n setThreadMetadataMap(metadataMap);\n setThreadExternalIdMap(externalMap);\n setThreads(normalized);\n\n // Use refs to avoid dependency cycle\n const curExtId = currentThreadExternalIdRef.current;\n const curId = currentThreadIdRef.current;\n\n let nextThreadId: string | null = null;\n\n if (preferredExternalId) {\n const preferred = rawThreads.find((thread) => (thread.externalId ?? thread.id) === preferredExternalId);\n if (preferred) nextThreadId = preferred.id;\n }\n\n if (!nextThreadId && curExtId) {\n const match = rawThreads.find((thread) => (thread.externalId ?? thread.id) === curExtId);\n if (match) nextThreadId = match.id;\n }\n\n if (!nextThreadId && curId && rawThreads.some((thread) => thread.id === curId)) {\n nextThreadId = curId;\n }\n\n if (!nextThreadId && normalized.length > 0) {\n nextThreadId = normalized[0].id;\n }\n\n setCurrentThreadId(nextThreadId ?? null);\n setCurrentThreadExternalId(nextThreadId ? externalMap[nextThreadId] ?? null : null);\n\n return nextThreadId;\n }, []); // No dependencies needed now as we use refs for reading current state\n\n const fetchAndSetThreadsState = useCallback(async (uid: string, preferredExternalId?: string | null) => {\n try {\n const rawThreads = await fetchThreads(uid, authToken);\n return updateThreadsState(rawThreads, preferredExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error loading threads', error);\n return null;\n }\n }, [authToken, updateThreadsState]);\n\n const loadThreadMessages = useCallback(async (threadId: string) => {\n const requestId = messagesRequestRef.current + 1;\n messagesRequestRef.current = requestId;\n setIsMessagesLoading(true);\n try {\n const rawMessages = await fetchThreadMessages(threadId, authToken);\n const resolvedMessages = await resolveAssetsInMessages(rawMessages as unknown as any[]);\n if (messagesRequestRef.current !== requestId) return;\n\n resolvedMessages.forEach((msg: any) => {\n if (msg.senderType === 'tool') {\n const metadata = msg.metadata as Record<string, unknown> | undefined;\n const output = (metadata?.output ?? metadata) as Record<string, unknown> | undefined;\n if (output) processToolOutput(output);\n }\n });\n\n const toolResultUpdates = resolvedMessages\n .map((msg) => extractToolResultUpdateFromMessage(msg as unknown as ServerMessage))\n .filter((update): update is ToolResultUpdate => update !== null);\n\n const viewMessages = resolvedMessages\n .filter((msg) => {\n const text = (typeof msg.content === 'string' ? msg.content : '').trim();\n const hasText = text.length > 0;\n const hasToolCalls = extractToolCallsFromServerMessage(msg as unknown as ServerMessage).length > 0;\n const meta = (msg.metadata ?? {}) as Record<string, unknown>;\n const hasAttachments = Array.isArray(meta.attachments) && (meta.attachments as unknown[]).length > 0;\n // Keep tool messages only if they carry attachments (e.g., generated media)\n if (msg.senderType === 'tool') {\n return hasAttachments;\n }\n // For agent/user/system, keep if there is text, tool calls, or attachments\n return hasText || hasToolCalls || hasAttachments;\n })\n .map(convertServerMessage);\n\n const hydratedMessages = mergePersistedToolResults(viewMessages, toolResultUpdates);\n setMessages(hydratedMessages);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error(`Error loading messages for thread ${threadId}`, error);\n } finally {\n if (messagesRequestRef.current === requestId) {\n setIsMessagesLoading(false);\n }\n }\n }, [authToken, processToolOutput]);\n\n const handleSelectThread = useCallback(async (threadId: string) => {\n setCurrentThreadId(threadId);\n setMessages([]);\n // Use ref for external map to avoid re-creation\n const extMap = threadExternalIdMapRef.current;\n setCurrentThreadExternalId(extMap[threadId] ?? null);\n await loadThreadMessages(threadId);\n }, [loadThreadMessages]);\n\n const handleCreateThread = useCallback((title?: string) => {\n messagesRequestRef.current += 1;\n setIsMessagesLoading(false);\n const id = generateId();\n const now = nowTs();\n const newThread: ChatThread = {\n id,\n title: title?.trim() || 'New Chat',\n createdAt: now,\n updatedAt: now,\n messageCount: 0,\n metadata: { pendingTitle: title?.trim() || undefined },\n };\n\n setThreads((prev) => [newThread, ...prev]);\n setThreadMetadataMap((prev) => ({ ...prev, [id]: { pendingTitle: title?.trim() || undefined } }));\n setThreadExternalIdMap((prev) => ({ ...prev, [id]: id }));\n setCurrentThreadId(id);\n setCurrentThreadExternalId(id);\n setMessages([]);\n }, []);\n\n const handleRenameThread = useCallback(async (threadId: string, newTitle: string) => {\n const trimmedTitle = newTitle.trim();\n if (!trimmedTitle) return;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, title: trimmedTitle, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread (not yet persisted)\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (isPlaceholder) {\n // Store title in metadata for when thread is created\n setThreadMetadataMap((prev) => ({\n ...prev,\n [threadId]: { ...prev[threadId], pendingTitle: trimmedTitle },\n }));\n } else {\n // Persist to backend\n try {\n await updateThreadApi(threadId, { name: trimmedTitle }, authToken);\n } catch (error) {\n console.error('Failed to rename thread:', error);\n // Revert on error - refetch threads\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [authToken, userId, fetchAndSetThreadsState]);\n\n const handleArchiveThread = useCallback(async (threadId: string) => {\n // Find current archive status\n const thread = threadsRef.current.find((t) => t.id === threadId);\n if (!thread) return;\n\n const newArchivedStatus = !thread.isArchived;\n\n // Update local state immediately\n setThreads((prev) =>\n prev.map((t) => (t.id === threadId ? { ...t, isArchived: newArchivedStatus, updatedAt: nowTs() } : t))\n );\n\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n if (!isPlaceholder) {\n try {\n await updateThreadApi(threadId, { status: newArchivedStatus ? 'archived' : 'active' }, authToken);\n } catch (error) {\n console.error('Failed to archive thread:', error);\n // Revert on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [authToken, userId, fetchAndSetThreadsState]);\n\n const handleDeleteThread = useCallback(async (threadId: string) => {\n // Check if this is a placeholder thread\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholder = extMap[threadId] === threadId;\n\n // Remove from local state immediately\n setThreads((prev) => prev.filter((t) => t.id !== threadId));\n setThreadMetadataMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n setThreadExternalIdMap((prev) => {\n const next = { ...prev };\n delete next[threadId];\n return next;\n });\n\n // If deleting current thread, switch to another\n if (currentThreadIdRef.current === threadId) {\n const remaining = threadsRef.current.filter((t) => t.id !== threadId);\n if (remaining.length > 0) {\n setCurrentThreadId(remaining[0].id);\n setCurrentThreadExternalId(extMap[remaining[0].id] ?? null);\n await loadThreadMessages(remaining[0].id);\n } else {\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n }\n }\n\n if (!isPlaceholder) {\n try {\n await deleteThreadApi(threadId, authToken);\n } catch (error) {\n console.error('Failed to delete thread:', error);\n // Refetch to restore state on error\n if (userId) {\n await fetchAndSetThreadsState(userId, currentThreadExternalIdRef.current);\n }\n }\n }\n }, [authToken, userId, fetchAndSetThreadsState, loadThreadMessages]);\n\n const handleStop = useCallback(() => {\n abortControllerRef.current?.abort();\n abortControllerRef.current = null;\n setIsStreaming(false);\n setMessages((prev) => {\n // Check if any message needs updating before creating new array\n const hasStreaming = prev.some((msg) => msg.isStreaming);\n if (!hasStreaming) return prev;\n return prev.map((msg) => (msg.isStreaming ? { ...msg, isStreaming: false, isComplete: true } : msg));\n });\n }, []);\n\n const handleStreamAssetEvent = useCallback((payload: any, assistantMessageId: string) => {\n // Handle ASSET_CREATED event from copilotz\n if (!payload?.dataUrl) return;\n\n const mimeType = payload.mime || 'image/png';\n const dataUrl = payload.dataUrl;\n\n // Determine attachment kind based on mime type\n let kind: 'image' | 'audio' | 'video' = 'image';\n if (mimeType.startsWith('audio/')) {\n kind = 'audio';\n } else if (mimeType.startsWith('video/')) {\n kind = 'video';\n }\n\n const mediaAttachment: MediaAttachment = {\n kind,\n dataUrl,\n mimeType,\n };\n\n setMessages((prev) => prev.map((msg) => (msg.id === assistantMessageId\n ? {\n ...msg,\n attachments: [...(msg.attachments || []), mediaAttachment],\n isStreaming: false,\n isComplete: true\n }\n : msg)));\n }, []);\n\n const sendCopilotzMessage = useCallback(async (\n params: {\n threadId?: string | null;\n threadExternalId?: string | null;\n content: string;\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown> }>;\n userId: string;\n userName?: string;\n userMetadata?: Record<string, unknown>;\n agentName?: string | null;\n onBeforeStart?: (assistantMessageId: string) => void;\n },\n ) => {\n // Track current assistant streaming bubble id so we can split bubbles between events\n let currentAssistantId = generateId();\n params.onBeforeStart?.(currentAssistantId);\n\n let hasStreamProgress = false;\n let pendingStartNewAssistantBubble = false;\n\n // Combined function to ensure bubble exists AND update content in a single setMessages call\n const updateStreamingMessage = (partial: string) => {\n if (partial && partial.length > 0) {\n hasStreamProgress = true;\n }\n\n // Keep feedback visible while the run is active. A token segment can finish\n // before tool calls or subsequent token segments start.\n const nextStreaming = true;\n const nextComplete = false;\n \n setMessages((prev) => {\n // First, check if we need to create a new streaming bubble\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx >= 0 && prev[idx].role === 'assistant' && prev[idx].isStreaming) {\n // Found our current bubble - just update it\n const msg = prev[idx];\n if (msg.content === partial && msg.isStreaming === nextStreaming && msg.isComplete === nextComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[idx] = { ...msg, content: partial, isStreaming: nextStreaming, isComplete: nextComplete };\n return updated;\n }\n \n // Check if last message is a streaming assistant we can reuse\n const last = prev[prev.length - 1];\n if (last && last.role === 'assistant' && last.isStreaming) {\n currentAssistantId = last.id;\n pendingStartNewAssistantBubble = false;\n if (last.content === partial && last.isStreaming === nextStreaming && last.isComplete === nextComplete) {\n return prev; // No change needed\n }\n const updated = [...prev];\n updated[prev.length - 1] = { ...last, content: partial, isStreaming: nextStreaming, isComplete: nextComplete };\n return updated;\n }\n \n // Need to create a new bubble\n if (pendingStartNewAssistantBubble || !prev.length || (prev[prev.length - 1].role !== 'assistant' || !prev[prev.length - 1].isStreaming)) {\n const newId = generateId();\n currentAssistantId = newId;\n pendingStartNewAssistantBubble = false;\n return [\n ...prev,\n {\n id: newId,\n role: 'assistant' as const,\n content: partial,\n timestamp: nowTs(),\n isStreaming: nextStreaming,\n isComplete: nextComplete,\n },\n ];\n }\n \n return prev;\n });\n };\n\n const finalizeCurrentAssistantBubble = () => {\n setMessages((prev) => {\n const idx = prev.findIndex((m) => m.id === currentAssistantId);\n if (idx < 0) return prev;\n const msg = prev[idx];\n // Skip update if already finalized\n if (!msg.isStreaming && msg.isComplete) return prev;\n const updated = [...prev];\n updated[idx] = { ...msg, isStreaming: false, isComplete: true };\n return updated;\n });\n };\n\n // Using Refs for accessing current state inside callback\n const curThreadId = currentThreadIdRef.current;\n\n // Build a ServerMessage-like object from various streaming event payloads\n const toServerMessageFromEvent = async (event: any): Promise<ServerMessage | null> => {\n if (!event) return null;\n const type = (event?.type as string) || '';\n const payload = event?.payload ?? event;\n\n // TOOL_CALL bubble\n if (type === 'TOOL_CALL') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n const call = (payload?.call ?? (metadata as any)?.call) as Record<string, unknown> | undefined;\n const func = (call?.function ?? (payload as any)?.function) as Record<string, unknown> | undefined;\n\n // Extract tool name from various possible locations\n const toolName =\n (func?.name as string) ||\n (payload?.name as string) ||\n (call?.name as string) ||\n (metadata.toolName as string) ||\n (metadata.tool as string) ||\n 'tool';\n\n // Robust args extraction across shapes, including the call.function.arguments pattern\n let argsObj: Record<string, unknown> = {};\n const possibleArgs = [\n func?.arguments, // Try call.function.arguments first (most specific for this event structure)\n payload?.args,\n call?.arguments,\n (metadata as any)?.args,\n (metadata as any)?.arguments,\n ];\n for (const candidate of possibleArgs) {\n if (candidate === undefined || candidate === null) continue;\n try {\n if (typeof candidate === 'string') {\n argsObj = JSON.parse(candidate);\n break;\n }\n if (typeof candidate === 'object') {\n argsObj = candidate as Record<string, unknown>;\n break;\n }\n } catch { /* ignore */ }\n }\n\n const output =\n (metadata as any)?.output !== undefined ? (metadata as any).output\n : payload?.output !== undefined ? payload.output\n : undefined;\n\n // Extract call ID from various locations\n const callId =\n (call?.id as string) ||\n (func?.id as string) ||\n (payload?.id as string) ||\n generateId();\n\n const statusVal =\n (payload?.status as string) ||\n ((event as any)?.status as string) ||\n 'pending';\n\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n toolCalls: [{\n id: callId,\n name: toolName,\n args: argsObj as Record<string, unknown>,\n output,\n status: statusVal,\n }] as Array<Record<string, unknown>>,\n } as unknown as ServerMessage;\n }\n\n // MESSAGE bubble (agent text only - ignore system/tool messages and empty content)\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = payload?.senderType || payload?.sender?.type;\n // Only process agent messages, skip system/tool/user messages\n if (senderType !== 'agent') {\n return null;\n }\n const content = typeof payload?.content === 'string' ? payload.content : '';\n // Skip messages with empty content (especially NEW_MESSAGE events that only have toolCalls)\n if (!content.trim()) {\n return null;\n }\n return {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'agent',\n content,\n metadata: (payload?.metadata ?? {}) as Record<string, unknown>,\n } as unknown as ServerMessage;\n }\n\n // ASSET_CREATED bubble (tool-generated media)\n if (type === 'ASSET_CREATED') {\n // Only render assets created by tools (ignore user uploads)\n const by = (payload?.by as string) || '';\n if (by && by !== 'tool') return null;\n\n const mime = (payload?.mime as string) || 'image/png';\n const ref = (payload?.ref as string) || (payload?.assetRef as string) || '';\n if (!ref) return null;\n const kind = mime.startsWith('audio/') ? 'audio' : (mime.startsWith('video/') ? 'video' : 'image');\n const msgLike = {\n id: generateId(),\n threadId: curThreadId ?? '',\n senderType: 'tool',\n content: '',\n metadata: {\n attachments: [{ kind, assetRef: ref, mimeType: mime }],\n },\n } as unknown as ServerMessage;\n // Resolve assetRef → dataUrl via service\n const [resolved] = await resolveAssetsInMessages([msgLike] as any);\n return resolved as unknown as ServerMessage;\n }\n\n return null;\n };\n\n const abortController = new AbortController();\n abortControllerRef.current?.abort();\n abortControllerRef.current = abortController;\n setIsStreaming(true);\n\n try {\n const normalizedUserMetadata = params.userMetadata\n ? JSON.parse(JSON.stringify(params.userMetadata)) as Record<string, unknown>\n : undefined;\n\n const contextSeed = userContextSeedRef.current;\n const contextMetadata = contextSeed\n ? JSON.parse(JSON.stringify(contextSeed)) as Record<string, unknown>\n : undefined;\n const requestContent = params.content && params.content.length > 0 ? params.content : '';\n\n const metadataKey = params.threadId ?? params.threadExternalId ?? undefined;\n // Read from ref to avoid dependency on threadMetadataMap\n const currentThreadMetadataMap = threadMetadataMapRef.current;\n const messageMetadata = metadataKey ? currentThreadMetadataMap[metadataKey]?.userContext as Record<string, unknown> | undefined : undefined;\n const threadMetadata = metadataKey ? currentThreadMetadataMap[metadataKey] : undefined;\n\n const mergedMetadata = {\n ...(messageMetadata ?? {}),\n ...(params.metadata ?? {}),\n } as Record<string, unknown>;\n\n const finalMetadata = Object.keys(mergedMetadata).length > 0 ? mergedMetadata : undefined;\n\n await runCopilotzStream({\n authToken,\n threadId: params.threadId ?? undefined,\n threadExternalId: params.threadExternalId ?? undefined,\n content: requestContent,\n user: {\n externalId: params.userId,\n name: params.userName ?? params.userId,\n metadata: {\n ...(contextMetadata ? contextMetadata : {}),\n ...(normalizedUserMetadata ?? {}),\n },\n },\n attachments: params.attachments,\n metadata: finalMetadata,\n threadMetadata: params.threadMetadata ?? threadMetadata,\n toolCalls: params.toolCalls,\n selectedAgent: params.agentName ?? preferredAgentRef.current ?? null,\n onToken: (token) => updateStreamingMessage(token),\n onMessageEvent: async (event: any) => {\n const intercepted = applyEventInterceptor(event);\n if (intercepted && typeof intercepted === 'object' && intercepted.handled) {\n return;\n }\n\n const type = (event?.type as string) || '';\n const payload = getEventPayload(event);\n\n // Handle MESSAGE/NEW_MESSAGE events for tool responses\n if (type === 'MESSAGE' || type === 'NEW_MESSAGE') {\n const senderType = getEventSenderType(payload);\n \n // Handle tool responses: update the matching tool call status\n if (senderType === 'tool') {\n const metadata = (payload?.metadata ?? {}) as Record<string, unknown>;\n \n // Extract tool call information from metadata.toolCalls array\n const toolCallsArray = metadata?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCallData = toolCallsArray && toolCallsArray.length > 0 ? toolCallsArray[0] : undefined;\n \n if (!toolCallData) {\n return; // No tool call data found\n }\n \n // Notify onToolOutput callback with the full metadata (includes toolCalls array)\n // This allows consumers to react to tool completions in real-time\n processToolOutput(metadata);\n \n // Extract tool call ID and name\n const toolCallId = toolCallData.id as string | undefined;\n const toolCallName = toolCallData.name as string | undefined;\n \n // Extract the tool result/output\n const toolResult = toolCallData.output || payload?.content;\n \n // Check if the tool execution failed\n const toolStatus = (toolCallData.status as string) || 'completed';\n const isFailed = toolStatus === 'failed' || toolCallData?.error;\n \n // Update the tool call status in the assistant message\n setMessages((prev) => {\n const updated = [...prev];\n // Find the assistant message with the matching tool call\n for (let i = updated.length - 1; i >= 0; i--) {\n if (updated[i].role === 'assistant' && updated[i].toolCalls) {\n const toolCalls = updated[i].toolCalls;\n if (toolCalls) {\n // Try to find by ID first, then by name for pending/running tools\n let toolCallIndex = toolCallId \n ? toolCalls.findIndex(tc => tc.id === toolCallId)\n : -1;\n \n // If not found by ID, try to find a pending/running tool with the same name\n if (toolCallIndex === -1 && toolCallName) {\n toolCallIndex = toolCalls.findIndex(\n tc => tc.name === toolCallName && \n (tc.status === 'pending' || tc.status === 'running')\n );\n }\n \n if (toolCallIndex !== -1) {\n const updatedToolCalls = [...toolCalls];\n updatedToolCalls[toolCallIndex] = {\n ...updatedToolCalls[toolCallIndex],\n status: isFailed ? 'failed' : 'completed',\n result: toolResult,\n endTime: Date.now(),\n };\n updated[i] = {\n ...updated[i],\n toolCalls: updatedToolCalls,\n isStreaming: true,\n isComplete: false,\n };\n break;\n }\n }\n }\n }\n return updated;\n });\n return; // Don't create a separate bubble for tool responses\n }\n \n handleStreamMessageEvent(event);\n if (senderType === 'agent') {\n currentAssistantId = generateId();\n pendingStartNewAssistantBubble = true;\n }\n return;\n }\n\n // TOOL_CALL events: render inside current assistant bubble\n if (type === 'TOOL_CALL') {\n const sm = await toServerMessageFromEvent(event);\n const toolCalls = sm?.toolCalls as Array<Record<string, unknown>> | undefined;\n const toolCall = toolCalls && toolCalls[0];\n if (!toolCall) return;\n\n setMessages((prev) =>\n (() => {\n const appendToolCall = (msg: ChatViewMessage) => ({\n ...msg,\n toolCalls: [\n ...(Array.isArray(msg.toolCalls) ? msg.toolCalls : []),\n {\n id: (toolCall.id as string) ?? generateId(),\n name: (toolCall.name as string) ?? 'tool',\n arguments:\n (toolCall.args as Record<string, unknown>) ??\n (toolCall.arguments as Record<string, unknown>) ??\n {},\n result: toolCall.output,\n status:\n (toolCall.status as 'pending' | 'running' | 'completed' | 'failed') ??\n 'running',\n startTime: Date.now(),\n },\n ],\n });\n\n const currentIdx = prev.findIndex((message) => (\n message.id === currentAssistantId &&\n message.role === 'assistant' &&\n message.isStreaming\n ));\n if (currentIdx >= 0) {\n const next = [...prev];\n next[currentIdx] = appendToolCall({\n ...next[currentIdx],\n isStreaming: true,\n isComplete: false,\n });\n return next;\n }\n\n const last = prev[prev.length - 1];\n if (!pendingStartNewAssistantBubble && last?.role === 'assistant' && last.isStreaming) {\n currentAssistantId = last.id;\n const next = [...prev];\n next[prev.length - 1] = appendToolCall({\n ...last,\n isStreaming: true,\n isComplete: false,\n });\n return next;\n }\n\n // No assistant message yet – create one to host the tool call\n const newId = generateId();\n currentAssistantId = newId;\n pendingStartNewAssistantBubble = false;\n return [\n ...prev,\n appendToolCall({\n id: newId,\n role: 'assistant',\n content: '',\n timestamp: nowTs(),\n isStreaming: true,\n isComplete: false,\n }),\n ];\n })(),\n );\n hasStreamProgress = true;\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Other event types (ASSET_CREATED, etc.) should render as their own bubbles\n const sm = await toServerMessageFromEvent(event);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n finalizeCurrentAssistantBubble();\n setMessages((prev) => [...prev, viewMsg]);\n pendingStartNewAssistantBubble = true;\n return;\n }\n\n // Fallback for unknown events\n handleStreamMessageEvent(event);\n },\n onAssetEvent: async (payload: any) => {\n const intercepted = applyEventInterceptor({ type: 'ASSET_CREATED', payload });\n if (intercepted && typeof intercepted === 'object' && intercepted.handled) {\n return;\n }\n\n // Treat as ASSET_CREATED event in unified handler\n await (async () => {\n if (!hasStreamProgress) return;\n finalizeCurrentAssistantBubble();\n const evt = { type: 'ASSET_CREATED', payload };\n const sm = await toServerMessageFromEvent(evt);\n if (sm) {\n const viewMsg = convertServerMessage(sm as unknown as ServerMessage);\n setMessages((prev) => [...prev, viewMsg]);\n }\n // Defer creating a new assistant bubble until next TOKEN arrives\n pendingStartNewAssistantBubble = true;\n })();\n },\n signal: abortController.signal,\n });\n } finally {\n setIsStreaming(false);\n setMessages((prev) => {\n const hasStreaming = prev.some((msg) => msg.isStreaming);\n if (!hasStreaming) return prev;\n return prev.map((msg) => (msg.isStreaming\n ? { ...msg, isStreaming: false, isComplete: true }\n : msg));\n });\n abortControllerRef.current = null;\n }\n\n return currentAssistantId;\n }, [authToken, applyEventInterceptor, handleStreamMessageEvent, handleStreamAssetEvent]);\n\n const handleSendMessage = useCallback(async (content: string, attachments: MediaAttachment[] = []) => {\n if (!content.trim() && attachments.length === 0) return;\n if (!userId) return;\n\n const timestamp = nowTs();\n const curThreadId = currentThreadIdRef.current;\n const curThreadExtId = currentThreadExternalIdRef.current;\n\n const existingThreadId = curThreadId ?? undefined;\n // Use Ref to check without adding dependency\n const extMap = threadExternalIdMapRef.current;\n const isPlaceholderThread = existingThreadId\n ? extMap[existingThreadId] === existingThreadId\n : false;\n\n const threadIdForSend = isPlaceholderThread ? undefined : existingThreadId;\n\n let effectiveThreadExternalId = curThreadExtId ?? (isPlaceholderThread ? existingThreadId : undefined);\n\n if (!threadIdForSend) {\n if (!effectiveThreadExternalId) {\n effectiveThreadExternalId = generateId();\n }\n setCurrentThreadExternalId(effectiveThreadExternalId);\n } else if (curThreadExtId !== (effectiveThreadExternalId ?? null)) {\n setCurrentThreadExternalId(effectiveThreadExternalId ?? null);\n }\n\n const conversationKey = threadIdForSend ?? effectiveThreadExternalId!;\n\n // Get pending title for new threads if any\n const currentMetadata = threadMetadataMapRef.current[conversationKey];\n const pendingTitle = currentMetadata?.pendingTitle as string | undefined;\n\n const userMessage: ChatViewMessage = {\n id: generateId(),\n role: 'user',\n content,\n timestamp,\n attachments: attachments.length > 0 ? attachments : undefined,\n isComplete: true,\n };\n\n // Create an assistant message placeholder with streaming state for typewriter effect\n const assistantPlaceholder: ChatViewMessage = {\n id: generateId(),\n role: 'assistant',\n content: '',\n timestamp: timestamp + 1,\n isStreaming: true,\n isComplete: false,\n };\n\n // Add user message and assistant placeholder for typewriter loading effect\n setMessages((prev) => [...prev, userMessage, assistantPlaceholder]);\n setSpecialState(null);\n\n // Use ref for threads check\n if (!threadsRef.current.some(t => t.id === conversationKey)) {\n const newThread: ChatThread = {\n id: conversationKey,\n title: content.slice(0, 40) || 'Nova conversa',\n createdAt: timestamp,\n updatedAt: timestamp,\n messageCount: 0,\n };\n setThreads(prev => [newThread, ...prev]);\n setThreadMetadataMap(prev => ({ ...prev, [conversationKey]: {} }));\n setThreadExternalIdMap(prev => ({ ...prev, [conversationKey]: effectiveThreadExternalId ?? null }));\n }\n\n try {\n await sendCopilotzMessage({\n threadId: threadIdForSend,\n threadExternalId: effectiveThreadExternalId,\n content,\n attachments,\n userId,\n // userName can be anything, but let's try to find it in context or just fallback\n userName: (userContextSeedRef.current?.profile as any)?.full_name ?? userId,\n agentName: preferredAgentRef.current,\n // Include pending title for new threads\n threadMetadata: pendingTitle ? { name: pendingTitle } : undefined,\n });\n\n // Wait to ensure the assistant message is persisted before refreshing\n await new Promise((r) => setTimeout(r, 1000));\n // Refresh threads list to update metadata (message count, timestamps, etc.)\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(userId, effectiveThreadExternalId ?? existingThreadId ?? null);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error sending Copilotz message', error);\n const nextSpecialState = getSpecialStateFromError(error);\n if (nextSpecialState) {\n setSpecialState(nextSpecialState);\n setMessages((prev) => prev.filter((msg) => !msg.isStreaming));\n return;\n }\n setMessages((prev) => prev.map((msg) => (msg.isStreaming\n ? {\n ...msg,\n isStreaming: false,\n isComplete: true,\n content: 'Desculpe, ocorreu um erro ao gerar a resposta. Por favor, tente novamente.',\n }\n : msg)));\n }\n }, [userId, authToken, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, getSpecialStateFromError]);\n\n const bootstrapConversation = useCallback(async (uid: string) => {\n if (!bootstrap?.initialToolCalls && !bootstrap?.initialMessage) return;\n\n const bootstrapThreadExternalId = generateId();\n setCurrentThreadId(bootstrapThreadExternalId);\n setCurrentThreadExternalId(bootstrapThreadExternalId);\n setThreadExternalIdMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: bootstrapThreadExternalId }));\n setThreadMetadataMap((prev) => ({ ...prev, [bootstrapThreadExternalId]: {} }));\n // Clear messages; let streaming create bubbles as needed\n setMessages([]);\n setSpecialState(null);\n\n try {\n await sendCopilotzMessage({\n threadExternalId: bootstrapThreadExternalId,\n content: bootstrap.initialMessage || '',\n toolCalls: bootstrap.initialToolCalls,\n userId: uid,\n agentName: preferredAgentRef.current,\n threadMetadata: {\n name: defaultThreadName || 'Main Thread',\n },\n });\n\n // Give the backend time to persist tool outputs/messages before refresh\n await new Promise((r) => setTimeout(r, 1000));\n\n // Refresh threads list to update metadata\n // Don't reload messages since we already have them from streaming\n await fetchAndSetThreadsState(uid, bootstrapThreadExternalId);\n } catch (error) {\n if (isAbortError(error)) return;\n console.error('Error bootstrapping conversation', error);\n const nextSpecialState = getSpecialStateFromError(error);\n if (nextSpecialState) {\n setSpecialState(nextSpecialState);\n setMessages([]);\n return;\n }\n setMessages([\n {\n id: generateId(),\n role: 'assistant',\n content: 'Não foi possível iniciar a conversa. Tente novamente mais tarde.',\n timestamp: nowTs(),\n isStreaming: false,\n isComplete: true,\n },\n ]);\n }\n }, [authToken, fetchAndSetThreadsState, loadThreadMessages, sendCopilotzMessage, bootstrap, defaultThreadName, getSpecialStateFromError]);\n\n const reset = useCallback(() => {\n messagesRequestRef.current += 1;\n setThreads([]);\n setThreadMetadataMap({});\n setThreadExternalIdMap({});\n setCurrentThreadId(null);\n setCurrentThreadExternalId(null);\n setMessages([]);\n setUserContextSeed({});\n setIsMessagesLoading(false);\n setIsStreaming(false);\n setSpecialState(null);\n abortControllerRef.current?.abort();\n }, []);\n\n // Initialize when userId changes\n useEffect(() => {\n if (userId) {\n // Guard against double initialization in StrictMode\n if (initializationRef.current.userId === userId && initializationRef.current.started) {\n return;\n }\n initializationRef.current = { userId, started: true };\n\n const init = async () => {\n // Use URL thread ID as preferred if available\n const urlPreferredThread = isUrlSyncEnabled ? urlState.threadId : undefined;\n const preferredThreadId = await fetchAndSetThreadsState(userId, urlPreferredThread);\n if (preferredThreadId) {\n await loadThreadMessages(preferredThreadId);\n } else if (bootstrap) {\n await bootstrapConversation(userId);\n }\n };\n init();\n } else {\n initializationRef.current = { userId: null, started: false };\n reset();\n }\n }, [userId, authToken, fetchAndSetThreadsState, loadThreadMessages, bootstrapConversation, reset, bootstrap, isUrlSyncEnabled, urlState.threadId]);\n\n // Sync currentThreadExternalId to URL when it changes\n useEffect(() => {\n if (!isUrlSyncEnabled) return;\n // Only sync after initial load is complete\n if (!initializationRef.current.started) return;\n \n setUrlThreadId(currentThreadExternalId);\n }, [currentThreadExternalId, isUrlSyncEnabled, setUrlThreadId]);\n\n // Sync metadata map effects\n useEffect(() => {\n if (!currentThreadId) return;\n const metadata = threadMetadataMap[currentThreadId];\n if (!metadata) return;\n\n if (metadata.userContext && typeof metadata.userContext === 'object') {\n setUserContextSeed((prev) => ({ ...prev, ...(metadata.userContext as Partial<ChatUserContext>) }));\n }\n }, [currentThreadId, threadMetadataMap]);\n\n return {\n messages,\n isMessagesLoading,\n threads,\n currentThreadId,\n isStreaming,\n specialState,\n clearSpecialState,\n userContextSeed,\n sendMessage: handleSendMessage,\n createThread: handleCreateThread,\n selectThread: handleSelectThread,\n renameThread: handleRenameThread,\n archiveThread: handleArchiveThread,\n deleteThread: handleDeleteThread,\n stopGeneration: handleStop,\n fetchAndSetThreadsState,\n loadThreadMessages,\n reset,\n // URL state\n /** Initial prompt from URL (if urlSync enabled) - use for pre-filling input */\n initialPrompt: isUrlSyncEnabled ? urlState.prompt : null,\n /** Clear the initial prompt from URL (call after consuming it) */\n clearInitialPrompt: clearUrlPrompt,\n /** URL agent ID (if urlSync enabled) - use for agent pre-selection */\n urlAgentId: isUrlSyncEnabled ? urlState.agentId : null,\n /** Update agent ID in URL */\n setUrlAgentId,\n };\n}\n","import type { MediaAttachment } from '@copilotz/chat-ui';\n\nconst rawBaseValue = (import.meta as { env?: Record<string, string | undefined> }).env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst runtimeProcess: typeof process | undefined = typeof process !== 'undefined' ? process : undefined;\n\nconst API_KEY = (() => {\n const env = (import.meta as { env?: Record<string, string | undefined> }).env ?? {};\n const candidates = [\n env.VITE_API_KEY,\n env.VITE_COPILOTZ_API_KEY,\n runtimeProcess?.env?.COPILOTZ_API_KEY,\n runtimeProcess?.env?.API_KEY,\n ];\n return candidates.find((value) => typeof value === 'string' && value.length > 0);\n})();\n\nconst withAuthHeaders = (\n headers: Record<string, string> = {},\n authToken?: string | null,\n): Record<string, string> => {\n const token = authToken || API_KEY;\n if (token) {\n return { ...headers, Authorization: `Bearer ${token}` };\n }\n return headers;\n};\n\ntype RestThread = {\n id: string;\n name?: string | null;\n externalId?: string | null;\n description?: string | null;\n participants?: string[] | null;\n status?: string | null;\n metadata?: Record<string, unknown> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype RestMessage = {\n id: string;\n threadId: string;\n senderId?: string | null;\n senderType: string;\n senderUserId?: string | null;\n content?: string | null;\n metadata?: Record<string, unknown> | null;\n toolCalls?: Array<Record<string, unknown>> | null;\n createdAt?: string;\n updatedAt?: string;\n};\n\ntype MessageSenderType = 'agent' | 'user' | 'tool' | 'system';\n\ntype MessageContent =\n | string\n | Array<\n | { type: 'text'; text: string }\n | { type: 'image'; url?: string; dataBase64?: string; mimeType?: string; alt?: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n | { type: 'file'; url?: string; dataBase64?: string; mimeType?: string; name?: string }\n | { type: 'json'; value: unknown }\n >;\n\ntype MessageToolCall = {\n id?: string | null;\n name: string;\n args: Record<string, unknown>;\n};\n\ntype MessageThread = {\n id?: string | null;\n name?: string | null;\n description?: string | null;\n externalId?: string | null;\n participants?: string[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessageSender = {\n id?: string | null;\n externalId?: string | null;\n type: MessageSenderType;\n name?: string | null;\n identifierType?: 'id' | 'name' | 'email' | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype MessagePayload = {\n content: MessageContent;\n sender: MessageSender;\n thread?: MessageThread | null;\n toolCalls?: MessageToolCall[] | null;\n metadata?: Record<string, unknown> | null;\n};\n\ntype StreamCallbacks = {\n onToken?: (token: string, isComplete: boolean, raw?: any) => void;\n onMessageEvent?: (payload: any) => void;\n onAssetEvent?: (payload: any) => void;\n signal?: AbortSignal;\n};\n\ntype RunOptions = {\n authToken?: string | null;\n threadId?: string;\n threadExternalId?: string;\n content: string;\n user: {\n externalId: string;\n name?: string;\n email?: string;\n metadata?: Record<string, unknown>;\n };\n attachments?: MediaAttachment[];\n metadata?: Record<string, unknown>;\n threadMetadata?: Record<string, unknown>;\n toolCalls?: Array<{ name: string; args: Record<string, unknown>; id?: string }>;\n selectedAgent?: string | null;\n} & StreamCallbacks;\n\nexport type CopilotzStreamResult = {\n text: string;\n messages: any[];\n media: Record<string, string> | null;\n};\n\nexport class CopilotzRequestError extends Error {\n status: number;\n code?: string;\n details?: unknown;\n\n constructor(message: string, options: { status: number; code?: string; details?: unknown }) {\n super(message);\n this.name = 'CopilotzRequestError';\n this.status = options.status;\n this.code = options.code;\n this.details = options.details;\n }\n}\n\nconst SSE_LINE_BREAK = '\\n\\n';\n\nconst appendChunk = (buffer: string, chunk: string): string => {\n if (!buffer) return chunk;\n if (!chunk) return buffer;\n if (chunk.startsWith(buffer)) return chunk;\n if (buffer.startsWith(chunk)) return buffer;\n const maxOverlap = Math.min(buffer.length, chunk.length);\n for (let i = maxOverlap; i > 0; i--) {\n if (buffer.endsWith(chunk.slice(0, i))) {\n return buffer + chunk.slice(i);\n }\n }\n return buffer + chunk;\n};\n\nconst parseErrorText = (rawText: string): unknown => {\n if (!rawText) return null;\n try {\n return JSON.parse(rawText);\n } catch {\n return null;\n }\n};\n\nconst toAttachmentPayload = (attachments?: MediaAttachment[]) => {\n if (!attachments || attachments.length === 0) return undefined;\n return attachments.map(att => {\n const base = {\n kind: att.kind,\n dataUrl: att.dataUrl,\n mimeType: att.mimeType,\n fileName: att.fileName,\n };\n if (att.kind === 'audio' || att.kind === 'video') {\n return {\n ...base,\n durationMs: att.durationMs,\n ...(att.kind === 'video' && 'poster' in att ? { poster: att.poster } : {}),\n };\n }\n return base;\n });\n};\n\n// --- Audio helpers: convert browser-recorded WebM/Opus to WAV (16-bit PCM) ---\nconst base64FromUint8 = (bytes: Uint8Array): string => {\n let binary = \"\";\n const chunkSize = 0x8000;\n for (let i = 0; i < bytes.length; i += chunkSize) {\n const chunk = bytes.subarray(i, i + chunkSize);\n binary += String.fromCharCode.apply(null, Array.from(chunk));\n }\n // btoa is available in browsers\n return btoa(binary);\n};\n\nconst parseDataUrl = (dataUrl: string): { mime: string; base64: string } | null => {\n const match = dataUrl.match(/^data:(.+?);base64,(.+)$/s);\n if (!match) return null;\n return { mime: match[1], base64: match[2] };\n};\n\nconst dataUrlToArrayBuffer = (dataUrl: string): ArrayBuffer => {\n const parsed = parseDataUrl(dataUrl);\n if (!parsed) return new ArrayBuffer(0);\n const binaryString = atob(parsed.base64);\n const len = binaryString.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n};\n\nconst encodeWav16BitPCM = (audioBuffer: AudioBuffer): Uint8Array => {\n const numChannels = audioBuffer.numberOfChannels;\n const sampleRate = audioBuffer.sampleRate;\n const numFrames = audioBuffer.length;\n const bytesPerSample = 2; // 16-bit\n const dataSize = numFrames * numChannels * bytesPerSample;\n const buffer = new ArrayBuffer(44 + dataSize);\n const view = new DataView(buffer);\n\n // RIFF header\n const writeString = (offset: number, str: string) => {\n for (let i = 0; i < str.length; i++) {\n view.setUint8(offset + i, str.charCodeAt(i));\n }\n };\n\n let offset = 0;\n writeString(offset, \"RIFF\"); offset += 4;\n view.setUint32(offset, 36 + dataSize, true); offset += 4;\n writeString(offset, \"WAVE\"); offset += 4;\n\n // fmt subchunk\n writeString(offset, \"fmt \"); offset += 4;\n view.setUint32(offset, 16, true); offset += 4; // Subchunk1Size (16 for PCM)\n view.setUint16(offset, 1, true); offset += 2; // AudioFormat (1 = PCM)\n view.setUint16(offset, numChannels, true); offset += 2; // NumChannels\n view.setUint32(offset, sampleRate, true); offset += 4; // SampleRate\n view.setUint32(offset, sampleRate * numChannels * bytesPerSample, true); offset += 4; // ByteRate\n view.setUint16(offset, numChannels * bytesPerSample, true); offset += 2; // BlockAlign\n view.setUint16(offset, 16, true); offset += 2; // BitsPerSample\n\n // data subchunk\n writeString(offset, \"data\"); offset += 4;\n view.setUint32(offset, dataSize, true); offset += 4;\n\n // Interleave channels and write PCM samples\n const channelData: Float32Array[] = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channelData.push(audioBuffer.getChannelData(ch));\n }\n\n let idx = 0;\n for (let i = 0; i < numFrames; i++) {\n for (let ch = 0; ch < numChannels; ch++) {\n let sample = channelData[ch][i];\n // Clamp\n sample = Math.max(-1, Math.min(1, sample));\n // Convert to 16-bit PCM\n const s = sample < 0 ? sample * 0x8000 : sample * 0x7FFF;\n view.setInt16(offset + idx, s, true);\n idx += 2;\n }\n }\n\n return new Uint8Array(buffer);\n};\n\nconst convertAudioDataUrlToWavBase64 = async (dataUrl: string): Promise<string | null> => {\n try {\n const ab = dataUrlToArrayBuffer(dataUrl);\n const ctx = new (window.AudioContext || (window as any).webkitAudioContext)();\n const audioBuffer = await ctx.decodeAudioData(ab.slice(0)); // ensure detached buffer\n // Optionally downsample here if desired; we'll keep source sampleRate.\n const wavBytes = encodeWav16BitPCM(audioBuffer);\n return base64FromUint8(wavBytes);\n } catch (_err) {\n return null;\n }\n};\n\nexport async function runCopilotzStream(options: RunOptions): Promise<CopilotzStreamResult> {\n const {\n authToken,\n threadId,\n threadExternalId,\n content,\n user,\n attachments,\n metadata,\n threadMetadata,\n toolCalls,\n selectedAgent,\n onToken,\n onMessageEvent,\n onAssetEvent,\n signal,\n } = options;\n\n const controller = new AbortController();\n if (signal) {\n signal.addEventListener('abort', () => controller.abort(signal.reason), { once: true });\n }\n\n // Audio attachments are sent as content parts and also mirrored in metadata\n // so the persisted message can render the same media after reload.\n const audioAttachments = attachments?.filter(att => att.kind === 'audio') ?? [];\n const attachmentPayload = toAttachmentPayload(attachments);\n\n const normalizedToolCalls =\n toolCalls?.map<MessageToolCall>((call) => ({\n id: call.id ?? crypto.randomUUID(),\n name: call.name,\n args: call.args ?? {},\n })) ?? [];\n\n const metadataToolCalls =\n normalizedToolCalls.length > 0\n ? normalizedToolCalls.map((tc) => ({\n id: tc.id ?? undefined,\n name: tc.name,\n args: JSON.stringify(tc.args ?? {}),\n }))\n : undefined;\n\n const baseMetadata = {\n ...(metadata ?? {}),\n ...(attachmentPayload ? { attachments: attachmentPayload } : {}),\n ...(metadataToolCalls ? { toolCalls: metadataToolCalls } : {}),\n userExternalId: user.externalId,\n } as Record<string, unknown>;\n\n const messageMetadata = Object.keys(baseMetadata).length > 0 ? baseMetadata : undefined;\n\n const senderMetadata = {\n ...(user.metadata ?? {}),\n ...(user.email ? { email: user.email } : {}),\n } as Record<string, unknown>;\n\n const mergedThreadMetadata = {\n ...(threadMetadata ?? {}),\n } as Record<string, unknown>;\n\n if (mergedThreadMetadata.userExternalId === undefined) {\n mergedThreadMetadata.userExternalId = user.externalId;\n }\n\n // Extract name from threadMetadata if present\n const threadName = (mergedThreadMetadata.name as string) ?? null;\n // Remove name from metadata since it's a top-level field\n const { name: _threadName, ...restThreadMetadata } = mergedThreadMetadata;\n\n const threadPayload: MessageThread | undefined = (threadId || threadExternalId || threadName || Object.keys(restThreadMetadata).length > 0)\n ? {\n id: threadId ?? null,\n externalId: threadExternalId ?? null,\n name: threadName,\n participants: [selectedAgent || 'assistant'],\n metadata: Object.keys(restThreadMetadata).length > 0 ? restThreadMetadata : null,\n }\n : undefined;\n\n // Prepare audio parts (convert to WAV when needed)\n const preparedAudioParts: Array<{ type: 'audio'; dataBase64?: string; url?: string; mimeType?: string; transcript?: string }> = [];\n for (const audioAtt of audioAttachments) {\n if (!audioAtt.dataUrl) continue;\n const parsed = parseDataUrl(audioAtt.dataUrl);\n if (parsed && (parsed.mime.includes('wav') || parsed.mime.includes('mp3') || parsed.mime.includes('mpeg'))) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: parsed.base64,\n mimeType: parsed.mime.includes('wav') ? 'audio/wav' : 'audio/mp3',\n });\n continue;\n }\n // Convert other formats (e.g., audio/webm) to WAV\n const wavBase64 = await convertAudioDataUrlToWavBase64(audioAtt.dataUrl);\n if (wavBase64) {\n preparedAudioParts.push({\n type: 'audio',\n dataBase64: wavBase64,\n mimeType: 'audio/wav',\n });\n } else {\n // Fallback: send as URL (may fail at provider side, but do not block)\n preparedAudioParts.push({\n type: 'audio',\n url: audioAtt.dataUrl,\n mimeType: audioAtt.mimeType || 'audio/webm',\n });\n }\n }\n\n // Build content array: include text and prepared audio parts\n const contentParts: MessageContent = (() => {\n const parts: Array<\n | { type: 'text'; text: string }\n | { type: 'audio'; url?: string; dataBase64?: string; mimeType?: string; transcript?: string }\n > = [];\n const text = (typeof content === 'string' && content.trim().length > 0) ? content : '';\n parts.push({ type: 'text', text });\n for (const p of preparedAudioParts) parts.push(p);\n if (parts.length === 1 && parts[0].type === 'text') return parts[0].text;\n return parts;\n })();\n\n const payload: MessagePayload = {\n content: contentParts,\n sender: {\n type: normalizedToolCalls.length > 0 ? 'agent' : 'user',\n externalId: user.externalId,\n id: normalizedToolCalls.length > 0 ? 'assistant' : undefined,\n name: normalizedToolCalls.length > 0 ? 'assistant' : (user.name ?? null),\n metadata: Object.keys(senderMetadata).length > 0 ? senderMetadata : null,\n },\n metadata: messageMetadata ?? null,\n thread: threadPayload ?? null,\n toolCalls: normalizedToolCalls.length > 0 ? normalizedToolCalls : null,\n };\n\n const response = await fetch(apiUrl('/v1/providers/web'), {\n method: 'POST',\n headers: withAuthHeaders({\n 'Content-Type': 'application/json',\n }, authToken),\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n\n if (!response.ok || !response.body) {\n const errorText = await response.text().catch(() => response.statusText);\n const parsed = parseErrorText(errorText);\n const details = parsed && typeof parsed === 'object' ? parsed : undefined;\n const detailsRecord = details as Record<string, unknown> | undefined;\n const message =\n (typeof detailsRecord?.message === 'string' && detailsRecord.message) ||\n (typeof detailsRecord?.error === 'string' && detailsRecord.error) ||\n errorText ||\n response.statusText ||\n 'Failed to run Copilotz agent';\n const code =\n typeof detailsRecord?.code === 'string'\n ? detailsRecord.code\n : (typeof detailsRecord?.error === 'string' && detailsRecord.error !== message\n ? detailsRecord.error\n : undefined);\n\n throw new CopilotzRequestError(message, {\n status: response.status,\n code,\n details,\n });\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder('utf-8');\n let buffer = '';\n let aggregatedText = '';\n const collectedMessages: any[] = [];\n let collectedMedia: Record<string, string> | null = null;\n\n const processEvent = (eventChunk: string) => {\n if (!eventChunk.trim()) return;\n const lines = eventChunk.split('\\n');\n let eventType = 'message';\n let dataRaw = '';\n for (const line of lines) {\n if (line.startsWith('event:')) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith('data:')) {\n dataRaw += line.slice(5).trim();\n }\n }\n\n if (!dataRaw) return;\n\n let payload: any;\n try {\n payload = JSON.parse(dataRaw);\n } catch (error) {\n console.warn('copilotzService: failed to parse SSE payload', error, dataRaw);\n return;\n }\n\n switch (eventType) {\n case 'TOKEN': {\n const chunk =\n typeof payload?.payload?.token === 'string'\n ? payload.payload.token\n : (typeof payload?.token === 'string' ? payload.token : '');\n if (chunk) {\n aggregatedText = appendChunk(aggregatedText, chunk);\n }\n const isComplete = Boolean(\n (payload && payload.payload && payload.payload.isComplete) ?? payload?.isComplete\n );\n if (chunk || isComplete) {\n onToken?.(aggregatedText, isComplete, payload);\n }\n break;\n }\n case 'MESSAGE': {\n collectedMessages.push(payload);\n // Pass the payload with its internal type (e.g., NEW_MESSAGE, MESSAGE, etc.)\n // The hook will use payload.type to determine the actual event type\n onMessageEvent?.(payload);\n const senderType =\n payload?.payload?.senderType ??\n payload?.payload?.sender?.type;\n\n if (senderType === 'agent' && typeof payload?.payload?.content === 'string') {\n aggregatedText = payload.payload.content;\n }\n break;\n }\n case 'TOOL_CALL': {\n // Pass TOOL_CALL events directly to the message event handler\n // The payload already has the full event structure with type: \"TOOL_CALL\"\n onMessageEvent?.(payload);\n break;\n }\n case 'ASSET_CREATED': {\n const assetPayload = (payload && typeof payload === 'object' && 'payload' in payload)\n ? (payload as { payload?: any }).payload\n : payload;\n // Convert ASSET_CREATED to media format for backward compatibility\n if (assetPayload?.dataUrl) {\n collectedMedia = {\n [assetPayload.assetId || '0']: assetPayload.dataUrl\n };\n }\n // Call the asset event handler\n onAssetEvent?.(assetPayload);\n break;\n }\n case 'ERROR':\n throw new Error(payload?.error || 'Copilotz stream error');\n default:\n // For other event types, wrap in a structure with type and payload\n onMessageEvent?.({ type: eventType, payload });\n }\n };\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n if (buffer.includes('\\r')) {\n buffer = buffer.replace(/\\r/g, '');\n }\n\n let eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n while (eventBoundary >= 0) {\n const chunk = buffer.slice(0, eventBoundary);\n buffer = buffer.slice(eventBoundary + SSE_LINE_BREAK.length);\n processEvent(chunk);\n eventBoundary = buffer.indexOf(SSE_LINE_BREAK);\n }\n }\n\n if (buffer.length > 0) {\n processEvent(buffer);\n }\n\n return {\n text: aggregatedText,\n messages: collectedMessages,\n media: collectedMedia,\n };\n}\n\nexport async function fetchThreads(userId: string, authToken?: string | null) {\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ \"metadata.userExternalId\": userId } ));\n params.set('sort', '-updatedAt');\n\n const res = await fetch(apiUrl(`/v1/rest/threads?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }, authToken),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load threads (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestThread[];\n}\n\nexport async function fetchThreadMessages(threadId: string, authToken?: string | null) {\n const graphParams = new URLSearchParams();\n graphParams.set('threadId', threadId);\n graphParams.set('limit', '500');\n\n try {\n const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }, authToken),\n });\n\n if (graphRes.ok) {\n const graphData = await graphRes.json();\n if (Array.isArray(graphData)) {\n return graphData as RestMessage[];\n }\n if (Array.isArray(graphData?.data)) {\n return graphData.data as RestMessage[];\n }\n return [];\n }\n\n // Only fall back for endpoint absence or gateway errors. For other failures,\n // preserve the real error instead of silently switching stores.\n if (![404, 405, 501, 502, 503, 504].includes(graphRes.status)) {\n const errorText = await graphRes.text().catch(() => graphRes.statusText);\n throw new Error(errorText || `Failed to load graph thread messages (${graphRes.status})`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : '';\n if (!/Failed to fetch/i.test(message)) {\n throw error;\n }\n }\n\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n params.set('sort', 'createdAt:asc');\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }, authToken),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to load thread messages (${res.status})`);\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data)) {\n return [];\n }\n\n return data as RestMessage[];\n}\n\nexport async function updateThread(threadId: string, updates: Partial<RestThread>, authToken?: string | null) {\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'PUT',\n headers: withAuthHeaders({ 'Content-Type': 'application/json', Accept: 'application/json' }, authToken),\n body: JSON.stringify(updates),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to update thread (${res.status})`);\n }\n\n const data = await res.json();\n return data?.body ?? data;\n}\n\nexport async function deleteMessagesByThreadId(threadId: string, authToken?: string | null) {\n const graphParams = new URLSearchParams();\n graphParams.set('threadId', threadId);\n\n try {\n const graphRes = await fetch(apiUrl(`/v1/messages?${graphParams.toString()}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }, authToken),\n });\n\n if (!graphRes.ok && ![404, 405, 501].includes(graphRes.status)) {\n const errorText = await graphRes.text().catch(() => graphRes.statusText);\n throw new Error(errorText || `Failed to delete graph messages (${graphRes.status})`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : '';\n if (!/Failed to fetch/i.test(message)) {\n throw error;\n }\n }\n\n // First fetch all messages for the thread (no field selection to avoid issues)\n const params = new URLSearchParams();\n params.set('filters', JSON.stringify({ threadId }));\n\n const res = await fetch(apiUrl(`/v1/rest/messages?${params.toString()}`), {\n headers: withAuthHeaders({ Accept: 'application/json' }, authToken),\n });\n\n if (!res.ok) {\n // If we can't fetch messages, we can't delete them - but this might be ok if there are none\n console.warn('Could not fetch messages for deletion:', res.status);\n return;\n }\n\n const { data } = await res.json();\n if (!Array.isArray(data) || data.length === 0) {\n return; // No messages to delete\n }\n\n // Delete each message sequentially to avoid overwhelming the server\n for (const msg of data) {\n if (msg?.id) {\n try {\n await fetch(apiUrl(`/v1/rest/messages/${msg.id}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }, authToken),\n });\n } catch {\n // Ignore individual message delete errors\n }\n }\n }\n}\n\nexport async function deleteThread(threadId: string, authToken?: string | null) {\n // First delete all messages in the thread to avoid foreign key constraint\n await deleteMessagesByThreadId(threadId, authToken);\n\n const res = await fetch(apiUrl(`/v1/rest/threads/${threadId}`), {\n method: 'DELETE',\n headers: withAuthHeaders({ Accept: 'application/json' }, authToken),\n });\n\n if (!res.ok) {\n const errorText = await res.text().catch(() => res.statusText);\n throw new Error(errorText || `Failed to delete thread (${res.status})`);\n }\n\n return true;\n}\n\nexport const copilotzService = {\n runCopilotzStream,\n fetchThreads,\n fetchThreadMessages,\n updateThread,\n deleteThread,\n};\n","// Minimal API client for Copilotz assets\n\ntype FetchAssetResult = {\n assetId: string;\n ref: string;\n dataUrl?: string;\n base64?: string;\n mime?: string;\n error?: string;\n};\n\nconst rawBaseValue = (import.meta as { env?: Record<string, string | undefined> }).env?.VITE_API_URL;\nconst rawBase = typeof rawBaseValue === 'string' && rawBaseValue.length > 0 ? rawBaseValue : '/api';\nconst normalizedBase = rawBase.replace(/\\/$/, '');\nconst API_BASE = normalizedBase.startsWith('http') || normalizedBase.startsWith('/')\n ? normalizedBase\n : `/${normalizedBase}`;\n\nconst apiUrl = (path: string) => `${API_BASE}${path}`;\n\nconst extractAssetId = (refOrId: string) =>\n refOrId.startsWith('asset://') ? refOrId.slice('asset://'.length) : refOrId;\n\nexport async function getAssetDataUrl(refOrId: string): Promise<{ dataUrl: string; mime?: string; assetId: string }> {\n const id = extractAssetId(refOrId);\n const res = await fetch(apiUrl(`/v1/assets/${encodeURIComponent(id)}?format=dataUrl`), {\n method: 'GET',\n headers: { Accept: 'application/json' },\n });\n if (!res.ok) {\n const text = await res.text().catch(() => res.statusText);\n throw new Error(text || `Failed to fetch asset ${refOrId}`);\n }\n const data = (await res.json()) as FetchAssetResult;\n if (!data?.dataUrl) {\n throw new Error(data?.error || `Asset ${refOrId} has no dataUrl`);\n }\n return { dataUrl: data.dataUrl, mime: data.mime, assetId: data.assetId };\n}\n\n// Resolve assets in messages by replacing metadata.attachments[].assetRef with dataUrl\ntype WithMetadata = {\n metadata?: Record<string, unknown> | null;\n};\n\nexport async function resolveAssetsInMessages<T extends WithMetadata>(messages: T[]): Promise<T[]> {\n // Deduplicate in-flight fetches so the same assetRef is resolved only once.\n const inFlightByRef = new Map<string, Promise<{ dataUrl: string; mime?: string; assetId: string }>>();\n\n const resolveAssetRef = (assetRef: string) => {\n if (!inFlightByRef.has(assetRef)) {\n inFlightByRef.set(assetRef, getAssetDataUrl(assetRef));\n }\n return inFlightByRef.get(assetRef)!;\n };\n\n return Promise.all(messages.map(async (msg) => {\n const meta = (msg.metadata ?? undefined) as Record<string, unknown> | undefined;\n const attachments = Array.isArray(meta?.attachments)\n ? (meta!.attachments as Array<Record<string, unknown>>)\n : undefined;\n\n if (!attachments || attachments.length === 0) {\n return msg;\n }\n\n const newAttachments = await Promise.all(attachments.map(async (att) => {\n const assetRef = typeof att?.assetRef === 'string' ? (att.assetRef as string) : undefined;\n if (!assetRef) return att;\n\n try {\n const { dataUrl, mime } = await resolveAssetRef(assetRef);\n const kind = typeof att.kind === 'string' ? (att.kind as string) : 'image';\n return {\n kind,\n dataUrl,\n mimeType: typeof att.mimeType === 'string' ? att.mimeType : (mime ?? undefined),\n } as Record<string, unknown>;\n } catch {\n // If fetching fails, keep original so UI can ignore gracefully\n return att;\n }\n }));\n\n const newMeta = { ...(meta ?? {}), attachments: newAttachments } as Record<string, unknown>;\n return { ...msg, metadata: newMeta };\n }));\n}\n\n","import { useState, useEffect, useCallback, useRef } from 'react';\n\n/**\n * Configuration for URL parameter names\n */\nexport interface UrlParamsConfig {\n /** URL param name for thread ID (default: 'thread') */\n thread?: string;\n /** URL param name for agent ID (default: 'agent') */\n agent?: string;\n /** URL param name for initial prompt (default: 'prompt') */\n prompt?: string;\n}\n\n/**\n * URL sync behavior configuration\n */\nexport interface UrlSyncConfig {\n /** Enable/disable URL sync (default: true) */\n enabled?: boolean;\n /** \n * How to update the URL when state changes:\n * - 'push': Creates browser history entries (back button works)\n * - 'replace': Updates URL without history entries (default)\n * - 'read-only': Only reads from URL, never writes\n */\n mode?: 'push' | 'replace' | 'read-only';\n /** Custom parameter names */\n params?: UrlParamsConfig;\n /**\n * Behavior for the prompt parameter:\n * - 'prefill': Pre-fills the input field (default)\n * - 'auto-send': Automatically sends the message on load\n */\n promptBehavior?: 'prefill' | 'auto-send';\n /**\n * Whether to clear the prompt param from URL after reading\n * Prevents re-sending on refresh (default: true)\n */\n clearPromptAfterRead?: boolean;\n}\n\n/**\n * State values parsed from URL\n */\nexport interface UrlState {\n threadId: string | null;\n agentId: string | null;\n prompt: string | null;\n}\n\n/**\n * Return type of useUrlState hook\n */\nexport interface UseUrlStateReturn {\n /** Current state parsed from URL */\n state: UrlState;\n /** Update thread ID in URL */\n setThreadId: (threadId: string | null) => void;\n /** Update agent ID in URL */\n setAgentId: (agentId: string | null) => void;\n /** Clear prompt from URL (call after consuming it) */\n clearPrompt: () => void;\n /** Whether URL sync is enabled */\n isEnabled: boolean;\n}\n\nconst DEFAULT_PARAMS: Required<UrlParamsConfig> = {\n thread: 'thread',\n agent: 'agent',\n prompt: 'prompt',\n};\n\n/**\n * Check if we're in a browser environment\n */\nconst isBrowser = typeof globalThis !== 'undefined' && typeof globalThis.location !== 'undefined';\n\n/**\n * Get current URL search params (SSR-safe)\n */\nconst getSearchParams = (): URLSearchParams => {\n if (!isBrowser) return new URLSearchParams();\n return new URLSearchParams(globalThis.location.search);\n};\n\n/**\n * Update URL with new search params\n */\nconst updateUrl = (params: URLSearchParams, mode: 'push' | 'replace') => {\n if (!isBrowser) return;\n \n const url = new URL(globalThis.location.href);\n url.search = params.toString();\n \n if (mode === 'push') {\n globalThis.history.pushState({}, '', url.toString());\n } else {\n globalThis.history.replaceState({}, '', url.toString());\n }\n};\n\n/**\n * Hook to manage chat state persistence via URL parameters.\n * \n * Supports:\n * - Thread ID: Navigate to specific conversation\n * - Agent ID: Pre-select an agent\n * - Prompt: Pre-fill or auto-send a message\n * \n * @example\n * ```tsx\n * const { state, setThreadId, setAgentId } = useUrlState({\n * enabled: true,\n * mode: 'replace',\n * params: { thread: 't', agent: 'a', prompt: 'q' }\n * });\n * \n * // Read initial values\n * console.log(state.threadId, state.agentId, state.prompt);\n * \n * // Update URL when thread changes\n * setThreadId('abc123');\n * ```\n */\nexport function useUrlState(config: UrlSyncConfig = {}): UseUrlStateReturn {\n const {\n enabled = true,\n mode = 'replace',\n params: userParams = {},\n clearPromptAfterRead = true,\n } = config;\n\n const params = { ...DEFAULT_PARAMS, ...userParams };\n const isReadOnly = mode === 'read-only';\n const updateMode = mode === 'read-only' ? 'replace' : mode;\n\n // Track if initial read has been done\n const initialReadDone = useRef(false);\n const promptCleared = useRef(false);\n\n // Parse initial state from URL\n const parseUrlState = useCallback((): UrlState => {\n if (!enabled || !isBrowser) {\n return { threadId: null, agentId: null, prompt: null };\n }\n\n const searchParams = getSearchParams();\n \n return {\n threadId: searchParams.get(params.thread) || null,\n agentId: searchParams.get(params.agent) || null,\n prompt: promptCleared.current ? null : (searchParams.get(params.prompt) || null),\n };\n }, [enabled, params.thread, params.agent, params.prompt]);\n\n const [state, setState] = useState<UrlState>(parseUrlState);\n\n // Read URL state on mount and handle popstate (back/forward navigation)\n useEffect(() => {\n if (!enabled || !isBrowser) return;\n\n // Initial read\n if (!initialReadDone.current) {\n const initialState = parseUrlState();\n setState(initialState);\n initialReadDone.current = true;\n\n // Clear prompt from URL after reading if configured\n if (clearPromptAfterRead && initialState.prompt && !isReadOnly) {\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n }\n }\n\n // Listen for popstate (browser back/forward)\n const handlePopState = () => {\n setState(parseUrlState());\n };\n\n globalThis.addEventListener('popstate', handlePopState);\n return () => globalThis.removeEventListener('popstate', handlePopState);\n }, [enabled, parseUrlState, clearPromptAfterRead, params.prompt, isReadOnly]);\n\n // Update thread ID in URL\n const setThreadId = useCallback((threadId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (threadId) {\n searchParams.set(params.thread, threadId);\n } else {\n searchParams.delete(params.thread);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, threadId }));\n }, [enabled, isReadOnly, params.thread, updateMode]);\n\n // Update agent ID in URL\n const setAgentId = useCallback((agentId: string | null) => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n \n if (agentId) {\n searchParams.set(params.agent, agentId);\n } else {\n searchParams.delete(params.agent);\n }\n\n updateUrl(searchParams, updateMode);\n setState(prev => ({ ...prev, agentId }));\n }, [enabled, isReadOnly, params.agent, updateMode]);\n\n // Clear prompt from URL\n const clearPrompt = useCallback(() => {\n if (!enabled || isReadOnly || !isBrowser) return;\n\n const searchParams = getSearchParams();\n searchParams.delete(params.prompt);\n updateUrl(searchParams, 'replace');\n promptCleared.current = true;\n setState(prev => ({ ...prev, prompt: null }));\n }, [enabled, isReadOnly, params.prompt]);\n\n return {\n state,\n setThreadId,\n setAgentId,\n clearPrompt,\n isEnabled: enabled,\n };\n}\n"],"mappings":";AAAA,SAAgB,SAAS,aAAAA,YAAW,YAAAC,iBAAgB;AACpD,SAAS,QAAQ,+BAA+B;A;;;;;ACOzC,IAAM,cAAc,CAAC,WAC1B,OAAO,QAAQ,sBAAsB,OAAO,EAAE,YAAA;AAQzC,IAAM,cAAc,CAAmB,WAC5C,OAAO;EAAQ;EAAyB,CAAC,OAAO,IAAI,OAClD,KAAK,GAAG,YAAA,IAAgB,GAAG,YAAA;AAC7B;AAQK,IAAM,eAAe,CAAmB,WAAgC;AAC7E,QAAM,YAAY,YAAY,MAAM;AAEpC,SAAQ,UAAU,OAAO,CAAC,EAAE,YAAA,IAAgB,UAAU,MAAM,CAAC;AAC/D;AAQO,IAAM,eAAe,IAA2C,YACrE,QACG,OAAO,CAAC,WAAW,OAAO,UAAU;AACnC,SACE,QAAQ,SAAS,KAChB,UAAqB,KAAA,MAAW,MACjC,MAAM,QAAQ,SAAS,MAAM;AAEjC,CAAC,EACA,KAAK,GAAG,EACR,KAAA;AAgBE,IAAM,cAAc,CAAC,UAA+B;AACzD,aAAW,QAAQ,OAAO;AACxB,QAAI,KAAK,WAAW,OAAO,KAAK,SAAS,UAAU,SAAS,SAAS;AACnE,aAAO;IACT;EACF;AACF;A;;;;;ACxEA,IAAA,oBAAe;EACb,OAAO;EACP,OAAO;EACP,QAAQ;EACR,SAAS;EACT,MAAM;EACN,QAAQ;EACR,aAAa;EACb,eAAe;EACf,gBAAgB;AAClB;;;ACcA,IAAM,OAAO;EACX,CACE;IACE,QAAQ;IACR,OAAO;IACP,cAAc;IACd;IACA,YAAY;IACZ;IACA;IACA,GAAG;EAAA,GAEL,QAEA;IACE;IACA;MACE;MACA,GAAG;MACH,OAAO;MACP,QAAQ;MACR,QAAQ;MACR,aAAa,sBAAuB,OAAO,WAAW,IAAI,KAAM,OAAO,IAAI,IAAI;MAC/E,WAAW,aAAa,UAAU,SAAS;MAC3C,GAAI,CAAC,YAAY,CAAC,YAAY,IAAI,KAAK,EAAE,eAAe,OAAA;MACxD,GAAG;IAAA;IAEL;MACE,GAAG,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,cAAc,KAAK,KAAK,CAAC;MAC3D,GAAI,MAAM,QAAQ,QAAQ,IAAI,WAAW,CAAC,QAAQ;IAAA;EACpD;AAEN;;;AC7CA,IAAM,mBAAmB,CAAC,UAAkB,aAAuB;AACjE,QAAM,YAAYC;IAAuC,CAAC,EAAE,WAAW,GAAG,MAAA,GAAS,QACjFC,eAAc,MAAM;MAClB;MACA;MACA,WAAW;QACT,UAAU,YAAY,aAAa,QAAQ,CAAC,CAAC;QAC7C,UAAU,QAAQ;QAClB;MAAA;MAEF,GAAG;IAAA,CACJ;EAAA;AAGH,YAAU,cAAc,aAAa,QAAQ;AAE7C,SAAO;AACT;;;ACzBO,IAAM,aAAuB;EAClC,CAAC,QAAQ,EAAE,GAAG,6CAA6C,KAAK,SAAA,CAAU;EAC1E,CAAC,UAAU,EAAE,IAAI,MAAM,IAAI,KAAK,GAAG,KAAK,KAAK,SAAA,CAAU;AACzD;AAaA,IAAM,OAAO,iBAAiB,QAAQ,UAAU;;;AClBhD,SAAS,YAAAC,WAAU,eAAAC,cAAa,UAAAC,SAAQ,aAAAC,kBAAiB;;;ACCzD,IAAM,eAAgB,YAA6D,KAAK;AACxF,IAAM,UAAU,OAAO,iBAAiB,YAAY,aAAa,SAAS,IAAI,eAAe;AAC7F,IAAM,iBAAiB,QAAQ,QAAQ,OAAO,EAAE;AAChD,IAAM,WAAW,eAAe,WAAW,MAAM,KAAK,eAAe,WAAW,GAAG,IAC/E,iBACA,IAAI,cAAc;AAEtB,IAAM,SAAS,CAAC,SAAiB,GAAG,QAAQ,GAAG,IAAI;AAEnD,IAAM,iBAA6C,OAAO,YAAY,cAAc,UAAU;AAE9F,IAAM,WAAW,MAAM;AACrB,QAAM,MAAO,YAA6D,OAAO,CAAC;AAClF,QAAM,aAAa;AAAA,IACjB,IAAI;AAAA,IACJ,IAAI;AAAA,IACJ,gBAAgB,KAAK;AAAA,IACrB,gBAAgB,KAAK;AAAA,EACvB;AACA,SAAO,WAAW,KAAK,CAAC,UAAU,OAAO,UAAU,YAAY,MAAM,SAAS,CAAC;AACjF,GAAG;AAEH,IAAM,kBAAkB,CACtB,UAAkC,CAAC,GACnC,cAC2B;AAC3B,QAAM,QAAQ,aAAa;AAC3B,MAAI,OAAO;AACT,WAAO,EAAE,GAAG,SAAS,eAAe,UAAU,KAAK,GAAG;AAAA,EACxD;AACA,SAAO;AACT;AAsGO,IAAM,uBAAN,cAAmC,MAAM;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,SAA+D;AAC1F,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS,QAAQ;AACtB,SAAK,OAAO,QAAQ;AACpB,SAAK,UAAU,QAAQ;AAAA,EACzB;AACF;AAEA,IAAM,iBAAiB;AAEvB,IAAM,cAAc,CAAC,QAAgB,UAA0B;AAC7D,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,MAAM,WAAW,MAAM,EAAG,QAAO;AACrC,MAAI,OAAO,WAAW,KAAK,EAAG,QAAO;AACrC,QAAM,aAAa,KAAK,IAAI,OAAO,QAAQ,MAAM,MAAM;AACvD,WAAS,IAAI,YAAY,IAAI,GAAG,KAAK;AACnC,QAAI,OAAO,SAAS,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG;AACtC,aAAO,SAAS,MAAM,MAAM,CAAC;AAAA,IAC/B;AAAA,EACF;AACA,SAAO,SAAS;AAClB;AAEA,IAAM,iBAAiB,CAAC,YAA6B;AACnD,MAAI,CAAC,QAAS,QAAO;AACrB,MAAI;AACF,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,IAAM,sBAAsB,CAAC,gBAAoC;AAC/D,MAAI,CAAC,eAAe,YAAY,WAAW,EAAG,QAAO;AACrD,SAAO,YAAY,IAAI,SAAO;AAC5B,UAAM,OAAO;AAAA,MACX,MAAM,IAAI;AAAA,MACV,SAAS,IAAI;AAAA,MACb,UAAU,IAAI;AAAA,MACd,UAAU,IAAI;AAAA,IAChB;AACA,QAAI,IAAI,SAAS,WAAW,IAAI,SAAS,SAAS;AAChD,aAAO;AAAA,QACL,GAAG;AAAA,QACH,YAAY,IAAI;AAAA,QAChB,GAAI,IAAI,SAAS,WAAW,YAAY,MAAM,EAAE,QAAQ,IAAI,OAAO,IAAI,CAAC;AAAA,MAC1E;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAGA,IAAM,kBAAkB,CAAC,UAA8B;AACrD,MAAI,SAAS;AACb,QAAM,YAAY;AAClB,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,WAAW;AAChD,UAAM,QAAQ,MAAM,SAAS,GAAG,IAAI,SAAS;AAC7C,cAAU,OAAO,aAAa,MAAM,MAAM,MAAM,KAAK,KAAK,CAAC;AAAA,EAC7D;AAEA,SAAO,KAAK,MAAM;AACpB;AAEA,IAAM,eAAe,CAAC,YAA6D;AACjF,QAAM,QAAQ,QAAQ,MAAM,2BAA2B;AACvD,MAAI,CAAC,MAAO,QAAO;AACnB,SAAO,EAAE,MAAM,MAAM,CAAC,GAAG,QAAQ,MAAM,CAAC,EAAE;AAC5C;AAEA,IAAM,uBAAuB,CAAC,YAAiC;AAC7D,QAAM,SAAS,aAAa,OAAO;AACnC,MAAI,CAAC,OAAQ,QAAO,IAAI,YAAY,CAAC;AACrC,QAAM,eAAe,KAAK,OAAO,MAAM;AACvC,QAAM,MAAM,aAAa;AACzB,QAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,UAAM,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,EACtC;AACA,SAAO,MAAM;AACf;AAEA,IAAM,oBAAoB,CAAC,gBAAyC;AAClE,QAAM,cAAc,YAAY;AAChC,QAAM,aAAa,YAAY;AAC/B,QAAM,YAAY,YAAY;AAC9B,QAAM,iBAAiB;AACvB,QAAM,WAAW,YAAY,cAAc;AAC3C,QAAM,SAAS,IAAI,YAAY,KAAK,QAAQ;AAC5C,QAAM,OAAO,IAAI,SAAS,MAAM;AAGhC,QAAM,cAAc,CAACC,SAAgB,QAAgB;AACnD,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACnC,WAAK,SAASA,UAAS,GAAG,IAAI,WAAW,CAAC,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,MAAI,SAAS;AACb,cAAY,QAAQ,MAAM;AAAG,YAAU;AACvC,OAAK,UAAU,QAAQ,KAAK,UAAU,IAAI;AAAG,YAAU;AACvD,cAAY,QAAQ,MAAM;AAAG,YAAU;AAGvC,cAAY,QAAQ,MAAM;AAAG,YAAU;AACvC,OAAK,UAAU,QAAQ,IAAI,IAAI;AAAG,YAAU;AAC5C,OAAK,UAAU,QAAQ,GAAG,IAAI;AAAG,YAAU;AAC3C,OAAK,UAAU,QAAQ,aAAa,IAAI;AAAG,YAAU;AACrD,OAAK,UAAU,QAAQ,YAAY,IAAI;AAAG,YAAU;AACpD,OAAK,UAAU,QAAQ,aAAa,cAAc,gBAAgB,IAAI;AAAG,YAAU;AACnF,OAAK,UAAU,QAAQ,cAAc,gBAAgB,IAAI;AAAG,YAAU;AACtE,OAAK,UAAU,QAAQ,IAAI,IAAI;AAAG,YAAU;AAG5C,cAAY,QAAQ,MAAM;AAAG,YAAU;AACvC,OAAK,UAAU,QAAQ,UAAU,IAAI;AAAG,YAAU;AAGlD,QAAM,cAA8B,CAAC;AACrC,WAAS,KAAK,GAAG,KAAK,aAAa,MAAM;AACvC,gBAAY,KAAK,YAAY,eAAe,EAAE,CAAC;AAAA,EACjD;AAEA,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAClC,aAAS,KAAK,GAAG,KAAK,aAAa,MAAM;AACvC,UAAI,SAAS,YAAY,EAAE,EAAE,CAAC;AAE9B,eAAS,KAAK,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC;AAEzC,YAAM,IAAI,SAAS,IAAI,SAAS,QAAS,SAAS;AAClD,WAAK,SAAS,SAAS,KAAK,GAAG,IAAI;AACnC,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO,IAAI,WAAW,MAAM;AAC9B;AAEA,IAAM,iCAAiC,OAAO,YAA4C;AACxF,MAAI;AACF,UAAM,KAAK,qBAAqB,OAAO;AACvC,UAAM,MAAM,KAAK,OAAO,gBAAiB,OAAe,oBAAoB;AAC5E,UAAM,cAAc,MAAM,IAAI,gBAAgB,GAAG,MAAM,CAAC,CAAC;AAEzD,UAAM,WAAW,kBAAkB,WAAW;AAC9C,WAAO,gBAAgB,QAAQ;AAAA,EACjC,SAAS,MAAM;AACb,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,kBAAkB,SAAoD;AAC1F,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,aAAa,IAAI,gBAAgB;AACvC,MAAI,QAAQ;AACV,WAAO,iBAAiB,SAAS,MAAM,WAAW,MAAM,OAAO,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC;AAAA,EACxF;AAIA,QAAM,mBAAmB,aAAa,OAAO,SAAO,IAAI,SAAS,OAAO,KAAK,CAAC;AAC9E,QAAM,oBAAoB,oBAAoB,WAAW;AAEzD,QAAM,sBACJ,WAAW,IAAqB,CAAC,UAAU;AAAA,IACzC,IAAI,KAAK,MAAM,OAAO,WAAW;AAAA,IACjC,MAAM,KAAK;AAAA,IACX,MAAM,KAAK,QAAQ,CAAC;AAAA,EACtB,EAAE,KAAK,CAAC;AAEV,QAAM,oBACJ,oBAAoB,SAAS,IACzB,oBAAoB,IAAI,CAAC,QAAQ;AAAA,IAC/B,IAAI,GAAG,MAAM;AAAA,IACb,MAAM,GAAG;AAAA,IACT,MAAM,KAAK,UAAU,GAAG,QAAQ,CAAC,CAAC;AAAA,EACpC,EAAE,IACF;AAEN,QAAM,eAAe;AAAA,IACnB,GAAI,YAAY,CAAC;AAAA,IACjB,GAAI,oBAAoB,EAAE,aAAa,kBAAkB,IAAI,CAAC;AAAA,IAC9D,GAAI,oBAAoB,EAAE,WAAW,kBAAkB,IAAI,CAAC;AAAA,IAC5D,gBAAgB,KAAK;AAAA,EACvB;AAEA,QAAM,kBAAkB,OAAO,KAAK,YAAY,EAAE,SAAS,IAAI,eAAe;AAE9E,QAAM,iBAAiB;AAAA,IACrB,GAAI,KAAK,YAAY,CAAC;AAAA,IACtB,GAAI,KAAK,QAAQ,EAAE,OAAO,KAAK,MAAM,IAAI,CAAC;AAAA,EAC5C;AAEA,QAAM,uBAAuB;AAAA,IAC3B,GAAI,kBAAkB,CAAC;AAAA,EACzB;AAEA,MAAI,qBAAqB,mBAAmB,QAAW;AACrD,yBAAqB,iBAAiB,KAAK;AAAA,EAC7C;AAGA,QAAM,aAAc,qBAAqB,QAAmB;AAE5D,QAAM,EAAE,MAAM,aAAa,GAAG,mBAAmB,IAAI;AAErD,QAAM,gBAA4C,YAAY,oBAAoB,cAAc,OAAO,KAAK,kBAAkB,EAAE,SAAS,IACrI;AAAA,IACE,IAAI,YAAY;AAAA,IAChB,YAAY,oBAAoB;AAAA,IAChC,MAAM;AAAA,IACN,cAAc,CAAC,iBAAiB,WAAW;AAAA,IAC3C,UAAU,OAAO,KAAK,kBAAkB,EAAE,SAAS,IAAI,qBAAqB;AAAA,EAC9E,IACA;AAGJ,QAAM,qBAA0H,CAAC;AACjI,aAAW,YAAY,kBAAkB;AACvC,QAAI,CAAC,SAAS,QAAS;AACvB,UAAM,SAAS,aAAa,SAAS,OAAO;AAC5C,QAAI,WAAW,OAAO,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK,SAAS,KAAK,KAAK,OAAO,KAAK,SAAS,MAAM,IAAI;AAC1G,yBAAmB,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,YAAY,OAAO;AAAA,QACnB,UAAU,OAAO,KAAK,SAAS,KAAK,IAAI,cAAc;AAAA,MACxD,CAAC;AACD;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,+BAA+B,SAAS,OAAO;AACvE,QAAI,WAAW;AACb,yBAAmB,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ,CAAC;AAAA,IACH,OAAO;AAEL,yBAAmB,KAAK;AAAA,QACtB,MAAM;AAAA,QACN,KAAK,SAAS;AAAA,QACd,UAAU,SAAS,YAAY;AAAA,MACjC,CAAC;AAAA,IACH;AAAA,EACF;AAGA,QAAM,gBAAgC,MAAM;AAC1C,UAAM,QAGF,CAAC;AACL,UAAM,OAAQ,OAAO,YAAY,YAAY,QAAQ,KAAK,EAAE,SAAS,IAAK,UAAU;AACpF,UAAM,KAAK,EAAE,MAAM,QAAQ,KAAK,CAAC;AACjC,eAAW,KAAK,mBAAoB,OAAM,KAAK,CAAC;AAChD,QAAI,MAAM,WAAW,KAAK,MAAM,CAAC,EAAE,SAAS,OAAQ,QAAO,MAAM,CAAC,EAAE;AACpE,WAAO;AAAA,EACT,GAAG;AAEH,QAAM,UAA0B;AAAA,IAC9B,SAAS;AAAA,IACT,QAAQ;AAAA,MACN,MAAM,oBAAoB,SAAS,IAAI,UAAU;AAAA,MACjD,YAAY,KAAK;AAAA,MACjB,IAAI,oBAAoB,SAAS,IAAI,cAAc;AAAA,MACnD,MAAM,oBAAoB,SAAS,IAAI,cAAe,KAAK,QAAQ;AAAA,MACnE,UAAU,OAAO,KAAK,cAAc,EAAE,SAAS,IAAI,iBAAiB;AAAA,IACtE;AAAA,IACA,UAAU,mBAAmB;AAAA,IAC7B,QAAQ,iBAAiB;AAAA,IACzB,WAAW,oBAAoB,SAAS,IAAI,sBAAsB;AAAA,EACpE;AAEA,QAAM,WAAW,MAAM,MAAM,OAAO,mBAAmB,GAAG;AAAA,IACxD,QAAQ;AAAA,IACR,SAAS,gBAAgB;AAAA,MACvB,gBAAgB;AAAA,IAClB,GAAG,SAAS;AAAA,IACZ,MAAM,KAAK,UAAU,OAAO;AAAA,IAC5B,QAAQ,WAAW;AAAA,EACrB,CAAC;AAED,MAAI,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM;AAClC,UAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,SAAS,UAAU;AACvE,UAAM,SAAS,eAAe,SAAS;AACvC,UAAM,UAAU,UAAU,OAAO,WAAW,WAAW,SAAS;AAChE,UAAM,gBAAgB;AACtB,UAAM,UACH,OAAO,eAAe,YAAY,YAAY,cAAc,WAC5D,OAAO,eAAe,UAAU,YAAY,cAAc,SAC3D,aACA,SAAS,cACT;AACF,UAAM,OACJ,OAAO,eAAe,SAAS,WAC3B,cAAc,OACb,OAAO,eAAe,UAAU,YAAY,cAAc,UAAU,UACnE,cAAc,QACd;AAER,UAAM,IAAI,qBAAqB,SAAS;AAAA,MACtC,QAAQ,SAAS;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,QAAM,UAAU,IAAI,YAAY,OAAO;AACvC,MAAI,SAAS;AACb,MAAI,iBAAiB;AACrB,QAAM,oBAA2B,CAAC;AAClC,MAAI,iBAAgD;AAEpD,QAAM,eAAe,CAAC,eAAuB;AAC3C,QAAI,CAAC,WAAW,KAAK,EAAG;AACxB,UAAM,QAAQ,WAAW,MAAM,IAAI;AACnC,QAAI,YAAY;AAChB,QAAI,UAAU;AACd,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,WAAW,QAAQ,GAAG;AAC7B,oBAAY,KAAK,MAAM,CAAC,EAAE,KAAK;AAAA,MACjC,WAAW,KAAK,WAAW,OAAO,GAAG;AACnC,mBAAW,KAAK,MAAM,CAAC,EAAE,KAAK;AAAA,MAChC;AAAA,IACF;AAEA,QAAI,CAAC,QAAS;AAEd,QAAIC;AACJ,QAAI;AACF,MAAAA,WAAU,KAAK,MAAM,OAAO;AAAA,IAC9B,SAAS,OAAO;AACd,cAAQ,KAAK,gDAAgD,OAAO,OAAO;AAC3E;AAAA,IACF;AAEA,YAAQ,WAAW;AAAA,MACjB,KAAK,SAAS;AACZ,cAAM,QACJ,OAAOA,UAAS,SAAS,UAAU,WAC/BA,SAAQ,QAAQ,QACf,OAAOA,UAAS,UAAU,WAAWA,SAAQ,QAAQ;AAC5D,YAAI,OAAO;AACT,2BAAiB,YAAY,gBAAgB,KAAK;AAAA,QACpD;AACA,cAAM,aAAa;AAAA,WAChBA,YAAWA,SAAQ,WAAWA,SAAQ,QAAQ,eAAeA,UAAS;AAAA,QACzE;AACA,YAAI,SAAS,YAAY;AACvB,oBAAU,gBAAgB,YAAYA,QAAO;AAAA,QAC/C;AACA;AAAA,MACF;AAAA,MACA,KAAK,WAAW;AACd,0BAAkB,KAAKA,QAAO;AAG9B,yBAAiBA,QAAO;AACxB,cAAM,aACJA,UAAS,SAAS,cAClBA,UAAS,SAAS,QAAQ;AAE5B,YAAI,eAAe,WAAW,OAAOA,UAAS,SAAS,YAAY,UAAU;AAC3E,2BAAiBA,SAAQ,QAAQ;AAAA,QACnC;AACA;AAAA,MACF;AAAA,MACA,KAAK,aAAa;AAGhB,yBAAiBA,QAAO;AACxB;AAAA,MACF;AAAA,MACA,KAAK,iBAAiB;AACpB,cAAM,eAAgBA,YAAW,OAAOA,aAAY,YAAY,aAAaA,WACxEA,SAA8B,UAC/BA;AAEJ,YAAI,cAAc,SAAS;AACzB,2BAAiB;AAAA,YACf,CAAC,aAAa,WAAW,GAAG,GAAG,aAAa;AAAA,UAC9C;AAAA,QACF;AAEA,uBAAe,YAAY;AAC3B;AAAA,MACF;AAAA,MACA,KAAK;AACH,cAAM,IAAI,MAAMA,UAAS,SAAS,uBAAuB;AAAA,MAC3D;AAEE,yBAAiB,EAAE,MAAM,WAAW,SAAAA,SAAQ,CAAC;AAAA,IACjD;AAAA,EACF;AAEA,SAAO,MAAM;AACX,UAAM,EAAE,OAAO,KAAK,IAAI,MAAM,OAAO,KAAK;AAC1C,QAAI,KAAM;AACV,cAAU,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AAChD,QAAI,OAAO,SAAS,IAAI,GAAG;AACzB,eAAS,OAAO,QAAQ,OAAO,EAAE;AAAA,IACnC;AAEA,QAAI,gBAAgB,OAAO,QAAQ,cAAc;AACjD,WAAO,iBAAiB,GAAG;AACzB,YAAM,QAAQ,OAAO,MAAM,GAAG,aAAa;AAC3C,eAAS,OAAO,MAAM,gBAAgB,eAAe,MAAM;AAC3D,mBAAa,KAAK;AAClB,sBAAgB,OAAO,QAAQ,cAAc;AAAA,IAC/C;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,iBAAa,MAAM;AAAA,EACrB;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,aAAa,QAAgB,WAA2B;AAC5E,QAAM,SAAS,IAAI,gBAAgB;AACnC,SAAO,IAAI,WAAW,KAAK,UAAU,EAAE,2BAA2B,OAAO,CAAE,CAAC;AAC5E,SAAO,IAAI,QAAQ,YAAY;AAE/B,QAAM,MAAM,MAAM,MAAM,OAAO,oBAAoB,OAAO,SAAS,CAAC,EAAE,GAAG;AAAA,IACvE,SAAS,gBAAgB,EAAE,QAAQ,mBAAmB,GAAG,SAAS;AAAA,EACpE,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,YAAY,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AAC7D,UAAM,IAAI,MAAM,aAAa,2BAA2B,IAAI,MAAM,GAAG;AAAA,EACvE;AAEA,QAAM,EAAE,KAAK,IAAI,MAAM,IAAI,KAAK;AAChC,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;AAEA,eAAsB,oBAAoB,UAAkB,WAA2B;AACrF,QAAM,cAAc,IAAI,gBAAgB;AACxC,cAAY,IAAI,YAAY,QAAQ;AACpC,cAAY,IAAI,SAAS,KAAK;AAE9B,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,OAAO,gBAAgB,YAAY,SAAS,CAAC,EAAE,GAAG;AAAA,MAC7E,SAAS,gBAAgB,EAAE,QAAQ,mBAAmB,GAAG,SAAS;AAAA,IACpE,CAAC;AAED,QAAI,SAAS,IAAI;AACf,YAAM,YAAY,MAAM,SAAS,KAAK;AACtC,UAAI,MAAM,QAAQ,SAAS,GAAG;AAC5B,eAAO;AAAA,MACT;AACA,UAAI,MAAM,QAAQ,WAAW,IAAI,GAAG;AAClC,eAAO,UAAU;AAAA,MACnB;AACA,aAAO,CAAC;AAAA,IACV;AAIA,QAAI,CAAC,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG,EAAE,SAAS,SAAS,MAAM,GAAG;AAC7D,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,SAAS,UAAU;AACvE,YAAM,IAAI,MAAM,aAAa,yCAAyC,SAAS,MAAM,GAAG;AAAA,IAC1F;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,QAAI,CAAC,mBAAmB,KAAK,OAAO,GAAG;AACrC,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,SAAS,IAAI,gBAAgB;AACnC,SAAO,IAAI,WAAW,KAAK,UAAU,EAAE,SAAS,CAAC,CAAC;AAClD,SAAO,IAAI,QAAQ,eAAe;AAElC,QAAM,MAAM,MAAM,MAAM,OAAO,qBAAqB,OAAO,SAAS,CAAC,EAAE,GAAG;AAAA,IACxE,SAAS,gBAAgB,EAAE,QAAQ,mBAAmB,GAAG,SAAS;AAAA,EACpE,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,YAAY,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AAC7D,UAAM,IAAI,MAAM,aAAa,mCAAmC,IAAI,MAAM,GAAG;AAAA,EAC/E;AAEA,QAAM,EAAE,KAAK,IAAI,MAAM,IAAI,KAAK;AAChC,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AACT;AAEA,eAAsB,aAAa,UAAkB,SAA8B,WAA2B;AAC5G,QAAM,MAAM,MAAM,MAAM,OAAO,oBAAoB,QAAQ,EAAE,GAAG;AAAA,IAC9D,QAAQ;AAAA,IACR,SAAS,gBAAgB,EAAE,gBAAgB,oBAAoB,QAAQ,mBAAmB,GAAG,SAAS;AAAA,IACtG,MAAM,KAAK,UAAU,OAAO;AAAA,EAC9B,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,YAAY,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AAC7D,UAAM,IAAI,MAAM,aAAa,4BAA4B,IAAI,MAAM,GAAG;AAAA,EACxE;AAEA,QAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,SAAO,MAAM,QAAQ;AACvB;AAEA,eAAsB,yBAAyB,UAAkB,WAA2B;AAC1F,QAAM,cAAc,IAAI,gBAAgB;AACxC,cAAY,IAAI,YAAY,QAAQ;AAEpC,MAAI;AACF,UAAM,WAAW,MAAM,MAAM,OAAO,gBAAgB,YAAY,SAAS,CAAC,EAAE,GAAG;AAAA,MAC7E,QAAQ;AAAA,MACR,SAAS,gBAAgB,EAAE,QAAQ,mBAAmB,GAAG,SAAS;AAAA,IACpE,CAAC;AAED,QAAI,CAAC,SAAS,MAAM,CAAC,CAAC,KAAK,KAAK,GAAG,EAAE,SAAS,SAAS,MAAM,GAAG;AAC9D,YAAM,YAAY,MAAM,SAAS,KAAK,EAAE,MAAM,MAAM,SAAS,UAAU;AACvE,YAAM,IAAI,MAAM,aAAa,oCAAoC,SAAS,MAAM,GAAG;AAAA,IACrF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,QAAI,CAAC,mBAAmB,KAAK,OAAO,GAAG;AACrC,YAAM;AAAA,IACR;AAAA,EACF;AAGA,QAAM,SAAS,IAAI,gBAAgB;AACnC,SAAO,IAAI,WAAW,KAAK,UAAU,EAAE,SAAS,CAAC,CAAC;AAElD,QAAM,MAAM,MAAM,MAAM,OAAO,qBAAqB,OAAO,SAAS,CAAC,EAAE,GAAG;AAAA,IACxE,SAAS,gBAAgB,EAAE,QAAQ,mBAAmB,GAAG,SAAS;AAAA,EACpE,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AAEX,YAAQ,KAAK,0CAA0C,IAAI,MAAM;AACjE;AAAA,EACF;AAEA,QAAM,EAAE,KAAK,IAAI,MAAM,IAAI,KAAK;AAChC,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,WAAW,GAAG;AAC7C;AAAA,EACF;AAGA,aAAW,OAAO,MAAM;AACtB,QAAI,KAAK,IAAI;AACX,UAAI;AACF,cAAM,MAAM,OAAO,qBAAqB,IAAI,EAAE,EAAE,GAAG;AAAA,UACjD,QAAQ;AAAA,UACR,SAAS,gBAAgB,EAAE,QAAQ,mBAAmB,GAAG,SAAS;AAAA,QACpE,CAAC;AAAA,MACH,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAsB,aAAa,UAAkB,WAA2B;AAE9E,QAAM,yBAAyB,UAAU,SAAS;AAElD,QAAM,MAAM,MAAM,MAAM,OAAO,oBAAoB,QAAQ,EAAE,GAAG;AAAA,IAC9D,QAAQ;AAAA,IACR,SAAS,gBAAgB,EAAE,QAAQ,mBAAmB,GAAG,SAAS;AAAA,EACpE,CAAC;AAED,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,YAAY,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AAC7D,UAAM,IAAI,MAAM,aAAa,4BAA4B,IAAI,MAAM,GAAG;AAAA,EACxE;AAEA,SAAO;AACT;AAEO,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACxuBA,IAAMC,gBAAgB,YAA6D,KAAK;AACxF,IAAMC,WAAU,OAAOD,kBAAiB,YAAYA,cAAa,SAAS,IAAIA,gBAAe;AAC7F,IAAME,kBAAiBD,SAAQ,QAAQ,OAAO,EAAE;AAChD,IAAME,YAAWD,gBAAe,WAAW,MAAM,KAAKA,gBAAe,WAAW,GAAG,IAC/EA,kBACA,IAAIA,eAAc;AAEtB,IAAME,UAAS,CAAC,SAAiB,GAAGD,SAAQ,GAAG,IAAI;AAEnD,IAAM,iBAAiB,CAAC,YACtB,QAAQ,WAAW,UAAU,IAAI,QAAQ,MAAM,WAAW,MAAM,IAAI;AAEtE,eAAsB,gBAAgB,SAA+E;AACnH,QAAM,KAAK,eAAe,OAAO;AACjC,QAAM,MAAM,MAAM,MAAMC,QAAO,cAAc,mBAAmB,EAAE,CAAC,iBAAiB,GAAG;AAAA,IACrF,QAAQ;AAAA,IACR,SAAS,EAAE,QAAQ,mBAAmB;AAAA,EACxC,CAAC;AACD,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,OAAO,MAAM,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,UAAU;AACxD,UAAM,IAAI,MAAM,QAAQ,yBAAyB,OAAO,EAAE;AAAA,EAC5D;AACA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,MAAI,CAAC,MAAM,SAAS;AAClB,UAAM,IAAI,MAAM,MAAM,SAAS,SAAS,OAAO,iBAAiB;AAAA,EAClE;AACA,SAAO,EAAE,SAAS,KAAK,SAAS,MAAM,KAAK,MAAM,SAAS,KAAK,QAAQ;AACzE;AAOA,eAAsB,wBAAgD,UAA6B;AAEjG,QAAM,gBAAgB,oBAAI,IAA0E;AAEpG,QAAM,kBAAkB,CAAC,aAAqB;AAC5C,QAAI,CAAC,cAAc,IAAI,QAAQ,GAAG;AAChC,oBAAc,IAAI,UAAU,gBAAgB,QAAQ,CAAC;AAAA,IACvD;AACA,WAAO,cAAc,IAAI,QAAQ;AAAA,EACnC;AAEA,SAAO,QAAQ,IAAI,SAAS,IAAI,OAAO,QAAQ;AAC7C,UAAM,OAAQ,IAAI,YAAY;AAC9B,UAAM,cAAc,MAAM,QAAQ,MAAM,WAAW,IAC9C,KAAM,cACP;AAEJ,QAAI,CAAC,eAAe,YAAY,WAAW,GAAG;AAC5C,aAAO;AAAA,IACT;AAEA,UAAM,iBAAiB,MAAM,QAAQ,IAAI,YAAY,IAAI,OAAO,QAAQ;AACtE,YAAM,WAAW,OAAO,KAAK,aAAa,WAAY,IAAI,WAAsB;AAChF,UAAI,CAAC,SAAU,QAAO;AAEtB,UAAI;AACF,cAAM,EAAE,SAAS,KAAK,IAAI,MAAM,gBAAgB,QAAQ;AACxD,cAAM,OAAO,OAAO,IAAI,SAAS,WAAY,IAAI,OAAkB;AACnE,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,UAAU,OAAO,IAAI,aAAa,WAAW,IAAI,WAAY,QAAQ;AAAA,QACvE;AAAA,MACF,QAAQ;AAEN,eAAO;AAAA,MACT;AAAA,IACF,CAAC,CAAC;AAEF,UAAM,UAAU,EAAE,GAAI,QAAQ,CAAC,GAAI,aAAa,eAAe;AAC/D,WAAO,EAAE,GAAG,KAAK,UAAU,QAAQ;AAAA,EACrC,CAAC,CAAC;AACJ;;;ACvFA,SAAS,UAAU,WAAW,aAAa,cAAc;AAmEzD,IAAM,iBAA4C;AAAA,EAChD,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,QAAQ;AACV;AAKA,IAAM,YAAY,OAAO,eAAe,eAAe,OAAO,WAAW,aAAa;AAKtF,IAAM,kBAAkB,MAAuB;AAC7C,MAAI,CAAC,UAAW,QAAO,IAAI,gBAAgB;AAC3C,SAAO,IAAI,gBAAgB,WAAW,SAAS,MAAM;AACvD;AAKA,IAAM,YAAY,CAAC,QAAyB,SAA6B;AACvE,MAAI,CAAC,UAAW;AAEhB,QAAM,MAAM,IAAI,IAAI,WAAW,SAAS,IAAI;AAC5C,MAAI,SAAS,OAAO,SAAS;AAE7B,MAAI,SAAS,QAAQ;AACnB,eAAW,QAAQ,UAAU,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AAAA,EACrD,OAAO;AACL,eAAW,QAAQ,aAAa,CAAC,GAAG,IAAI,IAAI,SAAS,CAAC;AAAA,EACxD;AACF;AAyBO,SAAS,YAAY,SAAwB,CAAC,GAAsB;AACzE,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,OAAO;AAAA,IACP,QAAQ,aAAa,CAAC;AAAA,IACtB,uBAAuB;AAAA,EACzB,IAAI;AAEJ,QAAM,SAAS,EAAE,GAAG,gBAAgB,GAAG,WAAW;AAClD,QAAM,aAAa,SAAS;AAC5B,QAAM,aAAa,SAAS,cAAc,YAAY;AAGtD,QAAM,kBAAkB,OAAO,KAAK;AACpC,QAAM,gBAAgB,OAAO,KAAK;AAGlC,QAAM,gBAAgB,YAAY,MAAgB;AAChD,QAAI,CAAC,WAAW,CAAC,WAAW;AAC1B,aAAO,EAAE,UAAU,MAAM,SAAS,MAAM,QAAQ,KAAK;AAAA,IACvD;AAEA,UAAM,eAAe,gBAAgB;AAErC,WAAO;AAAA,MACL,UAAU,aAAa,IAAI,OAAO,MAAM,KAAK;AAAA,MAC7C,SAAS,aAAa,IAAI,OAAO,KAAK,KAAK;AAAA,MAC3C,QAAQ,cAAc,UAAU,OAAQ,aAAa,IAAI,OAAO,MAAM,KAAK;AAAA,IAC7E;AAAA,EACF,GAAG,CAAC,SAAS,OAAO,QAAQ,OAAO,OAAO,OAAO,MAAM,CAAC;AAExD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAmB,aAAa;AAG1D,YAAU,MAAM;AACd,QAAI,CAAC,WAAW,CAAC,UAAW;AAG5B,QAAI,CAAC,gBAAgB,SAAS;AAC5B,YAAM,eAAe,cAAc;AACnC,eAAS,YAAY;AACrB,sBAAgB,UAAU;AAG1B,UAAI,wBAAwB,aAAa,UAAU,CAAC,YAAY;AAC9D,cAAM,eAAe,gBAAgB;AACrC,qBAAa,OAAO,OAAO,MAAM;AACjC,kBAAU,cAAc,SAAS;AACjC,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAGA,UAAM,iBAAiB,MAAM;AAC3B,eAAS,cAAc,CAAC;AAAA,IAC1B;AAEA,eAAW,iBAAiB,YAAY,cAAc;AACtD,WAAO,MAAM,WAAW,oBAAoB,YAAY,cAAc;AAAA,EACxE,GAAG,CAAC,SAAS,eAAe,sBAAsB,OAAO,QAAQ,UAAU,CAAC;AAG5E,QAAM,cAAc,YAAY,CAAC,aAA4B;AAC3D,QAAI,CAAC,WAAW,cAAc,CAAC,UAAW;AAE1C,UAAM,eAAe,gBAAgB;AAErC,QAAI,UAAU;AACZ,mBAAa,IAAI,OAAO,QAAQ,QAAQ;AAAA,IAC1C,OAAO;AACL,mBAAa,OAAO,OAAO,MAAM;AAAA,IACnC;AAEA,cAAU,cAAc,UAAU;AAClC,aAAS,WAAS,EAAE,GAAG,MAAM,SAAS,EAAE;AAAA,EAC1C,GAAG,CAAC,SAAS,YAAY,OAAO,QAAQ,UAAU,CAAC;AAGnD,QAAM,aAAa,YAAY,CAAC,YAA2B;AACzD,QAAI,CAAC,WAAW,cAAc,CAAC,UAAW;AAE1C,UAAM,eAAe,gBAAgB;AAErC,QAAI,SAAS;AACX,mBAAa,IAAI,OAAO,OAAO,OAAO;AAAA,IACxC,OAAO;AACL,mBAAa,OAAO,OAAO,KAAK;AAAA,IAClC;AAEA,cAAU,cAAc,UAAU;AAClC,aAAS,WAAS,EAAE,GAAG,MAAM,QAAQ,EAAE;AAAA,EACzC,GAAG,CAAC,SAAS,YAAY,OAAO,OAAO,UAAU,CAAC;AAGlD,QAAM,cAAc,YAAY,MAAM;AACpC,QAAI,CAAC,WAAW,cAAc,CAAC,UAAW;AAE1C,UAAM,eAAe,gBAAgB;AACrC,iBAAa,OAAO,OAAO,MAAM;AACjC,cAAU,cAAc,SAAS;AACjC,kBAAc,UAAU;AACxB,aAAS,WAAS,EAAE,GAAG,MAAM,QAAQ,KAAK,EAAE;AAAA,EAC9C,GAAG,CAAC,SAAS,YAAY,OAAO,MAAM,CAAC;AAEvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,EACb;AACF;;;AHpOA,IAAM,QAAQ,MAAM,KAAK,IAAI;AAC7B,IAAM,aAAa,MAChB,WAAW,QAAQ,aAAa,KAAK,MAAM,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACnG,IAAM,eAAe,CAAC,UACpB,iBAAiB,gBAAgB,MAAM,SAAS,gBAC5C,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAU,MAA4B,SAAS;AAC9G,IAAM,kBAAkB,CAAC,UAAe,OAAO,WAAW;AAC1D,IAAM,qBAAqB,CAAC,YAAqC,SAAS,cAAc,SAAS,QAAQ;AAsBzG,IAAM,sBAAsB,CAAC,WAAoC;AAC/D,MAAI,WAAW,UAAW,QAAO;AACjC,MAAI,WAAW,aAAa,WAAW,aAAc,QAAO;AAC5D,MAAI,WAAW,SAAU,QAAO;AAChC,SAAO;AACT;AAEA,IAAM,qBAAqB,CAAC,UAA4C;AACtE,MAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,UAAU;AAC7B,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,UAAI,UAAU,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,GAAG;AAClE,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,CAAC;AACV;AAEA,IAAM,oCAAoC,CAAC,QAAyC;AAClF,QAAM,WAAY,IAAI,YAAY;AAClC,QAAM,oBAAoB,MAAM,QAAS,IAAkE,SAAS,IAC9G,IAAkE,aAAa,CAAC,IAClF,CAAC;AACL,QAAM,oBAAoB,MAAM,QAAQ,UAAU,SAAS,IACtD,SAAS,YACV,CAAC;AAEL,QAAM,sBAAsB,oBAAI,IAAY;AAC5C,QAAM,SAA2B,CAAC;AAElC,QAAM,4BAA4B,CAAC,aAA8C;AAC/E,UAAM,KAAK,OAAO,SAAS,OAAO,WAAW,SAAS,KAAK;AAC3D,UAAM,OAAO,OAAO,SAAS,SAAS,WAAW,SAAS,OAAO;AAEjE,UAAM,OAAO,KACT,kBAAkB,UAAU,CAAC,WAAW,QAAQ,CAAC,oBAAoB,IAAI,GAAG,KAAK,WAAW,OAAO,EAAE,IACrG;AACJ,QAAI,QAAQ,EAAG,QAAO;AAEtB,WAAO,OACH,kBAAkB,UAAU,CAAC,WAAW,QAAQ,CAAC,oBAAoB,IAAI,GAAG,KAAK,WAAW,SAAS,IAAI,IACzG;AAAA,EACN;AAEA,QAAM,gBAAgB,CACpB,SACA,cACmB;AACnB,UAAM,KAAK,OAAO,QAAQ,OAAO,WAC7B,QAAQ,KACP,OAAO,WAAW,OAAO,WAAW,UAAU,KAAK;AACxD,UAAM,OAAO,OAAO,QAAQ,SAAS,WACjC,QAAQ,OACP,OAAO,WAAW,SAAS,WAAW,UAAU,OAAO;AAC5D,UAAM,UACJ,QAAQ,QAAQ,QAAQ,aAAa,WAAW,QAAQ,WAAW;AACrE,UAAM,SACJ,QAAQ,WAAW,SACf,QAAQ,SACR,QAAQ,WAAW,SACjB,QAAQ,SACR,WAAW,WAAW,SACpB,UAAU,SACV,WAAW;AACrB,UAAM,SAAS,oBAAoB,QAAQ,UAAU,WAAW,MAAM;AAEtE,WAAO;AAAA,MACL,GAAI,KAAK,EAAE,GAAG,IAAI,CAAC;AAAA,MACnB;AAAA,MACA,WAAW,mBAAmB,OAAO;AAAA,MACrC,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,oBAAkB,QAAQ,CAAC,aAAa;AACtC,UAAM,gBAAgB,0BAA0B,QAAQ;AACxD,UAAM,eAAe,iBAAiB,IAAI,kBAAkB,aAAa,IAAI;AAC7E,QAAI,iBAAiB,EAAG,qBAAoB,IAAI,aAAa;AAC7D,WAAO,KAAK,cAAc,UAAU,YAAY,CAAC;AAAA,EACnD,CAAC;AAED,oBAAkB,QAAQ,CAAC,UAAU,UAAU;AAC7C,QAAI,oBAAoB,IAAI,KAAK,EAAG;AACpC,WAAO,KAAK,cAAc,QAAQ,CAAC;AAAA,EACrC,CAAC;AAED,SAAO;AACT;AAEA,IAAM,qCAAqC,CAAC,QAAgD;AAC1F,MAAI,IAAI,eAAe,OAAQ,QAAO;AAEtC,QAAM,YAAY,kCAAkC,GAAG;AACvD,MAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,UAAU,WAAW,EAAG,QAAO;AAEhE,QAAM,gBAAgB,UAAU,CAAC;AACjC,QAAM,WAAY,IAAI,YAAY;AAClC,QAAM,iBAAiB,UAAU;AACjC,QAAM,SAAS,cAAc,WAAW,SAAY,cAAc,SAAS;AAE3E,SAAO;AAAA,IACL,GAAI,cAAc,KAAK,EAAE,IAAI,cAAc,GAAG,IAAI,CAAC;AAAA,IACnD,GAAI,cAAc,OAAO,EAAE,MAAM,cAAc,KAAK,IAAI,CAAC;AAAA,IACzD,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,IACzC,QAAQ,cAAc;AAAA,IACtB,SAAS,IAAI,YAAY,IAAI,KAAK,IAAI,SAAS,EAAE,QAAQ,IAAI,MAAM;AAAA,EACrE;AACF;AAEA,IAAM,4BAA4B,CAChC,UACA,YACsB;AACtB,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAM,eAAe,CAAC,GAAG,QAAQ;AAEjC,aAAW,UAAU,SAAS;AAC5B,aAAS,IAAI,aAAa,SAAS,GAAG,KAAK,GAAG,KAAK;AACjD,YAAM,UAAU,aAAa,CAAC;AAC9B,UAAI,QAAQ,SAAS,eAAe,CAAC,MAAM,QAAQ,QAAQ,SAAS,KAAK,QAAQ,UAAU,WAAW,GAAG;AACvG;AAAA,MACF;AAEA,YAAM,YAAY,QAAQ;AAE1B,UAAI,gBAAgB,OAAO,KACvB,UAAU,UAAU,CAAC,aAAa,SAAS,OAAO,OAAO,EAAE,IAC3D;AAEJ,UAAI,kBAAkB,MAAM,OAAO,MAAM;AACvC,wBAAgB,UAAU,UAAU,CAAC,aACnC,SAAS,SAAS,OAAO,SACxB,SAAS,WAAW,aAAa,SAAS,WAAW,aAAa,OAAO,SAAS,WAAW,YAC/F;AAAA,MACH;AAEA,UAAI,kBAAkB,GAAI;AAE1B,YAAM,mBAAmB,CAAC,GAAG,SAAS;AACtC,YAAM,UAAU,iBAAiB,aAAa;AAC9C,uBAAiB,aAAa,IAAI;AAAA,QAChC,GAAG;AAAA,QACH,QAAQ,OAAO;AAAA,QACf,GAAI,OAAO,WAAW,SAAY,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,QAC/D,SAAS,OAAO;AAAA,MAClB;AAEA,mBAAa,CAAC,IAAI;AAAA,QAChB,GAAG;AAAA,QACH,WAAW;AAAA,MACb;AACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,IAAM,uBAAuB,CAAC,QAAwC;AACpE,QAAM,YAAY,IAAI,YAAY,IAAI,KAAK,IAAI,SAAS,EAAE,QAAQ,IAAI,MAAM;AAC5E,QAAM,WAAY,IAAI,YAAY;AAClC,QAAM,kBAAkB,MAAM,QAAQ,UAAU,WAAW,IACtD,SAAU,cACX,CAAC;AAEL,QAAM,cAAiC,gBAAgB,QAAQ,CAAC,QAAQ;AACtE,UAAM,OAAO,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO;AACvD,UAAM,UAAU,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AAChE,UAAM,WAAW,OAAO,IAAI,aAAa,WAAW,IAAI,WAAW;AACnE,QAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,QAAI,SAAS,SAAS;AACpB,aAAO,CAAC,EAAE,MAAM,SAAS,SAAS,UAAU,YAAY,aAAa,CAAC;AAAA,IACxE;AACA,QAAI,SAAS,SAAS;AACpB,aAAO,CAAC;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,UAAU,YAAY;AAAA,QACtB,YAAY,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,MACpE,CAAC;AAAA,IACH;AACA,QAAI,SAAS,SAAS;AACpB,aAAO,CAAC;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,UAAU,YAAY;AAAA,QACtB,YAAY,OAAO,IAAI,eAAe,WAAW,IAAI,aAAa;AAAA,QAClE,QAAQ,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS;AAAA,MACxD,CAAC;AAAA,IACH;AACA,WAAO,CAAC;AAAA,EACV,CAAC;AAED,QAAM,OAAO,IAAI,eAAe,UAC5B,cACA,IAAI,eAAe,SACjB,SACA;AAEN,QAAM,kBAAkB,kCAAkC,GAAG;AAC7D,QAAM,kBAAkB,gBAAgB,IAAI,CAAC,cAAc;AAAA,IACzD,IAAI,SAAS,MAAM,WAAW;AAAA,IAC9B,MAAM,SAAS;AAAA,IACf,WAAW,SAAS;AAAA,IACpB,QAAQ,SAAS;AAAA,IACjB,GAAI,SAAS,WAAW,SAAY,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;AAAA,EACrE,EAAE;AAEF,QAAM,eAAe,gBAAgB,SAAS;AAC9C,QAAM,eAAe,IAAI,eAAe;AACxC,QAAM,UACJ,eACI,MACE,IAAI,WAAW,QAAQ,eAAe,KAAK;AAEnD,SAAO;AAAA,IACL,IAAI,IAAI;AAAA,IACR;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,YAAY,SAAS,IAAI,cAAc;AAAA,IACpD,aAAa;AAAA,IACb,YAAY;AAAA,IACZ;AAAA,IACA,WAAW,eAAe,kBAAkB;AAAA,EAC9C;AACF;AAkCO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AAErB,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,aAAa;AAAA,IACb,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,WAAW;AAAA,EACb,IAAI,YAAY,OAAO;AAEvB,QAAM,CAAC,SAAS,UAAU,IAAIC,UAAuB,CAAC,CAAC;AACvD,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAA8D,CAAC,CAAC;AAClH,QAAM,CAAC,qBAAqB,sBAAsB,IAAIA,UAAwC,CAAC,CAAC;AAEhG,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAwB,IAAI;AAC1E,QAAM,CAAC,yBAAyB,0BAA0B,IAAIA,UAAwB,IAAI;AAE1F,QAAM,CAAC,UAAU,WAAW,IAAIA,UAA4B,CAAC,CAAC;AAC9D,QAAM,CAAC,mBAAmB,oBAAoB,IAAIA,UAAS,KAAK;AAChE,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,KAAK;AACpD,QAAM,CAAC,cAAc,eAAe,IAAIA,UAAkC,IAAI;AAE9E,QAAM,CAAC,iBAAiB,kBAAkB,IAAIA,UAAmC,kBAAkB,CAAC,CAAC;AACrG,QAAM,oBAAoBC,QAAsB,sBAAsB,IAAI;AAI1E,QAAM,aAAaA,QAAO,OAAO;AACjC,QAAM,uBAAuBA,QAAO,iBAAiB;AACrD,QAAM,yBAAyBA,QAAO,mBAAmB;AACzD,QAAM,qBAAqBA,QAAO,eAAe;AACjD,QAAM,6BAA6BA,QAAO,uBAAuB;AACjE,QAAM,qBAAqBA,QAAO,eAAe;AAGjD,aAAW,UAAU;AACrB,uBAAqB,UAAU;AAC/B,yBAAuB,UAAU;AACjC,qBAAmB,UAAU;AAC7B,6BAA2B,UAAU;AACrC,qBAAmB,UAAU;AAC7B,oBAAkB,UAAU,sBAAsB;AAElD,QAAM,qBAAqBA,QAA+B,IAAI;AAC9D,QAAM,qBAAqBA,QAAe,CAAC;AAE3C,QAAM,oBAAoBA,QAAoD,EAAE,QAAQ,MAAM,SAAS,MAAM,CAAC;AAE9G,EAAAC,WAAU,MAAM;AACd,QAAI,gBAAgB;AAClB,yBAAmB,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,eAAe,EAAE;AAAA,IAC/D;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,oBAAoBC,aAAY,CAAC,WAAoC;AACzE,QAAI,CAAC,OAAQ;AAEb,UAAM,eAAyC,CAAC;AAGhD,QAAI,OAAO,eAAe,OAAO,OAAO,gBAAgB,UAAU;AAChE,aAAO,OAAO,cAAc,OAAO,WAAuC;AAAA,IAC5E;AAEA,QAAI,OAAO,KAAK,YAAY,EAAE,SAAS,GAAG;AACxC,yBAAmB,CAAC,UAAU,EAAE,GAAG,MAAM,GAAG,aAAa,EAAE;AAAA,IAC7D;AAEA,mBAAe,MAAM;AAAA,EACvB,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,oBAAoBA,aAAY,MAAM;AAC1C,oBAAgB,IAAI;AAAA,EACtB,GAAG,CAAC,CAAC;AAEL,QAAM,wBAAwBA,aAAY,CAAC,UAAmB;AAC5D,QAAI,CAAC,iBAAkB,QAAO;AAC9B,QAAI;AACF,YAAM,SAAS,iBAAiB,KAAK;AACrC,UAAI,UAAU,OAAO,WAAW,YAAY,OAAO,cAAc;AAC/D,wBAAgB,OAAO,YAAY;AAAA,MACrC;AACA,aAAO;AAAA,IACT,SAAS,OAAO;AACd,cAAQ,MAAM,uCAAuC,KAAK;AAC1D,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,gBAAgB,CAAC;AAErB,QAAM,2BAA2BA,aAAY,CAAC,UAAmB;AAC/D,QAAI,CAAC,oBAAqB,QAAO;AACjC,QAAI;AACF,aAAO,oBAAoB,KAAK,KAAK;AAAA,IACvC,SAAS,kBAAkB;AACzB,cAAQ,MAAM,2CAA2C,gBAAgB;AACzE,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,mBAAmB,CAAC;AAExB,QAAM,2BAA2BA,aAAY,CAAC,UAAe;AAC3D,UAAM,UAAU,gBAAgB,KAAK;AACrC,QAAI,CAAC,QAAS;AACd,UAAM,aAAa,mBAAmB,OAAO;AAE7C,QAAI,eAAe,QAAQ;AACzB,YAAM,WAAY,QAAQ,YAAY,MAAM,YAAY,CAAC;AACzD,YAAM,SAAU,UAAU,UAAU;AACpC,UAAI,OAAQ,mBAAkB,MAAM;AAGpC,YAAM,WAAY,UAAU,YAAwB,UAAU,QAAmB;AACjF,UAAI,UAAmC,CAAC;AACxC,UAAI;AACF,cAAM,SAAU,UAAU,aAAwB;AAClD,kBAAU,OAAO,WAAW,WAAW,KAAK,MAAM,MAAM,IAAK;AAAA,MAC/D,SAAS,GAAG;AAAA,MAAqB;AACjC,YAAM,YAAY,UAAU;AAC5B,YAAM,SAAU,QAAQ,cAAyB,WAAW;AAE5D,kBAAY,CAAC,SAAS;AACpB,cAAM,OAAO,CAAC,GAAG,IAAI;AACrB,iBAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACzC,gBAAM,IAAI,KAAK,CAAC;AAChB,cAAI,EAAE,SAAS,aAAa;AAC1B,kBAAM,WAAW,MAAM,QAAQ,EAAE,SAAS,IAAI,EAAE,YAAY,CAAC;AAC7D,iBAAK,CAAC,IAAI;AAAA,cACR,GAAG;AAAA,cACH,WAAW;AAAA,gBACT,GAAG;AAAA,gBACH;AAAA,kBACE,IAAI;AAAA,kBACJ,MAAM;AAAA,kBACN,WAAW;AAAA,kBACX,QAAQ;AAAA,kBACR,QAAQ;AAAA,kBACR,SAAS,KAAK,IAAI;AAAA,gBACpB;AAAA,cACF;AAAA,YACF;AACA;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT,CAAC;AACD;AAAA,IACF;AAEA,QAAI,eAAe,WAAW,OAAO,QAAQ,YAAY,UAAU;AACjE,kBAAY,CAAC,SAAS;AACpB,cAAM,OAAO,CAAC,GAAG,IAAI;AACrB,iBAAS,IAAI,KAAK,SAAS,GAAG,KAAK,GAAG,KAAK;AACzC,gBAAM,IAAI,KAAK,CAAC;AAChB,cAAI,EAAE,SAAS,eAAe,EAAE,aAAa;AAC3C,iBAAK,CAAC,IAAI,EAAE,GAAG,GAAG,SAAS,QAAQ,SAAS,aAAa,OAAO,YAAY,KAAK;AACjF,mBAAO;AAAA,UACT;AAAA,QACF;AAEA,cAAM,iBAAiB,QAAQ,QAAQ,KAAK;AAC5C,YAAI,CAAC,gBAAgB;AACnB,iBAAO;AAAA,QACT;AAEA,eAAO;AAAA,UACL,GAAG;AAAA,UACH;AAAA,YACE,IAAI,WAAW;AAAA,YACf,MAAM;AAAA,YACN,SAAS,QAAQ;AAAA,YACjB,WAAW,MAAM;AAAA,YACjB,aAAa;AAAA,YACb,YAAY;AAAA,YACZ,UAAW,QAAQ,YAAY;AAAA,UACjC;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,iBAAiB,CAAC;AAEtB,QAAM,qBAAqBA,aAAY,CAAC,YAA4B,wBAAwC;AAC1G,UAAM,cAAmE,CAAC;AAC1E,UAAM,cAA6C,CAAC;AAEpD,UAAM,aAAa,WAAW,IAAI,CAAC,WAAW;AAC5C,kBAAY,OAAO,EAAE,IAAI,OAAO,YAAY;AAC5C,kBAAY,OAAO,EAAE,IAAI,OAAO,cAAc;AAC9C,YAAM,YAAY,OAAO,YAAY,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ,IAAI,MAAM;AAClF,YAAM,YAAY,OAAO,YAAY,IAAI,KAAK,OAAO,SAAS,EAAE,QAAQ,IAAI;AAC5E,aAAO;AAAA,QACL,IAAI,OAAO;AAAA,QACX,OAAO,OAAO,QAAQ;AAAA,QACtB;AAAA,QACA;AAAA,QACA,cAAc,OAAO,OAAO,UAAU,iBAAiB,WACnD,OAAO,SAAU,eACjB;AAAA,QACJ,YAAY,OAAO,WAAW;AAAA,QAC9B,UAAU,OAAO,YAAY;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,yBAAqB,WAAW;AAChC,2BAAuB,WAAW;AAClC,eAAW,UAAU;AAGrB,UAAM,WAAW,2BAA2B;AAC5C,UAAM,QAAQ,mBAAmB;AAEjC,QAAI,eAA8B;AAElC,QAAI,qBAAqB;AACvB,YAAM,YAAY,WAAW,KAAK,CAAC,YAAY,OAAO,cAAc,OAAO,QAAQ,mBAAmB;AACtG,UAAI,UAAW,gBAAe,UAAU;AAAA,IAC1C;AAEA,QAAI,CAAC,gBAAgB,UAAU;AAC7B,YAAM,QAAQ,WAAW,KAAK,CAAC,YAAY,OAAO,cAAc,OAAO,QAAQ,QAAQ;AACvF,UAAI,MAAO,gBAAe,MAAM;AAAA,IAClC;AAEA,QAAI,CAAC,gBAAgB,SAAS,WAAW,KAAK,CAAC,WAAW,OAAO,OAAO,KAAK,GAAG;AAC9E,qBAAe;AAAA,IACjB;AAEA,QAAI,CAAC,gBAAgB,WAAW,SAAS,GAAG;AAC1C,qBAAe,WAAW,CAAC,EAAE;AAAA,IAC/B;AAEA,uBAAmB,gBAAgB,IAAI;AACvC,+BAA2B,eAAe,YAAY,YAAY,KAAK,OAAO,IAAI;AAElF,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,0BAA0BA,aAAY,OAAO,KAAa,wBAAwC;AACtG,QAAI;AACF,YAAM,aAAa,MAAM,aAAa,KAAK,SAAS;AACpD,aAAO,mBAAmB,YAAY,mBAAmB;AAAA,IAC3D,SAAS,OAAO;AACd,UAAI,aAAa,KAAK,EAAG;AACzB,cAAQ,MAAM,yBAAyB,KAAK;AAC5C,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,WAAW,kBAAkB,CAAC;AAElC,QAAM,qBAAqBA,aAAY,OAAO,aAAqB;AACjE,UAAM,YAAY,mBAAmB,UAAU;AAC/C,uBAAmB,UAAU;AAC7B,yBAAqB,IAAI;AACzB,QAAI;AACF,YAAM,cAAc,MAAM,oBAAoB,UAAU,SAAS;AACjE,YAAM,mBAAmB,MAAM,wBAAwB,WAA+B;AACtF,UAAI,mBAAmB,YAAY,UAAW;AAE9C,uBAAiB,QAAQ,CAAC,QAAa;AACrC,YAAI,IAAI,eAAe,QAAQ;AAC7B,gBAAM,WAAW,IAAI;AACrB,gBAAM,SAAU,UAAU,UAAU;AACpC,cAAI,OAAQ,mBAAkB,MAAM;AAAA,QACtC;AAAA,MACF,CAAC;AAED,YAAM,oBAAoB,iBACvB,IAAI,CAAC,QAAQ,mCAAmC,GAA+B,CAAC,EAChF,OAAO,CAAC,WAAuC,WAAW,IAAI;AAEjE,YAAM,eAAe,iBAClB,OAAO,CAAC,QAAQ;AACf,cAAM,QAAQ,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU,IAAI,KAAK;AACvE,cAAM,UAAU,KAAK,SAAS;AAC9B,cAAM,eAAe,kCAAkC,GAA+B,EAAE,SAAS;AACjG,cAAM,OAAQ,IAAI,YAAY,CAAC;AAC/B,cAAM,iBAAiB,MAAM,QAAQ,KAAK,WAAW,KAAM,KAAK,YAA0B,SAAS;AAEnG,YAAI,IAAI,eAAe,QAAQ;AAC7B,iBAAO;AAAA,QACT;AAEA,eAAO,WAAW,gBAAgB;AAAA,MACpC,CAAC,EACA,IAAI,oBAAoB;AAE3B,YAAM,mBAAmB,0BAA0B,cAAc,iBAAiB;AAClF,kBAAY,gBAAgB;AAAA,IAC9B,SAAS,OAAO;AACd,UAAI,aAAa,KAAK,EAAG;AACzB,cAAQ,MAAM,qCAAqC,QAAQ,IAAI,KAAK;AAAA,IACtE,UAAE;AACA,UAAI,mBAAmB,YAAY,WAAW;AAC5C,6BAAqB,KAAK;AAAA,MAC5B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,iBAAiB,CAAC;AAEjC,QAAM,qBAAqBA,aAAY,OAAO,aAAqB;AACjE,uBAAmB,QAAQ;AAC3B,gBAAY,CAAC,CAAC;AAEd,UAAM,SAAS,uBAAuB;AACtC,+BAA2B,OAAO,QAAQ,KAAK,IAAI;AACnD,UAAM,mBAAmB,QAAQ;AAAA,EACnC,GAAG,CAAC,kBAAkB,CAAC;AAEvB,QAAM,qBAAqBA,aAAY,CAAC,UAAmB;AACzD,uBAAmB,WAAW;AAC9B,yBAAqB,KAAK;AAC1B,UAAM,KAAK,WAAW;AACtB,UAAM,MAAM,MAAM;AAClB,UAAM,YAAwB;AAAA,MAC5B;AAAA,MACA,OAAO,OAAO,KAAK,KAAK;AAAA,MACxB,WAAW;AAAA,MACX,WAAW;AAAA,MACX,cAAc;AAAA,MACd,UAAU,EAAE,cAAc,OAAO,KAAK,KAAK,OAAU;AAAA,IACvD;AAEA,eAAW,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC;AACzC,yBAAqB,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,cAAc,OAAO,KAAK,KAAK,OAAU,EAAE,EAAE;AAChG,2BAAuB,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE;AACxD,uBAAmB,EAAE;AACrB,+BAA2B,EAAE;AAC7B,gBAAY,CAAC,CAAC;AAAA,EAChB,GAAG,CAAC,CAAC;AAEL,QAAM,qBAAqBA,aAAY,OAAO,UAAkB,aAAqB;AACnF,UAAM,eAAe,SAAS,KAAK;AACnC,QAAI,CAAC,aAAc;AAGnB;AAAA,MAAW,CAAC,SACV,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,WAAW,EAAE,GAAG,GAAG,OAAO,cAAc,WAAW,MAAM,EAAE,IAAI,CAAE;AAAA,IAC7F;AAGA,UAAM,SAAS,uBAAuB;AACtC,UAAM,gBAAgB,OAAO,QAAQ,MAAM;AAE3C,QAAI,eAAe;AAEjB,2BAAqB,CAAC,UAAU;AAAA,QAC9B,GAAG;AAAA,QACH,CAAC,QAAQ,GAAG,EAAE,GAAG,KAAK,QAAQ,GAAG,cAAc,aAAa;AAAA,MAC9D,EAAE;AAAA,IACJ,OAAO;AAEL,UAAI;AACF,cAAM,aAAgB,UAAU,EAAE,MAAM,aAAa,GAAG,SAAS;AAAA,MACnE,SAAS,OAAO;AACd,gBAAQ,MAAM,4BAA4B,KAAK;AAE/C,YAAI,QAAQ;AACV,gBAAM,wBAAwB,QAAQ,2BAA2B,OAAO;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,QAAQ,uBAAuB,CAAC;AAE/C,QAAM,sBAAsBA,aAAY,OAAO,aAAqB;AAElE,UAAM,SAAS,WAAW,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,QAAQ;AAC/D,QAAI,CAAC,OAAQ;AAEb,UAAM,oBAAoB,CAAC,OAAO;AAGlC;AAAA,MAAW,CAAC,SACV,KAAK,IAAI,CAAC,MAAO,EAAE,OAAO,WAAW,EAAE,GAAG,GAAG,YAAY,mBAAmB,WAAW,MAAM,EAAE,IAAI,CAAE;AAAA,IACvG;AAGA,UAAM,SAAS,uBAAuB;AACtC,UAAM,gBAAgB,OAAO,QAAQ,MAAM;AAE3C,QAAI,CAAC,eAAe;AAClB,UAAI;AACF,cAAM,aAAgB,UAAU,EAAE,QAAQ,oBAAoB,aAAa,SAAS,GAAG,SAAS;AAAA,MAClG,SAAS,OAAO;AACd,gBAAQ,MAAM,6BAA6B,KAAK;AAEhD,YAAI,QAAQ;AACV,gBAAM,wBAAwB,QAAQ,2BAA2B,OAAO;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,QAAQ,uBAAuB,CAAC;AAE/C,QAAM,qBAAqBA,aAAY,OAAO,aAAqB;AAEjE,UAAM,SAAS,uBAAuB;AACtC,UAAM,gBAAgB,OAAO,QAAQ,MAAM;AAG3C,eAAW,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,EAAE,OAAO,QAAQ,CAAC;AAC1D,yBAAqB,CAAC,SAAS;AAC7B,YAAM,OAAO,EAAE,GAAG,KAAK;AACvB,aAAO,KAAK,QAAQ;AACpB,aAAO;AAAA,IACT,CAAC;AACD,2BAAuB,CAAC,SAAS;AAC/B,YAAM,OAAO,EAAE,GAAG,KAAK;AACvB,aAAO,KAAK,QAAQ;AACpB,aAAO;AAAA,IACT,CAAC;AAGD,QAAI,mBAAmB,YAAY,UAAU;AAC3C,YAAM,YAAY,WAAW,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,QAAQ;AACpE,UAAI,UAAU,SAAS,GAAG;AACxB,2BAAmB,UAAU,CAAC,EAAE,EAAE;AAClC,mCAA2B,OAAO,UAAU,CAAC,EAAE,EAAE,KAAK,IAAI;AAC1D,cAAM,mBAAmB,UAAU,CAAC,EAAE,EAAE;AAAA,MAC1C,OAAO;AACL,2BAAmB,IAAI;AACvB,mCAA2B,IAAI;AAC/B,oBAAY,CAAC,CAAC;AAAA,MAChB;AAAA,IACF;AAEA,QAAI,CAAC,eAAe;AAClB,UAAI;AACF,cAAM,aAAgB,UAAU,SAAS;AAAA,MAC3C,SAAS,OAAO;AACd,gBAAQ,MAAM,4BAA4B,KAAK;AAE/C,YAAI,QAAQ;AACV,gBAAM,wBAAwB,QAAQ,2BAA2B,OAAO;AAAA,QAC1E;AAAA,MACF;AAAA,IACF;AAAA,EACF,GAAG,CAAC,WAAW,QAAQ,yBAAyB,kBAAkB,CAAC;AAEnE,QAAM,aAAaA,aAAY,MAAM;AACnC,uBAAmB,SAAS,MAAM;AAClC,uBAAmB,UAAU;AAC7B,mBAAe,KAAK;AACpB,gBAAY,CAAC,SAAS;AAEpB,YAAM,eAAe,KAAK,KAAK,CAAC,QAAQ,IAAI,WAAW;AACvD,UAAI,CAAC,aAAc,QAAO;AAC1B,aAAO,KAAK,IAAI,CAAC,QAAS,IAAI,cAAc,EAAE,GAAG,KAAK,aAAa,OAAO,YAAY,KAAK,IAAI,GAAI;AAAA,IACrG,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,yBAAyBA,aAAY,CAAC,SAAc,uBAA+B;AAEvF,QAAI,CAAC,SAAS,QAAS;AAEvB,UAAM,WAAW,QAAQ,QAAQ;AACjC,UAAM,UAAU,QAAQ;AAGxB,QAAI,OAAoC;AACxC,QAAI,SAAS,WAAW,QAAQ,GAAG;AACjC,aAAO;AAAA,IACT,WAAW,SAAS,WAAW,QAAQ,GAAG;AACxC,aAAO;AAAA,IACT;AAEA,UAAM,kBAAmC;AAAA,MACvC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,gBAAY,CAAC,SAAS,KAAK,IAAI,CAAC,QAAS,IAAI,OAAO,qBAChD;AAAA,MACA,GAAG;AAAA,MACH,aAAa,CAAC,GAAI,IAAI,eAAe,CAAC,GAAI,eAAe;AAAA,MACzD,aAAa;AAAA,MACb,YAAY;AAAA,IACd,IACE,GAAI,CAAC;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,sBAAsBA,aAAY,OACtC,WAcG;AAEH,QAAI,qBAAqB,WAAW;AACpC,WAAO,gBAAgB,kBAAkB;AAEzC,QAAI,oBAAoB;AACxB,QAAI,iCAAiC;AAGrC,UAAM,yBAAyB,CAAC,YAAoB;AAClD,UAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,4BAAoB;AAAA,MACtB;AAIA,YAAM,gBAAgB;AACtB,YAAM,eAAe;AAErB,kBAAY,CAAC,SAAS;AAEpB,cAAM,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,OAAO,kBAAkB;AAC7D,YAAI,OAAO,KAAK,KAAK,GAAG,EAAE,SAAS,eAAe,KAAK,GAAG,EAAE,aAAa;AAEvE,gBAAM,MAAM,KAAK,GAAG;AACpB,cAAI,IAAI,YAAY,WAAW,IAAI,gBAAgB,iBAAiB,IAAI,eAAe,cAAc;AACnG,mBAAO;AAAA,UACT;AACA,gBAAM,UAAU,CAAC,GAAG,IAAI;AACxB,kBAAQ,GAAG,IAAI,EAAE,GAAG,KAAK,SAAS,SAAS,aAAa,eAAe,YAAY,aAAa;AAChG,iBAAO;AAAA,QACT;AAGA,cAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AACjC,YAAI,QAAQ,KAAK,SAAS,eAAe,KAAK,aAAa;AACzD,+BAAqB,KAAK;AAC1B,2CAAiC;AACjC,cAAI,KAAK,YAAY,WAAW,KAAK,gBAAgB,iBAAiB,KAAK,eAAe,cAAc;AACtG,mBAAO;AAAA,UACT;AACA,gBAAM,UAAU,CAAC,GAAG,IAAI;AACxB,kBAAQ,KAAK,SAAS,CAAC,IAAI,EAAE,GAAG,MAAM,SAAS,SAAS,aAAa,eAAe,YAAY,aAAa;AAC7G,iBAAO;AAAA,QACT;AAGA,YAAI,kCAAkC,CAAC,KAAK,WAAW,KAAK,KAAK,SAAS,CAAC,EAAE,SAAS,eAAe,CAAC,KAAK,KAAK,SAAS,CAAC,EAAE,cAAc;AACxI,gBAAM,QAAQ,WAAW;AACzB,+BAAqB;AACrB,2CAAiC;AACjC,iBAAO;AAAA,YACL,GAAG;AAAA,YACH;AAAA,cACE,IAAI;AAAA,cACJ,MAAM;AAAA,cACN,SAAS;AAAA,cACT,WAAW,MAAM;AAAA,cACjB,aAAa;AAAA,cACb,YAAY;AAAA,YACd;AAAA,UACF;AAAA,QACF;AAEA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,UAAM,iCAAiC,MAAM;AAC3C,kBAAY,CAAC,SAAS;AACpB,cAAM,MAAM,KAAK,UAAU,CAAC,MAAM,EAAE,OAAO,kBAAkB;AAC7D,YAAI,MAAM,EAAG,QAAO;AACpB,cAAM,MAAM,KAAK,GAAG;AAEpB,YAAI,CAAC,IAAI,eAAe,IAAI,WAAY,QAAO;AAC/C,cAAM,UAAU,CAAC,GAAG,IAAI;AACxB,gBAAQ,GAAG,IAAI,EAAE,GAAG,KAAK,aAAa,OAAO,YAAY,KAAK;AAC9D,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAGA,UAAM,cAAc,mBAAmB;AAGvC,UAAM,2BAA2B,OAAO,UAA8C;AACpF,UAAI,CAAC,MAAO,QAAO;AACnB,YAAM,OAAQ,OAAO,QAAmB;AACxC,YAAM,UAAU,OAAO,WAAW;AAGlC,UAAI,SAAS,aAAa;AACxB,cAAM,WAAY,SAAS,YAAY,CAAC;AACxC,cAAM,OAAQ,SAAS,QAAS,UAAkB;AAClD,cAAM,OAAQ,MAAM,YAAa,SAAiB;AAGlD,cAAM,WACH,MAAM,QACN,SAAS,QACT,MAAM,QACN,SAAS,YACT,SAAS,QACV;AAGF,YAAI,UAAmC,CAAC;AACxC,cAAM,eAAe;AAAA,UACnB,MAAM;AAAA;AAAA,UACN,SAAS;AAAA,UACT,MAAM;AAAA,UACL,UAAkB;AAAA,UAClB,UAAkB;AAAA,QACrB;AACA,mBAAW,aAAa,cAAc;AACpC,cAAI,cAAc,UAAa,cAAc,KAAM;AACnD,cAAI;AACF,gBAAI,OAAO,cAAc,UAAU;AACjC,wBAAU,KAAK,MAAM,SAAS;AAC9B;AAAA,YACF;AACA,gBAAI,OAAO,cAAc,UAAU;AACjC,wBAAU;AACV;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAAe;AAAA,QACzB;AAEA,cAAM,SACH,UAAkB,WAAW,SAAa,SAAiB,SACxD,SAAS,WAAW,SAAY,QAAQ,SACtC;AAGR,cAAM,SACH,MAAM,MACN,MAAM,MACN,SAAS,MACV,WAAW;AAEb,cAAM,YACH,SAAS,UACR,OAAe,UACjB;AAEF,eAAO;AAAA,UACL,IAAI,WAAW;AAAA,UACf,UAAU,eAAe;AAAA,UACzB,YAAY;AAAA,UACZ,SAAS;AAAA,UACT,WAAW,CAAC;AAAA,YACV,IAAI;AAAA,YACJ,MAAM;AAAA,YACN,MAAM;AAAA,YACN;AAAA,YACA,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAI,SAAS,aAAa,SAAS,eAAe;AAChD,cAAM,aAAa,SAAS,cAAc,SAAS,QAAQ;AAE3D,YAAI,eAAe,SAAS;AAC1B,iBAAO;AAAA,QACT;AACA,cAAM,UAAU,OAAO,SAAS,YAAY,WAAW,QAAQ,UAAU;AAEzE,YAAI,CAAC,QAAQ,KAAK,GAAG;AACnB,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,UACL,IAAI,WAAW;AAAA,UACf,UAAU,eAAe;AAAA,UACzB,YAAY;AAAA,UACZ;AAAA,UACA,UAAW,SAAS,YAAY,CAAC;AAAA,QACnC;AAAA,MACF;AAGA,UAAI,SAAS,iBAAiB;AAE5B,cAAM,KAAM,SAAS,MAAiB;AACtC,YAAI,MAAM,OAAO,OAAQ,QAAO;AAEhC,cAAM,OAAQ,SAAS,QAAmB;AAC1C,cAAM,MAAO,SAAS,OAAmB,SAAS,YAAuB;AACzE,YAAI,CAAC,IAAK,QAAO;AACjB,cAAM,OAAO,KAAK,WAAW,QAAQ,IAAI,UAAW,KAAK,WAAW,QAAQ,IAAI,UAAU;AAC1F,cAAM,UAAU;AAAA,UACd,IAAI,WAAW;AAAA,UACf,UAAU,eAAe;AAAA,UACzB,YAAY;AAAA,UACZ,SAAS;AAAA,UACT,UAAU;AAAA,YACR,aAAa,CAAC,EAAE,MAAM,UAAU,KAAK,UAAU,KAAK,CAAC;AAAA,UACvD;AAAA,QACF;AAEA,cAAM,CAAC,QAAQ,IAAI,MAAM,wBAAwB,CAAC,OAAO,CAAQ;AACjE,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,IACT;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,uBAAmB,SAAS,MAAM;AAClC,uBAAmB,UAAU;AAC7B,mBAAe,IAAI;AAEnB,QAAI;AACF,YAAM,yBAAyB,OAAO,eAClC,KAAK,MAAM,KAAK,UAAU,OAAO,YAAY,CAAC,IAC9C;AAEJ,YAAM,cAAc,mBAAmB;AACvC,YAAM,kBAAkB,cACpB,KAAK,MAAM,KAAK,UAAU,WAAW,CAAC,IACtC;AACJ,YAAM,iBAAiB,OAAO,WAAW,OAAO,QAAQ,SAAS,IAAI,OAAO,UAAU;AAEtF,YAAM,cAAc,OAAO,YAAY,OAAO,oBAAoB;AAElE,YAAM,2BAA2B,qBAAqB;AACtD,YAAM,kBAAkB,cAAc,yBAAyB,WAAW,GAAG,cAAqD;AAClI,YAAM,iBAAiB,cAAc,yBAAyB,WAAW,IAAI;AAE7E,YAAM,iBAAiB;AAAA,QACrB,GAAI,mBAAmB,CAAC;AAAA,QACxB,GAAI,OAAO,YAAY,CAAC;AAAA,MAC1B;AAEA,YAAM,gBAAgB,OAAO,KAAK,cAAc,EAAE,SAAS,IAAI,iBAAiB;AAEhF,YAAM,kBAAkB;AAAA,QACtB;AAAA,QACA,UAAU,OAAO,YAAY;AAAA,QAC7B,kBAAkB,OAAO,oBAAoB;AAAA,QAC7C,SAAS;AAAA,QACT,MAAM;AAAA,UACJ,YAAY,OAAO;AAAA,UACnB,MAAM,OAAO,YAAY,OAAO;AAAA,UAChC,UAAU;AAAA,YACR,GAAI,kBAAkB,kBAAkB,CAAC;AAAA,YACzC,GAAI,0BAA0B,CAAC;AAAA,UACjC;AAAA,QACF;AAAA,QACA,aAAa,OAAO;AAAA,QACpB,UAAU;AAAA,QACV,gBAAgB,OAAO,kBAAkB;AAAA,QACzC,WAAW,OAAO;AAAA,QAClB,eAAe,OAAO,aAAa,kBAAkB,WAAW;AAAA,QAChE,SAAS,CAAC,UAAU,uBAAuB,KAAK;AAAA,QAChD,gBAAgB,OAAO,UAAe;AACpC,gBAAM,cAAc,sBAAsB,KAAK;AAC/C,cAAI,eAAe,OAAO,gBAAgB,YAAY,YAAY,SAAS;AACzE;AAAA,UACF;AAEA,gBAAM,OAAQ,OAAO,QAAmB;AACxC,gBAAM,UAAU,gBAAgB,KAAK;AAGrC,cAAI,SAAS,aAAa,SAAS,eAAe;AAChD,kBAAM,aAAa,mBAAmB,OAAO;AAG7C,gBAAI,eAAe,QAAQ;AACzB,oBAAM,WAAY,SAAS,YAAY,CAAC;AAGxC,oBAAM,iBAAiB,UAAU;AACjC,oBAAM,eAAe,kBAAkB,eAAe,SAAS,IAAI,eAAe,CAAC,IAAI;AAEvF,kBAAI,CAAC,cAAc;AACjB;AAAA,cACF;AAIA,gCAAkB,QAAQ;AAG1B,oBAAM,aAAa,aAAa;AAChC,oBAAM,eAAe,aAAa;AAGlC,oBAAM,aAAa,aAAa,UAAU,SAAS;AAGnD,oBAAM,aAAc,aAAa,UAAqB;AACtD,oBAAM,WAAW,eAAe,YAAY,cAAc;AAG1D,0BAAY,CAAC,SAAS;AACpB,sBAAM,UAAU,CAAC,GAAG,IAAI;AAExB,yBAAS,IAAI,QAAQ,SAAS,GAAG,KAAK,GAAG,KAAK;AAC5C,sBAAI,QAAQ,CAAC,EAAE,SAAS,eAAe,QAAQ,CAAC,EAAE,WAAW;AAC3D,0BAAM,YAAY,QAAQ,CAAC,EAAE;AAC7B,wBAAI,WAAW;AAEb,0BAAI,gBAAgB,aAChB,UAAU,UAAU,QAAM,GAAG,OAAO,UAAU,IAC9C;AAGJ,0BAAI,kBAAkB,MAAM,cAAc;AACxC,wCAAgB,UAAU;AAAA,0BACxB,QAAM,GAAG,SAAS,iBACZ,GAAG,WAAW,aAAa,GAAG,WAAW;AAAA,wBACjD;AAAA,sBACF;AAEA,0BAAI,kBAAkB,IAAI;AACxB,8BAAM,mBAAmB,CAAC,GAAG,SAAS;AACtC,yCAAiB,aAAa,IAAI;AAAA,0BAChC,GAAG,iBAAiB,aAAa;AAAA,0BACjC,QAAQ,WAAW,WAAW;AAAA,0BAC9B,QAAQ;AAAA,0BACR,SAAS,KAAK,IAAI;AAAA,wBACpB;AACA,gCAAQ,CAAC,IAAI;AAAA,0BACX,GAAG,QAAQ,CAAC;AAAA,0BACZ,WAAW;AAAA,0BACX,aAAa;AAAA,0BACb,YAAY;AAAA,wBACd;AACA;AAAA,sBACF;AAAA,oBACF;AAAA,kBACF;AAAA,gBACF;AACA,uBAAO;AAAA,cACT,CAAC;AACD;AAAA,YACF;AAEA,qCAAyB,KAAK;AAC9B,gBAAI,eAAe,SAAS;AAC1B,mCAAqB,WAAW;AAChC,+CAAiC;AAAA,YACnC;AACA;AAAA,UACF;AAGA,cAAI,SAAS,aAAa;AACxB,kBAAMC,MAAK,MAAM,yBAAyB,KAAK;AAC/C,kBAAM,YAAYA,KAAI;AACtB,kBAAM,WAAW,aAAa,UAAU,CAAC;AACzC,gBAAI,CAAC,SAAU;AAEf;AAAA,cAAY,CAAC,UACV,MAAM;AACL,sBAAM,iBAAiB,CAAC,SAA0B;AAAA,kBAChD,GAAG;AAAA,kBACH,WAAW;AAAA,oBACT,GAAI,MAAM,QAAQ,IAAI,SAAS,IAAI,IAAI,YAAY,CAAC;AAAA,oBACpD;AAAA,sBACE,IAAK,SAAS,MAAiB,WAAW;AAAA,sBAC1C,MAAO,SAAS,QAAmB;AAAA,sBACnC,WACG,SAAS,QACT,SAAS,aACV,CAAC;AAAA,sBACH,QAAQ,SAAS;AAAA,sBACjB,QACG,SAAS,UACV;AAAA,sBACF,WAAW,KAAK,IAAI;AAAA,oBACtB;AAAA,kBACF;AAAA,gBACF;AAEA,sBAAM,aAAa,KAAK,UAAU,CAAC,YACjC,QAAQ,OAAO,sBACf,QAAQ,SAAS,eACjB,QAAQ,WACT;AACD,oBAAI,cAAc,GAAG;AACnB,wBAAM,OAAO,CAAC,GAAG,IAAI;AACrB,uBAAK,UAAU,IAAI,eAAe;AAAA,oBAChC,GAAG,KAAK,UAAU;AAAA,oBAClB,aAAa;AAAA,oBACb,YAAY;AAAA,kBACd,CAAC;AACD,yBAAO;AAAA,gBACT;AAEA,sBAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AACjC,oBAAI,CAAC,kCAAkC,MAAM,SAAS,eAAe,KAAK,aAAa;AACrF,uCAAqB,KAAK;AAC1B,wBAAM,OAAO,CAAC,GAAG,IAAI;AACrB,uBAAK,KAAK,SAAS,CAAC,IAAI,eAAe;AAAA,oBACrC,GAAG;AAAA,oBACH,aAAa;AAAA,oBACb,YAAY;AAAA,kBACd,CAAC;AACD,yBAAO;AAAA,gBACT;AAGA,sBAAM,QAAQ,WAAW;AACzB,qCAAqB;AACrB,iDAAiC;AACjC,uBAAO;AAAA,kBACL,GAAG;AAAA,kBACH,eAAe;AAAA,oBACb,IAAI;AAAA,oBACJ,MAAM;AAAA,oBACN,SAAS;AAAA,oBACT,WAAW,MAAM;AAAA,oBACjB,aAAa;AAAA,oBACb,YAAY;AAAA,kBACd,CAAC;AAAA,gBACH;AAAA,cACF,GAAG;AAAA,YACL;AACA,gCAAoB;AACpB,6CAAiC;AACjC;AAAA,UACF;AAGA,gBAAM,KAAK,MAAM,yBAAyB,KAAK;AAC/C,cAAI,IAAI;AACN,kBAAM,UAAU,qBAAqB,EAA8B;AACnE,2CAA+B;AAC/B,wBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC;AACxC,6CAAiC;AACjC;AAAA,UACF;AAGA,mCAAyB,KAAK;AAAA,QAChC;AAAA,QACA,cAAc,OAAO,YAAiB;AACpC,gBAAM,cAAc,sBAAsB,EAAE,MAAM,iBAAiB,QAAQ,CAAC;AAC5E,cAAI,eAAe,OAAO,gBAAgB,YAAY,YAAY,SAAS;AACzE;AAAA,UACF;AAGA,iBAAO,YAAY;AACjB,gBAAI,CAAC,kBAAmB;AACxB,2CAA+B;AAC/B,kBAAM,MAAM,EAAE,MAAM,iBAAiB,QAAQ;AAC7C,kBAAM,KAAK,MAAM,yBAAyB,GAAG;AAC7C,gBAAI,IAAI;AACN,oBAAM,UAAU,qBAAqB,EAA8B;AACnE,0BAAY,CAAC,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC;AAAA,YAC1C;AAEA,6CAAiC;AAAA,UACnC,GAAG;AAAA,QACL;AAAA,QACA,QAAQ,gBAAgB;AAAA,MAC1B,CAAC;AAAA,IACH,UAAE;AACA,qBAAe,KAAK;AACpB,kBAAY,CAAC,SAAS;AACpB,cAAM,eAAe,KAAK,KAAK,CAAC,QAAQ,IAAI,WAAW;AACvD,YAAI,CAAC,aAAc,QAAO;AAC1B,eAAO,KAAK,IAAI,CAAC,QAAS,IAAI,cAC1B,EAAE,GAAG,KAAK,aAAa,OAAO,YAAY,KAAK,IAC/C,GAAI;AAAA,MACV,CAAC;AACD,yBAAmB,UAAU;AAAA,IAC/B;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,uBAAuB,0BAA0B,sBAAsB,CAAC;AAEvF,QAAM,oBAAoBD,aAAY,OAAO,SAAiB,cAAiC,CAAC,MAAM;AACpG,QAAI,CAAC,QAAQ,KAAK,KAAK,YAAY,WAAW,EAAG;AACjD,QAAI,CAAC,OAAQ;AAEb,UAAM,YAAY,MAAM;AACxB,UAAM,cAAc,mBAAmB;AACvC,UAAM,iBAAiB,2BAA2B;AAElD,UAAM,mBAAmB,eAAe;AAExC,UAAM,SAAS,uBAAuB;AACtC,UAAM,sBAAsB,mBACxB,OAAO,gBAAgB,MAAM,mBAC7B;AAEJ,UAAM,kBAAkB,sBAAsB,SAAY;AAE1D,QAAI,4BAA4B,mBAAmB,sBAAsB,mBAAmB;AAE5F,QAAI,CAAC,iBAAiB;AACpB,UAAI,CAAC,2BAA2B;AAC9B,oCAA4B,WAAW;AAAA,MACzC;AACA,iCAA2B,yBAAyB;AAAA,IACtD,WAAW,oBAAoB,6BAA6B,OAAO;AACjE,iCAA2B,6BAA6B,IAAI;AAAA,IAC9D;AAEA,UAAM,kBAAkB,mBAAmB;AAG3C,UAAM,kBAAkB,qBAAqB,QAAQ,eAAe;AACpE,UAAM,eAAe,iBAAiB;AAEtC,UAAM,cAA+B;AAAA,MACnC,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,aAAa,YAAY,SAAS,IAAI,cAAc;AAAA,MACpD,YAAY;AAAA,IACd;AAGA,UAAM,uBAAwC;AAAA,MAC5C,IAAI,WAAW;AAAA,MACf,MAAM;AAAA,MACN,SAAS;AAAA,MACT,WAAW,YAAY;AAAA,MACvB,aAAa;AAAA,MACb,YAAY;AAAA,IACd;AAGA,gBAAY,CAAC,SAAS,CAAC,GAAG,MAAM,aAAa,oBAAoB,CAAC;AAClE,oBAAgB,IAAI;AAGpB,QAAI,CAAC,WAAW,QAAQ,KAAK,OAAK,EAAE,OAAO,eAAe,GAAG;AAC3D,YAAM,YAAwB;AAAA,QAC5B,IAAI;AAAA,QACJ,OAAO,QAAQ,MAAM,GAAG,EAAE,KAAK;AAAA,QAC/B,WAAW;AAAA,QACX,WAAW;AAAA,QACX,cAAc;AAAA,MAChB;AACA,iBAAW,UAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;AACvC,2BAAqB,WAAS,EAAE,GAAG,MAAM,CAAC,eAAe,GAAG,CAAC,EAAE,EAAE;AACjE,6BAAuB,WAAS,EAAE,GAAG,MAAM,CAAC,eAAe,GAAG,6BAA6B,KAAK,EAAE;AAAA,IACpG;AAEA,QAAI;AACF,YAAM,oBAAoB;AAAA,QACxB,UAAU;AAAA,QACV,kBAAkB;AAAA,QAClB;AAAA,QACA;AAAA,QACA;AAAA;AAAA,QAEA,UAAW,mBAAmB,SAAS,SAAiB,aAAa;AAAA,QACrE,WAAW,kBAAkB;AAAA;AAAA,QAE7B,gBAAgB,eAAe,EAAE,MAAM,aAAa,IAAI;AAAA,MAC1D,CAAC;AAGD,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAG5C,YAAM,wBAAwB,QAAQ,6BAA6B,oBAAoB,IAAI;AAAA,IAC7F,SAAS,OAAO;AACd,UAAI,aAAa,KAAK,EAAG;AACzB,cAAQ,MAAM,kCAAkC,KAAK;AACrD,YAAM,mBAAmB,yBAAyB,KAAK;AACvD,UAAI,kBAAkB;AACpB,wBAAgB,gBAAgB;AAChC,oBAAY,CAAC,SAAS,KAAK,OAAO,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC;AAC5D;AAAA,MACF;AACA,kBAAY,CAAC,SAAS,KAAK,IAAI,CAAC,QAAS,IAAI,cACzC;AAAA,QACA,GAAG;AAAA,QACH,aAAa;AAAA,QACb,YAAY;AAAA,QACZ,SAAS;AAAA,MACX,IACE,GAAI,CAAC;AAAA,IACX;AAAA,EACF,GAAG,CAAC,QAAQ,WAAW,yBAAyB,oBAAoB,qBAAqB,wBAAwB,CAAC;AAElH,QAAM,wBAAwBA,aAAY,OAAO,QAAgB;AAC/D,QAAI,CAAC,WAAW,oBAAoB,CAAC,WAAW,eAAgB;AAEhE,UAAM,4BAA4B,WAAW;AAC7C,uBAAmB,yBAAyB;AAC5C,+BAA2B,yBAAyB;AACpD,2BAAuB,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,yBAAyB,GAAG,0BAA0B,EAAE;AACtG,yBAAqB,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,yBAAyB,GAAG,CAAC,EAAE,EAAE;AAE7E,gBAAY,CAAC,CAAC;AACd,oBAAgB,IAAI;AAEpB,QAAI;AACF,YAAM,oBAAoB;AAAA,QACxB,kBAAkB;AAAA,QAClB,SAAS,UAAU,kBAAkB;AAAA,QACrC,WAAW,UAAU;AAAA,QACrB,QAAQ;AAAA,QACR,WAAW,kBAAkB;AAAA,QAC7B,gBAAgB;AAAA,UACd,MAAM,qBAAqB;AAAA,QAC7B;AAAA,MACF,CAAC;AAGD,YAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,GAAI,CAAC;AAI5C,YAAM,wBAAwB,KAAK,yBAAyB;AAAA,IAC9D,SAAS,OAAO;AACd,UAAI,aAAa,KAAK,EAAG;AACzB,cAAQ,MAAM,oCAAoC,KAAK;AACvD,YAAM,mBAAmB,yBAAyB,KAAK;AACvD,UAAI,kBAAkB;AACpB,wBAAgB,gBAAgB;AAChC,oBAAY,CAAC,CAAC;AACd;AAAA,MACF;AACA,kBAAY;AAAA,QACV;AAAA,UACE,IAAI,WAAW;AAAA,UACf,MAAM;AAAA,UACN,SAAS;AAAA,UACT,WAAW,MAAM;AAAA,UACjB,aAAa;AAAA,UACb,YAAY;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,WAAW,yBAAyB,oBAAoB,qBAAqB,WAAW,mBAAmB,wBAAwB,CAAC;AAExI,QAAM,QAAQA,aAAY,MAAM;AAC9B,uBAAmB,WAAW;AAC9B,eAAW,CAAC,CAAC;AACb,yBAAqB,CAAC,CAAC;AACvB,2BAAuB,CAAC,CAAC;AACzB,uBAAmB,IAAI;AACvB,+BAA2B,IAAI;AAC/B,gBAAY,CAAC,CAAC;AACd,uBAAmB,CAAC,CAAC;AACrB,yBAAqB,KAAK;AAC1B,mBAAe,KAAK;AACpB,oBAAgB,IAAI;AACpB,uBAAmB,SAAS,MAAM;AAAA,EACpC,GAAG,CAAC,CAAC;AAGL,EAAAD,WAAU,MAAM;AACd,QAAI,QAAQ;AAEV,UAAI,kBAAkB,QAAQ,WAAW,UAAU,kBAAkB,QAAQ,SAAS;AACpF;AAAA,MACF;AACA,wBAAkB,UAAU,EAAE,QAAQ,SAAS,KAAK;AAEpD,YAAM,OAAO,YAAY;AAEvB,cAAM,qBAAqB,mBAAmB,SAAS,WAAW;AAClE,cAAM,oBAAoB,MAAM,wBAAwB,QAAQ,kBAAkB;AAClF,YAAI,mBAAmB;AACrB,gBAAM,mBAAmB,iBAAiB;AAAA,QAC5C,WAAW,WAAW;AACpB,gBAAM,sBAAsB,MAAM;AAAA,QACpC;AAAA,MACF;AACA,WAAK;AAAA,IACP,OAAO;AACL,wBAAkB,UAAU,EAAE,QAAQ,MAAM,SAAS,MAAM;AAC3D,YAAM;AAAA,IACR;AAAA,EACF,GAAG,CAAC,QAAQ,WAAW,yBAAyB,oBAAoB,uBAAuB,OAAO,WAAW,kBAAkB,SAAS,QAAQ,CAAC;AAGjJ,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,iBAAkB;AAEvB,QAAI,CAAC,kBAAkB,QAAQ,QAAS;AAExC,mBAAe,uBAAuB;AAAA,EACxC,GAAG,CAAC,yBAAyB,kBAAkB,cAAc,CAAC;AAG9D,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,gBAAiB;AACtB,UAAM,WAAW,kBAAkB,eAAe;AAClD,QAAI,CAAC,SAAU;AAEf,QAAI,SAAS,eAAe,OAAO,SAAS,gBAAgB,UAAU;AACpE,yBAAmB,CAAC,UAAU,EAAE,GAAG,MAAM,GAAI,SAAS,YAAyC,EAAE;AAAA,IACnG;AAAA,EACF,GAAG,CAAC,iBAAiB,iBAAiB,CAAC;AAEvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb,cAAc;AAAA,IACd,cAAc;AAAA,IACd,cAAc;AAAA,IACd,eAAe;AAAA,IACf,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA;AAAA;AAAA,IAGA,eAAe,mBAAmB,SAAS,SAAS;AAAA;AAAA,IAEpD,oBAAoB;AAAA;AAAA,IAEpB,YAAY,mBAAmB,SAAS,UAAU;AAAA;AAAA,IAElD;AAAA,EACF;AACF;;;ANnxC4C;AA1JrC,IAAM,eAA4C,CAAC;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe,CAAC;AAAA,EAChB,kBAAkB;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,gBAAgB,aAAa,KAAK,CAAC,UAAU,MAAM,OAAO,eAAe,KAAK;AAEpF,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAAG;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,YAAY;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,mBAAmB,YAAY,QAAQ;AAAA,IACvC;AAAA,IACA,oBAAoB,eAAe,QAAQ;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAGD,QAAM,CAAC,eAAe,gBAAgB,IAAIC,UAAS,KAAK;AAGxD,EAAAC,WAAU,MAAM;AACd,QAAI,cAAc,iBAAiB,eAAe,iBAAiB;AAEjE,YAAM,cAAc,aAAa,KAAK,CAAC,MAAM,EAAE,OAAO,UAAU;AAChE,UAAI,aAAa;AACf,sBAAc,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,iBAAiB,eAAe,YAAY,CAAC;AAG7D,EAAAA,WAAU,MAAM;AACd,QAAI,mBAAmB,SAAS,SAAS;AACvC,oBAAc,eAAe;AAAA,IAC/B;AAAA,EACF,GAAG,CAAC,iBAAiB,SAAS,SAAS,aAAa,CAAC;AAGrD,EAAAA,WAAU,MAAM;AACd,QAAI,iBAAiB,CAAC,iBAAiB,SAAS,mBAAmB,aAAa;AAE9E,YAAM,QAAQ,WAAW,MAAM;AAC7B,aAAK,YAAY,aAAa;AAC9B,2BAAmB;AACnB,yBAAiB,IAAI;AAAA,MACvB,GAAG,GAAG;AACN,aAAO,MAAM,aAAa,KAAK;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,eAAe,eAAe,SAAS,gBAAgB,aAAa,kBAAkB,CAAC;AAI3F,QAAM,gBAA+B,QAAQ,OAAO;AAAA,IAClD,eAAe,CAAC,SAAS,gBAAgB;AACvC,WAAK,YAAY,SAAS,WAAW;AACrC,qBAAe,gBAAgB,SAAS,WAAW;AAAA,IACrD;AAAA,IACA,kBAAkB,MAAM;AACtB,qBAAe;AACf,qBAAe,mBAAmB;AAAA,IACpC;AAAA,IACA,gBAAgB,CAAC,UAAU;AACzB,mBAAa,KAAK;AAClB,qBAAe,iBAAiB,KAAK;AAAA,IACvC;AAAA,IACA,gBAAgB,CAAC,aAAa;AAC5B,WAAK,aAAa,QAAQ;AAC1B,qBAAe,iBAAiB,QAAQ;AAAA,IAC1C;AAAA,IACA,gBAAgB,CAAC,UAAU,aAAa;AACtC,WAAK,aAAa,UAAU,QAAQ;AACpC,qBAAe,iBAAiB,UAAU,QAAQ;AAAA,IACpD;AAAA,IACA,iBAAiB,CAAC,aAAa;AAC7B,WAAK,cAAc,QAAQ;AAC3B,qBAAe,kBAAkB,QAAQ;AAAA,IAC3C;AAAA,IACA,gBAAgB,CAAC,aAAa;AAC5B,WAAKF,cAAa,QAAQ;AAC1B,qBAAe,iBAAiB,QAAQ;AAAA,IAC1C;AAAA,IACA,eAAe,OAAO,WAAW,YAAY;AAC3C,UAAI;AACF,cAAM,UAAU,UAAU,UAAU,OAAO;AAC3C,uBAAe,gBAAgB,WAAW,OAAO;AAAA,MACnD,SAAS,OAAO;AACd,gBAAQ,MAAM,0BAA0B,KAAK;AAAA,MAC/C;AAAA,IACF;AAAA;AAAA,IAEA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI,CAAC,aAAa,gBAAgB,cAAc,cAAc,cAAc,eAAeA,eAAc,eAAe,UAAU,aAAa,CAAC;AAKhJ,QAAM,eAA2B,QAAQ,MAAM;AAC7C,UAAM,OAAO,cAAc,CAAC;AAC5B,QAAI,CAAC,iBAAiB;AACpB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,iBAAiB;AAAA,QACf,GAAG,KAAK;AAAA,QACR,WAAW;AAAA,QACX,MAAM,KAAK,iBAAiB,QAAQ,oBAAC,QAAK,WAAU,WAAU;AAAA,MAChE;AAAA,IACF;AAAA,EACF,GAAG,CAAC,YAAY,eAAe,CAAC;AAEhC,QAAM,oBAAoB,YAAY;AAEtC,QAAM,sBAAsB;AAC5B,QAAM,sBAAsB,eAAe,qBAAqB,cAAc,EAAE,OAAO,kBAAkB,CAAC,IAAI;AAE9G,SACE,oBAAC,2BAAwB,SAAS,iBAC/B,iCACC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,cAAc;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM;AAAA,QACJ,IAAI;AAAA,QACJ,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,MACV;AAAA,MACA,WAAW;AAAA,QACT,MAAM,YAAY,UAAU;AAAA,QAC5B,QAAQ,YAAY,UAAU;AAAA,QAC9B,aAAa,YAAY,UAAU;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MAEA,cACE,iBAAiB,CAAC,iBAAiB,SAAS,mBAAmB,cAC3D,gBACA;AAAA,MAEN,wBAAwB,MAAM;AAC5B,2BAAmB;AACnB,yBAAiB,IAAI;AAAA,MACvB;AAAA;AAAA,EACF,GAEJ;AAEJ;","names":["useEffect","useState","forwardRef","createElement","useState","useCallback","useRef","useEffect","offset","payload","rawBaseValue","rawBase","normalizedBase","API_BASE","apiUrl","useState","useRef","useEffect","useCallback","sm","deleteThread","useState","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@copilotz/chat-adapter",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Copilotz chat adapter and API hook",
5
5
  "type": "module",
6
6
  "module": "./dist/index.js",