@draht/web-ui 2026.3.2-2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/CHANGELOG.md +276 -0
  2. package/README.md +601 -0
  3. package/dist/ChatPanel.d.ts +28 -0
  4. package/dist/ChatPanel.d.ts.map +1 -0
  5. package/dist/ChatPanel.js +193 -0
  6. package/dist/ChatPanel.js.map +1 -0
  7. package/dist/app.css +2 -0
  8. package/dist/components/AgentInterface.d.ts +39 -0
  9. package/dist/components/AgentInterface.d.ts.map +1 -0
  10. package/dist/components/AgentInterface.js +384 -0
  11. package/dist/components/AgentInterface.js.map +1 -0
  12. package/dist/components/AttachmentTile.d.ts +12 -0
  13. package/dist/components/AttachmentTile.d.ts.map +1 -0
  14. package/dist/components/AttachmentTile.js +110 -0
  15. package/dist/components/AttachmentTile.js.map +1 -0
  16. package/dist/components/ConsoleBlock.d.ts +12 -0
  17. package/dist/components/ConsoleBlock.d.ts.map +1 -0
  18. package/dist/components/ConsoleBlock.js +81 -0
  19. package/dist/components/ConsoleBlock.js.map +1 -0
  20. package/dist/components/CustomProviderCard.d.ts +17 -0
  21. package/dist/components/CustomProviderCard.d.ts.map +1 -0
  22. package/dist/components/CustomProviderCard.js +112 -0
  23. package/dist/components/CustomProviderCard.js.map +1 -0
  24. package/dist/components/ExpandableSection.d.ts +15 -0
  25. package/dist/components/ExpandableSection.d.ts.map +1 -0
  26. package/dist/components/ExpandableSection.js +61 -0
  27. package/dist/components/ExpandableSection.js.map +1 -0
  28. package/dist/components/Input.d.ts +26 -0
  29. package/dist/components/Input.d.ts.map +1 -0
  30. package/dist/components/Input.js +57 -0
  31. package/dist/components/Input.js.map +1 -0
  32. package/dist/components/MessageEditor.d.ts +44 -0
  33. package/dist/components/MessageEditor.d.ts.map +1 -0
  34. package/dist/components/MessageEditor.js +418 -0
  35. package/dist/components/MessageEditor.js.map +1 -0
  36. package/dist/components/MessageList.d.ts +14 -0
  37. package/dist/components/MessageList.d.ts.map +1 -0
  38. package/dist/components/MessageList.js +104 -0
  39. package/dist/components/MessageList.js.map +1 -0
  40. package/dist/components/Messages.d.ts +95 -0
  41. package/dist/components/Messages.d.ts.map +1 -0
  42. package/dist/components/Messages.js +363 -0
  43. package/dist/components/Messages.js.map +1 -0
  44. package/dist/components/ProviderKeyInput.d.ts +16 -0
  45. package/dist/components/ProviderKeyInput.d.ts.map +1 -0
  46. package/dist/components/ProviderKeyInput.js +168 -0
  47. package/dist/components/ProviderKeyInput.js.map +1 -0
  48. package/dist/components/SandboxedIframe.d.ts +85 -0
  49. package/dist/components/SandboxedIframe.d.ts.map +1 -0
  50. package/dist/components/SandboxedIframe.js +518 -0
  51. package/dist/components/SandboxedIframe.js.map +1 -0
  52. package/dist/components/StreamingMessageContainer.d.ts +19 -0
  53. package/dist/components/StreamingMessageContainer.d.ts.map +1 -0
  54. package/dist/components/StreamingMessageContainer.js +117 -0
  55. package/dist/components/StreamingMessageContainer.js.map +1 -0
  56. package/dist/components/ThinkingBlock.d.ts +11 -0
  57. package/dist/components/ThinkingBlock.d.ts.map +1 -0
  58. package/dist/components/ThinkingBlock.js +56 -0
  59. package/dist/components/ThinkingBlock.js.map +1 -0
  60. package/dist/components/message-renderer-registry.d.ts +12 -0
  61. package/dist/components/message-renderer-registry.d.ts.map +1 -0
  62. package/dist/components/message-renderer-registry.js +12 -0
  63. package/dist/components/message-renderer-registry.js.map +1 -0
  64. package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts +35 -0
  65. package/dist/components/sandbox/ArtifactsRuntimeProvider.d.ts.map +1 -0
  66. package/dist/components/sandbox/ArtifactsRuntimeProvider.js +192 -0
  67. package/dist/components/sandbox/ArtifactsRuntimeProvider.js.map +1 -0
  68. package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts +17 -0
  69. package/dist/components/sandbox/AttachmentsRuntimeProvider.d.ts.map +1 -0
  70. package/dist/components/sandbox/AttachmentsRuntimeProvider.js +65 -0
  71. package/dist/components/sandbox/AttachmentsRuntimeProvider.js.map +1 -0
  72. package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts +42 -0
  73. package/dist/components/sandbox/ConsoleRuntimeProvider.d.ts.map +1 -0
  74. package/dist/components/sandbox/ConsoleRuntimeProvider.js +159 -0
  75. package/dist/components/sandbox/ConsoleRuntimeProvider.js.map +1 -0
  76. package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts +30 -0
  77. package/dist/components/sandbox/FileDownloadRuntimeProvider.d.ts.map +1 -0
  78. package/dist/components/sandbox/FileDownloadRuntimeProvider.js +95 -0
  79. package/dist/components/sandbox/FileDownloadRuntimeProvider.js.map +1 -0
  80. package/dist/components/sandbox/RuntimeMessageBridge.d.ts +19 -0
  81. package/dist/components/sandbox/RuntimeMessageBridge.d.ts.map +1 -0
  82. package/dist/components/sandbox/RuntimeMessageBridge.js +74 -0
  83. package/dist/components/sandbox/RuntimeMessageBridge.js.map +1 -0
  84. package/dist/components/sandbox/RuntimeMessageRouter.d.ts +65 -0
  85. package/dist/components/sandbox/RuntimeMessageRouter.d.ts.map +1 -0
  86. package/dist/components/sandbox/RuntimeMessageRouter.js +166 -0
  87. package/dist/components/sandbox/RuntimeMessageRouter.js.map +1 -0
  88. package/dist/components/sandbox/SandboxRuntimeProvider.d.ts +48 -0
  89. package/dist/components/sandbox/SandboxRuntimeProvider.d.ts.map +1 -0
  90. package/dist/components/sandbox/SandboxRuntimeProvider.js +2 -0
  91. package/dist/components/sandbox/SandboxRuntimeProvider.js.map +1 -0
  92. package/dist/dialogs/ApiKeyPromptDialog.d.ts +15 -0
  93. package/dist/dialogs/ApiKeyPromptDialog.d.ts.map +1 -0
  94. package/dist/dialogs/ApiKeyPromptDialog.js +77 -0
  95. package/dist/dialogs/ApiKeyPromptDialog.js.map +1 -0
  96. package/dist/dialogs/AttachmentOverlay.d.ts +32 -0
  97. package/dist/dialogs/AttachmentOverlay.d.ts.map +1 -0
  98. package/dist/dialogs/AttachmentOverlay.js +576 -0
  99. package/dist/dialogs/AttachmentOverlay.js.map +1 -0
  100. package/dist/dialogs/CustomProviderDialog.d.ts +25 -0
  101. package/dist/dialogs/CustomProviderDialog.d.ts.map +1 -0
  102. package/dist/dialogs/CustomProviderDialog.js +270 -0
  103. package/dist/dialogs/CustomProviderDialog.js.map +1 -0
  104. package/dist/dialogs/ModelSelector.d.ts +27 -0
  105. package/dist/dialogs/ModelSelector.d.ts.map +1 -0
  106. package/dist/dialogs/ModelSelector.js +320 -0
  107. package/dist/dialogs/ModelSelector.js.map +1 -0
  108. package/dist/dialogs/PersistentStorageDialog.d.ts +17 -0
  109. package/dist/dialogs/PersistentStorageDialog.d.ts.map +1 -0
  110. package/dist/dialogs/PersistentStorageDialog.js +144 -0
  111. package/dist/dialogs/PersistentStorageDialog.js.map +1 -0
  112. package/dist/dialogs/ProvidersModelsTab.d.ts +20 -0
  113. package/dist/dialogs/ProvidersModelsTab.d.ts.map +1 -0
  114. package/dist/dialogs/ProvidersModelsTab.js +188 -0
  115. package/dist/dialogs/ProvidersModelsTab.js.map +1 -0
  116. package/dist/dialogs/SessionListDialog.d.ts +19 -0
  117. package/dist/dialogs/SessionListDialog.d.ts.map +1 -0
  118. package/dist/dialogs/SessionListDialog.js +152 -0
  119. package/dist/dialogs/SessionListDialog.js.map +1 -0
  120. package/dist/dialogs/SettingsDialog.d.ts +30 -0
  121. package/dist/dialogs/SettingsDialog.d.ts.map +1 -0
  122. package/dist/dialogs/SettingsDialog.js +222 -0
  123. package/dist/dialogs/SettingsDialog.js.map +1 -0
  124. package/dist/index.d.ts +67 -0
  125. package/dist/index.d.ts.map +1 -0
  126. package/dist/index.js +70 -0
  127. package/dist/index.js.map +1 -0
  128. package/dist/prompts/prompts.d.ts +11 -0
  129. package/dist/prompts/prompts.d.ts.map +1 -0
  130. package/dist/prompts/prompts.js +272 -0
  131. package/dist/prompts/prompts.js.map +1 -0
  132. package/dist/storage/app-storage.d.ts +33 -0
  133. package/dist/storage/app-storage.d.ts.map +1 -0
  134. package/dist/storage/app-storage.js +43 -0
  135. package/dist/storage/app-storage.js.map +1 -0
  136. package/dist/storage/backends/indexeddb-storage-backend.d.ts +27 -0
  137. package/dist/storage/backends/indexeddb-storage-backend.d.ts.map +1 -0
  138. package/dist/storage/backends/indexeddb-storage-backend.js +167 -0
  139. package/dist/storage/backends/indexeddb-storage-backend.js.map +1 -0
  140. package/dist/storage/store.d.ts +23 -0
  141. package/dist/storage/store.d.ts.map +1 -0
  142. package/dist/storage/store.js +24 -0
  143. package/dist/storage/store.js.map +1 -0
  144. package/dist/storage/stores/custom-providers-store.d.ts +25 -0
  145. package/dist/storage/stores/custom-providers-store.d.ts.map +1 -0
  146. package/dist/storage/stores/custom-providers-store.js +35 -0
  147. package/dist/storage/stores/custom-providers-store.js.map +1 -0
  148. package/dist/storage/stores/provider-keys-store.d.ts +14 -0
  149. package/dist/storage/stores/provider-keys-store.d.ts.map +1 -0
  150. package/dist/storage/stores/provider-keys-store.js +27 -0
  151. package/dist/storage/stores/provider-keys-store.js.map +1 -0
  152. package/dist/storage/stores/sessions-store.d.ts +32 -0
  153. package/dist/storage/stores/sessions-store.d.ts.map +1 -0
  154. package/dist/storage/stores/sessions-store.js +113 -0
  155. package/dist/storage/stores/sessions-store.js.map +1 -0
  156. package/dist/storage/stores/settings-store.d.ts +14 -0
  157. package/dist/storage/stores/settings-store.d.ts.map +1 -0
  158. package/dist/storage/stores/settings-store.js +28 -0
  159. package/dist/storage/stores/settings-store.js.map +1 -0
  160. package/dist/storage/types.d.ts +176 -0
  161. package/dist/storage/types.d.ts.map +1 -0
  162. package/dist/storage/types.js +2 -0
  163. package/dist/storage/types.js.map +1 -0
  164. package/dist/tools/artifacts/ArtifactElement.d.ts +9 -0
  165. package/dist/tools/artifacts/ArtifactElement.d.ts.map +1 -0
  166. package/dist/tools/artifacts/ArtifactElement.js +8 -0
  167. package/dist/tools/artifacts/ArtifactElement.js.map +1 -0
  168. package/dist/tools/artifacts/ArtifactPill.d.ts +4 -0
  169. package/dist/tools/artifacts/ArtifactPill.d.ts.map +1 -0
  170. package/dist/tools/artifacts/ArtifactPill.js +23 -0
  171. package/dist/tools/artifacts/ArtifactPill.js.map +1 -0
  172. package/dist/tools/artifacts/Console.d.ts +18 -0
  173. package/dist/tools/artifacts/Console.d.ts.map +1 -0
  174. package/dist/tools/artifacts/Console.js +92 -0
  175. package/dist/tools/artifacts/Console.js.map +1 -0
  176. package/dist/tools/artifacts/DocxArtifact.d.ts +22 -0
  177. package/dist/tools/artifacts/DocxArtifact.d.ts.map +1 -0
  178. package/dist/tools/artifacts/DocxArtifact.js +205 -0
  179. package/dist/tools/artifacts/DocxArtifact.js.map +1 -0
  180. package/dist/tools/artifacts/ExcelArtifact.d.ts +24 -0
  181. package/dist/tools/artifacts/ExcelArtifact.d.ts.map +1 -0
  182. package/dist/tools/artifacts/ExcelArtifact.js +213 -0
  183. package/dist/tools/artifacts/ExcelArtifact.js.map +1 -0
  184. package/dist/tools/artifacts/GenericArtifact.d.ts +19 -0
  185. package/dist/tools/artifacts/GenericArtifact.d.ts.map +1 -0
  186. package/dist/tools/artifacts/GenericArtifact.js +114 -0
  187. package/dist/tools/artifacts/GenericArtifact.js.map +1 -0
  188. package/dist/tools/artifacts/HtmlArtifact.d.ts +27 -0
  189. package/dist/tools/artifacts/HtmlArtifact.d.ts.map +1 -0
  190. package/dist/tools/artifacts/HtmlArtifact.js +187 -0
  191. package/dist/tools/artifacts/HtmlArtifact.js.map +1 -0
  192. package/dist/tools/artifacts/ImageArtifact.d.ts +20 -0
  193. package/dist/tools/artifacts/ImageArtifact.d.ts.map +1 -0
  194. package/dist/tools/artifacts/ImageArtifact.js +117 -0
  195. package/dist/tools/artifacts/ImageArtifact.js.map +1 -0
  196. package/dist/tools/artifacts/MarkdownArtifact.d.ts +19 -0
  197. package/dist/tools/artifacts/MarkdownArtifact.d.ts.map +1 -0
  198. package/dist/tools/artifacts/MarkdownArtifact.js +79 -0
  199. package/dist/tools/artifacts/MarkdownArtifact.js.map +1 -0
  200. package/dist/tools/artifacts/PdfArtifact.d.ts +25 -0
  201. package/dist/tools/artifacts/PdfArtifact.d.ts.map +1 -0
  202. package/dist/tools/artifacts/PdfArtifact.js +181 -0
  203. package/dist/tools/artifacts/PdfArtifact.js.map +1 -0
  204. package/dist/tools/artifacts/SvgArtifact.d.ts +18 -0
  205. package/dist/tools/artifacts/SvgArtifact.d.ts.map +1 -0
  206. package/dist/tools/artifacts/SvgArtifact.js +75 -0
  207. package/dist/tools/artifacts/SvgArtifact.js.map +1 -0
  208. package/dist/tools/artifacts/TextArtifact.d.ts +19 -0
  209. package/dist/tools/artifacts/TextArtifact.d.ts.map +1 -0
  210. package/dist/tools/artifacts/TextArtifact.js +141 -0
  211. package/dist/tools/artifacts/TextArtifact.js.map +1 -0
  212. package/dist/tools/artifacts/artifacts-tool-renderer.d.ts +11 -0
  213. package/dist/tools/artifacts/artifacts-tool-renderer.d.ts.map +1 -0
  214. package/dist/tools/artifacts/artifacts-tool-renderer.js +273 -0
  215. package/dist/tools/artifacts/artifacts-tool-renderer.js.map +1 -0
  216. package/dist/tools/artifacts/artifacts.d.ts +63 -0
  217. package/dist/tools/artifacts/artifacts.d.ts.map +1 -0
  218. package/dist/tools/artifacts/artifacts.js +664 -0
  219. package/dist/tools/artifacts/artifacts.js.map +1 -0
  220. package/dist/tools/artifacts/index.d.ts +8 -0
  221. package/dist/tools/artifacts/index.d.ts.map +1 -0
  222. package/dist/tools/artifacts/index.js +8 -0
  223. package/dist/tools/artifacts/index.js.map +1 -0
  224. package/dist/tools/extract-document.d.ts +24 -0
  225. package/dist/tools/extract-document.d.ts.map +1 -0
  226. package/dist/tools/extract-document.js +216 -0
  227. package/dist/tools/extract-document.js.map +1 -0
  228. package/dist/tools/index.d.ts +16 -0
  229. package/dist/tools/index.d.ts.map +1 -0
  230. package/dist/tools/index.js +33 -0
  231. package/dist/tools/index.js.map +1 -0
  232. package/dist/tools/javascript-repl.d.ts +44 -0
  233. package/dist/tools/javascript-repl.d.ts.map +1 -0
  234. package/dist/tools/javascript-repl.js +224 -0
  235. package/dist/tools/javascript-repl.js.map +1 -0
  236. package/dist/tools/renderer-registry.d.ts +23 -0
  237. package/dist/tools/renderer-registry.d.ts.map +1 -0
  238. package/dist/tools/renderer-registry.js +107 -0
  239. package/dist/tools/renderer-registry.js.map +1 -0
  240. package/dist/tools/renderers/BashRenderer.d.ts +10 -0
  241. package/dist/tools/renderers/BashRenderer.d.ts.map +1 -0
  242. package/dist/tools/renderers/BashRenderer.js +42 -0
  243. package/dist/tools/renderers/BashRenderer.js.map +1 -0
  244. package/dist/tools/renderers/CalculateRenderer.d.ts +10 -0
  245. package/dist/tools/renderers/CalculateRenderer.d.ts.map +1 -0
  246. package/dist/tools/renderers/CalculateRenderer.js +45 -0
  247. package/dist/tools/renderers/CalculateRenderer.js.map +1 -0
  248. package/dist/tools/renderers/DefaultRenderer.d.ts +6 -0
  249. package/dist/tools/renderers/DefaultRenderer.d.ts.map +1 -0
  250. package/dist/tools/renderers/DefaultRenderer.js +94 -0
  251. package/dist/tools/renderers/DefaultRenderer.js.map +1 -0
  252. package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts +10 -0
  253. package/dist/tools/renderers/GetCurrentTimeRenderer.d.ts.map +1 -0
  254. package/dist/tools/renderers/GetCurrentTimeRenderer.js +72 -0
  255. package/dist/tools/renderers/GetCurrentTimeRenderer.js.map +1 -0
  256. package/dist/tools/types.d.ts +10 -0
  257. package/dist/tools/types.d.ts.map +1 -0
  258. package/dist/tools/types.js +2 -0
  259. package/dist/tools/types.js.map +1 -0
  260. package/dist/utils/attachment-utils.d.ts +19 -0
  261. package/dist/utils/attachment-utils.d.ts.map +1 -0
  262. package/dist/utils/attachment-utils.js +415 -0
  263. package/dist/utils/attachment-utils.js.map +1 -0
  264. package/dist/utils/auth-token.d.ts +3 -0
  265. package/dist/utils/auth-token.d.ts.map +1 -0
  266. package/dist/utils/auth-token.js +19 -0
  267. package/dist/utils/auth-token.js.map +1 -0
  268. package/dist/utils/format.d.ts +6 -0
  269. package/dist/utils/format.d.ts.map +1 -0
  270. package/dist/utils/format.js +47 -0
  271. package/dist/utils/format.js.map +1 -0
  272. package/dist/utils/i18n.d.ts +636 -0
  273. package/dist/utils/i18n.d.ts.map +1 -0
  274. package/dist/utils/i18n.js +418 -0
  275. package/dist/utils/i18n.js.map +1 -0
  276. package/dist/utils/model-discovery.d.ts +38 -0
  277. package/dist/utils/model-discovery.d.ts.map +1 -0
  278. package/dist/utils/model-discovery.js +243 -0
  279. package/dist/utils/model-discovery.js.map +1 -0
  280. package/dist/utils/proxy-utils.d.ts +45 -0
  281. package/dist/utils/proxy-utils.d.ts.map +1 -0
  282. package/dist/utils/proxy-utils.js +116 -0
  283. package/dist/utils/proxy-utils.js.map +1 -0
  284. package/dist/utils/test-sessions.d.ts +359 -0
  285. package/dist/utils/test-sessions.d.ts.map +1 -0
  286. package/dist/utils/test-sessions.js +2325 -0
  287. package/dist/utils/test-sessions.js.map +1 -0
  288. package/example/README.md +61 -0
  289. package/example/index.html +13 -0
  290. package/example/package.json +25 -0
  291. package/example/src/app.css +1 -0
  292. package/example/src/custom-messages.ts +99 -0
  293. package/example/src/env.d.ts +1 -0
  294. package/example/src/main.ts +421 -0
  295. package/example/tsconfig.json +23 -0
  296. package/example/vite.config.ts +6 -0
  297. package/package.json +53 -0
  298. package/scripts/count-prompt-tokens.ts +88 -0
  299. package/src/ChatPanel.ts +207 -0
  300. package/src/app.css +68 -0
  301. package/src/components/AgentInterface.ts +388 -0
  302. package/src/components/AttachmentTile.ts +107 -0
  303. package/src/components/ConsoleBlock.ts +72 -0
  304. package/src/components/CustomProviderCard.ts +100 -0
  305. package/src/components/ExpandableSection.ts +46 -0
  306. package/src/components/Input.ts +113 -0
  307. package/src/components/MessageEditor.ts +400 -0
  308. package/src/components/MessageList.ts +95 -0
  309. package/src/components/Messages.ts +383 -0
  310. package/src/components/ProviderKeyInput.ts +153 -0
  311. package/src/components/SandboxedIframe.ts +626 -0
  312. package/src/components/StreamingMessageContainer.ts +103 -0
  313. package/src/components/ThinkingBlock.ts +43 -0
  314. package/src/components/message-renderer-registry.ts +28 -0
  315. package/src/components/sandbox/ArtifactsRuntimeProvider.ts +219 -0
  316. package/src/components/sandbox/AttachmentsRuntimeProvider.ts +66 -0
  317. package/src/components/sandbox/ConsoleRuntimeProvider.ts +186 -0
  318. package/src/components/sandbox/FileDownloadRuntimeProvider.ts +110 -0
  319. package/src/components/sandbox/RuntimeMessageBridge.ts +82 -0
  320. package/src/components/sandbox/RuntimeMessageRouter.ts +216 -0
  321. package/src/components/sandbox/SandboxRuntimeProvider.ts +52 -0
  322. package/src/dialogs/ApiKeyPromptDialog.ts +75 -0
  323. package/src/dialogs/AttachmentOverlay.ts +636 -0
  324. package/src/dialogs/CustomProviderDialog.ts +274 -0
  325. package/src/dialogs/ModelSelector.ts +313 -0
  326. package/src/dialogs/PersistentStorageDialog.ts +144 -0
  327. package/src/dialogs/ProvidersModelsTab.ts +212 -0
  328. package/src/dialogs/SessionListDialog.ts +150 -0
  329. package/src/dialogs/SettingsDialog.ts +214 -0
  330. package/src/index.ts +119 -0
  331. package/src/prompts/prompts.ts +282 -0
  332. package/src/storage/app-storage.ts +60 -0
  333. package/src/storage/backends/indexeddb-storage-backend.ts +193 -0
  334. package/src/storage/store.ts +33 -0
  335. package/src/storage/stores/custom-providers-store.ts +62 -0
  336. package/src/storage/stores/provider-keys-store.ts +33 -0
  337. package/src/storage/stores/sessions-store.ts +136 -0
  338. package/src/storage/stores/settings-store.ts +34 -0
  339. package/src/storage/types.ts +206 -0
  340. package/src/tools/artifacts/ArtifactElement.ts +14 -0
  341. package/src/tools/artifacts/ArtifactPill.ts +26 -0
  342. package/src/tools/artifacts/Console.ts +93 -0
  343. package/src/tools/artifacts/DocxArtifact.ts +213 -0
  344. package/src/tools/artifacts/ExcelArtifact.ts +231 -0
  345. package/src/tools/artifacts/GenericArtifact.ts +117 -0
  346. package/src/tools/artifacts/HtmlArtifact.ts +195 -0
  347. package/src/tools/artifacts/ImageArtifact.ts +116 -0
  348. package/src/tools/artifacts/MarkdownArtifact.ts +82 -0
  349. package/src/tools/artifacts/PdfArtifact.ts +201 -0
  350. package/src/tools/artifacts/SvgArtifact.ts +78 -0
  351. package/src/tools/artifacts/TextArtifact.ts +148 -0
  352. package/src/tools/artifacts/artifacts-tool-renderer.ts +310 -0
  353. package/src/tools/artifacts/artifacts.ts +713 -0
  354. package/src/tools/artifacts/index.ts +7 -0
  355. package/src/tools/extract-document.ts +275 -0
  356. package/src/tools/index.ts +46 -0
  357. package/src/tools/javascript-repl.ts +293 -0
  358. package/src/tools/renderer-registry.ts +130 -0
  359. package/src/tools/renderers/BashRenderer.ts +52 -0
  360. package/src/tools/renderers/CalculateRenderer.ts +58 -0
  361. package/src/tools/renderers/DefaultRenderer.ts +103 -0
  362. package/src/tools/renderers/GetCurrentTimeRenderer.ts +92 -0
  363. package/src/tools/types.ts +15 -0
  364. package/src/utils/attachment-utils.ts +472 -0
  365. package/src/utils/auth-token.ts +22 -0
  366. package/src/utils/format.ts +42 -0
  367. package/src/utils/i18n.ts +653 -0
  368. package/src/utils/model-discovery.ts +277 -0
  369. package/src/utils/proxy-utils.ts +134 -0
  370. package/src/utils/test-sessions.ts +2357 -0
  371. package/tsconfig.build.json +20 -0
  372. package/tsconfig.json +7 -0
package/README.md ADDED
@@ -0,0 +1,601 @@
1
+ # @mariozechner/pi-web-ui
2
+
3
+ Reusable web UI components for building AI chat interfaces powered by [@mariozechner/pi-ai](../ai) and [@mariozechner/pi-agent-core](../agent).
4
+
5
+ Built with [mini-lit](https://github.com/badlogic/mini-lit) web components and Tailwind CSS v4.
6
+
7
+ ## Features
8
+
9
+ - **Chat UI**: Complete interface with message history, streaming, and tool execution
10
+ - **Tools**: JavaScript REPL, document extraction, and artifacts (HTML, SVG, Markdown, etc.)
11
+ - **Attachments**: PDF, DOCX, XLSX, PPTX, images with preview and text extraction
12
+ - **Artifacts**: Interactive HTML, SVG, Markdown with sandboxed execution
13
+ - **Storage**: IndexedDB-backed storage for sessions, API keys, and settings
14
+ - **CORS Proxy**: Automatic proxy handling for browser environments
15
+ - **Custom Providers**: Support for Ollama, LM Studio, vLLM, and OpenAI-compatible APIs
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @mariozechner/pi-web-ui @mariozechner/pi-agent-core @mariozechner/pi-ai
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ See the [example](./example) directory for a complete working application.
26
+
27
+ ```typescript
28
+ import { Agent } from '@mariozechner/pi-agent-core';
29
+ import { getModel } from '@mariozechner/pi-ai';
30
+ import {
31
+ ChatPanel,
32
+ AppStorage,
33
+ IndexedDBStorageBackend,
34
+ ProviderKeysStore,
35
+ SessionsStore,
36
+ SettingsStore,
37
+ setAppStorage,
38
+ defaultConvertToLlm,
39
+ ApiKeyPromptDialog,
40
+ } from '@mariozechner/pi-web-ui';
41
+ import '@mariozechner/pi-web-ui/app.css';
42
+
43
+ // Set up storage
44
+ const settings = new SettingsStore();
45
+ const providerKeys = new ProviderKeysStore();
46
+ const sessions = new SessionsStore();
47
+
48
+ const backend = new IndexedDBStorageBackend({
49
+ dbName: 'my-app',
50
+ version: 1,
51
+ stores: [
52
+ settings.getConfig(),
53
+ providerKeys.getConfig(),
54
+ sessions.getConfig(),
55
+ SessionsStore.getMetadataConfig(),
56
+ ],
57
+ });
58
+
59
+ settings.setBackend(backend);
60
+ providerKeys.setBackend(backend);
61
+ sessions.setBackend(backend);
62
+
63
+ const storage = new AppStorage(settings, providerKeys, sessions, undefined, backend);
64
+ setAppStorage(storage);
65
+
66
+ // Create agent
67
+ const agent = new Agent({
68
+ initialState: {
69
+ systemPrompt: 'You are a helpful assistant.',
70
+ model: getModel('anthropic', 'claude-sonnet-4-5-20250929'),
71
+ thinkingLevel: 'off',
72
+ messages: [],
73
+ tools: [],
74
+ },
75
+ convertToLlm: defaultConvertToLlm,
76
+ });
77
+
78
+ // Create chat panel
79
+ const chatPanel = new ChatPanel();
80
+ await chatPanel.setAgent(agent, {
81
+ onApiKeyRequired: (provider) => ApiKeyPromptDialog.prompt(provider),
82
+ });
83
+
84
+ document.body.appendChild(chatPanel);
85
+ ```
86
+
87
+ ## Architecture
88
+
89
+ ```
90
+ ┌─────────────────────────────────────────────────────┐
91
+ │ ChatPanel │
92
+ │ ┌─────────────────────┐ ┌─────────────────────┐ │
93
+ │ │ AgentInterface │ │ ArtifactsPanel │ │
94
+ │ │ (messages, input) │ │ (HTML, SVG, MD) │ │
95
+ │ └─────────────────────┘ └─────────────────────┘ │
96
+ └─────────────────────────────────────────────────────┘
97
+
98
+
99
+ ┌─────────────────────────────────────────────────────┐
100
+ │ Agent (from pi-agent-core) │
101
+ │ - State management (messages, model, tools) │
102
+ │ - Event emission (agent_start, message_update, ...) │
103
+ │ - Tool execution │
104
+ └─────────────────────────────────────────────────────┘
105
+
106
+
107
+ ┌─────────────────────────────────────────────────────┐
108
+ │ AppStorage │
109
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
110
+ │ │ Settings │ │ Provider │ │ Sessions │ │
111
+ │ │ Store │ │Keys Store│ │ Store │ │
112
+ │ └──────────┘ └──────────┘ └──────────┘ │
113
+ │ │ │
114
+ │ IndexedDBStorageBackend │
115
+ └─────────────────────────────────────────────────────┘
116
+ ```
117
+
118
+ ## Components
119
+
120
+ ### ChatPanel
121
+
122
+ High-level chat interface with built-in artifacts panel.
123
+
124
+ ```typescript
125
+ const chatPanel = new ChatPanel();
126
+ await chatPanel.setAgent(agent, {
127
+ // Prompt for API key when needed
128
+ onApiKeyRequired: async (provider) => ApiKeyPromptDialog.prompt(provider),
129
+
130
+ // Hook before sending messages
131
+ onBeforeSend: async () => { /* save draft, etc. */ },
132
+
133
+ // Handle cost display click
134
+ onCostClick: () => { /* show cost breakdown */ },
135
+
136
+ // Custom sandbox URL for browser extensions
137
+ sandboxUrlProvider: () => chrome.runtime.getURL('sandbox.html'),
138
+
139
+ // Add custom tools
140
+ toolsFactory: (agent, agentInterface, artifactsPanel, runtimeProvidersFactory) => {
141
+ const replTool = createJavaScriptReplTool();
142
+ replTool.runtimeProvidersFactory = runtimeProvidersFactory;
143
+ return [replTool];
144
+ },
145
+ });
146
+ ```
147
+
148
+ ### AgentInterface
149
+
150
+ Lower-level chat interface for custom layouts.
151
+
152
+ ```typescript
153
+ const chat = document.createElement('agent-interface') as AgentInterface;
154
+ chat.session = agent;
155
+ chat.enableAttachments = true;
156
+ chat.enableModelSelector = true;
157
+ chat.enableThinkingSelector = true;
158
+ chat.onApiKeyRequired = async (provider) => { /* ... */ };
159
+ chat.onBeforeSend = async () => { /* ... */ };
160
+ ```
161
+
162
+ Properties:
163
+ - `session`: Agent instance
164
+ - `enableAttachments`: Show attachment button (default: true)
165
+ - `enableModelSelector`: Show model selector (default: true)
166
+ - `enableThinkingSelector`: Show thinking level selector (default: true)
167
+ - `showThemeToggle`: Show theme toggle (default: false)
168
+
169
+ ### Agent (from pi-agent-core)
170
+
171
+ ```typescript
172
+ import { Agent } from '@mariozechner/pi-agent-core';
173
+
174
+ const agent = new Agent({
175
+ initialState: {
176
+ model: getModel('anthropic', 'claude-sonnet-4-5-20250929'),
177
+ systemPrompt: 'You are helpful.',
178
+ thinkingLevel: 'off',
179
+ messages: [],
180
+ tools: [],
181
+ },
182
+ convertToLlm: defaultConvertToLlm,
183
+ });
184
+
185
+ // Events
186
+ agent.subscribe((event) => {
187
+ switch (event.type) {
188
+ case 'agent_start': // Agent loop started
189
+ case 'agent_end': // Agent loop finished
190
+ case 'turn_start': // LLM call started
191
+ case 'turn_end': // LLM call finished
192
+ case 'message_start':
193
+ case 'message_update': // Streaming update
194
+ case 'message_end':
195
+ break;
196
+ }
197
+ });
198
+
199
+ // Send message
200
+ await agent.prompt('Hello!');
201
+ await agent.prompt({ role: 'user-with-attachments', content: 'Check this', attachments, timestamp: Date.now() });
202
+
203
+ // Control
204
+ agent.abort();
205
+ agent.setModel(newModel);
206
+ agent.setThinkingLevel('medium');
207
+ agent.setTools([...]);
208
+ agent.queueMessage(customMessage);
209
+ ```
210
+
211
+ ## Message Types
212
+
213
+ ### UserMessageWithAttachments
214
+
215
+ User message with file attachments:
216
+
217
+ ```typescript
218
+ const message: UserMessageWithAttachments = {
219
+ role: 'user-with-attachments',
220
+ content: 'Analyze this document',
221
+ attachments: [pdfAttachment],
222
+ timestamp: Date.now(),
223
+ };
224
+
225
+ // Type guard
226
+ if (isUserMessageWithAttachments(msg)) {
227
+ console.log(msg.attachments);
228
+ }
229
+ ```
230
+
231
+ ### ArtifactMessage
232
+
233
+ For session persistence of artifacts:
234
+
235
+ ```typescript
236
+ const artifact: ArtifactMessage = {
237
+ role: 'artifact',
238
+ action: 'create', // or 'update', 'delete'
239
+ filename: 'chart.html',
240
+ content: '<div>...</div>',
241
+ timestamp: new Date().toISOString(),
242
+ };
243
+
244
+ // Type guard
245
+ if (isArtifactMessage(msg)) {
246
+ console.log(msg.filename);
247
+ }
248
+ ```
249
+
250
+ ### Custom Message Types
251
+
252
+ Extend via declaration merging:
253
+
254
+ ```typescript
255
+ interface SystemNotification {
256
+ role: 'system-notification';
257
+ message: string;
258
+ level: 'info' | 'warning' | 'error';
259
+ timestamp: string;
260
+ }
261
+
262
+ declare module '@mariozechner/pi-agent-core' {
263
+ interface CustomAgentMessages {
264
+ 'system-notification': SystemNotification;
265
+ }
266
+ }
267
+
268
+ // Register renderer
269
+ registerMessageRenderer('system-notification', {
270
+ render: (msg) => html`<div class="alert">${msg.message}</div>`,
271
+ });
272
+
273
+ // Extend convertToLlm
274
+ function myConvertToLlm(messages: AgentMessage[]): Message[] {
275
+ const processed = messages.map((m) => {
276
+ if (m.role === 'system-notification') {
277
+ return { role: 'user', content: `<system>${m.message}</system>`, timestamp: Date.now() };
278
+ }
279
+ return m;
280
+ });
281
+ return defaultConvertToLlm(processed);
282
+ }
283
+ ```
284
+
285
+ ## Message Transformer
286
+
287
+ `convertToLlm` transforms app messages to LLM-compatible format:
288
+
289
+ ```typescript
290
+ import { defaultConvertToLlm, convertAttachments } from '@mariozechner/pi-web-ui';
291
+
292
+ // defaultConvertToLlm handles:
293
+ // - UserMessageWithAttachments → user message with image/text content blocks
294
+ // - ArtifactMessage → filtered out (UI-only)
295
+ // - Standard messages (user, assistant, toolResult) → passed through
296
+ ```
297
+
298
+ ## Tools
299
+
300
+ ### JavaScript REPL
301
+
302
+ Execute JavaScript in a sandboxed browser environment:
303
+
304
+ ```typescript
305
+ import { createJavaScriptReplTool } from '@mariozechner/pi-web-ui';
306
+
307
+ const replTool = createJavaScriptReplTool();
308
+
309
+ // Configure runtime providers for artifact/attachment access
310
+ replTool.runtimeProvidersFactory = () => [
311
+ new AttachmentsRuntimeProvider(attachments),
312
+ new ArtifactsRuntimeProvider(artifactsPanel, agent, true), // read-write
313
+ ];
314
+
315
+ agent.setTools([replTool]);
316
+ ```
317
+
318
+ ### Extract Document
319
+
320
+ Extract text from documents at URLs:
321
+
322
+ ```typescript
323
+ import { createExtractDocumentTool } from '@mariozechner/pi-web-ui';
324
+
325
+ const extractTool = createExtractDocumentTool();
326
+ extractTool.corsProxyUrl = 'https://corsproxy.io/?';
327
+
328
+ agent.setTools([extractTool]);
329
+ ```
330
+
331
+ ### Artifacts Tool
332
+
333
+ Built into ArtifactsPanel, supports: HTML, SVG, Markdown, text, JSON, images, PDF, DOCX, XLSX.
334
+
335
+ ```typescript
336
+ const artifactsPanel = new ArtifactsPanel();
337
+ artifactsPanel.agent = agent;
338
+
339
+ // The tool is available as artifactsPanel.tool
340
+ agent.setTools([artifactsPanel.tool]);
341
+ ```
342
+
343
+ ### Custom Tool Renderers
344
+
345
+ ```typescript
346
+ import { registerToolRenderer, type ToolRenderer } from '@mariozechner/pi-web-ui';
347
+
348
+ const myRenderer: ToolRenderer = {
349
+ render(params, result, isStreaming) {
350
+ return {
351
+ content: html`<div>...</div>`,
352
+ isCustom: false, // true = no card wrapper
353
+ };
354
+ },
355
+ };
356
+
357
+ registerToolRenderer('my_tool', myRenderer);
358
+ ```
359
+
360
+ ## Storage
361
+
362
+ ### Setup
363
+
364
+ ```typescript
365
+ import {
366
+ AppStorage,
367
+ IndexedDBStorageBackend,
368
+ SettingsStore,
369
+ ProviderKeysStore,
370
+ SessionsStore,
371
+ CustomProvidersStore,
372
+ setAppStorage,
373
+ getAppStorage,
374
+ } from '@mariozechner/pi-web-ui';
375
+
376
+ // Create stores
377
+ const settings = new SettingsStore();
378
+ const providerKeys = new ProviderKeysStore();
379
+ const sessions = new SessionsStore();
380
+ const customProviders = new CustomProvidersStore();
381
+
382
+ // Create backend with all store configs
383
+ const backend = new IndexedDBStorageBackend({
384
+ dbName: 'my-app',
385
+ version: 1,
386
+ stores: [
387
+ settings.getConfig(),
388
+ providerKeys.getConfig(),
389
+ sessions.getConfig(),
390
+ SessionsStore.getMetadataConfig(),
391
+ customProviders.getConfig(),
392
+ ],
393
+ });
394
+
395
+ // Wire stores to backend
396
+ settings.setBackend(backend);
397
+ providerKeys.setBackend(backend);
398
+ sessions.setBackend(backend);
399
+ customProviders.setBackend(backend);
400
+
401
+ // Create and set global storage
402
+ const storage = new AppStorage(settings, providerKeys, sessions, customProviders, backend);
403
+ setAppStorage(storage);
404
+ ```
405
+
406
+ ### SettingsStore
407
+
408
+ Key-value settings:
409
+
410
+ ```typescript
411
+ await storage.settings.set('proxy.enabled', true);
412
+ await storage.settings.set('proxy.url', 'https://proxy.example.com');
413
+ const enabled = await storage.settings.get<boolean>('proxy.enabled');
414
+ ```
415
+
416
+ ### ProviderKeysStore
417
+
418
+ API keys by provider:
419
+
420
+ ```typescript
421
+ await storage.providerKeys.set('anthropic', 'sk-ant-...');
422
+ const key = await storage.providerKeys.get('anthropic');
423
+ const providers = await storage.providerKeys.list();
424
+ ```
425
+
426
+ ### SessionsStore
427
+
428
+ Chat sessions with metadata:
429
+
430
+ ```typescript
431
+ // Save session
432
+ await storage.sessions.save(sessionData, metadata);
433
+
434
+ // Load session
435
+ const data = await storage.sessions.get(sessionId);
436
+ const metadata = await storage.sessions.getMetadata(sessionId);
437
+
438
+ // List sessions (sorted by lastModified)
439
+ const allMetadata = await storage.sessions.getAllMetadata();
440
+
441
+ // Update title
442
+ await storage.sessions.updateTitle(sessionId, 'New Title');
443
+
444
+ // Delete
445
+ await storage.sessions.delete(sessionId);
446
+ ```
447
+
448
+ ### CustomProvidersStore
449
+
450
+ Custom LLM providers:
451
+
452
+ ```typescript
453
+ const provider: CustomProvider = {
454
+ id: crypto.randomUUID(),
455
+ name: 'My Ollama',
456
+ type: 'ollama',
457
+ baseUrl: 'http://localhost:11434',
458
+ };
459
+
460
+ await storage.customProviders.set(provider);
461
+ const all = await storage.customProviders.getAll();
462
+ ```
463
+
464
+ ## Attachments
465
+
466
+ Load and process files:
467
+
468
+ ```typescript
469
+ import { loadAttachment, type Attachment } from '@mariozechner/pi-web-ui';
470
+
471
+ // From File input
472
+ const file = inputElement.files[0];
473
+ const attachment = await loadAttachment(file);
474
+
475
+ // From URL
476
+ const attachment = await loadAttachment('https://example.com/doc.pdf');
477
+
478
+ // From ArrayBuffer
479
+ const attachment = await loadAttachment(arrayBuffer, 'document.pdf');
480
+
481
+ // Attachment structure
482
+ interface Attachment {
483
+ id: string;
484
+ type: 'image' | 'document';
485
+ fileName: string;
486
+ mimeType: string;
487
+ size: number;
488
+ content: string; // base64 encoded
489
+ extractedText?: string; // For documents
490
+ preview?: string; // base64 preview image
491
+ }
492
+ ```
493
+
494
+ Supported formats: PDF, DOCX, XLSX, PPTX, images, text files.
495
+
496
+ ## CORS Proxy
497
+
498
+ For browser environments with CORS restrictions:
499
+
500
+ ```typescript
501
+ import { createStreamFn, shouldUseProxyForProvider, isCorsError } from '@mariozechner/pi-web-ui';
502
+
503
+ // AgentInterface auto-configures proxy from settings
504
+ // For manual setup:
505
+ agent.streamFn = createStreamFn(async () => {
506
+ const enabled = await storage.settings.get<boolean>('proxy.enabled');
507
+ return enabled ? await storage.settings.get<string>('proxy.url') : undefined;
508
+ });
509
+
510
+ // Providers requiring proxy:
511
+ // - zai: always
512
+ // - anthropic: only OAuth tokens (sk-ant-oat-*)
513
+ ```
514
+
515
+ ## Dialogs
516
+
517
+ ### SettingsDialog
518
+
519
+ ```typescript
520
+ import { SettingsDialog, ProvidersModelsTab, ProxyTab, ApiKeysTab } from '@mariozechner/pi-web-ui';
521
+
522
+ SettingsDialog.open([
523
+ new ProvidersModelsTab(), // Custom providers + model list
524
+ new ProxyTab(), // CORS proxy settings
525
+ new ApiKeysTab(), // API keys per provider
526
+ ]);
527
+ ```
528
+
529
+ ### SessionListDialog
530
+
531
+ ```typescript
532
+ import { SessionListDialog } from '@mariozechner/pi-web-ui';
533
+
534
+ SessionListDialog.open(
535
+ async (sessionId) => { /* load session */ },
536
+ (deletedId) => { /* handle deletion */ },
537
+ );
538
+ ```
539
+
540
+ ### ApiKeyPromptDialog
541
+
542
+ ```typescript
543
+ import { ApiKeyPromptDialog } from '@mariozechner/pi-web-ui';
544
+
545
+ const success = await ApiKeyPromptDialog.prompt('anthropic');
546
+ ```
547
+
548
+ ### ModelSelector
549
+
550
+ ```typescript
551
+ import { ModelSelector } from '@mariozechner/pi-web-ui';
552
+
553
+ ModelSelector.open(currentModel, (selectedModel) => {
554
+ agent.setModel(selectedModel);
555
+ });
556
+ ```
557
+
558
+ ## Styling
559
+
560
+ Import the pre-built CSS:
561
+
562
+ ```typescript
563
+ import '@mariozechner/pi-web-ui/app.css';
564
+ ```
565
+
566
+ Or use Tailwind with custom config:
567
+
568
+ ```css
569
+ @import '@mariozechner/mini-lit/themes/claude.css';
570
+ @tailwind base;
571
+ @tailwind components;
572
+ @tailwind utilities;
573
+ ```
574
+
575
+ ## Internationalization
576
+
577
+ ```typescript
578
+ import { i18n, setLanguage, translations } from '@mariozechner/pi-web-ui';
579
+
580
+ // Add translations
581
+ translations.de = {
582
+ 'Loading...': 'Laden...',
583
+ 'No sessions yet': 'Noch keine Sitzungen',
584
+ };
585
+
586
+ setLanguage('de');
587
+ console.log(i18n('Loading...')); // "Laden..."
588
+ ```
589
+
590
+ ## Examples
591
+
592
+ - [example/](./example) - Complete web app with sessions, artifacts, custom messages
593
+ - [sitegeist](https://sitegeist.ai) - Browser extension using pi-web-ui
594
+
595
+ ## Known Issues
596
+
597
+ - **PersistentStorageDialog**: Currently broken
598
+
599
+ ## License
600
+
601
+ MIT
@@ -0,0 +1,28 @@
1
+ import { LitElement } from "lit";
2
+ import "./components/AgentInterface.js";
3
+ import type { Agent, AgentTool } from "@draht/agent-core";
4
+ import type { AgentInterface } from "./components/AgentInterface.js";
5
+ import type { SandboxRuntimeProvider } from "./components/sandbox/SandboxRuntimeProvider.js";
6
+ import { ArtifactsPanel } from "./tools/artifacts/index.js";
7
+ export declare class ChatPanel extends LitElement {
8
+ agent?: Agent;
9
+ agentInterface?: AgentInterface;
10
+ artifactsPanel?: ArtifactsPanel;
11
+ private hasArtifacts;
12
+ private artifactCount;
13
+ private showArtifactsPanel;
14
+ private windowWidth;
15
+ private resizeHandler;
16
+ createRenderRoot(): this;
17
+ connectedCallback(): void;
18
+ disconnectedCallback(): void;
19
+ setAgent(agent: Agent, config?: {
20
+ onApiKeyRequired?: (provider: string) => Promise<boolean>;
21
+ onBeforeSend?: () => void | Promise<void>;
22
+ onCostClick?: () => void;
23
+ sandboxUrlProvider?: () => string;
24
+ toolsFactory?: (agent: Agent, agentInterface: AgentInterface, artifactsPanel: ArtifactsPanel, runtimeProvidersFactory: () => SandboxRuntimeProvider[]) => AgentTool<any>[];
25
+ }): Promise<void>;
26
+ render(): import("lit").TemplateResult<1>;
27
+ }
28
+ //# sourceMappingURL=ChatPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChatPanel.d.ts","sourceRoot":"","sources":["../src/ChatPanel.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,UAAU,EAAE,MAAM,KAAK,CAAC;AAEvC,OAAO,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAGrE,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAC;AAC7F,OAAO,EAAE,cAAc,EAAyB,MAAM,4BAA4B,CAAC;AAOnF,qBACa,SAAU,SAAQ,UAAU;IACxB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,cAAc,CAAC,EAAE,cAAc,CAAC;IACvC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,WAAW,CAAK;IAEjC,OAAO,CAAC,aAAa,CAGnB;IAEF,gBAAgB,SAEf;IAEQ,iBAAiB,SAazB;IAEQ,oBAAoB,SAG5B;IAEK,QAAQ,CACb,KAAK,EAAE,KAAK,EACZ,MAAM,CAAC,EAAE;QACR,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1D,YAAY,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1C,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;QACzB,kBAAkB,CAAC,EAAE,MAAM,MAAM,CAAC;QAClC,YAAY,CAAC,EAAE,CACd,KAAK,EAAE,KAAK,EACZ,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,cAAc,EAC9B,uBAAuB,EAAE,MAAM,sBAAsB,EAAE,KACnD,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;KACtB,iBAsFD;IAED,MAAM,oCAiDL;CACD"}