@k2b/ui 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/README.md +1 -1
  2. package/dist/base.css +147 -2
  3. package/dist/browser/actions/ContextMenu.js +35 -4
  4. package/dist/browser/actions/ContextMenu.js.map +1 -1
  5. package/dist/browser/actions/DragAndDrop.js +89 -0
  6. package/dist/browser/actions/DragAndDrop.js.map +1 -0
  7. package/dist/browser/actions/Dropdown.js +184 -158
  8. package/dist/browser/actions/Dropdown.js.map +1 -1
  9. package/dist/browser/actions/GestureMenu.js +95 -139
  10. package/dist/browser/actions/GestureMenu.js.map +1 -1
  11. package/dist/browser/actions/Toolbar.js +379 -48
  12. package/dist/browser/actions/Toolbar.js.map +1 -1
  13. package/dist/browser/actions/drag-and-drop-messages.js +75 -0
  14. package/dist/browser/actions/drag-and-drop-messages.js.map +1 -0
  15. package/dist/browser/actions/drag-and-drop.js +692 -0
  16. package/dist/browser/actions/drag-and-drop.js.map +1 -0
  17. package/dist/browser/actions/index.js +1 -0
  18. package/dist/browser/actions/index.js.map +1 -1
  19. package/dist/browser/actions/menu-rows.js +15 -0
  20. package/dist/browser/actions/menu-rows.js.map +1 -0
  21. package/dist/browser/actions/menu-sheet.js +154 -0
  22. package/dist/browser/actions/menu-sheet.js.map +1 -0
  23. package/dist/browser/actions/toolbar-messages.js +20 -0
  24. package/dist/browser/actions/toolbar-messages.js.map +1 -0
  25. package/dist/browser/chart-inspection.js +3 -0
  26. package/dist/browser/chart-inspection.js.map +1 -0
  27. package/dist/browser/chat/ChatComposer.js +714 -410
  28. package/dist/browser/chat/ChatComposer.js.map +1 -1
  29. package/dist/browser/chat/ChatDecision.js +778 -0
  30. package/dist/browser/chat/ChatDecision.js.map +1 -0
  31. package/dist/browser/chat/ChatPrimitives.js +34 -28
  32. package/dist/browser/chat/ChatPrimitives.js.map +1 -1
  33. package/dist/browser/chat/ChatTimeline.js.map +1 -1
  34. package/dist/browser/chat/chat-messages.js +25 -1
  35. package/dist/browser/chat/chat-messages.js.map +1 -1
  36. package/dist/browser/chat/command-search.js +13 -3
  37. package/dist/browser/chat/command-search.js.map +1 -1
  38. package/dist/browser/chat/index.js +8 -1
  39. package/dist/browser/chat/index.js.map +1 -1
  40. package/dist/browser/chat/reaction-people.js +15 -0
  41. package/dist/browser/chat/reaction-people.js.map +1 -0
  42. package/dist/browser/chat/types.js.map +1 -1
  43. package/dist/browser/content/Calendar.js +3 -3
  44. package/dist/browser/content/Calendar.js.map +1 -1
  45. package/dist/browser/content/Chart.js +60 -86
  46. package/dist/browser/content/Chart.js.map +1 -1
  47. package/dist/browser/content/ChartSnapshotView.js +7 -10
  48. package/dist/browser/content/ChartSnapshotView.js.map +1 -1
  49. package/dist/browser/content/FileBrowser.js +2 -2
  50. package/dist/browser/content/FileBrowser.js.map +1 -1
  51. package/dist/browser/content/FileTree.js +42 -36
  52. package/dist/browser/content/FileTree.js.map +1 -1
  53. package/dist/browser/content/FileTypeIcon.js +72 -0
  54. package/dist/browser/content/FileTypeIcon.js.map +1 -0
  55. package/dist/browser/content/FileView.js +2 -2
  56. package/dist/browser/content/FileView.js.map +1 -1
  57. package/dist/browser/content/MessageRow.js +330 -448
  58. package/dist/browser/content/MessageRow.js.map +1 -1
  59. package/dist/browser/content/ReactionBar.js +419 -0
  60. package/dist/browser/content/ReactionBar.js.map +1 -0
  61. package/dist/browser/content/ReferenceChip.js +162 -0
  62. package/dist/browser/content/ReferenceChip.js.map +1 -0
  63. package/dist/browser/content/calendar-pointer.js +9 -0
  64. package/dist/browser/content/calendar-pointer.js.map +1 -1
  65. package/dist/browser/content/calendar-time-view.js +6 -3
  66. package/dist/browser/content/calendar-time-view.js.map +1 -1
  67. package/dist/browser/content/chart-inspection-core.js +557 -0
  68. package/dist/browser/content/chart-inspection-core.js.map +1 -0
  69. package/dist/browser/content/chart-inspection.js +10 -445
  70. package/dist/browser/content/chart-inspection.js.map +1 -1
  71. package/dist/browser/content/chart-line-gaps.js +1 -1
  72. package/dist/browser/content/chart-line-gaps.js.map +1 -1
  73. package/dist/browser/content/chart-snapshot.js +1 -1
  74. package/dist/browser/content/chart-snapshot.js.map +1 -1
  75. package/dist/browser/content/index.js +3 -0
  76. package/dist/browser/content/index.js.map +1 -1
  77. package/dist/browser/feedback/dialog-core.js +135 -23
  78. package/dist/browser/feedback/dialog-core.js.map +1 -1
  79. package/dist/browser/index.js +1 -0
  80. package/dist/browser/index.js.map +1 -1
  81. package/dist/browser/input-mode.js +40 -0
  82. package/dist/browser/input-mode.js.map +1 -0
  83. package/dist/browser/inputs/FileDropTarget.js +24 -9
  84. package/dist/browser/inputs/FileDropTarget.js.map +1 -1
  85. package/dist/browser/inputs/FileInputs.js +2 -2
  86. package/dist/browser/inputs/FileInputs.js.map +1 -1
  87. package/dist/browser/inputs/SelectChip.js +9 -0
  88. package/dist/browser/inputs/SelectChip.js.map +1 -1
  89. package/dist/browser/inputs/emoji/EmojiPicker.js +13 -0
  90. package/dist/browser/inputs/emoji/EmojiPicker.js.map +1 -1
  91. package/dist/browser/inputs/file-drop.js.map +1 -1
  92. package/dist/browser/layout/AppOverview.js +1 -1
  93. package/dist/browser/layout/AppOverview.js.map +1 -1
  94. package/dist/browser/layout/AppWorkspace.js +644 -445
  95. package/dist/browser/layout/AppWorkspace.js.map +1 -1
  96. package/dist/browser/layout/DetailPanel.js +283 -197
  97. package/dist/browser/layout/DetailPanel.js.map +1 -1
  98. package/dist/browser/layout/Discussion.js +233 -185
  99. package/dist/browser/layout/Discussion.js.map +1 -1
  100. package/dist/browser/layout/PanelDialog.js +88 -86
  101. package/dist/browser/layout/PanelDialog.js.map +1 -1
  102. package/dist/browser/layout/ResizeSeparator.js +81 -0
  103. package/dist/browser/layout/ResizeSeparator.js.map +1 -0
  104. package/dist/browser/layout/SidebarSwitcher.js +9 -2
  105. package/dist/browser/layout/SidebarSwitcher.js.map +1 -1
  106. package/dist/browser/layout/TabBar.js +15 -12
  107. package/dist/browser/layout/TabBar.js.map +1 -1
  108. package/dist/browser/layout/TableOfContents.js +10 -2
  109. package/dist/browser/layout/TableOfContents.js.map +1 -1
  110. package/dist/browser/layout/app-workspace-controller.js +130 -17
  111. package/dist/browser/layout/app-workspace-controller.js.map +1 -1
  112. package/dist/browser/layout/detail-panel-messages.js +35 -0
  113. package/dist/browser/layout/detail-panel-messages.js.map +1 -0
  114. package/dist/browser/layout/index.js +3 -1
  115. package/dist/browser/layout/index.js.map +1 -1
  116. package/dist/browser/layout/resize-separator.js +90 -0
  117. package/dist/browser/layout/resize-separator.js.map +1 -0
  118. package/dist/browser/layout/workspace-messages.js +12 -2
  119. package/dist/browser/layout/workspace-messages.js.map +1 -1
  120. package/dist/browser/surfaces/Avatar.js +50 -20
  121. package/dist/browser/surfaces/Avatar.js.map +1 -1
  122. package/dist/browser/surfaces/AvatarStack.js +406 -0
  123. package/dist/browser/surfaces/AvatarStack.js.map +1 -0
  124. package/dist/browser/surfaces/LinkCard.js +1 -1
  125. package/dist/browser/surfaces/LinkCard.js.map +1 -1
  126. package/dist/browser/surfaces/Placeholder.js +14 -3
  127. package/dist/browser/surfaces/Placeholder.js.map +1 -1
  128. package/dist/browser/surfaces/StatCell.js +23 -0
  129. package/dist/browser/surfaces/StatCell.js.map +1 -1
  130. package/dist/browser/surfaces/avatar-messages.js +8 -2
  131. package/dist/browser/surfaces/avatar-messages.js.map +1 -1
  132. package/dist/browser/surfaces/index.js +1 -0
  133. package/dist/browser/surfaces/index.js.map +1 -1
  134. package/dist/browser/widgets/Widget.js +1 -1
  135. package/dist/browser/widgets/Widget.js.map +1 -1
  136. package/dist/ssr/actions/ContextMenu.js +26 -3
  137. package/dist/ssr/actions/ContextMenu.js.map +1 -1
  138. package/dist/ssr/actions/DragAndDrop.js +63 -0
  139. package/dist/ssr/actions/DragAndDrop.js.map +1 -0
  140. package/dist/ssr/actions/Dropdown.js +140 -72
  141. package/dist/ssr/actions/Dropdown.js.map +1 -1
  142. package/dist/ssr/actions/GestureMenu.js +76 -107
  143. package/dist/ssr/actions/GestureMenu.js.map +1 -1
  144. package/dist/ssr/actions/Toolbar.js +294 -14
  145. package/dist/ssr/actions/Toolbar.js.map +1 -1
  146. package/dist/ssr/actions/drag-and-drop-messages.js +75 -0
  147. package/dist/ssr/actions/drag-and-drop-messages.js.map +1 -0
  148. package/dist/ssr/actions/drag-and-drop.js +692 -0
  149. package/dist/ssr/actions/drag-and-drop.js.map +1 -0
  150. package/dist/ssr/actions/index.js +1 -0
  151. package/dist/ssr/actions/index.js.map +1 -1
  152. package/dist/ssr/actions/menu-rows.js +15 -0
  153. package/dist/ssr/actions/menu-rows.js.map +1 -0
  154. package/dist/ssr/actions/menu-sheet.js +138 -0
  155. package/dist/ssr/actions/menu-sheet.js.map +1 -0
  156. package/dist/ssr/actions/toolbar-messages.js +20 -0
  157. package/dist/ssr/actions/toolbar-messages.js.map +1 -0
  158. package/dist/ssr/chart-inspection.js +3 -0
  159. package/dist/ssr/chart-inspection.js.map +1 -0
  160. package/dist/ssr/chat/ChatComposer.js +393 -102
  161. package/dist/ssr/chat/ChatComposer.js.map +1 -1
  162. package/dist/ssr/chat/ChatDecision.js +465 -0
  163. package/dist/ssr/chat/ChatDecision.js.map +1 -0
  164. package/dist/ssr/chat/ChatPrimitives.js +2 -2
  165. package/dist/ssr/chat/ChatPrimitives.js.map +1 -1
  166. package/dist/ssr/chat/ChatTimeline.js.map +1 -1
  167. package/dist/ssr/chat/chat-messages.js +25 -1
  168. package/dist/ssr/chat/chat-messages.js.map +1 -1
  169. package/dist/ssr/chat/command-search.js +13 -3
  170. package/dist/ssr/chat/command-search.js.map +1 -1
  171. package/dist/ssr/chat/index.js +8 -1
  172. package/dist/ssr/chat/index.js.map +1 -1
  173. package/dist/ssr/chat/reaction-people.js +15 -0
  174. package/dist/ssr/chat/reaction-people.js.map +1 -0
  175. package/dist/ssr/chat/types.js.map +1 -1
  176. package/dist/ssr/content/Calendar.js +3 -3
  177. package/dist/ssr/content/Calendar.js.map +1 -1
  178. package/dist/ssr/content/Chart.js +25 -38
  179. package/dist/ssr/content/Chart.js.map +1 -1
  180. package/dist/ssr/content/ChartSnapshotView.js +7 -10
  181. package/dist/ssr/content/ChartSnapshotView.js.map +1 -1
  182. package/dist/ssr/content/FileBrowser.js +2 -2
  183. package/dist/ssr/content/FileBrowser.js.map +1 -1
  184. package/dist/ssr/content/FileTree.js +21 -14
  185. package/dist/ssr/content/FileTree.js.map +1 -1
  186. package/dist/ssr/content/FileTypeIcon.js +50 -0
  187. package/dist/ssr/content/FileTypeIcon.js.map +1 -0
  188. package/dist/ssr/content/FileView.js +2 -2
  189. package/dist/ssr/content/FileView.js.map +1 -1
  190. package/dist/ssr/content/MessageRow.js +98 -152
  191. package/dist/ssr/content/MessageRow.js.map +1 -1
  192. package/dist/ssr/content/ReactionBar.js +304 -0
  193. package/dist/ssr/content/ReactionBar.js.map +1 -0
  194. package/dist/ssr/content/ReferenceChip.js +121 -0
  195. package/dist/ssr/content/ReferenceChip.js.map +1 -0
  196. package/dist/ssr/content/calendar-pointer.js +9 -0
  197. package/dist/ssr/content/calendar-pointer.js.map +1 -1
  198. package/dist/ssr/content/calendar-time-view.js +6 -3
  199. package/dist/ssr/content/calendar-time-view.js.map +1 -1
  200. package/dist/ssr/content/chart-inspection-core.js +557 -0
  201. package/dist/ssr/content/chart-inspection-core.js.map +1 -0
  202. package/dist/ssr/content/chart-inspection.js +10 -445
  203. package/dist/ssr/content/chart-inspection.js.map +1 -1
  204. package/dist/ssr/content/chart-line-gaps.js +1 -1
  205. package/dist/ssr/content/chart-line-gaps.js.map +1 -1
  206. package/dist/ssr/content/chart-snapshot.js +1 -1
  207. package/dist/ssr/content/chart-snapshot.js.map +1 -1
  208. package/dist/ssr/content/index.js +3 -0
  209. package/dist/ssr/content/index.js.map +1 -1
  210. package/dist/ssr/feedback/dialog-core.js +135 -23
  211. package/dist/ssr/feedback/dialog-core.js.map +1 -1
  212. package/dist/ssr/index.js +1 -0
  213. package/dist/ssr/index.js.map +1 -1
  214. package/dist/ssr/input-mode.js +40 -0
  215. package/dist/ssr/input-mode.js.map +1 -0
  216. package/dist/ssr/inputs/FileDropTarget.js +17 -5
  217. package/dist/ssr/inputs/FileDropTarget.js.map +1 -1
  218. package/dist/ssr/inputs/FileInputs.js +2 -2
  219. package/dist/ssr/inputs/FileInputs.js.map +1 -1
  220. package/dist/ssr/inputs/SelectChip.js +9 -0
  221. package/dist/ssr/inputs/SelectChip.js.map +1 -1
  222. package/dist/ssr/inputs/emoji/EmojiPicker.js +12 -0
  223. package/dist/ssr/inputs/emoji/EmojiPicker.js.map +1 -1
  224. package/dist/ssr/inputs/file-drop.js.map +1 -1
  225. package/dist/ssr/layout/AppOverview.js +1 -1
  226. package/dist/ssr/layout/AppOverview.js.map +1 -1
  227. package/dist/ssr/layout/AppWorkspace.js +272 -95
  228. package/dist/ssr/layout/AppWorkspace.js.map +1 -1
  229. package/dist/ssr/layout/DetailPanel.js +112 -58
  230. package/dist/ssr/layout/DetailPanel.js.map +1 -1
  231. package/dist/ssr/layout/Discussion.js +63 -36
  232. package/dist/ssr/layout/Discussion.js.map +1 -1
  233. package/dist/ssr/layout/PanelDialog.js +7 -6
  234. package/dist/ssr/layout/PanelDialog.js.map +1 -1
  235. package/dist/ssr/layout/ResizeSeparator.js +45 -0
  236. package/dist/ssr/layout/ResizeSeparator.js.map +1 -0
  237. package/dist/ssr/layout/SidebarSwitcher.js +9 -2
  238. package/dist/ssr/layout/SidebarSwitcher.js.map +1 -1
  239. package/dist/ssr/layout/TabBar.js +1 -1
  240. package/dist/ssr/layout/TabBar.js.map +1 -1
  241. package/dist/ssr/layout/TableOfContents.js +10 -2
  242. package/dist/ssr/layout/TableOfContents.js.map +1 -1
  243. package/dist/ssr/layout/app-workspace-controller.js +130 -17
  244. package/dist/ssr/layout/app-workspace-controller.js.map +1 -1
  245. package/dist/ssr/layout/detail-panel-messages.js +35 -0
  246. package/dist/ssr/layout/detail-panel-messages.js.map +1 -0
  247. package/dist/ssr/layout/index.js +3 -1
  248. package/dist/ssr/layout/index.js.map +1 -1
  249. package/dist/ssr/layout/resize-separator.js +90 -0
  250. package/dist/ssr/layout/resize-separator.js.map +1 -0
  251. package/dist/ssr/layout/workspace-messages.js +12 -2
  252. package/dist/ssr/layout/workspace-messages.js.map +1 -1
  253. package/dist/ssr/surfaces/Avatar.js +20 -2
  254. package/dist/ssr/surfaces/Avatar.js.map +1 -1
  255. package/dist/ssr/surfaces/AvatarStack.js +286 -0
  256. package/dist/ssr/surfaces/AvatarStack.js.map +1 -0
  257. package/dist/ssr/surfaces/LinkCard.js +1 -1
  258. package/dist/ssr/surfaces/LinkCard.js.map +1 -1
  259. package/dist/ssr/surfaces/Placeholder.js +4 -2
  260. package/dist/ssr/surfaces/Placeholder.js.map +1 -1
  261. package/dist/ssr/surfaces/StatCell.js +23 -0
  262. package/dist/ssr/surfaces/StatCell.js.map +1 -1
  263. package/dist/ssr/surfaces/avatar-messages.js +8 -2
  264. package/dist/ssr/surfaces/avatar-messages.js.map +1 -1
  265. package/dist/ssr/surfaces/index.js +1 -0
  266. package/dist/ssr/surfaces/index.js.map +1 -1
  267. package/dist/ssr/widgets/Widget.js +1 -1
  268. package/dist/ssr/widgets/Widget.js.map +1 -1
  269. package/dist/styles.css +1 -1
  270. package/dist/types/actions/ContextMenu.d.ts +9 -0
  271. package/dist/types/actions/DragAndDrop.d.ts +29 -0
  272. package/dist/types/actions/Dropdown.d.ts +12 -5
  273. package/dist/types/actions/GestureMenu.d.ts +6 -4
  274. package/dist/types/actions/Toolbar.d.ts +20 -0
  275. package/dist/types/actions/drag-and-drop-messages.d.ts +35 -0
  276. package/dist/types/actions/drag-and-drop.d.ts +36 -0
  277. package/dist/types/actions/index.d.ts +3 -1
  278. package/dist/types/actions/menu-rows.d.ts +5 -0
  279. package/dist/types/actions/menu-sheet.d.ts +22 -0
  280. package/dist/types/actions/toolbar-messages.d.ts +8 -0
  281. package/dist/types/chart-inspection.d.ts +2 -0
  282. package/dist/types/chat/ChatComposer.d.ts +26 -1
  283. package/dist/types/chat/ChatDecision.d.ts +133 -0
  284. package/dist/types/chat/ChatPrimitives.d.ts +4 -1
  285. package/dist/types/chat/ChatTimeline.d.ts +2 -1
  286. package/dist/types/chat/chat-messages.d.ts +13 -2
  287. package/dist/types/chat/command-search.d.ts +5 -0
  288. package/dist/types/chat/index.d.ts +25 -1
  289. package/dist/types/chat/reaction-people.d.ts +9 -0
  290. package/dist/types/chat/types.d.ts +54 -1
  291. package/dist/types/content/Chart.d.ts +11 -5
  292. package/dist/types/content/FileTypeIcon.d.ts +27 -0
  293. package/dist/types/content/MessageRow.d.ts +3 -10
  294. package/dist/types/content/ReactionBar.d.ts +32 -0
  295. package/dist/types/content/ReferenceChip.d.ts +49 -0
  296. package/dist/types/content/calendar-pointer.d.ts +6 -0
  297. package/dist/types/content/chart-inspection-core.d.ts +61 -0
  298. package/dist/types/content/chart-inspection.d.ts +4 -20
  299. package/dist/types/content/chart-snapshot.d.ts +1 -1
  300. package/dist/types/content/index.d.ts +5 -1
  301. package/dist/types/feedback/dialog-core.d.ts +16 -1
  302. package/dist/types/index.d.ts +1 -0
  303. package/dist/types/input-mode.d.ts +7 -0
  304. package/dist/types/inputs/FileDropTarget.d.ts +6 -3
  305. package/dist/types/inputs/SelectChip.d.ts +2 -0
  306. package/dist/types/inputs/file-drop.d.ts +2 -0
  307. package/dist/types/layout/AppWorkspace.d.ts +5 -3
  308. package/dist/types/layout/DetailPanel.d.ts +11 -0
  309. package/dist/types/layout/Discussion.d.ts +8 -0
  310. package/dist/types/layout/ResizeSeparator.d.ts +9 -0
  311. package/dist/types/layout/TabBar.d.ts +7 -0
  312. package/dist/types/layout/TableOfContents.d.ts +2 -0
  313. package/dist/types/layout/app-workspace-controller.d.ts +2 -0
  314. package/dist/types/layout/detail-panel-messages.d.ts +15 -0
  315. package/dist/types/layout/index.d.ts +3 -1
  316. package/dist/types/layout/resize-separator.d.ts +18 -0
  317. package/dist/types/layout/workspace-messages.d.ts +5 -0
  318. package/dist/types/surfaces/Avatar.d.ts +12 -0
  319. package/dist/types/surfaces/AvatarStack.d.ts +41 -0
  320. package/dist/types/surfaces/StatCell.d.ts +6 -0
  321. package/dist/types/surfaces/avatar-messages.d.ts +3 -0
  322. package/dist/types/surfaces/index.d.ts +3 -1
  323. package/package.json +7 -2
@@ -26,40 +26,42 @@ var _tmpl$ = /*#__PURE__*/_$template(`<span><strong>`),
26
26
  _tmpl$1 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__input role=group><!$><!/><textarea rows=1></textarea><!$><!/>`),
27
27
  _tmpl$10 = /*#__PURE__*/_$template(`<span>`),
28
28
  _tmpl$11 = /*#__PURE__*/_$template(`<small>`),
29
- _tmpl$12 = /*#__PURE__*/_$template(`<button class=k2b-chat-composer__command type=button role=option tabindex=-1><i aria-hidden=true></i><span class=k2b-chat-composer__command-text><strong></strong><!$><!/>`),
30
- _tmpl$13 = /*#__PURE__*/_$template(`<b>`),
31
- _tmpl$14 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory><div class=k2b-chat-composer__commands role=listbox>`),
32
- _tmpl$15 = /*#__PURE__*/_$template(`<div role=status class=k2b-chat-composer__loading><i class="ti ti-loader-2 k2b-spin"aria-hidden=true></i><strong>`),
33
- _tmpl$16 = /*#__PURE__*/_$template(`<div role=status><i class="ti ti-alert-circle"></i> <!$><!/>`),
34
- _tmpl$17 = /*#__PURE__*/_$template(`<div role=status>`),
35
- _tmpl$18 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory><div class=k2b-chat-composer__commands role=listbox><!$><!/><!$><!/><!$><!/><!$><!/>`),
36
- _tmpl$19 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-slot><div></div><!$><!/><!$><!/>`),
37
- _tmpl$20 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__hint aria-live=polite>`),
38
- _tmpl$21 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachments role=list tabindex=0>`),
39
- _tmpl$22 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__error role=alert><i class="ti ti-alert-circle"aria-hidden=true></i><!$><!/>`),
40
- _tmpl$23 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__row><!$><!/><!$><!/><div class=k2b-chat-composer__field><!$><!/><div class=k2b-chat-composer__field-tools><!$><!/><!$><!/><!$><!/></div></div><!$><!/>`),
41
- _tmpl$24 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-shell><!$><!/><section role=group><!$><!/><!$><!/><!$><!/><!$><!/></section><div class=k2b-sr-only role=status aria-live=polite></div><div class=k2b-chat-composer__status role=status><!$><!/><!$><!/>`),
42
- _tmpl$25 = /*#__PURE__*/_$template(`<button type=button role=option tabindex=-1><span class=k2b-chat-composer__emoji-glyph aria-hidden=true></span><strong></strong><!$><!/>`),
43
- _tmpl$26 = /*#__PURE__*/_$template(`<small>:<!$><!/>:`),
44
- _tmpl$27 = /*#__PURE__*/_$template(`<i class="ti ti-loader-2 k2b-spin"aria-hidden=true>`),
45
- _tmpl$28 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__command-placeholder aria-hidden=true><span></span><span><span></span><span>`),
46
- _tmpl$29 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__command-group role=group><div class=k2b-chat-composer__command-heading role=presentation><span></span><!$><!/></div><!$><!/><!$><!/>`),
47
- _tmpl$30 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__hint-text>`),
48
- _tmpl$31 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__dictation><i aria-hidden=true></i><span>`),
49
- _tmpl$32 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__hint-action>`),
50
- _tmpl$33 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-remove><i class="ti ti-x"aria-hidden=true>`),
51
- _tmpl$34 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment role=listitem><div class=k2b-chat-composer__attachment-content><!$><!/><!$><!/></div><!$><!/>`),
52
- _tmpl$35 = /*#__PURE__*/_$template(`<img>`),
53
- _tmpl$36 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment-identity><!$><!/><!$><!/>`),
54
- _tmpl$37 = /*#__PURE__*/_$template(`<a class=k2b-chat-composer__attachment-link target=_blank rel="noopener noreferrer"><!$><!/><!$><!/>`),
55
- _tmpl$38 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-action><!$><!/><!$><!/>`),
56
- _tmpl$39 = /*#__PURE__*/_$template(`<footer class=k2b-chat-composer__footer>`),
57
- _tmpl$40 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__tools><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
58
- _tmpl$41 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__submit><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
59
- _tmpl$42 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__status-line><i aria-hidden=true></i><span>`),
60
- _tmpl$43 = /*#__PURE__*/_$template(`<span class=k2b-sr-only>`);
29
+ _tmpl$12 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__command-end><i class="ti ti-check"aria-hidden=true></i><span class=k2b-sr-only>`),
30
+ _tmpl$13 = /*#__PURE__*/_$template(`<button class=k2b-chat-composer__command type=button role=option tabindex=-1><i aria-hidden=true></i><span class=k2b-chat-composer__command-text><strong></strong><!$><!/></span><!$><!/>`),
31
+ _tmpl$14 = /*#__PURE__*/_$template(`<b>`),
32
+ _tmpl$15 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory><div class=k2b-chat-composer__commands role=listbox>`),
33
+ _tmpl$16 = /*#__PURE__*/_$template(`<div role=status class=k2b-chat-composer__loading><i class="ti ti-loader-2 k2b-spin"aria-hidden=true></i><strong>`),
34
+ _tmpl$17 = /*#__PURE__*/_$template(`<div role=status><i class="ti ti-alert-circle"></i> <!$><!/>`),
35
+ _tmpl$18 = /*#__PURE__*/_$template(`<div role=status>`),
36
+ _tmpl$19 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-accessory data-commands><div class=k2b-chat-composer__commands role=listbox><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
37
+ _tmpl$20 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-slot><div></div><!$><!/><!$><!/>`),
38
+ _tmpl$21 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__hint aria-live=polite>`),
39
+ _tmpl$22 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachments role=list tabindex=0>`),
40
+ _tmpl$23 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__error role=alert><i class="ti ti-alert-circle"aria-hidden=true></i><!$><!/>`),
41
+ _tmpl$24 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__row><!$><!/><!$><!/><div class=k2b-chat-composer__field><!$><!/><div class=k2b-chat-composer__field-tools><!$><!/><!$><!/><!$><!/></div></div><!$><!/>`),
42
+ _tmpl$25 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer-shell><!$><!/><section role=group><!$><!/><!$><!/><!$><!/><!$><!/></section><div class=k2b-sr-only role=status aria-live=polite></div><div class=k2b-chat-composer__status role=status><!$><!/><!$><!/>`),
43
+ _tmpl$26 = /*#__PURE__*/_$template(`<button type=button role=option tabindex=-1><span class=k2b-chat-composer__emoji-glyph aria-hidden=true></span><strong></strong><!$><!/>`),
44
+ _tmpl$27 = /*#__PURE__*/_$template(`<small>:<!$><!/>:`),
45
+ _tmpl$28 = /*#__PURE__*/_$template(`<i class="ti ti-loader-2 k2b-spin"aria-hidden=true>`),
46
+ _tmpl$29 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__command-placeholder aria-hidden=true><span></span><span><span></span><span>`),
47
+ _tmpl$30 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__command-group role=group><div class=k2b-chat-composer__command-heading role=presentation><span></span><!$><!/></div><!$><!/><!$><!/>`),
48
+ _tmpl$31 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__hint-text>`),
49
+ _tmpl$32 = /*#__PURE__*/_$template(`<span class=k2b-chat-composer__dictation><i aria-hidden=true></i><span>`),
50
+ _tmpl$33 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__hint-action>`),
51
+ _tmpl$34 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-remove><i class="ti ti-x"aria-hidden=true>`),
52
+ _tmpl$35 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment role=listitem><div class=k2b-chat-composer__attachment-content><!$><!/><!$><!/></div><!$><!/>`),
53
+ _tmpl$36 = /*#__PURE__*/_$template(`<img>`),
54
+ _tmpl$37 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__attachment-identity><!$><!/><!$><!/>`),
55
+ _tmpl$38 = /*#__PURE__*/_$template(`<a class=k2b-chat-composer__attachment-link target=_blank rel="noopener noreferrer"><!$><!/><!$><!/>`),
56
+ _tmpl$39 = /*#__PURE__*/_$template(`<button type=button class=k2b-chat-composer__attachment-action><!$><!/><!$><!/>`),
57
+ _tmpl$40 = /*#__PURE__*/_$template(`<footer class=k2b-chat-composer__footer>`),
58
+ _tmpl$41 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__tools><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
59
+ _tmpl$42 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__submit><!$><!/><!$><!/><!$><!/><!$><!/><!$><!/>`),
60
+ _tmpl$43 = /*#__PURE__*/_$template(`<div class=k2b-chat-composer__status-line><i aria-hidden=true></i><span>`),
61
+ _tmpl$44 = /*#__PURE__*/_$template(`<span class=k2b-sr-only>`);
61
62
  import { batch, children, createEffect, createMemo, createSignal, createUniqueId, For, onCleanup, onMount, Show, untrack } from "solid-js";
62
63
  import { Dropdown } from "../actions/Dropdown";
64
+ import { dialogHistorySettled, holdDialogHistory } from "../feedback/dialog-core";
63
65
  import { Tooltip } from "../feedback/Tooltip";
64
66
  import { replaceTextareaRange } from "../inputs/editor-dom";
65
67
  import { completedEmojiShortcode, emojiInTone, emojiName, emojiShortcodeQuery, loadEmojiIndex, suggestEmoji } from "../inputs/emoji/emoji-index";
@@ -83,7 +85,10 @@ const emojiSuggestionLimit = 8;
83
85
  // Keep editor undo text within approximately 2 MiB, plus the current edit.
84
86
  const composerUndoBudgetChars = 1_000_000;
85
87
 
86
- /** An action can cancel and restore its token, or report a short completion message. */
88
+ /**
89
+ * An action can cancel and restore its token, report a short completion message, or hand back a reference chosen in a
90
+ * dialog: `mention` takes the token's place exactly as a `mention` row does, and Ctrl/⌘+Z brings the token back.
91
+ */
87
92
 
88
93
  /** A fixed place in the slash list. Sections keep the given order, also while searching. */
89
94
 
@@ -121,12 +126,40 @@ const isTouchOnly = () => typeof matchMedia === "function" && matchMedia(touchOn
121
126
  const microphoneHoldMs = 500;
122
127
  /** Keeps the field focused (and a phone's keyboard open) when a composer button is pressed with a mouse or finger. */
123
128
  const keepFieldFocus = event => event.preventDefault();
129
+ /**
130
+ * Keeps one tap from reaching the page: its pointer, touch and mouse events stop at the window, and neither focus nor a
131
+ * click happens. A finger's tap ends with `touchend`, a scroll with `pointercancel`, a mouse's press with `click`.
132
+ */
133
+ const swallowTap = down => {
134
+ const blocked = ["pointerup", "pointercancel", "touchstart", "touchend", "mousedown", "mouseup", "click", "contextmenu"];
135
+ const stop = () => {
136
+ window.removeEventListener("pointerdown", next, true);
137
+ for (const type of blocked) window.removeEventListener(type, block, true);
138
+ };
139
+ const block = event => {
140
+ event.stopPropagation();
141
+ if (event.type !== "pointercancel" && event.type !== "touchstart" && event.type !== "pointerup") event.preventDefault();
142
+ if (event.type === "click" || event.type === "touchend" || event.type === "pointercancel") stop();
143
+ };
144
+ // The next press is a new gesture, whatever became of this one.
145
+ const next = event => {
146
+ if (event !== down) stop();
147
+ };
148
+ down.stopPropagation();
149
+ down.preventDefault();
150
+ window.addEventListener("pointerdown", next, true);
151
+ for (const type of blocked) window.addEventListener(type, block, {
152
+ capture: true,
153
+ passive: false
154
+ });
155
+ };
124
156
  const attachmentIcon = attachment => attachment.icon ?? (attachment.kind === "image" ? "ti ti-photo" : attachment.kind === "resource" ? "ti ti-link" : "ti ti-file");
125
157
  const hasContent = items => items.some(item => item != null && typeof item !== "boolean" && item !== "");
126
158
  export function ChatComposer(props) {
127
159
  const accessory = children(() => props.accessory);
128
160
  const hasAccessory = () => hasContent(accessory.toArray());
129
161
  const hint = children(() => props.hint);
162
+ const footer = children(() => props.footerContent);
130
163
  const messages = useUiMessages();
131
164
  const markdownToolbarMessages = useMarkdownToolbarMessages();
132
165
  const chatMessages = useChatMessages();
@@ -147,6 +180,7 @@ export function ChatComposer(props) {
147
180
  const [closedAt, setClosedAt] = createSignal();
148
181
  // Where the pending native edit starts; a selection replaced as a whole starts at its beginning.
149
182
  let inputStart;
183
+ let inputEnd;
150
184
  const [commandStatus, setCommandStatus] = createSignal();
151
185
  const [announcement, setAnnouncement] = createSignal();
152
186
  let statusTimer;
@@ -165,6 +199,7 @@ export function ChatComposer(props) {
165
199
  });
166
200
  const [addingFiles, setAddingFiles] = createSignal(false);
167
201
  const [submitting, setSubmitting] = createSignal(false);
202
+ let shellRef;
168
203
  let composerRef;
169
204
  let textareaRef;
170
205
  let fileInputRef;
@@ -192,6 +227,45 @@ export function ChatComposer(props) {
192
227
  const [searching, setSearching] = createSignal(false);
193
228
  const [searchError, setSearchError] = createSignal(false);
194
229
  const [executing, setExecuting] = createSignal(false);
230
+ const [modelOpen, setModelOpen] = createSignal();
231
+ const [choosingModel, setChoosingModel] = createSignal(false);
232
+ let resolveModel;
233
+ const finishModelSelection = id => {
234
+ const resolve = resolveModel;
235
+ resolveModel = undefined;
236
+ if (choosingModel()) {
237
+ setModelOpen(false);
238
+ // Let the controlled close reach Dropdown before returning normal clicks to its own state.
239
+ queueMicrotask(() => {
240
+ if (!choosingModel()) setModelOpen(undefined);
241
+ });
242
+ }
243
+ setChoosingModel(false);
244
+ resolve?.(id);
245
+ };
246
+ const blockedBesidesCommand = () => Boolean(props.disabled || stopping() || state() === "submitting" || addingFiles() || submitting());
247
+ const usableModelControl = () => !conversation() && !footer() && !blockedBesidesCommand() && !running() && Boolean(props.models?.length && props.onModelChange);
248
+ const openModelSelection = () => {
249
+ if (!usableModelControl()) return Promise.resolve(null);
250
+ finishModelSelection(null);
251
+ return new Promise(resolve => {
252
+ resolveModel = resolve;
253
+ setChoosingModel(true);
254
+ setModelOpen(true);
255
+ queueMicrotask(() => {
256
+ if (!choosingModel() || !modelOpen()) return;
257
+ // Start on the current model, as a click on the chip would show it checked.
258
+ const menu = composerRef?.querySelector(".k2b-chat-composer__model");
259
+ (menu?.querySelector('[role="menuitemradio"][aria-checked="true"]:not(:disabled)') ?? menu?.querySelector('[role="menuitemradio"]:not(:disabled)'))?.focus();
260
+ });
261
+ });
262
+ };
263
+ createEffect(() => {
264
+ if (!usableModelControl()) finishModelSelection(null);
265
+ });
266
+ onCleanup(() => finishModelSelection(null));
267
+ const [commandOpening, setCommandOpening] = createSignal(0);
268
+ let retrySearch = false;
195
269
  let highlightRef;
196
270
  let commandListRef;
197
271
  const mentions = () => props.mentions ?? [];
@@ -225,7 +299,21 @@ export function ChatComposer(props) {
225
299
  const token = caretCommandToken();
226
300
  return dismissed() || composing() || token?.start === closedAt() ? null : token;
227
301
  });
302
+ const openingStart = createMemo(() => commandQuery()?.start);
303
+ createEffect(() => {
304
+ props.draftKey;
305
+ const start = openingStart();
306
+ if (start !== undefined) setCommandOpening(opening => opening + 1);
307
+ });
228
308
  const parsedCommandQuery = createMemo(() => parseChatCommandQuery(commandQuery()?.query ?? "", props.commandScopes ?? []));
309
+ const commandFallbackRow = createMemo(() => {
310
+ const parsed = parsedCommandQuery();
311
+ const query = parsed.query.trim();
312
+ return commandQuery() && (query || parsed.scope) ? props.commandFallback?.({
313
+ query,
314
+ scope: parsed.scope?.id
315
+ }) : undefined;
316
+ });
229
317
  const currentCommandScope = createMemo(() => parsedCommandQuery().scope?.id);
230
318
  createEffect(() => {
231
319
  currentCommandScope();
@@ -241,9 +329,12 @@ export function ChatComposer(props) {
241
329
  searchResults: searchResultsScope() === parsedCommandQuery().scope?.id ? searchResults() : [],
242
330
  searchResultsFresh: searchResultsQuery() === commandQuery()?.query && searchResultsScope() === parsedCommandQuery().scope?.id,
243
331
  searchSettled: searchResultsQuery() !== undefined && searchResultsScope() === parsedCommandQuery().scope?.id,
244
- searching: searching()
332
+ searching: searching(),
333
+ fallback: commandFallbackRow()
245
334
  }));
246
335
  const commandMatches = createMemo(() => commandQuery() ? commandModel().rows.map(row => row.command) : []);
336
+ /** Rows that matched; an unscoped fallback row only follows them. */
337
+ const foundCommandCount = () => commandMatches().length - (commandModel().fallback ? 1 : 0);
247
338
  const currentCommandQuery = createMemo(() => caretCommandToken()?.query);
248
339
  // Arrow marking belongs to one token in one draft; another draft or `/` starts at the top row again.
249
340
  createEffect(() => {
@@ -252,21 +343,46 @@ export function ChatComposer(props) {
252
343
  currentCommandQuery();
253
344
  setCommandMoved(false);
254
345
  });
255
- const commandsOpen = () => Boolean(!emojiOpen() && commandQuery() && (localCommands().length || props.searchCommands));
346
+ const commandsOpen = () => Boolean(!emojiOpen() && commandQuery() && (localCommands().length || props.searchCommands || commandFallbackRow()));
347
+ const commandSheetHeld = createMemo(() => commandsOpen() && isTouchOnly());
348
+ createEffect(() => {
349
+ if (!commandSheetHeld()) return;
350
+ onCleanup(holdDialogHistory(() => setClosedAt(commandQuery()?.start)));
351
+ });
256
352
  const suggestionsOpen = () => commandsOpen() || emojiOpen();
257
353
  createEffect(() => {
258
354
  if (!suggestionsOpen()) return;
259
355
  let disposed = false;
260
356
  const measure = () => {
261
357
  if (disposed || !commandListRef) return;
262
- let top = window.visualViewport?.offsetTop ?? 0;
263
- for (let parent = commandListRef.parentElement; parent; parent = parent.parentElement) {
264
- if (/(auto|scroll|hidden|clip)/.test(window.getComputedStyle(parent).overflowY)) {
358
+ const accessory = commandListRef.parentElement;
359
+ const viewportTop = window.visualViewport?.offsetTop ?? 0;
360
+ let top = viewportTop;
361
+ // The column a phone sheet spans: the nearest ancestor that clips sideways, or the page.
362
+ let column;
363
+ for (let parent = accessory.parentElement; parent; parent = parent.parentElement) {
364
+ const style = window.getComputedStyle(parent);
365
+ if (/(auto|scroll|hidden|clip)/.test(style.overflowY)) {
265
366
  top = Math.max(top, parent.getBoundingClientRect().top);
266
367
  }
368
+ if (!column && /(auto|scroll|hidden|clip)/.test(style.overflowX)) {
369
+ const left = parent.getBoundingClientRect().left + parent.clientLeft;
370
+ column = {
371
+ left,
372
+ right: left + parent.clientWidth
373
+ };
374
+ }
267
375
  }
268
- const bottom = commandListRef.parentElement.getBoundingClientRect().bottom;
376
+ const page = document.documentElement.clientWidth;
377
+ const left = Math.max(0, column?.left ?? 0);
378
+ const right = Math.min(page, column?.right ?? page);
379
+ const slot = accessory.parentElement.getBoundingClientRect();
380
+ const bottom = accessory.getBoundingClientRect().bottom;
269
381
  commandListRef.style.setProperty("--k2b-chat-command-space", `${Math.max(40, bottom - top - 8)}px`);
382
+ // Only a list that reaches the screen's top edge keeps clear of a notch or the status bar.
383
+ commandListRef.style.setProperty("--k2b-chat-command-safe-top", top === viewportTop ? "env(safe-area-inset-top, 0px)" : "0px");
384
+ accessory.style.setProperty("--k2b-chat-command-reach-left", `${Math.max(0, slot.left - left)}px`);
385
+ accessory.style.setProperty("--k2b-chat-command-reach-right", `${Math.max(0, right - slot.right)}px`);
270
386
  };
271
387
  queueMicrotask(measure);
272
388
  window.addEventListener("resize", measure);
@@ -279,6 +395,20 @@ export function ChatComposer(props) {
279
395
  window.visualViewport?.removeEventListener("resize", measure);
280
396
  });
281
397
  });
398
+ // A press outside the command list and the field closes the list, as Escape does; the text stays. With a mouse or a
399
+ // trackpad the press then acts as usual. On a touch-only device a tap outside the composer closes only the list: it
400
+ // reaches nothing beneath, and the field keeps focus, so the keyboard stays open.
401
+ createEffect(() => {
402
+ if (!commandsOpen()) return;
403
+ const onPointerDown = event => {
404
+ const target = event.target;
405
+ if (!(target instanceof Node) || commandListRef?.contains(target) || textareaRef?.parentElement?.contains(target)) return;
406
+ setClosedAt(commandQuery()?.start);
407
+ if (isTouchOnly() && !shellRef?.contains(target)) swallowTap(event);
408
+ };
409
+ window.addEventListener("pointerdown", onPointerDown, true);
410
+ onCleanup(() => window.removeEventListener("pointerdown", onPointerDown, true));
411
+ });
282
412
  createEffect(() => {
283
413
  props.draftKey;
284
414
  const token = commandQuery();
@@ -287,12 +417,17 @@ export function ChatComposer(props) {
287
417
  setSearching(false);
288
418
  return;
289
419
  }
420
+ running();
290
421
  const parsed = parsedCommandQuery();
422
+ const opening = commandOpening();
291
423
  const abort = new AbortController();
292
424
  setSearching(true);
425
+ const delay = retrySearch ? 0 : 120;
426
+ retrySearch = false;
293
427
  const timer = setTimeout(() => {
294
428
  Promise.resolve().then(() => props.searchCommands(parsed.query, abort.signal, {
295
- scope: parsed.scope?.id
429
+ scope: parsed.scope?.id,
430
+ opening
296
431
  })).then(results => {
297
432
  if (!abort.signal.aborted) {
298
433
  batch(() => {
@@ -310,7 +445,7 @@ export function ChatComposer(props) {
310
445
  }).finally(() => {
311
446
  if (!abort.signal.aborted) setSearching(false);
312
447
  });
313
- }, 120);
448
+ }, delay);
314
449
  onCleanup(() => {
315
450
  clearTimeout(timer);
316
451
  abort.abort();
@@ -369,6 +504,7 @@ export function ChatComposer(props) {
369
504
  untrack(() => {
370
505
  history.length = 0;
371
506
  historyIndex = -1;
507
+ finishModelSelection(null);
372
508
  setDismissed(true);
373
509
  setClosedAt(undefined);
374
510
  setSearchResults([]);
@@ -394,6 +530,13 @@ export function ChatComposer(props) {
394
530
  };
395
531
  const edit = (value, nextMentions = reconcileChatMentions(props.value, value, mentions())) => {
396
532
  if (commandStatus()?.tone === "error") showCommandStatus();
533
+ // Replacing `/` can leave its position and query identical, but starts a new opening.
534
+ if (inputStart !== undefined && inputEnd !== undefined && props.value.slice(inputStart, inputEnd).includes("/")) {
535
+ setCommandOpening(opening => opening + 1);
536
+ setSearchResults([]);
537
+ setSearchResultsQuery(undefined);
538
+ setCommandMoved(false);
539
+ }
397
540
  // An edit that starts at or before the closed `/` (select all, then type `/`) replaces it; the new `/` may open again.
398
541
  const closed = closedAt();
399
542
  if (closed !== undefined) {
@@ -402,6 +545,7 @@ export function ChatComposer(props) {
402
545
  if (Math.min(same, inputStart ?? same) <= closed) setClosedAt(undefined);
403
546
  }
404
547
  inputStart = undefined;
548
+ inputEnd = undefined;
405
549
  record();
406
550
  props.onValueChange(value);
407
551
  props.onMentionsChange?.(nextMentions);
@@ -445,7 +589,9 @@ export function ChatComposer(props) {
445
589
  /** The conversation field stays editable while a message is sent, so it keeps the focus and a phone its keyboard. */
446
590
  const editBlocked = () => conversation() ? busy() : blocked();
447
591
  const hasDraft = () => Boolean(props.value.trim() || !running() && attachments().length > 0);
448
- const canSubmit = () => !blocked() && hasDraft() && !(running() && runningSubmitIntent() === "steer" && mentions().length);
592
+ /** The draft may go out now, apart from a submission that is already on its way. */
593
+ const submittable = () => !busy() && hasDraft() && !(running() && runningSubmitIntent() === "steer" && mentions().length);
594
+ const canSubmit = () => !submitting() && submittable();
449
595
  const canSelectFiles = () => Boolean(props.fileSelection && !props.fileSelection.disabled && !running() && !blocked());
450
596
  const hasAddMenu = () => Boolean(props.fileSelection || props.menuActions?.length);
451
597
  const hasContextUsage = () => {
@@ -547,12 +693,78 @@ export function ChatComposer(props) {
547
693
  _$effect(() => _$setAttribute(_el$2, "title", attachment.name));
548
694
  return _el$;
549
695
  })();
550
- const chooseFiles = () => {
696
+
697
+ /** `onNothing` runs when the person closes the selection without a file. */
698
+ const chooseFiles = onNothing => {
551
699
  const selection = props.fileSelection;
552
- if (!selection?.choose) return fileInputRef?.click();
553
- selection.choose().then(
700
+ if (!selection?.choose) {
701
+ const input = fileInputRef;
702
+ if (input && onNothing) {
703
+ const done = new AbortController();
704
+ input.addEventListener("cancel", () => {
705
+ done.abort();
706
+ onNothing();
707
+ }, {
708
+ signal: done.signal
709
+ });
710
+ input.addEventListener("change", () => done.abort(), {
711
+ signal: done.signal
712
+ });
713
+ }
714
+ return input?.click();
715
+ }
716
+ const failed = error => {
717
+ onNothing?.();
718
+ (props.fileSelection?.onError ?? props.onError)?.(error);
719
+ };
720
+ let chosen;
721
+ try {
722
+ chosen = selection.choose();
723
+ } catch (error) {
724
+ failed(error);
725
+ return;
726
+ }
727
+ chosen.then(
554
728
  // A single-file composer keeps the first chosen file, as its file dialog and drops do.
555
- files => void runFiles(selection.multiple === false ? files.slice(0, 1) : files), error => (props.fileSelection?.onError ?? props.onError)?.(error));
729
+ files => {
730
+ if (files.length === 0) onNothing?.();else void runFiles(selection.multiple === false ? files.slice(0, 1) : files);
731
+ }, failed);
732
+ };
733
+
734
+ /**
735
+ * "Attach files" from the slash list: the token leaves as one edit, and the selection opens synchronously, inside the
736
+ * key or click that chose the row, because the device's file dialog needs that activation. Closing the selection
737
+ * without a file brings the token back, unless the draft changed meanwhile.
738
+ */
739
+ const attachFilesFromCommand = token => {
740
+ if (!canSelectFiles()) return;
741
+ const key = props.draftKey;
742
+ const previous = snapshot();
743
+ const previousHistory = {
744
+ entries: [...history],
745
+ index: historyIndex
746
+ };
747
+ const nextValue = props.value.slice(0, token.start) + props.value.slice(token.end);
748
+ edit(nextValue, reconcileChatMentions(props.value, nextValue, mentions()));
749
+ setDismissed(true);
750
+ chooseFiles(() => {
751
+ if (props.draftKey !== key || props.value !== nextValue) return;
752
+ setDismissed(true);
753
+ props.onValueChange(previous.value);
754
+ props.onMentionsChange?.(previous.mentions);
755
+ history.splice(0, history.length, ...previousHistory.entries);
756
+ historyIndex = previousHistory.index;
757
+ queueMicrotask(() => {
758
+ textareaRef?.setSelectionRange(token.end, token.end);
759
+ syncCaret();
760
+ focus();
761
+ });
762
+ });
763
+ queueMicrotask(() => {
764
+ if (props.draftKey !== key || props.value !== nextValue) return;
765
+ textareaRef?.setSelectionRange(token.start, token.start);
766
+ syncCaret();
767
+ });
556
768
  };
557
769
  const runFiles = async files => {
558
770
  if (!canSelectFiles()) return;
@@ -571,18 +783,26 @@ export function ChatComposer(props) {
571
783
  };
572
784
  const submit = async () => {
573
785
  if (!canSubmit()) return;
574
- const intent = running() ? runningSubmitIntent() : "send";
575
- const previousValue = props.value;
576
- const previousAttachments = attachments();
577
- const previousMentions = mentions();
578
- const input = {
579
- intent,
580
- text: previousValue,
581
- mentions: previousMentions,
582
- attachments: intent !== "steer" ? previousAttachments : []
583
- };
786
+ const key = props.draftKey;
584
787
  setSubmitting(true);
585
788
  try {
789
+ if (isTouchOnly()) {
790
+ if (commandSheetHeld()) setClosedAt(commandQuery()?.start);
791
+ // The sheet's Back entry leaves first, so a submit handler that navigates finds the history settled.
792
+ await dialogHistorySettled();
793
+ // A draft that another one replaced, or that may no longer go out, is not sent and keeps its text.
794
+ if (disposed || props.draftKey !== key || !submittable()) return;
795
+ }
796
+ const intent = running() ? runningSubmitIntent() : "send";
797
+ const previousValue = props.value;
798
+ const previousAttachments = attachments();
799
+ const previousMentions = mentions();
800
+ const input = {
801
+ intent,
802
+ text: previousValue,
803
+ mentions: previousMentions,
804
+ attachments: intent !== "steer" ? previousAttachments : []
805
+ };
586
806
  await runChatSubmission({
587
807
  clear: () => {
588
808
  props.onValueChange("");
@@ -625,6 +845,7 @@ export function ChatComposer(props) {
625
845
  };
626
846
  const executeCommand = async (command, tab = false) => {
627
847
  const token = commandQuery();
848
+ const heldHistory = commandSheetHeld();
628
849
  if (!token || blocked()) return;
629
850
  if (command.disabled || command.reason) {
630
851
  // A new object each time, so choosing the same row again inserts and announces its reason again.
@@ -633,7 +854,16 @@ export function ChatComposer(props) {
633
854
  } : undefined);
634
855
  return;
635
856
  }
636
- if (command.scope && (tab || !command.action && !command.mention) && narrowCommand(command)) return;
857
+ if (command.searchAgain) {
858
+ retrySearch = true;
859
+ setCommandOpening(opening => opening + 1);
860
+ return;
861
+ }
862
+ if (command.scope && (tab || !command.action && !command.mention && !command.attachFiles) && narrowCommand(command)) return;
863
+ if (command.attachFiles) {
864
+ attachFilesFromCommand(token);
865
+ return;
866
+ }
637
867
  const previous = snapshot();
638
868
  const key = props.draftKey;
639
869
  const replacement = command.mention ? command.mention.name + " " : "";
@@ -654,6 +884,7 @@ export function ChatComposer(props) {
654
884
  setExecuting(true);
655
885
  let submitRequested = false;
656
886
  let restored = false;
887
+ let mentioned;
657
888
  const restore = () => {
658
889
  if (props.draftKey !== key || props.value !== nextValue) return;
659
890
  setDismissed(true);
@@ -668,17 +899,50 @@ export function ChatComposer(props) {
668
899
  text: command.busyLabel
669
900
  } : undefined);
670
901
  try {
902
+ // The sheet's Back entry leaves first, so an action that navigates or opens a dialog finds the history settled.
903
+ if (heldHistory && command.action) {
904
+ await dialogHistorySettled();
905
+ // Another draft or no composer any more: the command does not run against it.
906
+ if (disposed || props.draftKey !== key) return;
907
+ }
671
908
  const result = await command.action?.({
672
909
  setValue: value => edit(value),
673
910
  submit: () => {
674
911
  submitRequested = true;
675
912
  },
676
- focus
913
+ focus,
914
+ openModelSelection
677
915
  });
678
916
  if (result === "cancelled") {
679
917
  submitRequested = false;
680
918
  restore();
681
919
  showCommandStatus();
920
+ } else if (result && "mention" in result) {
921
+ // One undo step from the token to the reference, as if the row had been a reference itself.
922
+ if (props.draftKey === key && props.value === nextValue) {
923
+ restore();
924
+ restored = false;
925
+ const name = result.mention.name;
926
+ const withMention = previous.value.slice(0, token.start) + name + " " + previous.value.slice(token.end);
927
+ edit(withMention, [...reconcileChatMentions(previous.value, withMention, previous.mentions), {
928
+ start: token.start,
929
+ end: token.start + name.length,
930
+ attachment: result.mention
931
+ }]);
932
+ setDismissed(true);
933
+ mentioned = {
934
+ value: withMention,
935
+ caret: token.start + name.length + 1
936
+ };
937
+ showCommandStatus();
938
+ } else {
939
+ // The pick is lost; say so, also when the draft moved to another key meanwhile (such as a new chat saved
940
+ // while the dialog was open), so it never ends in silence.
941
+ showCommandStatus({
942
+ tone: "error",
943
+ text: chatMessages().commandDraftChanged
944
+ });
945
+ }
682
946
  } else if (result) {
683
947
  showCommandStatus({
684
948
  tone: "done",
@@ -700,8 +964,8 @@ export function ChatComposer(props) {
700
964
  if (submitRequested && props.draftKey === key) await submit();
701
965
  queueMicrotask(() => {
702
966
  if (props.draftKey !== key) return;
703
- if (restored || props.value === nextValue) {
704
- const position = restored ? token.end : token.start + replacement.length;
967
+ if (restored || props.value === nextValue || mentioned && props.value === mentioned.value) {
968
+ const position = restored ? token.end : mentioned?.caret ?? token.start + replacement.length;
705
969
  textareaRef?.setSelectionRange(position, position);
706
970
  }
707
971
  syncCaret();
@@ -971,7 +1235,7 @@ export function ChatComposer(props) {
971
1235
  get disabled() {
972
1236
  return !canSelectFiles();
973
1237
  },
974
- onClick: chooseFiles,
1238
+ onClick: () => chooseFiles(),
975
1239
  get children() {
976
1240
  var _el$5 = _$getNextElement(_tmpl$3);
977
1241
  _$effect(() => _$className(_el$5, addingFiles() ? "ti ti-loader-2 k2b-spin" : "ti ti-plus"));
@@ -1282,6 +1546,7 @@ export function ChatComposer(props) {
1282
1546
  _el$22.$$keydown = onKeyDown;
1283
1547
  _el$22.$$beforeinput = event => {
1284
1548
  inputStart = event.currentTarget.selectionStart;
1549
+ inputEnd = event.currentTarget.selectionEnd;
1285
1550
  if (event.inputType === "historyUndo" || event.inputType === "historyRedo") {
1286
1551
  event.preventDefault();
1287
1552
  restoreHistory(event.inputType === "historyUndo" ? -1 : 1);
@@ -1380,17 +1645,19 @@ export function ChatComposer(props) {
1380
1645
  const highlight = () => commandRowMap().get(command)?.highlight;
1381
1646
  const title = () => command.label ?? command.name;
1382
1647
  return (() => {
1383
- var _el$29 = _$getNextElement(_tmpl$12),
1648
+ var _el$29 = _$getNextElement(_tmpl$13),
1384
1649
  _el$30 = _el$29.firstChild,
1385
1650
  _el$31 = _el$30.nextSibling,
1386
1651
  _el$32 = _el$31.firstChild,
1387
1652
  _el$34 = _el$32.nextSibling,
1388
- [_el$35, _co$6] = _$getNextMarker(_el$34.nextSibling);
1653
+ [_el$35, _co$6] = _$getNextMarker(_el$34.nextSibling),
1654
+ _el$39 = _el$31.nextSibling,
1655
+ [_el$40, _co$7] = _$getNextMarker(_el$39.nextSibling);
1389
1656
  _el$29.$$click = event => {
1390
1657
  event.preventDefault();
1391
1658
  void executeCommand(command);
1392
1659
  };
1393
- _el$29.$$pointerdown = event => event.preventDefault();
1660
+ _el$29.$$mousedown = keepFieldFocus;
1394
1661
  _$insert(_el$32, _$createComponent(Show, {
1395
1662
  get when() {
1396
1663
  return highlight();
@@ -1399,9 +1666,9 @@ export function ChatComposer(props) {
1399
1666
  return title();
1400
1667
  },
1401
1668
  children: range => [_$memo(() => title().slice(0, range()[0])), (() => {
1402
- var _el$36 = _$getNextElement(_tmpl$13);
1403
- _$insert(_el$36, () => title().slice(range()[0], range()[1]));
1404
- return _el$36;
1669
+ var _el$41 = _$getNextElement(_tmpl$14);
1670
+ _$insert(_el$41, () => title().slice(range()[0], range()[1]));
1671
+ return _el$41;
1405
1672
  })(), _$memo(() => title().slice(range()[1]))]
1406
1673
  }));
1407
1674
  _$insert(_el$31, _$createComponent(Show, {
@@ -1415,6 +1682,18 @@ export function ChatComposer(props) {
1415
1682
  return _el$33;
1416
1683
  }
1417
1684
  }), _el$35, _co$6);
1685
+ _$insert(_el$29, _$createComponent(Show, {
1686
+ get when() {
1687
+ return command.selected;
1688
+ },
1689
+ get children() {
1690
+ var _el$36 = _$getNextElement(_tmpl$12),
1691
+ _el$37 = _el$36.firstChild,
1692
+ _el$38 = _el$37.nextSibling;
1693
+ _$insert(_el$38, () => chatMessages().commandSelected);
1694
+ return _el$36;
1695
+ }
1696
+ }), _el$40, _co$7);
1418
1697
  _$effect(_p$ => {
1419
1698
  var _v$12 = commandOptionId(command),
1420
1699
  _v$13 = selectedCommand() === command,
@@ -1445,83 +1724,85 @@ export function ChatComposer(props) {
1445
1724
  })();
1446
1725
  };
1447
1726
  return (() => {
1448
- var _el$37 = _$getNextElement(_tmpl$24),
1449
- _el$103 = _el$37.firstChild,
1450
- [_el$104, _co$26] = _$getNextMarker(_el$103.nextSibling),
1451
- _el$65 = _el$104.nextSibling,
1452
- _el$89 = _el$65.firstChild,
1453
- [_el$90, _co$20] = _$getNextMarker(_el$89.nextSibling),
1454
- _el$91 = _el$90.nextSibling,
1455
- [_el$92, _co$21] = _$getNextMarker(_el$91.nextSibling),
1456
- _el$93 = _el$92.nextSibling,
1457
- [_el$94, _co$22] = _$getNextMarker(_el$93.nextSibling),
1458
- _el$95 = _el$94.nextSibling,
1459
- [_el$96, _co$23] = _$getNextMarker(_el$95.nextSibling),
1460
- _el$97 = _el$65.nextSibling,
1727
+ var _el$42 = _$getNextElement(_tmpl$25),
1728
+ _el$110 = _el$42.firstChild,
1729
+ [_el$111, _co$28] = _$getNextMarker(_el$110.nextSibling),
1730
+ _el$72 = _el$111.nextSibling,
1731
+ _el$96 = _el$72.firstChild,
1732
+ [_el$97, _co$22] = _$getNextMarker(_el$96.nextSibling),
1461
1733
  _el$98 = _el$97.nextSibling,
1462
- _el$99 = _el$98.firstChild,
1463
- [_el$100, _co$24] = _$getNextMarker(_el$99.nextSibling),
1464
- _el$101 = _el$100.nextSibling,
1465
- [_el$102, _co$25] = _$getNextMarker(_el$101.nextSibling);
1466
- _$insert(_el$37, _$createComponent(Show, {
1734
+ [_el$99, _co$23] = _$getNextMarker(_el$98.nextSibling),
1735
+ _el$100 = _el$99.nextSibling,
1736
+ [_el$101, _co$24] = _$getNextMarker(_el$100.nextSibling),
1737
+ _el$102 = _el$101.nextSibling,
1738
+ [_el$103, _co$25] = _$getNextMarker(_el$102.nextSibling),
1739
+ _el$104 = _el$72.nextSibling,
1740
+ _el$105 = _el$104.nextSibling,
1741
+ _el$106 = _el$105.firstChild,
1742
+ [_el$107, _co$26] = _$getNextMarker(_el$106.nextSibling),
1743
+ _el$108 = _el$107.nextSibling,
1744
+ [_el$109, _co$27] = _$getNextMarker(_el$108.nextSibling);
1745
+ var _ref$6 = shellRef;
1746
+ typeof _ref$6 === "function" ? _$use(_ref$6, _el$42) : shellRef = _el$42;
1747
+ _$insert(_el$42, _$createComponent(Show, {
1467
1748
  get when() {
1468
1749
  return suggestionsOpen() || hasAccessory();
1469
1750
  },
1470
1751
  get children() {
1471
- var _el$38 = _$getNextElement(_tmpl$19),
1472
- _el$39 = _el$38.firstChild,
1473
- _el$61 = _el$39.nextSibling,
1474
- [_el$62, _co$10] = _$getNextMarker(_el$61.nextSibling),
1475
- _el$63 = _el$62.nextSibling,
1476
- [_el$64, _co$11] = _$getNextMarker(_el$63.nextSibling);
1477
- _$insert(_el$39, accessory);
1478
- _$insert(_el$38, _$createComponent(Show, {
1752
+ var _el$43 = _$getNextElement(_tmpl$20),
1753
+ _el$44 = _el$43.firstChild,
1754
+ _el$68 = _el$44.nextSibling,
1755
+ [_el$69, _co$12] = _$getNextMarker(_el$68.nextSibling),
1756
+ _el$70 = _el$69.nextSibling,
1757
+ [_el$71, _co$13] = _$getNextMarker(_el$70.nextSibling);
1758
+ _$insert(_el$44, accessory);
1759
+ _$insert(_el$43, _$createComponent(Show, {
1479
1760
  get when() {
1480
1761
  return emojiOpen();
1481
1762
  },
1482
1763
  get children() {
1483
- var _el$40 = _$getNextElement(_tmpl$14),
1484
- _el$41 = _el$40.firstChild;
1485
- var _ref$6 = commandListRef;
1486
- typeof _ref$6 === "function" ? _$use(_ref$6, _el$41) : commandListRef = _el$41;
1487
- _$setAttribute(_el$41, "id", commandListId);
1488
- _$insert(_el$41, _$createComponent(For, {
1764
+ var _el$45 = _$getNextElement(_tmpl$15),
1765
+ _el$46 = _el$45.firstChild;
1766
+ var _ref$7 = commandListRef;
1767
+ typeof _ref$7 === "function" ? _$use(_ref$7, _el$46) : commandListRef = _el$46;
1768
+ _$setAttribute(_el$46, "id", commandListId);
1769
+ _$insert(_el$46, _$createComponent(For, {
1489
1770
  get each() {
1490
1771
  return emojiMatches();
1491
1772
  },
1492
1773
  children: (entry, index) => (() => {
1493
- var _el$105 = _$getNextElement(_tmpl$25),
1494
- _el$106 = _el$105.firstChild,
1495
- _el$107 = _el$106.nextSibling,
1496
- _el$108 = _el$107.nextSibling,
1497
- [_el$109, _co$27] = _$getNextMarker(_el$108.nextSibling);
1498
- _el$105.$$click = () => pickEmojiSuggestion(index());
1499
- _el$105.$$pointerdown = event => event.preventDefault();
1500
- _$insert(_el$106, () => emojiInTone(entry, props.emoji?.skinTone ?? 0));
1501
- _$insert(_el$107, () => emojiName(entry, locale()));
1502
- _$insert(_el$105, _$createComponent(Show, {
1774
+ var _el$112 = _$getNextElement(_tmpl$26),
1775
+ _el$113 = _el$112.firstChild,
1776
+ _el$114 = _el$113.nextSibling,
1777
+ _el$115 = _el$114.nextSibling,
1778
+ [_el$116, _co$29] = _$getNextMarker(_el$115.nextSibling);
1779
+ _el$112.$$click = () => pickEmojiSuggestion(index());
1780
+ _el$112.$$mousedown = keepFieldFocus;
1781
+ _$insert(_el$113, () => emojiInTone(entry, props.emoji?.skinTone ?? 0));
1782
+ _$insert(_el$114, () => emojiName(entry, locale()));
1783
+ _$insert(_el$112, _$createComponent(Show, {
1503
1784
  get when() {
1504
1785
  return entry.shortcodes[0];
1505
1786
  },
1506
1787
  children: code => (() => {
1507
- var _el$110 = _$getNextElement(_tmpl$26),
1508
- _el$111 = _el$110.firstChild,
1509
- _el$113 = _el$111.nextSibling,
1510
- [_el$114, _co$28] = _$getNextMarker(_el$113.nextSibling),
1511
- _el$112 = _el$114.nextSibling;
1512
- _$insert(_el$110, code, _el$114, _co$28);
1513
- return _el$110;
1788
+ var _el$117 = _$getNextElement(_tmpl$27),
1789
+ _el$118 = _el$117.firstChild,
1790
+ _el$120 = _el$118.nextSibling,
1791
+ [_el$121, _co$30] = _$getNextMarker(_el$120.nextSibling),
1792
+ _el$119 = _el$121.nextSibling;
1793
+ _$insert(_el$117, code, _el$121, _co$30);
1794
+ return _el$117;
1514
1795
  })()
1515
- }), _el$109, _co$27);
1796
+ }), _el$116, _co$29);
1516
1797
  _$effect(_p$ => {
1517
1798
  var _v$28 = `${commandListId}-${index()}`,
1518
1799
  _v$29 = index() === selectedCommandIndex(),
1519
1800
  _v$30 = emojiName(entry, locale()),
1520
1801
  _v$31 = index() === selectedCommandIndex() ? "true" : undefined;
1521
- _v$28 !== _p$.e && _$setAttribute(_el$105, "id", _p$.e = _v$28);
1522
- _v$29 !== _p$.t && _$setAttribute(_el$105, "aria-selected", _p$.t = _v$29);
1523
- _v$30 !== _p$.a && _$setAttribute(_el$105, "aria-label", _p$.a = _v$30);
1524
- _v$31 !== _p$.o && _$setAttribute(_el$105, "data-active", _p$.o = _v$31);
1802
+ _v$28 !== _p$.e && _$setAttribute(_el$112, "id", _p$.e = _v$28);
1803
+ _v$29 !== _p$.t && _$setAttribute(_el$112, "aria-selected", _p$.t = _v$29);
1804
+ _v$30 !== _p$.a && _$setAttribute(_el$112, "aria-label", _p$.a = _v$30);
1805
+ _v$31 !== _p$.o && _$setAttribute(_el$112, "data-active", _p$.o = _v$31);
1525
1806
  return _p$;
1526
1807
  }, {
1527
1808
  e: undefined,
@@ -1530,32 +1811,34 @@ export function ChatComposer(props) {
1530
1811
  o: undefined
1531
1812
  });
1532
1813
  _$runHydrationEvents();
1533
- return _el$105;
1814
+ return _el$112;
1534
1815
  })()
1535
1816
  }));
1536
- _$effect(() => _$setAttribute(_el$41, "aria-label", chatMessages().emojiSuggestions));
1537
- return _el$40;
1817
+ _$effect(() => _$setAttribute(_el$46, "aria-label", chatMessages().emojiSuggestions));
1818
+ return _el$45;
1538
1819
  }
1539
- }), _el$62, _co$10);
1540
- _$insert(_el$38, _$createComponent(Show, {
1820
+ }), _el$69, _co$12);
1821
+ _$insert(_el$43, _$createComponent(Show, {
1541
1822
  get when() {
1542
1823
  return commandsOpen();
1543
1824
  },
1544
1825
  get children() {
1545
- var _el$42 = _$getNextElement(_tmpl$18),
1546
- _el$43 = _el$42.firstChild,
1547
- _el$53 = _el$43.firstChild,
1548
- [_el$54, _co$8] = _$getNextMarker(_el$53.nextSibling),
1549
- _el$55 = _el$54.nextSibling,
1550
- [_el$56, _co$9] = _$getNextMarker(_el$55.nextSibling),
1551
- _el$57 = _el$56.nextSibling,
1552
- [_el$58, _co$0] = _$getNextMarker(_el$57.nextSibling),
1553
- _el$59 = _el$58.nextSibling,
1554
- [_el$60, _co$1] = _$getNextMarker(_el$59.nextSibling);
1555
- var _ref$7 = commandListRef;
1556
- typeof _ref$7 === "function" ? _$use(_ref$7, _el$43) : commandListRef = _el$43;
1557
- _$setAttribute(_el$43, "id", commandListId);
1558
- _$insert(_el$43, _$createComponent(For, {
1826
+ var _el$47 = _$getNextElement(_tmpl$19),
1827
+ _el$48 = _el$47.firstChild,
1828
+ _el$58 = _el$48.firstChild,
1829
+ [_el$59, _co$9] = _$getNextMarker(_el$58.nextSibling),
1830
+ _el$60 = _el$59.nextSibling,
1831
+ [_el$61, _co$0] = _$getNextMarker(_el$60.nextSibling),
1832
+ _el$62 = _el$61.nextSibling,
1833
+ [_el$63, _co$1] = _$getNextMarker(_el$62.nextSibling),
1834
+ _el$64 = _el$63.nextSibling,
1835
+ [_el$65, _co$10] = _$getNextMarker(_el$64.nextSibling),
1836
+ _el$66 = _el$65.nextSibling,
1837
+ [_el$67, _co$11] = _$getNextMarker(_el$66.nextSibling);
1838
+ var _ref$8 = commandListRef;
1839
+ typeof _ref$8 === "function" ? _$use(_ref$8, _el$48) : commandListRef = _el$48;
1840
+ _$setAttribute(_el$48, "id", commandListId);
1841
+ _$insert(_el$48, _$createComponent(For, {
1559
1842
  get each() {
1560
1843
  return commandModel().groups.map(commandGroupKey);
1561
1844
  },
@@ -1574,343 +1857,350 @@ export function ChatComposer(props) {
1574
1857
  });
1575
1858
  },
1576
1859
  get children() {
1577
- var _el$115 = _$getNextElement(_tmpl$29),
1578
- _el$116 = _el$115.firstChild,
1579
- _el$117 = _el$116.firstChild,
1580
- _el$119 = _el$117.nextSibling,
1581
- [_el$120, _co$29] = _$getNextMarker(_el$119.nextSibling),
1582
- _el$122 = _el$116.nextSibling,
1583
- [_el$123, _co$30] = _$getNextMarker(_el$122.nextSibling),
1584
- _el$124 = _el$123.nextSibling,
1585
- [_el$125, _co$31] = _$getNextMarker(_el$124.nextSibling);
1586
- _$insert(_el$117, () => group()?.scopeTitle ?? group()?.section?.label);
1587
- _$insert(_el$116, _$createComponent(Show, {
1860
+ var _el$122 = _$getNextElement(_tmpl$30),
1861
+ _el$123 = _el$122.firstChild,
1862
+ _el$124 = _el$123.firstChild,
1863
+ _el$126 = _el$124.nextSibling,
1864
+ [_el$127, _co$31] = _$getNextMarker(_el$126.nextSibling),
1865
+ _el$129 = _el$123.nextSibling,
1866
+ [_el$130, _co$32] = _$getNextMarker(_el$129.nextSibling),
1867
+ _el$131 = _el$130.nextSibling,
1868
+ [_el$132, _co$33] = _$getNextMarker(_el$131.nextSibling);
1869
+ _$insert(_el$124, () => group()?.scopeTitle ?? group()?.section?.label);
1870
+ _$insert(_el$123, _$createComponent(Show, {
1588
1871
  get when() {
1589
1872
  return group()?.loading;
1590
1873
  },
1591
1874
  get children() {
1592
- return _$getNextElement(_tmpl$27);
1875
+ return _$getNextElement(_tmpl$28);
1593
1876
  }
1594
- }), _el$120, _co$29);
1595
- _$insert(_el$115, _$createComponent(For, {
1877
+ }), _el$127, _co$31);
1878
+ _$insert(_el$122, _$createComponent(For, {
1596
1879
  get each() {
1597
1880
  return rows();
1598
1881
  },
1599
1882
  children: renderCommandRow
1600
- }), _el$123, _co$30);
1601
- _$insert(_el$115, _$createComponent(Show, {
1883
+ }), _el$130, _co$32);
1884
+ _$insert(_el$122, _$createComponent(Show, {
1602
1885
  get when() {
1603
1886
  return group()?.placeholder;
1604
1887
  },
1605
1888
  get children() {
1606
- return _$getNextElement(_tmpl$28);
1889
+ return _$getNextElement(_tmpl$29);
1607
1890
  }
1608
- }), _el$125, _co$31);
1891
+ }), _el$132, _co$33);
1609
1892
  _$effect(_p$ => {
1610
1893
  var _v$32 = headingId(),
1611
1894
  _v$33 = headingId();
1612
- _v$32 !== _p$.e && _$setAttribute(_el$115, "aria-labelledby", _p$.e = _v$32);
1613
- _v$33 !== _p$.t && _$setAttribute(_el$116, "id", _p$.t = _v$33);
1895
+ _v$32 !== _p$.e && _$setAttribute(_el$122, "aria-labelledby", _p$.e = _v$32);
1896
+ _v$33 !== _p$.t && _$setAttribute(_el$123, "id", _p$.t = _v$33);
1614
1897
  return _p$;
1615
1898
  }, {
1616
1899
  e: undefined,
1617
1900
  t: undefined
1618
1901
  });
1619
- return _el$115;
1902
+ return _el$122;
1620
1903
  }
1621
1904
  });
1622
1905
  }
1623
- }), _el$54, _co$8);
1624
- _$insert(_el$43, _$createComponent(Show, {
1906
+ }), _el$59, _co$9);
1907
+ _$insert(_el$48, _$createComponent(Show, {
1625
1908
  get when() {
1626
- return _$memo(() => !!(searching() && commandMatches().length === 0))() && !commandModel().groups.some(group => group.section || group.scopeTitle);
1909
+ return _$memo(() => !!(searching() && foundCommandCount() === 0))() && !commandModel().groups.some(group => group.section || group.scopeTitle);
1627
1910
  },
1628
1911
  get children() {
1629
- var _el$44 = _$getNextElement(_tmpl$15),
1630
- _el$45 = _el$44.firstChild,
1631
- _el$46 = _el$45.nextSibling;
1632
- _$insert(_el$46, () => messages().loading);
1633
- return _el$44;
1912
+ var _el$49 = _$getNextElement(_tmpl$16),
1913
+ _el$50 = _el$49.firstChild,
1914
+ _el$51 = _el$50.nextSibling;
1915
+ _$insert(_el$51, () => messages().loading);
1916
+ return _el$49;
1634
1917
  }
1635
- }), _el$56, _co$9);
1636
- _$insert(_el$43, _$createComponent(Show, {
1918
+ }), _el$61, _co$0);
1919
+ _$insert(_el$48, _$createComponent(Show, {
1637
1920
  get when() {
1638
1921
  return searchError();
1639
1922
  },
1640
1923
  get children() {
1641
- var _el$47 = _$getNextElement(_tmpl$16),
1642
- _el$48 = _el$47.firstChild,
1643
- _el$49 = _el$48.nextSibling,
1644
- _el$50 = _el$49.nextSibling,
1645
- [_el$51, _co$7] = _$getNextMarker(_el$50.nextSibling);
1646
- _$insert(_el$47, () => messages().error, _el$51, _co$7);
1647
- return _el$47;
1924
+ var _el$52 = _$getNextElement(_tmpl$17),
1925
+ _el$53 = _el$52.firstChild,
1926
+ _el$54 = _el$53.nextSibling,
1927
+ _el$55 = _el$54.nextSibling,
1928
+ [_el$56, _co$8] = _$getNextMarker(_el$55.nextSibling);
1929
+ _$insert(_el$52, () => messages().error, _el$56, _co$8);
1930
+ return _el$52;
1648
1931
  }
1649
- }), _el$58, _co$0);
1650
- _$insert(_el$43, _$createComponent(Show, {
1932
+ }), _el$63, _co$1);
1933
+ _$insert(_el$48, _$createComponent(Show, {
1651
1934
  get when() {
1652
- return _$memo(() => !!(!searching() && !searchError()))() && commandMatches().length === 0;
1935
+ return _$memo(() => !!(!searching() && !searchError()))() && foundCommandCount() === 0;
1653
1936
  },
1654
1937
  get children() {
1655
- var _el$52 = _$getNextElement(_tmpl$17);
1656
- _$insert(_el$52, (() => {
1938
+ var _el$57 = _$getNextElement(_tmpl$18);
1939
+ _$insert(_el$57, (() => {
1657
1940
  var _c$ = _$memo(() => !!!parsedCommandQuery().query.trim());
1658
1941
  return () => _c$() ? messages().noResults : chatMessages().commandsNothingFound({
1659
1942
  query: parsedCommandQuery().query.trim()
1660
1943
  });
1661
1944
  })());
1662
- return _el$52;
1945
+ return _el$57;
1663
1946
  }
1664
- }), _el$60, _co$1);
1947
+ }), _el$65, _co$10);
1948
+ _$insert(_el$48, _$createComponent(Show, {
1949
+ get when() {
1950
+ return commandModel().fallback?.command;
1951
+ },
1952
+ keyed: true,
1953
+ children: command => renderCommandRow(command)
1954
+ }), _el$67, _co$11);
1665
1955
  _$effect(_p$ => {
1666
1956
  var _v$19 = chatMessages().commands,
1667
1957
  _v$20 = searching() ? "true" : undefined;
1668
- _v$19 !== _p$.e && _$setAttribute(_el$43, "aria-label", _p$.e = _v$19);
1669
- _v$20 !== _p$.t && _$setAttribute(_el$43, "aria-busy", _p$.t = _v$20);
1958
+ _v$19 !== _p$.e && _$setAttribute(_el$48, "aria-label", _p$.e = _v$19);
1959
+ _v$20 !== _p$.t && _$setAttribute(_el$48, "aria-busy", _p$.t = _v$20);
1670
1960
  return _p$;
1671
1961
  }, {
1672
1962
  e: undefined,
1673
1963
  t: undefined
1674
1964
  });
1675
- return _el$42;
1965
+ return _el$47;
1676
1966
  }
1677
- }), _el$64, _co$11);
1967
+ }), _el$71, _co$13);
1678
1968
  _$effect(_p$ => {
1679
1969
  var _v$21 = hasAccessory() ? undefined : "true",
1680
1970
  _v$22 = suggestionsOpen() ? "hidden" : undefined,
1681
1971
  _v$23 = suggestionsOpen();
1682
- _v$21 !== _p$.e && _$setAttribute(_el$38, "data-overlay", _p$.e = _v$21);
1683
- _v$22 !== _p$.t && _$setStyleProperty(_el$39, "visibility", _p$.t = _v$22);
1684
- _v$23 !== _p$.a && _$setProperty(_el$39, "inert", _p$.a = _v$23);
1972
+ _v$21 !== _p$.e && _$setAttribute(_el$43, "data-overlay", _p$.e = _v$21);
1973
+ _v$22 !== _p$.t && _$setStyleProperty(_el$44, "visibility", _p$.t = _v$22);
1974
+ _v$23 !== _p$.a && _$setProperty(_el$44, "inert", _p$.a = _v$23);
1685
1975
  return _p$;
1686
1976
  }, {
1687
1977
  e: undefined,
1688
1978
  t: undefined,
1689
1979
  a: undefined
1690
1980
  });
1691
- return _el$38;
1981
+ return _el$43;
1692
1982
  }
1693
- }), _el$104, _co$26);
1694
- var _ref$8 = composerRef;
1695
- typeof _ref$8 === "function" ? _$use(_ref$8, _el$65) : composerRef = _el$65;
1696
- _$insert(_el$65, _$createComponent(Show, {
1983
+ }), _el$111, _co$28);
1984
+ var _ref$9 = composerRef;
1985
+ typeof _ref$9 === "function" ? _$use(_ref$9, _el$72) : composerRef = _el$72;
1986
+ _$insert(_el$72, _$createComponent(Show, {
1697
1987
  get when() {
1698
1988
  return showHint();
1699
1989
  },
1700
1990
  get children() {
1701
- var _el$66 = _$getNextElement(_tmpl$20);
1702
- _$insert(_el$66, _$createComponent(Show, {
1991
+ var _el$73 = _$getNextElement(_tmpl$21);
1992
+ _$insert(_el$73, _$createComponent(Show, {
1703
1993
  get when() {
1704
1994
  return dictationStatus();
1705
1995
  },
1706
1996
  get fallback() {
1707
1997
  return (() => {
1708
- var _el$126 = _$getNextElement(_tmpl$30);
1709
- _$insert(_el$126, hint);
1710
- return _el$126;
1998
+ var _el$133 = _$getNextElement(_tmpl$31);
1999
+ _$insert(_el$133, hint);
2000
+ return _el$133;
1711
2001
  })();
1712
2002
  },
1713
2003
  children: status => [(() => {
1714
- var _el$127 = _$getNextElement(_tmpl$31),
1715
- _el$128 = _el$127.firstChild,
1716
- _el$129 = _el$128.nextSibling;
1717
- _$insert(_el$129, () => status().text);
2004
+ var _el$134 = _$getNextElement(_tmpl$32),
2005
+ _el$135 = _el$134.firstChild,
2006
+ _el$136 = _el$135.nextSibling;
2007
+ _$insert(_el$136, () => status().text);
1718
2008
  _$effect(_p$ => {
1719
2009
  var _v$34 = dictation() ?? undefined,
1720
2010
  _v$35 = status().icon;
1721
- _v$34 !== _p$.e && _$setAttribute(_el$127, "data-state", _p$.e = _v$34);
1722
- _v$35 !== _p$.t && _$className(_el$128, _p$.t = _v$35);
2011
+ _v$34 !== _p$.e && _$setAttribute(_el$134, "data-state", _p$.e = _v$34);
2012
+ _v$35 !== _p$.t && _$className(_el$135, _p$.t = _v$35);
1723
2013
  return _p$;
1724
2014
  }, {
1725
2015
  e: undefined,
1726
2016
  t: undefined
1727
2017
  });
1728
- return _el$127;
2018
+ return _el$134;
1729
2019
  })(), _$createComponent(Show, {
1730
2020
  get when() {
1731
2021
  return _$memo(() => dictation() === "refined")() ? props.microphone?.onRestoreOriginal : undefined;
1732
2022
  },
1733
2023
  children: restore => (() => {
1734
- var _el$130 = _$getNextElement(_tmpl$32);
1735
- _el$130.$$click = () => reportChatFailure(restore(), props.onError);
1736
- _el$130.$$mousedown = keepFieldFocus;
1737
- _$insert(_el$130, () => chatMessages().restoreOriginal);
1738
- _$effect(() => _$setProperty(_el$130, "disabled", microphoneDisabled()));
2024
+ var _el$137 = _$getNextElement(_tmpl$33);
2025
+ _el$137.$$click = () => reportChatFailure(restore(), props.onError);
2026
+ _el$137.$$mousedown = keepFieldFocus;
2027
+ _$insert(_el$137, () => chatMessages().restoreOriginal);
2028
+ _$effect(() => _$setProperty(_el$137, "disabled", microphoneDisabled()));
1739
2029
  _$runHydrationEvents();
1740
- return _el$130;
2030
+ return _el$137;
1741
2031
  })()
1742
2032
  })]
1743
2033
  }));
1744
- return _el$66;
2034
+ return _el$73;
1745
2035
  }
1746
- }), _el$90, _co$20);
1747
- _$insert(_el$65, _$createComponent(Show, {
2036
+ }), _el$97, _co$22);
2037
+ _$insert(_el$72, _$createComponent(Show, {
1748
2038
  get when() {
1749
2039
  return attachments().length > 0;
1750
2040
  },
1751
2041
  get children() {
1752
- var _el$67 = _$getNextElement(_tmpl$21);
1753
- _$insert(_el$67, _$createComponent(For, {
2042
+ var _el$74 = _$getNextElement(_tmpl$22);
2043
+ _$insert(_el$74, _$createComponent(For, {
1754
2044
  get each() {
1755
2045
  return attachments();
1756
2046
  },
1757
2047
  children: attachment => (() => {
1758
- var _el$131 = _$getNextElement(_tmpl$34),
1759
- _el$132 = _el$131.firstChild,
1760
- _el$133 = _el$132.firstChild,
1761
- [_el$134, _co$32] = _$getNextMarker(_el$133.nextSibling),
1762
- _el$135 = _el$134.nextSibling,
1763
- [_el$136, _co$33] = _$getNextMarker(_el$135.nextSibling),
1764
- _el$138 = _el$132.nextSibling,
1765
- [_el$139, _co$34] = _$getNextMarker(_el$138.nextSibling);
1766
- _$insert(_el$132, _$createComponent(Show, {
2048
+ var _el$138 = _$getNextElement(_tmpl$35),
2049
+ _el$139 = _el$138.firstChild,
2050
+ _el$140 = _el$139.firstChild,
2051
+ [_el$141, _co$34] = _$getNextMarker(_el$140.nextSibling),
2052
+ _el$142 = _el$141.nextSibling,
2053
+ [_el$143, _co$35] = _$getNextMarker(_el$142.nextSibling),
2054
+ _el$145 = _el$139.nextSibling,
2055
+ [_el$146, _co$36] = _$getNextMarker(_el$145.nextSibling);
2056
+ _$insert(_el$139, _$createComponent(Show, {
1767
2057
  get when() {
1768
2058
  return attachment.href;
1769
2059
  },
1770
2060
  get fallback() {
1771
2061
  return (() => {
1772
- var _el$140 = _$getNextElement(_tmpl$36),
1773
- _el$142 = _el$140.firstChild,
1774
- [_el$143, _co$35] = _$getNextMarker(_el$142.nextSibling),
1775
- _el$144 = _el$143.nextSibling,
1776
- [_el$145, _co$36] = _$getNextMarker(_el$144.nextSibling);
1777
- _$insert(_el$140, _$createComponent(Show, {
2062
+ var _el$147 = _$getNextElement(_tmpl$37),
2063
+ _el$149 = _el$147.firstChild,
2064
+ [_el$150, _co$37] = _$getNextMarker(_el$149.nextSibling),
2065
+ _el$151 = _el$150.nextSibling,
2066
+ [_el$152, _co$38] = _$getNextMarker(_el$151.nextSibling);
2067
+ _$insert(_el$147, _$createComponent(Show, {
1778
2068
  get when() {
1779
2069
  return _$memo(() => attachment.kind === "image")() && attachment.previewUrl;
1780
2070
  },
1781
2071
  get fallback() {
1782
2072
  return (() => {
1783
- var _el$146 = _$getNextElement(_tmpl$3);
1784
- _$effect(() => _$className(_el$146, attachmentIcon(attachment)));
1785
- return _el$146;
2073
+ var _el$153 = _$getNextElement(_tmpl$3);
2074
+ _$effect(() => _$className(_el$153, attachmentIcon(attachment)));
2075
+ return _el$153;
1786
2076
  })();
1787
2077
  },
1788
2078
  get children() {
1789
- var _el$141 = _$getNextElement(_tmpl$35);
2079
+ var _el$148 = _$getNextElement(_tmpl$36);
1790
2080
  _$effect(_p$ => {
1791
2081
  var _v$38 = attachment.previewUrl,
1792
2082
  _v$39 = attachment.alt ?? "";
1793
- _v$38 !== _p$.e && _$setAttribute(_el$141, "src", _p$.e = _v$38);
1794
- _v$39 !== _p$.t && _$setAttribute(_el$141, "alt", _p$.t = _v$39);
2083
+ _v$38 !== _p$.e && _$setAttribute(_el$148, "src", _p$.e = _v$38);
2084
+ _v$39 !== _p$.t && _$setAttribute(_el$148, "alt", _p$.t = _v$39);
1795
2085
  return _p$;
1796
2086
  }, {
1797
2087
  e: undefined,
1798
2088
  t: undefined
1799
2089
  });
1800
- return _el$141;
2090
+ return _el$148;
1801
2091
  }
1802
- }), _el$143, _co$35);
1803
- _$insert(_el$140, () => renderAttachmentCopy(attachment), _el$145, _co$36);
1804
- return _el$140;
2092
+ }), _el$150, _co$37);
2093
+ _$insert(_el$147, () => renderAttachmentCopy(attachment), _el$152, _co$38);
2094
+ return _el$147;
1805
2095
  })();
1806
2096
  },
1807
2097
  children: href => (() => {
1808
- var _el$147 = _$getNextElement(_tmpl$37),
1809
- _el$149 = _el$147.firstChild,
1810
- [_el$150, _co$37] = _$getNextMarker(_el$149.nextSibling),
1811
- _el$151 = _el$150.nextSibling,
1812
- [_el$152, _co$38] = _$getNextMarker(_el$151.nextSibling);
1813
- _$insert(_el$147, _$createComponent(Show, {
2098
+ var _el$154 = _$getNextElement(_tmpl$38),
2099
+ _el$156 = _el$154.firstChild,
2100
+ [_el$157, _co$39] = _$getNextMarker(_el$156.nextSibling),
2101
+ _el$158 = _el$157.nextSibling,
2102
+ [_el$159, _co$40] = _$getNextMarker(_el$158.nextSibling);
2103
+ _$insert(_el$154, _$createComponent(Show, {
1814
2104
  get when() {
1815
2105
  return _$memo(() => attachment.kind === "image")() && attachment.previewUrl;
1816
2106
  },
1817
2107
  get fallback() {
1818
2108
  return (() => {
1819
- var _el$153 = _$getNextElement(_tmpl$3);
1820
- _$effect(() => _$className(_el$153, attachmentIcon(attachment)));
1821
- return _el$153;
2109
+ var _el$160 = _$getNextElement(_tmpl$3);
2110
+ _$effect(() => _$className(_el$160, attachmentIcon(attachment)));
2111
+ return _el$160;
1822
2112
  })();
1823
2113
  },
1824
2114
  get children() {
1825
- var _el$148 = _$getNextElement(_tmpl$35);
2115
+ var _el$155 = _$getNextElement(_tmpl$36);
1826
2116
  _$effect(_p$ => {
1827
2117
  var _v$40 = attachment.previewUrl,
1828
2118
  _v$41 = attachment.alt ?? "";
1829
- _v$40 !== _p$.e && _$setAttribute(_el$148, "src", _p$.e = _v$40);
1830
- _v$41 !== _p$.t && _$setAttribute(_el$148, "alt", _p$.t = _v$41);
2119
+ _v$40 !== _p$.e && _$setAttribute(_el$155, "src", _p$.e = _v$40);
2120
+ _v$41 !== _p$.t && _$setAttribute(_el$155, "alt", _p$.t = _v$41);
1831
2121
  return _p$;
1832
2122
  }, {
1833
2123
  e: undefined,
1834
2124
  t: undefined
1835
2125
  });
1836
- return _el$148;
2126
+ return _el$155;
1837
2127
  }
1838
- }), _el$150, _co$37);
1839
- _$insert(_el$147, () => renderAttachmentCopy(attachment), _el$152, _co$38);
2128
+ }), _el$157, _co$39);
2129
+ _$insert(_el$154, () => renderAttachmentCopy(attachment), _el$159, _co$40);
1840
2130
  _$effect(_p$ => {
1841
2131
  var _v$42 = href(),
1842
2132
  _v$43 = chatMessages().openInNewTab({
1843
2133
  name: attachment.name
1844
2134
  });
1845
- _v$42 !== _p$.e && _$setAttribute(_el$147, "href", _p$.e = _v$42);
1846
- _v$43 !== _p$.t && _$setAttribute(_el$147, "aria-label", _p$.t = _v$43);
2135
+ _v$42 !== _p$.e && _$setAttribute(_el$154, "href", _p$.e = _v$42);
2136
+ _v$43 !== _p$.t && _$setAttribute(_el$154, "aria-label", _p$.t = _v$43);
1847
2137
  return _p$;
1848
2138
  }, {
1849
2139
  e: undefined,
1850
2140
  t: undefined
1851
2141
  });
1852
- return _el$147;
2142
+ return _el$154;
1853
2143
  })()
1854
- }), _el$134, _co$32);
1855
- _$insert(_el$132, _$createComponent(Show, {
2144
+ }), _el$141, _co$34);
2145
+ _$insert(_el$139, _$createComponent(Show, {
1856
2146
  get when() {
1857
2147
  return attachment.action;
1858
2148
  },
1859
2149
  children: action => (() => {
1860
- var _el$154 = _$getNextElement(_tmpl$38),
1861
- _el$155 = _el$154.firstChild,
1862
- [_el$156, _co$39] = _$getNextMarker(_el$155.nextSibling),
1863
- _el$157 = _el$156.nextSibling,
1864
- [_el$158, _co$40] = _$getNextMarker(_el$157.nextSibling);
1865
- _el$154.$$click = () => reportChatFailure(() => executeChatAction(action()), props.onError);
1866
- _$insert(_el$154, _$createComponent(Show, {
2150
+ var _el$161 = _$getNextElement(_tmpl$39),
2151
+ _el$162 = _el$161.firstChild,
2152
+ [_el$163, _co$41] = _$getNextMarker(_el$162.nextSibling),
2153
+ _el$164 = _el$163.nextSibling,
2154
+ [_el$165, _co$42] = _$getNextMarker(_el$164.nextSibling);
2155
+ _el$161.$$click = () => reportChatFailure(() => executeChatAction(action()), props.onError);
2156
+ _$insert(_el$161, _$createComponent(Show, {
1867
2157
  get when() {
1868
2158
  return action().icon;
1869
2159
  },
1870
2160
  children: icon => (() => {
1871
- var _el$159 = _$getNextElement(_tmpl$3);
1872
- _$effect(() => _$className(_el$159, icon()));
1873
- return _el$159;
2161
+ var _el$166 = _$getNextElement(_tmpl$3);
2162
+ _$effect(() => _$className(_el$166, icon()));
2163
+ return _el$166;
1874
2164
  })()
1875
- }), _el$156, _co$39);
1876
- _$insert(_el$154, () => action().label, _el$158, _co$40);
1877
- _$effect(() => _$setProperty(_el$154, "disabled", blocked() || action().disabled));
2165
+ }), _el$163, _co$41);
2166
+ _$insert(_el$161, () => action().label, _el$165, _co$42);
2167
+ _$effect(() => _$setProperty(_el$161, "disabled", blocked() || action().disabled));
1878
2168
  _$runHydrationEvents();
1879
- return _el$154;
2169
+ return _el$161;
1880
2170
  })()
1881
- }), _el$136, _co$33);
1882
- _$insert(_el$131, _$createComponent(Show, {
2171
+ }), _el$143, _co$35);
2172
+ _$insert(_el$138, _$createComponent(Show, {
1883
2173
  get when() {
1884
2174
  return props.onAttachmentsChange;
1885
2175
  },
1886
2176
  get children() {
1887
- var _el$137 = _$getNextElement(_tmpl$33);
1888
- _el$137.$$click = () => setAttachments(attachments().filter(candidate => candidate.id !== attachment.id));
2177
+ var _el$144 = _$getNextElement(_tmpl$34);
2178
+ _el$144.$$click = () => setAttachments(attachments().filter(candidate => candidate.id !== attachment.id));
1889
2179
  _$effect(_p$ => {
1890
2180
  var _v$36 = selectMessages().removeNamed({
1891
2181
  name: attachment.name
1892
2182
  }),
1893
2183
  _v$37 = blocked();
1894
- _v$36 !== _p$.e && _$setAttribute(_el$137, "aria-label", _p$.e = _v$36);
1895
- _v$37 !== _p$.t && _$setProperty(_el$137, "disabled", _p$.t = _v$37);
2184
+ _v$36 !== _p$.e && _$setAttribute(_el$144, "aria-label", _p$.e = _v$36);
2185
+ _v$37 !== _p$.t && _$setProperty(_el$144, "disabled", _p$.t = _v$37);
1896
2186
  return _p$;
1897
2187
  }, {
1898
2188
  e: undefined,
1899
2189
  t: undefined
1900
2190
  });
1901
2191
  _$runHydrationEvents();
1902
- return _el$137;
2192
+ return _el$144;
1903
2193
  }
1904
- }), _el$139, _co$34);
1905
- _$effect(() => _el$132.classList.toggle("k2b-chat-composer__attachment-content--action", !!Boolean(attachment.action)));
1906
- return _el$131;
2194
+ }), _el$146, _co$36);
2195
+ _$effect(() => _el$139.classList.toggle("k2b-chat-composer__attachment-content--action", !!Boolean(attachment.action)));
2196
+ return _el$138;
1907
2197
  })()
1908
2198
  }));
1909
- _$effect(() => _$setAttribute(_el$67, "aria-label", chatMessages().attachments));
1910
- return _el$67;
2199
+ _$effect(() => _$setAttribute(_el$74, "aria-label", chatMessages().attachments));
2200
+ return _el$74;
1911
2201
  }
1912
- }), _el$92, _co$21);
1913
- _$insert(_el$65, _$createComponent(Show, {
2202
+ }), _el$99, _co$23);
2203
+ _$insert(_el$72, _$createComponent(Show, {
1914
2204
  get when() {
1915
2205
  return conversation();
1916
2206
  },
@@ -1920,49 +2210,49 @@ export function ChatComposer(props) {
1920
2210
  return props.error;
1921
2211
  },
1922
2212
  get children() {
1923
- var _el$160 = _$getNextElement(_tmpl$22),
1924
- _el$161 = _el$160.firstChild,
1925
- _el$162 = _el$161.nextSibling,
1926
- [_el$163, _co$41] = _$getNextMarker(_el$162.nextSibling);
1927
- _$insert(_el$160, () => props.error, _el$163, _co$41);
1928
- return _el$160;
2213
+ var _el$167 = _$getNextElement(_tmpl$23),
2214
+ _el$168 = _el$167.firstChild,
2215
+ _el$169 = _el$168.nextSibling,
2216
+ [_el$170, _co$43] = _$getNextMarker(_el$169.nextSibling);
2217
+ _$insert(_el$167, () => props.error, _el$170, _co$43);
2218
+ return _el$167;
1929
2219
  }
1930
2220
  }), _$memo(formatRow), (() => {
1931
- var _el$164 = _$getNextElement(_tmpl$39);
1932
- _$insert(_el$164, _$createComponent(Show, {
2221
+ var _el$171 = _$getNextElement(_tmpl$40);
2222
+ _$insert(_el$171, _$createComponent(Show, {
1933
2223
  get when() {
1934
- return props.footerContent;
2224
+ return footer();
1935
2225
  },
1936
2226
  get fallback() {
1937
2227
  return [(() => {
1938
- var _el$165 = _$getNextElement(_tmpl$40),
1939
- _el$166 = _el$165.firstChild,
1940
- [_el$167, _co$42] = _$getNextMarker(_el$166.nextSibling),
1941
- _el$168 = _el$167.nextSibling,
1942
- [_el$169, _co$43] = _$getNextMarker(_el$168.nextSibling),
1943
- _el$170 = _el$169.nextSibling,
1944
- [_el$171, _co$44] = _$getNextMarker(_el$170.nextSibling),
1945
- _el$172 = _el$171.nextSibling,
1946
- [_el$173, _co$45] = _$getNextMarker(_el$172.nextSibling),
1947
- _el$174 = _el$173.nextSibling,
1948
- [_el$175, _co$46] = _$getNextMarker(_el$174.nextSibling),
1949
- _el$176 = _el$175.nextSibling,
1950
- [_el$177, _co$47] = _$getNextMarker(_el$176.nextSibling),
1951
- _el$178 = _el$177.nextSibling,
1952
- [_el$179, _co$48] = _$getNextMarker(_el$178.nextSibling);
1953
- _$insert(_el$165, () => props.footerTools, _el$167, _co$42);
1954
- _$insert(_el$165, _$createComponent(Show, {
2228
+ var _el$172 = _$getNextElement(_tmpl$41),
2229
+ _el$173 = _el$172.firstChild,
2230
+ [_el$174, _co$44] = _$getNextMarker(_el$173.nextSibling),
2231
+ _el$175 = _el$174.nextSibling,
2232
+ [_el$176, _co$45] = _$getNextMarker(_el$175.nextSibling),
2233
+ _el$177 = _el$176.nextSibling,
2234
+ [_el$178, _co$46] = _$getNextMarker(_el$177.nextSibling),
2235
+ _el$179 = _el$178.nextSibling,
2236
+ [_el$180, _co$47] = _$getNextMarker(_el$179.nextSibling),
2237
+ _el$181 = _el$180.nextSibling,
2238
+ [_el$182, _co$48] = _$getNextMarker(_el$181.nextSibling),
2239
+ _el$183 = _el$182.nextSibling,
2240
+ [_el$184, _co$49] = _$getNextMarker(_el$183.nextSibling),
2241
+ _el$185 = _el$184.nextSibling,
2242
+ [_el$186, _co$50] = _$getNextMarker(_el$185.nextSibling);
2243
+ _$insert(_el$172, () => props.footerTools, _el$174, _co$44);
2244
+ _$insert(_el$172, _$createComponent(Show, {
1955
2245
  get when() {
1956
2246
  return hasAddMenu();
1957
2247
  },
1958
2248
  get children() {
1959
2249
  return addMenu("ti ti-plus");
1960
2250
  }
1961
- }), _el$169, _co$43);
1962
- _$insert(_el$165, fileInput, _el$171, _co$44);
1963
- _$insert(_el$165, formatToggle, _el$173, _co$45);
1964
- _$insert(_el$165, emojiButton, _el$175, _co$46);
1965
- _$insert(_el$165, _$createComponent(Show, {
2251
+ }), _el$176, _co$45);
2252
+ _$insert(_el$172, fileInput, _el$178, _co$46);
2253
+ _$insert(_el$172, formatToggle, _el$180, _co$47);
2254
+ _$insert(_el$172, emojiButton, _el$182, _co$48);
2255
+ _$insert(_el$172, _$createComponent(Show, {
1966
2256
  get when() {
1967
2257
  return (props.models?.length ?? 0) > 0;
1968
2258
  },
@@ -1987,31 +2277,43 @@ export function ChatComposer(props) {
1987
2277
  image: model.image
1988
2278
  }));
1989
2279
  },
2280
+ get open() {
2281
+ return modelOpen();
2282
+ },
2283
+ onOpenChange: open => {
2284
+ if (!choosingModel()) return;
2285
+ setModelOpen(open);
2286
+ // Dropdown closes before committing the choice; let onValueChange settle it first.
2287
+ if (!open) queueMicrotask(() => {
2288
+ if (!modelOpen()) finishModelSelection(null);
2289
+ });
2290
+ },
1990
2291
  get disabled() {
1991
- return blocked() || running() || !props.onModelChange;
2292
+ return (choosingModel() ? blockedBesidesCommand() : blocked()) || running() || !props.onModelChange;
1992
2293
  },
1993
2294
  onValueChange: modelId => {
1994
2295
  props.onModelChange?.(modelId);
2296
+ finishModelSelection(modelId);
1995
2297
  queueMicrotask(focus);
1996
2298
  }
1997
2299
  });
1998
2300
  }
1999
- }), _el$177, _co$47);
2000
- _$insert(_el$165, () => props.modelDetails, _el$179, _co$48);
2001
- return _el$165;
2301
+ }), _el$184, _co$49);
2302
+ _$insert(_el$172, () => props.modelDetails, _el$186, _co$50);
2303
+ return _el$172;
2002
2304
  })(), (() => {
2003
- var _el$180 = _$getNextElement(_tmpl$41),
2004
- _el$181 = _el$180.firstChild,
2005
- [_el$182, _co$49] = _$getNextMarker(_el$181.nextSibling),
2006
- _el$183 = _el$182.nextSibling,
2007
- [_el$184, _co$50] = _$getNextMarker(_el$183.nextSibling),
2008
- _el$185 = _el$184.nextSibling,
2009
- [_el$186, _co$51] = _$getNextMarker(_el$185.nextSibling),
2010
- _el$187 = _el$186.nextSibling,
2011
- [_el$188, _co$52] = _$getNextMarker(_el$187.nextSibling),
2012
- _el$189 = _el$188.nextSibling,
2013
- [_el$190, _co$53] = _$getNextMarker(_el$189.nextSibling);
2014
- _$insert(_el$180, _$createComponent(For, {
2305
+ var _el$187 = _$getNextElement(_tmpl$42),
2306
+ _el$188 = _el$187.firstChild,
2307
+ [_el$189, _co$51] = _$getNextMarker(_el$188.nextSibling),
2308
+ _el$190 = _el$189.nextSibling,
2309
+ [_el$191, _co$52] = _$getNextMarker(_el$190.nextSibling),
2310
+ _el$192 = _el$191.nextSibling,
2311
+ [_el$193, _co$53] = _$getNextMarker(_el$192.nextSibling),
2312
+ _el$194 = _el$193.nextSibling,
2313
+ [_el$195, _co$54] = _$getNextMarker(_el$194.nextSibling),
2314
+ _el$196 = _el$195.nextSibling,
2315
+ [_el$197, _co$55] = _$getNextMarker(_el$196.nextSibling);
2316
+ _$insert(_el$187, _$createComponent(For, {
2015
2317
  get each() {
2016
2318
  return props.contextActions;
2017
2319
  },
@@ -2035,13 +2337,13 @@ export function ChatComposer(props) {
2035
2337
  },
2036
2338
  onClick: () => reportChatFailure(() => executeChatAction(action), props.onError),
2037
2339
  get children() {
2038
- var _el$191 = _$getNextElement(_tmpl$3);
2039
- _$effect(() => _$className(_el$191, action.icon ?? "ti ti-dots"));
2040
- return _el$191;
2340
+ var _el$198 = _$getNextElement(_tmpl$3);
2341
+ _$effect(() => _$className(_el$198, action.icon ?? "ti ti-dots"));
2342
+ return _el$198;
2041
2343
  }
2042
2344
  })
2043
- }), _el$182, _co$49);
2044
- _$insert(_el$180, _$createComponent(Show, {
2345
+ }), _el$189, _co$51);
2346
+ _$insert(_el$187, _$createComponent(Show, {
2045
2347
  get when() {
2046
2348
  return _$memo(() => !!hasContextUsage())() ? props.contextUsage ?? {} : undefined;
2047
2349
  },
@@ -2053,16 +2355,18 @@ export function ChatComposer(props) {
2053
2355
  return props.onError;
2054
2356
  }
2055
2357
  }))
2056
- }), _el$184, _co$50);
2057
- _$insert(_el$180, () => props.submitTools, _el$186, _co$51);
2058
- _$insert(_el$180, microphoneControl, _el$188, _co$52);
2059
- _$insert(_el$180, sendControl, _el$190, _co$53);
2060
- return _el$180;
2358
+ }), _el$191, _co$52);
2359
+ _$insert(_el$187, () => props.submitTools, _el$193, _co$53);
2360
+ _$insert(_el$187, microphoneControl, _el$195, _co$54);
2361
+ _$insert(_el$187, sendControl, _el$197, _co$55);
2362
+ return _el$187;
2061
2363
  })()];
2062
2364
  },
2063
- children: content => content()
2365
+ get children() {
2366
+ return footer();
2367
+ }
2064
2368
  }));
2065
- return _el$164;
2369
+ return _el$171;
2066
2370
  })()];
2067
2371
  },
2068
2372
  get children() {
@@ -2071,43 +2375,43 @@ export function ChatComposer(props) {
2071
2375
  return props.error;
2072
2376
  },
2073
2377
  get children() {
2074
- var _el$68 = _$getNextElement(_tmpl$22),
2075
- _el$69 = _el$68.firstChild,
2076
- _el$70 = _el$69.nextSibling,
2077
- [_el$71, _co$12] = _$getNextMarker(_el$70.nextSibling);
2078
- _$insert(_el$68, () => props.error, _el$71, _co$12);
2079
- return _el$68;
2378
+ var _el$75 = _$getNextElement(_tmpl$23),
2379
+ _el$76 = _el$75.firstChild,
2380
+ _el$77 = _el$76.nextSibling,
2381
+ [_el$78, _co$14] = _$getNextMarker(_el$77.nextSibling);
2382
+ _$insert(_el$75, () => props.error, _el$78, _co$14);
2383
+ return _el$75;
2080
2384
  }
2081
2385
  }), _$memo(() => formatRow()), (() => {
2082
- var _el$72 = _$getNextElement(_tmpl$23),
2083
- _el$83 = _el$72.firstChild,
2084
- [_el$84, _co$17] = _$getNextMarker(_el$83.nextSibling),
2085
- _el$85 = _el$84.nextSibling,
2086
- [_el$86, _co$18] = _$getNextMarker(_el$85.nextSibling),
2087
- _el$73 = _el$86.nextSibling,
2088
- _el$81 = _el$73.firstChild,
2089
- [_el$82, _co$16] = _$getNextMarker(_el$81.nextSibling),
2090
- _el$74 = _el$82.nextSibling,
2091
- _el$75 = _el$74.firstChild,
2092
- [_el$76, _co$13] = _$getNextMarker(_el$75.nextSibling),
2093
- _el$77 = _el$76.nextSibling,
2094
- [_el$78, _co$14] = _$getNextMarker(_el$77.nextSibling),
2095
- _el$79 = _el$78.nextSibling,
2096
- [_el$80, _co$15] = _$getNextMarker(_el$79.nextSibling),
2097
- _el$87 = _el$73.nextSibling,
2098
- [_el$88, _co$19] = _$getNextMarker(_el$87.nextSibling);
2099
- _$insert(_el$72, attachControl, _el$84, _co$17);
2100
- _$insert(_el$72, fileInput, _el$86, _co$18);
2101
- _$insert(_el$73, field, _el$82, _co$16);
2102
- _$insert(_el$74, formatToggle, _el$76, _co$13);
2103
- _$insert(_el$74, emojiButton, _el$78, _co$14);
2104
- _$insert(_el$74, microphoneControl, _el$80, _co$15);
2105
- _$insert(_el$72, sendControl, _el$88, _co$19);
2106
- return _el$72;
2386
+ var _el$79 = _$getNextElement(_tmpl$24),
2387
+ _el$90 = _el$79.firstChild,
2388
+ [_el$91, _co$19] = _$getNextMarker(_el$90.nextSibling),
2389
+ _el$92 = _el$91.nextSibling,
2390
+ [_el$93, _co$20] = _$getNextMarker(_el$92.nextSibling),
2391
+ _el$80 = _el$93.nextSibling,
2392
+ _el$88 = _el$80.firstChild,
2393
+ [_el$89, _co$18] = _$getNextMarker(_el$88.nextSibling),
2394
+ _el$81 = _el$89.nextSibling,
2395
+ _el$82 = _el$81.firstChild,
2396
+ [_el$83, _co$15] = _$getNextMarker(_el$82.nextSibling),
2397
+ _el$84 = _el$83.nextSibling,
2398
+ [_el$85, _co$16] = _$getNextMarker(_el$84.nextSibling),
2399
+ _el$86 = _el$85.nextSibling,
2400
+ [_el$87, _co$17] = _$getNextMarker(_el$86.nextSibling),
2401
+ _el$94 = _el$80.nextSibling,
2402
+ [_el$95, _co$21] = _$getNextMarker(_el$94.nextSibling);
2403
+ _$insert(_el$79, attachControl, _el$91, _co$19);
2404
+ _$insert(_el$79, fileInput, _el$93, _co$20);
2405
+ _$insert(_el$80, field, _el$89, _co$18);
2406
+ _$insert(_el$81, formatToggle, _el$83, _co$15);
2407
+ _$insert(_el$81, emojiButton, _el$85, _co$16);
2408
+ _$insert(_el$81, microphoneControl, _el$87, _co$17);
2409
+ _$insert(_el$79, sendControl, _el$95, _co$21);
2410
+ return _el$79;
2107
2411
  })()];
2108
2412
  }
2109
- }), _el$94, _co$22);
2110
- _$insert(_el$65, _$createComponent(Show, {
2413
+ }), _el$101, _co$24);
2414
+ _$insert(_el$72, _$createComponent(Show, {
2111
2415
  get when() {
2112
2416
  return props.fileSelection;
2113
2417
  },
@@ -2126,60 +2430,60 @@ export function ChatComposer(props) {
2126
2430
  },
2127
2431
  onDrop: files => void runFiles(files)
2128
2432
  })
2129
- }), _el$96, _co$23);
2130
- _$insert(_el$97, _$createComponent(Show, {
2433
+ }), _el$103, _co$25);
2434
+ _$insert(_el$104, _$createComponent(Show, {
2131
2435
  get when() {
2132
2436
  return suggestionAnnouncement();
2133
2437
  },
2134
2438
  keyed: true,
2135
2439
  children: announced => (() => {
2136
- var _el$192 = _$getNextElement(_tmpl$10);
2137
- _$insert(_el$192, () => announced.text);
2138
- return _el$192;
2440
+ var _el$199 = _$getNextElement(_tmpl$10);
2441
+ _$insert(_el$199, () => announced.text);
2442
+ return _el$199;
2139
2443
  })()
2140
2444
  }));
2141
- _$insert(_el$98, _$createComponent(Show, {
2445
+ _$insert(_el$105, _$createComponent(Show, {
2142
2446
  get when() {
2143
2447
  return _$memo(() => !!!suggestionsOpen())() && commandStatus();
2144
2448
  },
2145
2449
  children: status => (() => {
2146
- var _el$193 = _$getNextElement(_tmpl$42),
2147
- _el$194 = _el$193.firstChild,
2148
- _el$195 = _el$194.nextSibling;
2149
- _$insert(_el$195, () => status().text);
2450
+ var _el$200 = _$getNextElement(_tmpl$43),
2451
+ _el$201 = _el$200.firstChild,
2452
+ _el$202 = _el$201.nextSibling;
2453
+ _$insert(_el$202, () => status().text);
2150
2454
  _$effect(_p$ => {
2151
2455
  var _v$44 = status().tone,
2152
2456
  _v$45 = status().tone === "busy" ? "ti ti-loader-2 k2b-spin" : status().tone === "done" ? "ti ti-check" : "ti ti-alert-circle";
2153
- _v$44 !== _p$.e && _$setAttribute(_el$193, "data-tone", _p$.e = _v$44);
2154
- _v$45 !== _p$.t && _$className(_el$194, _p$.t = _v$45);
2457
+ _v$44 !== _p$.e && _$setAttribute(_el$200, "data-tone", _p$.e = _v$44);
2458
+ _v$45 !== _p$.t && _$className(_el$201, _p$.t = _v$45);
2155
2459
  return _p$;
2156
2460
  }, {
2157
2461
  e: undefined,
2158
2462
  t: undefined
2159
2463
  });
2160
- return _el$193;
2464
+ return _el$200;
2161
2465
  })()
2162
- }), _el$100, _co$24);
2163
- _$insert(_el$98, _$createComponent(Show, {
2466
+ }), _el$107, _co$26);
2467
+ _$insert(_el$105, _$createComponent(Show, {
2164
2468
  get when() {
2165
2469
  return _$memo(() => !!suggestionsOpen())() && announcement();
2166
2470
  },
2167
2471
  keyed: true,
2168
2472
  children: announced => (() => {
2169
- var _el$196 = _$getNextElement(_tmpl$43);
2170
- _$insert(_el$196, () => announced.text);
2171
- return _el$196;
2473
+ var _el$203 = _$getNextElement(_tmpl$44);
2474
+ _$insert(_el$203, () => announced.text);
2475
+ return _el$203;
2172
2476
  })()
2173
- }), _el$102, _co$25);
2477
+ }), _el$109, _co$27);
2174
2478
  _$effect(_p$ => {
2175
2479
  var _v$24 = `k2b-chat-composer ${props.class ?? ""}`,
2176
2480
  _v$25 = running() ? "true" : undefined,
2177
2481
  _v$26 = conversation() ? "conversation" : undefined,
2178
2482
  _v$27 = props.label ?? chatMessages().messageComposer;
2179
- _v$24 !== _p$.e && _$className(_el$65, _p$.e = _v$24);
2180
- _v$25 !== _p$.t && _$setAttribute(_el$65, "data-running", _p$.t = _v$25);
2181
- _v$26 !== _p$.a && _$setAttribute(_el$65, "data-variant", _p$.a = _v$26);
2182
- _v$27 !== _p$.o && _$setAttribute(_el$65, "aria-label", _p$.o = _v$27);
2483
+ _v$24 !== _p$.e && _$className(_el$72, _p$.e = _v$24);
2484
+ _v$25 !== _p$.t && _$setAttribute(_el$72, "data-running", _p$.t = _v$25);
2485
+ _v$26 !== _p$.a && _$setAttribute(_el$72, "data-variant", _p$.a = _v$26);
2486
+ _v$27 !== _p$.o && _$setAttribute(_el$72, "aria-label", _p$.o = _v$27);
2183
2487
  return _p$;
2184
2488
  }, {
2185
2489
  e: undefined,
@@ -2187,8 +2491,8 @@ export function ChatComposer(props) {
2187
2491
  a: undefined,
2188
2492
  o: undefined
2189
2493
  });
2190
- return _el$37;
2494
+ return _el$42;
2191
2495
  })();
2192
2496
  }
2193
- _$delegateEvents(["input", "click", "keyup", "beforeinput", "keydown", "pointerdown", "mousedown"]);
2497
+ _$delegateEvents(["input", "click", "keyup", "beforeinput", "keydown", "mousedown"]);
2194
2498
  //# sourceMappingURL=ChatComposer.js.map