@8wave/ai-elements 0.110.0 → 0.111.0-beta.11

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 (234) hide show
  1. package/README.md +1 -0
  2. package/dist/_chunks/{Agent-Su_LDF9_.js → Agent-tE7ZJPxG.js} +80 -78
  3. package/dist/_chunks/Agent-tE7ZJPxG.js.map +1 -0
  4. package/dist/_chunks/{Document-DecVclEe.js → Document-Bmx6774B.js} +33 -21
  5. package/dist/_chunks/Document-Bmx6774B.js.map +1 -0
  6. package/dist/_chunks/Media-Cft7Pwrh.js +108 -0
  7. package/dist/_chunks/Media-Cft7Pwrh.js.map +1 -0
  8. package/dist/_chunks/{PkLazyImg-ClL4nr95.js → PkLazyImg-Dbj2dDXA.js} +2 -2
  9. package/dist/_chunks/{PkLazyImg-ClL4nr95.js.map → PkLazyImg-Dbj2dDXA.js.map} +1 -1
  10. package/dist/_chunks/{PkStreamingMarkdown-CwqsJnJJ.js → PkStreamingMarkdown-CNI8aV8t.js} +636 -427
  11. package/dist/_chunks/PkStreamingMarkdown-CNI8aV8t.js.map +1 -0
  12. package/dist/_chunks/{PkToolRequestGeolocation-CEVpl50q.js → PkToolRequestGeolocation-Bzy4IYSp.js} +4 -4
  13. package/dist/_chunks/PkToolRequestGeolocation-Bzy4IYSp.js.map +1 -0
  14. package/dist/_chunks/{PkToolRequestOAuthConnection-CncDU-Kl.js → PkToolRequestOAuthConnection-13CQH07t.js} +5 -5
  15. package/dist/_chunks/PkToolRequestOAuthConnection-13CQH07t.js.map +1 -0
  16. package/dist/_chunks/{PkToolShowArtifact-M6jlSmyJ.js → PkToolShowArtifact-CGbHDEie.js} +4 -4
  17. package/dist/_chunks/{PkToolShowArtifact-M6jlSmyJ.js.map → PkToolShowArtifact-CGbHDEie.js.map} +1 -1
  18. package/dist/_chunks/{PkToolShowCalendarEvent-C41JgOUA.js → PkToolShowCalendarEvent-DIFX_rUz.js} +3 -3
  19. package/dist/_chunks/{PkToolShowCalendarEvent-C41JgOUA.js.map → PkToolShowCalendarEvent-DIFX_rUz.js.map} +1 -1
  20. package/dist/_chunks/{PkToolShowComparison-DbbUD9pg.js → PkToolShowComparison-CWLFWT9h.js} +7 -7
  21. package/dist/_chunks/PkToolShowComparison-CWLFWT9h.js.map +1 -0
  22. package/dist/_chunks/{PkToolShowContactForm-D_dW59Dl.js → PkToolShowContactForm-CYxgatUA.js} +5 -5
  23. package/dist/_chunks/PkToolShowContactForm-CYxgatUA.js.map +1 -0
  24. package/dist/_chunks/{PkToolShowDiagram-Hy9qh68O.js → PkToolShowDiagram-Dx1Ba0PG.js} +4 -4
  25. package/dist/_chunks/PkToolShowDiagram-Dx1Ba0PG.js.map +1 -0
  26. package/dist/_chunks/{PkToolShowEmail-Dn3JHYIR.js → PkToolShowEmail-DnFFgzom.js} +3 -3
  27. package/dist/_chunks/{PkToolShowEmail-Dn3JHYIR.js.map → PkToolShowEmail-DnFFgzom.js.map} +1 -1
  28. package/dist/_chunks/{PkToolShowForm-DbJHMDbt.js → PkToolShowForm-B6x3Lp2i.js} +7 -8
  29. package/dist/_chunks/PkToolShowForm-B6x3Lp2i.js.map +1 -0
  30. package/dist/_chunks/{PkToolShowImageGallery-C1lzlO0y.js → PkToolShowImageGallery-D99N_Plf.js} +2 -2
  31. package/dist/_chunks/{PkToolShowImageGallery-C1lzlO0y.js.map → PkToolShowImageGallery-D99N_Plf.js.map} +1 -1
  32. package/dist/_chunks/{PkToolShowLocation-CKhPxKFA.js → PkToolShowLocation-AfnrtFVJ.js} +3 -3
  33. package/dist/_chunks/{PkToolShowLocation-CKhPxKFA.js.map → PkToolShowLocation-AfnrtFVJ.js.map} +1 -1
  34. package/dist/_chunks/{PkToolShowMessage-U9CCU7eG.js → PkToolShowMessage-DUo2c-im.js} +3 -3
  35. package/dist/_chunks/{PkToolShowMessage-U9CCU7eG.js.map → PkToolShowMessage-DUo2c-im.js.map} +1 -1
  36. package/dist/_chunks/{PkToolShowProductList-UeiRMLHu.js → PkToolShowProductList-BN6Qk1_y.js} +3 -3
  37. package/dist/_chunks/{PkToolShowProductList-UeiRMLHu.js.map → PkToolShowProductList-BN6Qk1_y.js.map} +1 -1
  38. package/dist/_chunks/{PkToolShowQrCode-CypLrfh5.js → PkToolShowQrCode-BLqeBecX.js} +3 -3
  39. package/dist/_chunks/{PkToolShowQrCode-CypLrfh5.js.map → PkToolShowQrCode-BLqeBecX.js.map} +1 -1
  40. package/dist/_chunks/{PkToolShowSources-B69JmwbZ.js → PkToolShowSources-DpZb5FUP.js} +5 -5
  41. package/dist/_chunks/PkToolShowSources-DpZb5FUP.js.map +1 -0
  42. package/dist/_chunks/{PkToolShowSuggestedReply-CKxSH0Y9.js → PkToolShowSuggestedReply-C10nNgBs.js} +3 -3
  43. package/dist/_chunks/{PkToolShowSuggestedReply-CKxSH0Y9.js.map → PkToolShowSuggestedReply-C10nNgBs.js.map} +1 -1
  44. package/dist/_chunks/{PkToolShowVideo-BgKxdBcC.js → PkToolShowVideo-S9b4QHUj.js} +2 -2
  45. package/dist/_chunks/{PkToolShowVideo-BgKxdBcC.js.map → PkToolShowVideo-S9b4QHUj.js.map} +1 -1
  46. package/dist/_chunks/{PkToolShowWeather-LPd3tC77.js → PkToolShowWeather-CqhG430w.js} +2 -2
  47. package/dist/_chunks/PkToolShowWeather-CqhG430w.js.map +1 -0
  48. package/dist/_chunks/{PkToolShowWebPages-ep_erFF0.js → PkToolShowWebPages-txAZi_iG.js} +3 -3
  49. package/dist/_chunks/{PkToolShowWebPages-ep_erFF0.js.map → PkToolShowWebPages-txAZi_iG.js.map} +1 -1
  50. package/dist/_chunks/PkUrl-BPbjZJ1A.js.map +1 -1
  51. package/dist/_chunks/{VvCheckboxGroup.es-Bdu2gFLN.js → VvCheckboxGroup.es-CTrF3pue.js} +2 -2
  52. package/dist/_chunks/{VvCheckboxGroup.es-Bdu2gFLN.js.map → VvCheckboxGroup.es-CTrF3pue.js.map} +1 -1
  53. package/dist/_chunks/{VvCombobox.es-C0wpJIr_.js → VvCombobox.es-BWiXmQ_S.js} +10 -10
  54. package/dist/_chunks/{VvCombobox.es-C0wpJIr_.js.map → VvCombobox.es-BWiXmQ_S.js.map} +1 -1
  55. package/dist/_chunks/{VvInputText.es-Zgtw2YNw.js → VvInputText.es-Bo9I6g8H.js} +6 -6
  56. package/dist/_chunks/{VvInputText.es-Zgtw2YNw.js.map → VvInputText.es-Bo9I6g8H.js.map} +1 -1
  57. package/dist/_chunks/{VvRadioGroup.es-DZLL19SC.js → VvRadioGroup.es-9ooHCuik.js} +2 -2
  58. package/dist/_chunks/{VvRadioGroup.es-DZLL19SC.js.map → VvRadioGroup.es-9ooHCuik.js.map} +1 -1
  59. package/dist/_chunks/{VvSelect.es-ovnZRHG5.js → VvSelect.es-DG0VuWtP.js} +2 -2
  60. package/dist/_chunks/{VvSelect.es-ovnZRHG5.js.map → VvSelect.es-DG0VuWtP.js.map} +1 -1
  61. package/dist/_chunks/{VvTextarea.es-DbP5Lt2T.js → VvTextarea.es-Dg3pxdZy.js} +6 -6
  62. package/dist/_chunks/{VvTextarea.es-DbP5Lt2T.js.map → VvTextarea.es-Dg3pxdZy.js.map} +1 -1
  63. package/dist/_chunks/{browser-NgY6LXg-.js → browser-B0Xnbqi7.js} +726 -751
  64. package/dist/_chunks/browser-B0Xnbqi7.js.map +1 -0
  65. package/dist/_chunks/{dist-n5iFNYf-.js → dist-QdjZA6MJ.js} +143 -133
  66. package/dist/_chunks/{dist-n5iFNYf-.js.map → dist-QdjZA6MJ.js.map} +1 -1
  67. package/dist/_chunks/{index.es-dtdl3VFG.js → index.es-0YpCa4c5.js} +6 -6
  68. package/dist/_chunks/{index.es-dtdl3VFG.js.map → index.es-0YpCa4c5.js.map} +1 -1
  69. package/dist/_chunks/{index.es-BJnUA_36.js → index.es-CHkJ2TMJ.js} +10 -10
  70. package/dist/_chunks/{index.es-BJnUA_36.js.map → index.es-CHkJ2TMJ.js.map} +1 -1
  71. package/dist/_chunks/text-DbSEK8si.js.map +1 -1
  72. package/dist/ai-elements.es.js +3077 -3134
  73. package/dist/ai-elements.es.js.map +1 -1
  74. package/dist-vue/PkChatbot.js +1 -1
  75. package/dist-vue/PkChatbotEmptyState.js +1 -1
  76. package/dist-vue/PkChatbotError.js +1 -1
  77. package/dist-vue/PkChatbotFeedbackForm.js +1 -1
  78. package/dist-vue/PkChatbotFilePreview.js +1 -1
  79. package/dist-vue/PkChatbotInput.js +1 -1
  80. package/dist-vue/PkChatbotMessages.js +1 -1
  81. package/dist-vue/PkChatbotStepPayload.js +1 -1
  82. package/dist-vue/PkChatbotStepToolDetail.js +1 -1
  83. package/dist-vue/PkChatbotSteps.js +1 -1
  84. package/dist-vue/PkChatbotViewChat.js +1 -1
  85. package/dist-vue/PkChatbotViewConversations.js +1 -1
  86. package/dist-vue/PkChatbotViewFiles.js +1 -1
  87. package/dist-vue/PkChatbotViewProfile.js +1 -1
  88. package/dist-vue/_chunks/{Agent-C8BsTAxk.js → Agent-De2gFNjR.js} +165 -176
  89. package/dist-vue/_chunks/Agent-De2gFNjR.js.map +1 -0
  90. package/dist-vue/_chunks/{Document-CaUfI_SZ.js → Document-8umjeTVS.js} +84 -72
  91. package/dist-vue/_chunks/Document-8umjeTVS.js.map +1 -0
  92. package/dist-vue/_chunks/Media-_HfFLHGD.js.map +1 -1
  93. package/dist-vue/_chunks/{PkChatbot-o7k7d-fj.js → PkChatbot-CMajc7tE.js} +61 -61
  94. package/dist-vue/_chunks/PkChatbot-CMajc7tE.js.map +1 -0
  95. package/dist-vue/_chunks/{PkChatbotEmptyState-BvaeBxhx.js → PkChatbotEmptyState-BtzBYOHJ.js} +2 -2
  96. package/dist-vue/_chunks/{PkChatbotEmptyState-BvaeBxhx.js.map → PkChatbotEmptyState-BtzBYOHJ.js.map} +1 -1
  97. package/dist-vue/_chunks/{PkChatbotError-CBP2mf-n.js → PkChatbotError-gvDpRcEz.js} +21 -19
  98. package/dist-vue/_chunks/PkChatbotError-gvDpRcEz.js.map +1 -0
  99. package/dist-vue/_chunks/{PkChatbotFeedbackForm-DO1QIgmo.js → PkChatbotFeedbackForm-CxLOdwkm.js} +2 -2
  100. package/dist-vue/_chunks/PkChatbotFeedbackForm-CxLOdwkm.js.map +1 -0
  101. package/dist-vue/_chunks/{PkChatbotFilePreview-DO1wZPPj.js → PkChatbotFilePreview-CwiVQDF2.js} +3 -3
  102. package/dist-vue/_chunks/PkChatbotFilePreview-CwiVQDF2.js.map +1 -0
  103. package/dist-vue/_chunks/{PkChatbotInput-D8x52cVm.js → PkChatbotInput-MSpF6SB6.js} +140 -125
  104. package/dist-vue/_chunks/PkChatbotInput-MSpF6SB6.js.map +1 -0
  105. package/dist-vue/_chunks/PkChatbotMessages-Bz5q8EtT.js +776 -0
  106. package/dist-vue/_chunks/PkChatbotMessages-Bz5q8EtT.js.map +1 -0
  107. package/dist-vue/_chunks/{PkChatbotStepPayload-BH6piqOi.js → PkChatbotStepPayload-XW4gT9AZ.js} +2 -2
  108. package/dist-vue/_chunks/{PkChatbotStepPayload-BH6piqOi.js.map → PkChatbotStepPayload-XW4gT9AZ.js.map} +1 -1
  109. package/dist-vue/_chunks/{PkChatbotStepToolDetail-BJ7xUvgi.js → PkChatbotStepToolDetail-C4-K6Glw.js} +3 -3
  110. package/dist-vue/_chunks/{PkChatbotStepToolDetail-BJ7xUvgi.js.map → PkChatbotStepToolDetail-C4-K6Glw.js.map} +1 -1
  111. package/dist-vue/_chunks/PkChatbotSteps-CrqjWpv0.js +190 -0
  112. package/dist-vue/_chunks/PkChatbotSteps-CrqjWpv0.js.map +1 -0
  113. package/dist-vue/_chunks/{PkChatbotViewChat-CNH_glPI.js → PkChatbotViewChat-DXu5ncaU.js} +10 -10
  114. package/dist-vue/_chunks/{PkChatbotViewChat-CNH_glPI.js.map → PkChatbotViewChat-DXu5ncaU.js.map} +1 -1
  115. package/dist-vue/_chunks/{PkChatbotViewConversations-BENvHLZt.js → PkChatbotViewConversations-3LaZPFyw.js} +2 -2
  116. package/dist-vue/_chunks/{PkChatbotViewConversations-BENvHLZt.js.map → PkChatbotViewConversations-3LaZPFyw.js.map} +1 -1
  117. package/dist-vue/_chunks/{PkChatbotViewFiles-qmLESi1V.js → PkChatbotViewFiles-CTqnbsCj.js} +3 -3
  118. package/dist-vue/_chunks/{PkChatbotViewFiles-qmLESi1V.js.map → PkChatbotViewFiles-CTqnbsCj.js.map} +1 -1
  119. package/dist-vue/_chunks/{PkChatbotViewProfile-DzfZnitQ.js → PkChatbotViewProfile-B-Mp1jGQ.js} +2 -2
  120. package/dist-vue/_chunks/{PkChatbotViewProfile-DzfZnitQ.js.map → PkChatbotViewProfile-B-Mp1jGQ.js.map} +1 -1
  121. package/dist-vue/_chunks/PkRelativeTime--1cIphlA.js.map +1 -1
  122. package/dist-vue/_chunks/{PkStreamingMarkdown-D8_LwZMR.js → PkStreamingMarkdown-D0IOaETI.js} +432 -419
  123. package/dist-vue/_chunks/PkStreamingMarkdown-D0IOaETI.js.map +1 -0
  124. package/dist-vue/_chunks/{PkSvgViewer-DPpE9fiz.js → PkSvgViewer-D-0M5bqg.js} +2 -2
  125. package/dist-vue/_chunks/PkSvgViewer-D-0M5bqg.js.map +1 -0
  126. package/dist-vue/_chunks/{PkToolRequestGeolocation-D1ZPmWiB.js → PkToolRequestGeolocation-Q3N3jlO8.js} +3 -3
  127. package/dist-vue/_chunks/PkToolRequestGeolocation-Q3N3jlO8.js.map +1 -0
  128. package/dist-vue/_chunks/{PkToolRequestOAuthConnection-CoJyKEE6.js → PkToolRequestOAuthConnection-lYoTJIF_.js} +4 -4
  129. package/dist-vue/_chunks/PkToolRequestOAuthConnection-lYoTJIF_.js.map +1 -0
  130. package/dist-vue/_chunks/{PkToolShowArtifact-CEXdfOGG.js → PkToolShowArtifact-DHdJuzDi.js} +2 -2
  131. package/dist-vue/_chunks/{PkToolShowArtifact-CEXdfOGG.js.map → PkToolShowArtifact-DHdJuzDi.js.map} +1 -1
  132. package/dist-vue/_chunks/{PkToolShowComparison-DMSjIpCR.js → PkToolShowComparison-BLn4pkno.js} +5 -5
  133. package/dist-vue/_chunks/PkToolShowComparison-BLn4pkno.js.map +1 -0
  134. package/dist-vue/_chunks/{PkToolShowContactForm-DHmzAIVF.js → PkToolShowContactForm-DceSyuX8.js} +3 -3
  135. package/dist-vue/_chunks/PkToolShowContactForm-DceSyuX8.js.map +1 -0
  136. package/dist-vue/_chunks/{PkToolShowDiagram-DuDp5EHd.js → PkToolShowDiagram-pwc0wpNo.js} +4 -4
  137. package/dist-vue/_chunks/PkToolShowDiagram-pwc0wpNo.js.map +1 -0
  138. package/dist-vue/_chunks/{PkToolShowEmail-CavhsPvi.js → PkToolShowEmail-DF__nKpR.js} +2 -2
  139. package/dist-vue/_chunks/{PkToolShowEmail-CavhsPvi.js.map → PkToolShowEmail-DF__nKpR.js.map} +1 -1
  140. package/dist-vue/_chunks/{PkToolShowForm-CO5A_j9L.js → PkToolShowForm-Dx10jOXm.js} +7 -7
  141. package/dist-vue/_chunks/PkToolShowForm-Dx10jOXm.js.map +1 -0
  142. package/dist-vue/_chunks/{PkToolShowImageGallery-V9U3LJfF.js → PkToolShowImageGallery-DudQzBx4.js} +2 -2
  143. package/dist-vue/_chunks/{PkToolShowImageGallery-V9U3LJfF.js.map → PkToolShowImageGallery-DudQzBx4.js.map} +1 -1
  144. package/dist-vue/_chunks/{PkToolShowMessage-DQojxDiV.js → PkToolShowMessage-Ck6VP-gw.js} +2 -2
  145. package/dist-vue/_chunks/{PkToolShowMessage-DQojxDiV.js.map → PkToolShowMessage-Ck6VP-gw.js.map} +1 -1
  146. package/dist-vue/_chunks/{PkToolShowProductList-Cn0yewM3.js → PkToolShowProductList-zfM8cx-l.js} +2 -2
  147. package/dist-vue/_chunks/{PkToolShowProductList-Cn0yewM3.js.map → PkToolShowProductList-zfM8cx-l.js.map} +1 -1
  148. package/dist-vue/_chunks/{PkToolShowSources-BvWOzVkQ.js → PkToolShowSources-Dlaz2Y77.js} +5 -5
  149. package/dist-vue/_chunks/PkToolShowSources-Dlaz2Y77.js.map +1 -0
  150. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DQFOVonE.js → PkToolShowSuggestedReply-DWLkUh2L.js} +2 -2
  151. package/dist-vue/_chunks/{PkToolShowSuggestedReply-DQFOVonE.js.map → PkToolShowSuggestedReply-DWLkUh2L.js.map} +1 -1
  152. package/dist-vue/_chunks/PkToolShowWeather-Bzqalzh8.js.map +1 -1
  153. package/dist-vue/_chunks/{PkToolShowWebPages-Bzkkn9GV.js → PkToolShowWebPages-CosBYLrE.js} +2 -2
  154. package/dist-vue/_chunks/{PkToolShowWebPages-Bzkkn9GV.js.map → PkToolShowWebPages-CosBYLrE.js.map} +1 -1
  155. package/dist-vue/_chunks/{PkUrl-xUBKVJCv.js → PkUrl-B5CNTQj9.js} +2 -2
  156. package/dist-vue/_chunks/PkUrl-B5CNTQj9.js.map +1 -0
  157. package/dist-vue/_chunks/{createChatbotApiClient-CJ_5_3IT.js → createChatbotApiClient-MkaPbGWB.js} +6 -3
  158. package/dist-vue/_chunks/createChatbotApiClient-MkaPbGWB.js.map +1 -0
  159. package/dist-vue/_chunks/{useChatbotStore-CiRAuq7v.js → useChatbotStore-BzfqjiYz.js} +6 -3
  160. package/dist-vue/_chunks/useChatbotStore-BzfqjiYz.js.map +1 -0
  161. package/dist-vue/_chunks/useDialogConfirm-KWz0ohCQ.js.map +1 -1
  162. package/dist-vue/_chunks/{utils-Coqik0XI.js → utils-C1666_6C.js} +58 -43
  163. package/dist-vue/_chunks/utils-C1666_6C.js.map +1 -0
  164. package/dist-vue/api.js +1 -1
  165. package/dist-vue/composables.js +3 -3
  166. package/dist-vue/index.js +3869 -3490
  167. package/dist-vue/index.js.map +1 -1
  168. package/dist-vue/locales.js +36 -8
  169. package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +20 -3
  170. package/dist-vue/packages/components/src/chat/PkChatButton.d.ts +3 -2
  171. package/dist-vue/packages/components/src/chat/PkLanguageModel.d.ts +26 -2
  172. package/dist-vue/packages/components/src/chat/PkLanguageModelCombobox.d.ts +53 -1
  173. package/dist-vue/packages/components/src/chat/PkModelOption.d.ts +19 -0
  174. package/dist-vue/packages/components/src/chat/PkReasoningSettings.d.ts +6 -0
  175. package/dist-vue/packages/components/src/chat/PkStreamingMarkdown.d.ts +6 -0
  176. package/dist-vue/packages/components/src/chat/PkStreamingMarkdownAutoscroll.d.ts +1 -0
  177. package/dist-vue/packages/components/src/chat/constants.d.ts +5 -18
  178. package/dist-vue/packages/components/src/chat/index.d.ts +3 -1
  179. package/dist-vue/packages/components/src/chat/modelCatalog.d.ts +46 -0
  180. package/dist-vue/packages/components/src/chat/utils.d.ts +16 -0
  181. package/dist-vue/packages/components/src/table/PkTableSortable.d.ts +13 -1
  182. package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +18 -0
  183. package/dist-vue/packages/composable/src/useChatbotError.d.ts +2 -0
  184. package/dist-vue/packages/models/src/schema/Agent.d.ts +70 -10
  185. package/dist-vue/packages/models/src/schema/Chat.d.ts +31 -0
  186. package/dist-vue/packages/models/src/schema/ModelProvider.d.ts +316 -0
  187. package/dist-vue/packages/models/src/schema/Organization.d.ts +142 -2
  188. package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +20 -0
  189. package/dist-vue/packages/models/src/schema/SubAgent.d.ts +20 -0
  190. package/dist-vue/packages/models/src/schema/UserOverview.d.ts +41 -0
  191. package/dist-vue/packages/models/src/schema/constants.d.ts +56 -91
  192. package/dist-vue/packages/models/src/schema/index.d.ts +1 -0
  193. package/dist-vue/style.css +1 -1
  194. package/package.json +1 -1
  195. package/dist/_chunks/Agent-Su_LDF9_.js.map +0 -1
  196. package/dist/_chunks/Document-DecVclEe.js.map +0 -1
  197. package/dist/_chunks/Media-C6SOQfJZ.js +0 -122
  198. package/dist/_chunks/Media-C6SOQfJZ.js.map +0 -1
  199. package/dist/_chunks/PkStreamingMarkdown-CwqsJnJJ.js.map +0 -1
  200. package/dist/_chunks/PkToolRequestGeolocation-CEVpl50q.js.map +0 -1
  201. package/dist/_chunks/PkToolRequestOAuthConnection-CncDU-Kl.js.map +0 -1
  202. package/dist/_chunks/PkToolShowComparison-DbbUD9pg.js.map +0 -1
  203. package/dist/_chunks/PkToolShowContactForm-D_dW59Dl.js.map +0 -1
  204. package/dist/_chunks/PkToolShowDiagram-Hy9qh68O.js.map +0 -1
  205. package/dist/_chunks/PkToolShowForm-DbJHMDbt.js.map +0 -1
  206. package/dist/_chunks/PkToolShowSources-B69JmwbZ.js.map +0 -1
  207. package/dist/_chunks/PkToolShowWeather-LPd3tC77.js.map +0 -1
  208. package/dist/_chunks/browser-NgY6LXg-.js.map +0 -1
  209. package/dist/_chunks/utils-YJ0ZOLDG.js +0 -185
  210. package/dist/_chunks/utils-YJ0ZOLDG.js.map +0 -1
  211. package/dist-vue/_chunks/Agent-C8BsTAxk.js.map +0 -1
  212. package/dist-vue/_chunks/Document-CaUfI_SZ.js.map +0 -1
  213. package/dist-vue/_chunks/PkChatbot-o7k7d-fj.js.map +0 -1
  214. package/dist-vue/_chunks/PkChatbotError-CBP2mf-n.js.map +0 -1
  215. package/dist-vue/_chunks/PkChatbotFeedbackForm-DO1QIgmo.js.map +0 -1
  216. package/dist-vue/_chunks/PkChatbotFilePreview-DO1wZPPj.js.map +0 -1
  217. package/dist-vue/_chunks/PkChatbotInput-D8x52cVm.js.map +0 -1
  218. package/dist-vue/_chunks/PkChatbotMessages-BFlU046I.js +0 -771
  219. package/dist-vue/_chunks/PkChatbotMessages-BFlU046I.js.map +0 -1
  220. package/dist-vue/_chunks/PkChatbotSteps-DtV1beDc.js +0 -180
  221. package/dist-vue/_chunks/PkChatbotSteps-DtV1beDc.js.map +0 -1
  222. package/dist-vue/_chunks/PkStreamingMarkdown-D8_LwZMR.js.map +0 -1
  223. package/dist-vue/_chunks/PkSvgViewer-DPpE9fiz.js.map +0 -1
  224. package/dist-vue/_chunks/PkToolRequestGeolocation-D1ZPmWiB.js.map +0 -1
  225. package/dist-vue/_chunks/PkToolRequestOAuthConnection-CoJyKEE6.js.map +0 -1
  226. package/dist-vue/_chunks/PkToolShowComparison-DMSjIpCR.js.map +0 -1
  227. package/dist-vue/_chunks/PkToolShowContactForm-DHmzAIVF.js.map +0 -1
  228. package/dist-vue/_chunks/PkToolShowDiagram-DuDp5EHd.js.map +0 -1
  229. package/dist-vue/_chunks/PkToolShowForm-CO5A_j9L.js.map +0 -1
  230. package/dist-vue/_chunks/PkToolShowSources-BvWOzVkQ.js.map +0 -1
  231. package/dist-vue/_chunks/PkUrl-xUBKVJCv.js.map +0 -1
  232. package/dist-vue/_chunks/createChatbotApiClient-CJ_5_3IT.js.map +0 -1
  233. package/dist-vue/_chunks/useChatbotStore-CiRAuq7v.js.map +0 -1
  234. package/dist-vue/_chunks/utils-Coqik0XI.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { D as e } from "./Agent-C8BsTAxk.js";
1
+ import { D as e } from "./Agent-De2gFNjR.js";
2
2
  import { VvButton as t, VvIcon as n } from "@volverjs/ui-vue/components";
3
3
  import { Fragment as r, computed as i, createBlock as a, createCommentVNode as o, createElementBlock as s, createElementVNode as c, createVNode as l, defineComponent as u, onMounted as d, onUnmounted as f, openBlock as p, ref as m, toDisplayString as h, unref as g } from "vue";
4
4
  import { useI18n as _ } from "vue-i18n";
@@ -97,8 +97,8 @@ var v = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
97
97
  class: "text-16 shrink-0"
98
98
  }), c("strong", b, h(I.value), 1)]), c("div", x, [W.value ? (p(), s("div", S, [l(u, {
99
99
  name: "ri:check-line",
100
- class: "text-16 text-word-3"
101
- }), c("strong", ee, h(g(N)("messagePart.requestOAuthConnectionSuccess", { name: I.value })), 1)])) : H.value ? (p(), s("div", te, [l(u, { name: "line-md:loading-loop" }), c("span", ne, h(g(N)("messagePart.requestOAuthConnection")), 1)])) : U.value ? (p(), s("div", re, [c("div", C, [l(u, {
100
+ class: "text-16 text-success"
101
+ }), c("strong", ee, h(g(N)("messagePart.requestOAuthConnectionSuccess", { name: I.value })), 1)])) : H.value ? (p(), s("div", te, [l(u, { name: "loading-loop" }), c("span", ne, h(g(N)("messagePart.requestOAuthConnection")), 1)])) : U.value ? (p(), s("div", re, [c("div", C, [l(u, {
102
102
  name: "ri:close-line",
103
103
  class: "text-danger"
104
104
  }), c("strong", w, h(U.value), 1)]), G.value ? (p(), a(d, {
@@ -119,4 +119,4 @@ var v = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
119
119
  //#endregion
120
120
  export { A as default };
121
121
 
122
- //# sourceMappingURL=PkToolRequestOAuthConnection-CoJyKEE6.js.map
122
+ //# sourceMappingURL=PkToolRequestOAuthConnection-lYoTJIF_.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolRequestOAuthConnection-lYoTJIF_.js","names":[],"sources":["../../../../packages/components/src/chat/PkToolRequestOAuthConnection.vue","../../../../packages/components/src/chat/PkToolRequestOAuthConnection.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, onMounted, onUnmounted, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { isVoiceRenderAck } from 'models'\n\n const props = defineProps<{\n part: unknown\n resolveConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; authorizeUrl: string }>\n checkConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; connected: boolean }>\n }>()\n\n const emit = defineEmits<{\n connected: [mcpServerId: string]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n /** How often the connection is re-read while the sign-in window is out. */\n const POLL_INTERVAL_MS = 2000\n /**\n * How long we keep asking. The only end to a sign-in nobody finishes:\n * `popup.closed` cannot be that signal, because the browser disowns the\n * handle when the provider severs the opener (that is what\n * `Cross-Origin-Opener-Policy` does), so it reads as closed from the first\n * check of the very flow this watch exists for. Long enough for a password\n * manager and a second factor.\n */\n const POLL_TIMEOUT_MS = 5 * 60 * 1000\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n toolCallId?: string\n input?: { serverName: string }\n output?: unknown\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n const serverName = computed(() => toolPart.value.input?.serverName)\n\n /**\n * A card drawn during a CALL arrives already \"answered\": the turn could\n * not wait for the connection, so the backend closed the tool with a note\n * saying the card was drawn (see `isVoiceRenderAck`, same rule as the\n * forms). That note is not a connection, and without this the card\n * rendered its inert fallback: the caller was told to connect the account\n * and given nothing to click (measured 2026-08-07).\n */\n const isRenderAck = computed(() => isVoiceRenderAck(toolPart.value.output))\n\n /** The output this card wrote itself once the connection went through. */\n const isConnectedByOutput = computed(\n () =>\n (toolPart.value.output as { connected?: unknown } | undefined)\n ?.connected === true,\n )\n\n const isAwaitingConnection = computed(\n () => state.value === 'input-available' || isRenderAck.value,\n )\n\n const mcpServerId = ref<string | null>(null)\n /**\n * Set once THIS card's sign-in went through, and never from a plain read of\n * the connection: a card still asking is the turn saying it could not use\n * that integration, and a token row can outlive its usefulness (a refresh\n * that failed transiently keeps the row, so the turn sees no usable token\n * while a status read still sees one). Trusting the read there would have\n * left the card claiming success, with no button, on a turn still waiting.\n * It doubles as the guard that resumes the turn exactly once, whichever\n * channel got there first.\n */\n const hasConnected = ref(false)\n /** A sign-in window we opened is still out there. */\n const isSigningIn = ref(false)\n const oauthError = ref<string | null>(null)\n\n const isDone = computed(\n () => hasConnected.value || isConnectedByOutput.value,\n )\n const canConnect = computed(\n () => Boolean(serverName.value) && Boolean(props.resolveConnection),\n )\n\n /**\n * Whether the server says this user has connected, asked without minting\n * anything: no OAuth `state` is burned by looking.\n */\n async function isConnectedNow(): Promise<boolean> {\n if (!serverName.value || !props.checkConnection) {\n return false\n }\n try {\n const status = await props.checkConnection(serverName.value)\n mcpServerId.value = status.mcpServerId\n return status.connected\n } catch {\n // Not knowing is not an error to show: the sign-in window is still\n // out there and the next read may well answer.\n return false\n }\n }\n\n let pollTimer: ReturnType<typeof setTimeout> | undefined\n /**\n * Which sign-in a running tick belongs to. A tick suspended on its read\n * outlives the attempt that scheduled it: without this it woke up inside\n * the NEXT attempt, restarted its own chain over that one's timer and then\n * stopped it on its own older deadline.\n */\n let signInAttempt = 0\n /** The window this attempt opened, the only sender we accept a report from. */\n let signInWindow: Window | null = null\n\n function stopWatching() {\n if (pollTimer !== undefined) {\n clearTimeout(pollTimer)\n pollTimer = undefined\n }\n signInAttempt += 1\n signInWindow = null\n isSigningIn.value = false\n }\n\n function settleConnected(connectedServerId: string) {\n stopWatching()\n if (hasConnected.value) {\n return\n }\n hasConnected.value = true\n mcpServerId.value = connectedServerId\n oauthError.value = null\n emit('connected', connectedServerId)\n }\n\n /**\n * Watches the connection from THIS window while the sign-in window is away.\n *\n * The callback page reports through `window.opener`, and a provider that\n * sends `Cross-Origin-Opener-Policy` anywhere in its redirect chain takes\n * that opener away: the connection then succeeds with nobody listening, the\n * card stays on its button and the suspended turn is never resumed\n * (reported 2026-08-27). This channel never goes through that window, so it\n * survives whatever the provider does to it. Chained rather than periodic:\n * a read slower than the interval would otherwise overlap the next one.\n */\n function watchForConnection(popup: Window) {\n stopWatching()\n const attempt = signInAttempt\n signInWindow = popup\n isSigningIn.value = true\n const deadline = Date.now() + POLL_TIMEOUT_MS\n const tick = async () => {\n if (attempt !== signInAttempt || Date.now() > deadline) {\n if (attempt === signInAttempt) {\n stopWatching()\n }\n return\n }\n const connected = await isConnectedNow()\n if (attempt !== signInAttempt) {\n return\n }\n if (connected && mcpServerId.value) {\n settleConnected(mcpServerId.value)\n return\n }\n pollTimer = setTimeout(tick, POLL_INTERVAL_MS)\n }\n pollTimer = setTimeout(tick, POLL_INTERVAL_MS)\n }\n\n /**\n * The callback page's own report, when the browser let it through: faster\n * than the poll, and the only channel carrying the failure reason.\n *\n * Accepted only from the window this card opened, and only while that\n * sign-in is out: the listener stays up for as long as the card is on\n * screen, and nothing else with a handle on this page may resume a turn by\n * posting a message at it.\n */\n function onMessage(event: MessageEvent) {\n if (\n event.data?.type !== 'mcp-oauth-complete' ||\n !isSigningIn.value ||\n event.source !== signInWindow\n ) {\n return\n }\n const reportedServerId = event.data.mcpServerId as string | undefined\n if (\n reportedServerId &&\n mcpServerId.value &&\n reportedServerId !== mcpServerId.value\n ) {\n return\n }\n if (!event.data.success) {\n // A failure carries no server id: the callback never got that far.\n stopWatching()\n oauthError.value = event.data.error ?? 'Unknown error'\n return\n }\n const connectedServerId = reportedServerId ?? mcpServerId.value\n if (connectedServerId) {\n settleConnected(connectedServerId)\n }\n }\n\n /**\n * Opens the provider's sign-in, on an authorize URL minted NOW.\n *\n * The URL carries an OAuth `state` that lives ten minutes server-side.\n * Minted when the card rendered, it was routinely expired by the time\n * anyone clicked, and the callback then failed on a sign-in the user had\n * just completed. The window is opened blank first, synchronously, or the\n * popup blocker kills it while we wait for the URL.\n */\n async function openAuthWindow() {\n if (\n !serverName.value ||\n !props.resolveConnection ||\n isSigningIn.value\n ) {\n return\n }\n oauthError.value = null\n const popup = window.open(\n '',\n 'mcp_oauth',\n 'width=600,height=700,menubar=no,toolbar=no',\n )\n if (!popup) {\n oauthError.value = $t('auth.popupBlocked')\n return\n }\n watchForConnection(popup)\n try {\n const connection = await props.resolveConnection(serverName.value)\n mcpServerId.value = connection.mcpServerId\n popup.location.href = connection.authorizeUrl\n } catch (err) {\n stopWatching()\n popup.close()\n oauthError.value =\n err instanceof Error ? err.message : 'Failed to resolve OAuth'\n }\n }\n\n // For the card's whole life, not just between the click and the answer: a\n // card that re-renders while the sign-in window is away used to lose the\n // listener with it, and the completion landed on nobody.\n onMounted(() => window.addEventListener('message', onMessage))\n onUnmounted(() => {\n window.removeEventListener('message', onMessage)\n stopWatching()\n })\n</script>\n\n<template>\n <!-- The same frame and header as the other tool cards: this was the only\n one drawing itself as a tinted box (DESIGN.md). -->\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface text-12\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:link-m\" class=\"text-16 shrink-0\" />\n <strong class=\"truncate\">{{ serverName }}</strong>\n </div>\n <div class=\"p-sm\">\n <!-- Connected: just now, or by this card on an earlier visit -->\n <template v-if=\"isDone\">\n <div class=\"flex items-center gap-8\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <strong class=\"font-medium text-word-1\">\n {{\n $t('messagePart.requestOAuthConnectionSuccess', {\n name: serverName,\n })\n }}\n </strong>\n </div>\n </template>\n\n <!-- Signing in: the window is out and we are watching for it -->\n <template v-else-if=\"isSigningIn\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"loading-loop\" />\n <span class=\"text-10\">{{\n $t('messagePart.requestOAuthConnection')\n }}</span>\n </div>\n </template>\n\n <!-- OAuth error -->\n <template v-else-if=\"oauthError\">\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:close-line\" class=\"text-danger\" />\n <strong class=\"text-10\">\n {{ oauthError }}\n </strong>\n </div>\n <VvButton\n v-if=\"canConnect\"\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </div>\n </template>\n\n <!-- Waiting on the user: show the connect button -->\n <template v-else-if=\"isAwaitingConnection && canConnect\">\n <div class=\"flex items-center gap-6 text-word-3 mb-xs\">\n <span>\n {{\n $t('messagePart.requestOAuthConnectionPrompt', {\n name: serverName,\n })\n }}\n </span>\n </div>\n <VvButton\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </template>\n <!-- Fallback for unknown state -->\n <template v-else>\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:link-m\" />\n <span class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionInfo', {\n name: serverName,\n })\n }}\n </span>\n </div>\n </template>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, onMounted, onUnmounted, ref } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { isVoiceRenderAck } from 'models'\n\n const props = defineProps<{\n part: unknown\n resolveConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; authorizeUrl: string }>\n checkConnection?: (\n serverName: string,\n ) => Promise<{ mcpServerId: string; connected: boolean }>\n }>()\n\n const emit = defineEmits<{\n connected: [mcpServerId: string]\n }>()\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n /** How often the connection is re-read while the sign-in window is out. */\n const POLL_INTERVAL_MS = 2000\n /**\n * How long we keep asking. The only end to a sign-in nobody finishes:\n * `popup.closed` cannot be that signal, because the browser disowns the\n * handle when the provider severs the opener (that is what\n * `Cross-Origin-Opener-Policy` does), so it reads as closed from the first\n * check of the very flow this watch exists for. Long enough for a password\n * manager and a second factor.\n */\n const POLL_TIMEOUT_MS = 5 * 60 * 1000\n\n const toolPart = computed(() => {\n return props.part as {\n state?: string\n toolCallId?: string\n input?: { serverName: string }\n output?: unknown\n }\n })\n\n const state = computed(() => toolPart.value.state ?? 'unknown')\n const serverName = computed(() => toolPart.value.input?.serverName)\n\n /**\n * A card drawn during a CALL arrives already \"answered\": the turn could\n * not wait for the connection, so the backend closed the tool with a note\n * saying the card was drawn (see `isVoiceRenderAck`, same rule as the\n * forms). That note is not a connection, and without this the card\n * rendered its inert fallback: the caller was told to connect the account\n * and given nothing to click (measured 2026-08-07).\n */\n const isRenderAck = computed(() => isVoiceRenderAck(toolPart.value.output))\n\n /** The output this card wrote itself once the connection went through. */\n const isConnectedByOutput = computed(\n () =>\n (toolPart.value.output as { connected?: unknown } | undefined)\n ?.connected === true,\n )\n\n const isAwaitingConnection = computed(\n () => state.value === 'input-available' || isRenderAck.value,\n )\n\n const mcpServerId = ref<string | null>(null)\n /**\n * Set once THIS card's sign-in went through, and never from a plain read of\n * the connection: a card still asking is the turn saying it could not use\n * that integration, and a token row can outlive its usefulness (a refresh\n * that failed transiently keeps the row, so the turn sees no usable token\n * while a status read still sees one). Trusting the read there would have\n * left the card claiming success, with no button, on a turn still waiting.\n * It doubles as the guard that resumes the turn exactly once, whichever\n * channel got there first.\n */\n const hasConnected = ref(false)\n /** A sign-in window we opened is still out there. */\n const isSigningIn = ref(false)\n const oauthError = ref<string | null>(null)\n\n const isDone = computed(\n () => hasConnected.value || isConnectedByOutput.value,\n )\n const canConnect = computed(\n () => Boolean(serverName.value) && Boolean(props.resolveConnection),\n )\n\n /**\n * Whether the server says this user has connected, asked without minting\n * anything: no OAuth `state` is burned by looking.\n */\n async function isConnectedNow(): Promise<boolean> {\n if (!serverName.value || !props.checkConnection) {\n return false\n }\n try {\n const status = await props.checkConnection(serverName.value)\n mcpServerId.value = status.mcpServerId\n return status.connected\n } catch {\n // Not knowing is not an error to show: the sign-in window is still\n // out there and the next read may well answer.\n return false\n }\n }\n\n let pollTimer: ReturnType<typeof setTimeout> | undefined\n /**\n * Which sign-in a running tick belongs to. A tick suspended on its read\n * outlives the attempt that scheduled it: without this it woke up inside\n * the NEXT attempt, restarted its own chain over that one's timer and then\n * stopped it on its own older deadline.\n */\n let signInAttempt = 0\n /** The window this attempt opened, the only sender we accept a report from. */\n let signInWindow: Window | null = null\n\n function stopWatching() {\n if (pollTimer !== undefined) {\n clearTimeout(pollTimer)\n pollTimer = undefined\n }\n signInAttempt += 1\n signInWindow = null\n isSigningIn.value = false\n }\n\n function settleConnected(connectedServerId: string) {\n stopWatching()\n if (hasConnected.value) {\n return\n }\n hasConnected.value = true\n mcpServerId.value = connectedServerId\n oauthError.value = null\n emit('connected', connectedServerId)\n }\n\n /**\n * Watches the connection from THIS window while the sign-in window is away.\n *\n * The callback page reports through `window.opener`, and a provider that\n * sends `Cross-Origin-Opener-Policy` anywhere in its redirect chain takes\n * that opener away: the connection then succeeds with nobody listening, the\n * card stays on its button and the suspended turn is never resumed\n * (reported 2026-08-27). This channel never goes through that window, so it\n * survives whatever the provider does to it. Chained rather than periodic:\n * a read slower than the interval would otherwise overlap the next one.\n */\n function watchForConnection(popup: Window) {\n stopWatching()\n const attempt = signInAttempt\n signInWindow = popup\n isSigningIn.value = true\n const deadline = Date.now() + POLL_TIMEOUT_MS\n const tick = async () => {\n if (attempt !== signInAttempt || Date.now() > deadline) {\n if (attempt === signInAttempt) {\n stopWatching()\n }\n return\n }\n const connected = await isConnectedNow()\n if (attempt !== signInAttempt) {\n return\n }\n if (connected && mcpServerId.value) {\n settleConnected(mcpServerId.value)\n return\n }\n pollTimer = setTimeout(tick, POLL_INTERVAL_MS)\n }\n pollTimer = setTimeout(tick, POLL_INTERVAL_MS)\n }\n\n /**\n * The callback page's own report, when the browser let it through: faster\n * than the poll, and the only channel carrying the failure reason.\n *\n * Accepted only from the window this card opened, and only while that\n * sign-in is out: the listener stays up for as long as the card is on\n * screen, and nothing else with a handle on this page may resume a turn by\n * posting a message at it.\n */\n function onMessage(event: MessageEvent) {\n if (\n event.data?.type !== 'mcp-oauth-complete' ||\n !isSigningIn.value ||\n event.source !== signInWindow\n ) {\n return\n }\n const reportedServerId = event.data.mcpServerId as string | undefined\n if (\n reportedServerId &&\n mcpServerId.value &&\n reportedServerId !== mcpServerId.value\n ) {\n return\n }\n if (!event.data.success) {\n // A failure carries no server id: the callback never got that far.\n stopWatching()\n oauthError.value = event.data.error ?? 'Unknown error'\n return\n }\n const connectedServerId = reportedServerId ?? mcpServerId.value\n if (connectedServerId) {\n settleConnected(connectedServerId)\n }\n }\n\n /**\n * Opens the provider's sign-in, on an authorize URL minted NOW.\n *\n * The URL carries an OAuth `state` that lives ten minutes server-side.\n * Minted when the card rendered, it was routinely expired by the time\n * anyone clicked, and the callback then failed on a sign-in the user had\n * just completed. The window is opened blank first, synchronously, or the\n * popup blocker kills it while we wait for the URL.\n */\n async function openAuthWindow() {\n if (\n !serverName.value ||\n !props.resolveConnection ||\n isSigningIn.value\n ) {\n return\n }\n oauthError.value = null\n const popup = window.open(\n '',\n 'mcp_oauth',\n 'width=600,height=700,menubar=no,toolbar=no',\n )\n if (!popup) {\n oauthError.value = $t('auth.popupBlocked')\n return\n }\n watchForConnection(popup)\n try {\n const connection = await props.resolveConnection(serverName.value)\n mcpServerId.value = connection.mcpServerId\n popup.location.href = connection.authorizeUrl\n } catch (err) {\n stopWatching()\n popup.close()\n oauthError.value =\n err instanceof Error ? err.message : 'Failed to resolve OAuth'\n }\n }\n\n // For the card's whole life, not just between the click and the answer: a\n // card that re-renders while the sign-in window is away used to lose the\n // listener with it, and the completion landed on nobody.\n onMounted(() => window.addEventListener('message', onMessage))\n onUnmounted(() => {\n window.removeEventListener('message', onMessage)\n stopWatching()\n })\n</script>\n\n<template>\n <!-- The same frame and header as the other tool cards: this was the only\n one drawing itself as a tinted box (DESIGN.md). -->\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface text-12\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:link-m\" class=\"text-16 shrink-0\" />\n <strong class=\"truncate\">{{ serverName }}</strong>\n </div>\n <div class=\"p-sm\">\n <!-- Connected: just now, or by this card on an earlier visit -->\n <template v-if=\"isDone\">\n <div class=\"flex items-center gap-8\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <strong class=\"font-medium text-word-1\">\n {{\n $t('messagePart.requestOAuthConnectionSuccess', {\n name: serverName,\n })\n }}\n </strong>\n </div>\n </template>\n\n <!-- Signing in: the window is out and we are watching for it -->\n <template v-else-if=\"isSigningIn\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"loading-loop\" />\n <span class=\"text-10\">{{\n $t('messagePart.requestOAuthConnection')\n }}</span>\n </div>\n </template>\n\n <!-- OAuth error -->\n <template v-else-if=\"oauthError\">\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:close-line\" class=\"text-danger\" />\n <strong class=\"text-10\">\n {{ oauthError }}\n </strong>\n </div>\n <VvButton\n v-if=\"canConnect\"\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </div>\n </template>\n\n <!-- Waiting on the user: show the connect button -->\n <template v-else-if=\"isAwaitingConnection && canConnect\">\n <div class=\"flex items-center gap-6 text-word-3 mb-xs\">\n <span>\n {{\n $t('messagePart.requestOAuthConnectionPrompt', {\n name: serverName,\n })\n }}\n </span>\n </div>\n <VvButton\n modifiers=\"primary-small\"\n icon=\"ri:external-link-line\"\n :label=\"\n $t('messagePart.requestOAuthConnectionButton', {\n name: serverName,\n })\n \"\n @click=\"openAuthWindow\" />\n </template>\n <!-- Fallback for unknown state -->\n <template v-else>\n <div class=\"flex items-center gap-8 text-word-3\">\n <VvIcon name=\"ri:link-m\" />\n <span class=\"text-10\">\n {{\n $t('messagePart.requestOAuthConnectionInfo', {\n name: serverName,\n })\n }}\n </span>\n </div>\n </template>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;6BAsBU,IAAmB,KASnB,IAAkB;;;;;;;;;EA1BxB,IAAM,IAAQ,GAUR,IAAO,GAIP,EAAE,GAAG,MAAO,EAAQ,EAAE,UAAU,SAAS,CAAC,GAc1C,IAAW,QACN,EAAM,IAMhB,GAEK,IAAQ,QAAe,EAAS,MAAM,SAAS,SAAS,GACxD,IAAa,QAAe,EAAS,MAAM,OAAO,UAAU,GAU5D,IAAc,QAAe,EAAiB,EAAS,MAAM,MAAM,CAAC,GAGpE,IAAsB,QAEnB,EAAS,MAAM,QACV,cAAc,EAC5B,GAEM,IAAuB,QACnB,EAAM,UAAU,qBAAqB,EAAY,KAC3D,GAEM,IAAc,EAAmB,IAAI,GAWrC,IAAe,EAAI,EAAK,GAExB,IAAc,EAAI,EAAK,GACvB,IAAa,EAAmB,IAAI,GAEpC,IAAS,QACL,EAAa,SAAS,EAAoB,KACpD,GACM,IAAa,QACT,EAAQ,EAAW,SAAU,EAAQ,EAAM,iBACrD;EAMA,eAAe,IAAmC;GAC9C,IAAI,CAAC,EAAW,SAAS,CAAC,EAAM,iBAC5B,OAAO;GAEX,IAAI;IACA,IAAM,IAAS,MAAM,EAAM,gBAAgB,EAAW,KAAK;IAE3D,OADA,EAAY,QAAQ,EAAO,aACpB,EAAO;GAClB,QAAQ;IAGJ,OAAO;GACX;EACJ;EAEA,IAAI,GAOA,IAAgB,GAEhB,IAA8B;EAElC,SAAS,IAAe;GAOpB,AANI,MAAc,KAAA,MACd,aAAa,CAAS,GACtB,IAAY,KAAA,IAEhB,KAAiB,GACjB,IAAe,MACf,EAAY,QAAQ;EACxB;EAEA,SAAS,EAAgB,GAA2B;GAChD,EAAa,GACT,GAAa,UAGjB,EAAa,QAAQ,IACrB,EAAY,QAAQ,GACpB,EAAW,QAAQ,MACnB,EAAK,aAAa,CAAiB;EACvC;EAaA,SAAS,GAAmB,GAAe;GACvC,EAAa;GACb,IAAM,IAAU;GAEhB,AADA,IAAe,GACf,EAAY,QAAQ;GACpB,IAAM,IAAW,KAAK,IAAI,IAAI,GACxB,IAAO,YAAY;IACrB,IAAI,MAAY,KAAiB,KAAK,IAAI,IAAI,GAAU;KACpD,AAAI,MAAY,KACZ,EAAa;KAEjB;IACJ;IACA,IAAM,IAAY,MAAM,EAAe;IACnC,UAAY,GAGhB;SAAI,KAAa,EAAY,OAAO;MAChC,EAAgB,EAAY,KAAK;MACjC;KACJ;KACA,IAAY,WAAW,GAAM,CAAgB;IAD7C;GAEJ;GACA,IAAY,WAAW,GAAM,CAAgB;EACjD;EAWA,SAAS,EAAU,GAAqB;GACpC,IACI,EAAM,MAAM,SAAS,wBACrB,CAAC,EAAY,SACb,EAAM,WAAW,GAEjB;GAEJ,IAAM,IAAmB,EAAM,KAAK;GACpC,IACI,KACA,EAAY,SACZ,MAAqB,EAAY,OAEjC;GAEJ,IAAI,CAAC,EAAM,KAAK,SAAS;IAGrB,AADA,EAAa,GACb,EAAW,QAAQ,EAAM,KAAK,SAAS;IACvC;GACJ;GACA,IAAM,IAAoB,KAAoB,EAAY;GAC1D,AAAI,KACA,EAAgB,CAAiB;EAEzC;EAWA,eAAe,IAAiB;GAC5B,IACI,CAAC,EAAW,SACZ,CAAC,EAAM,qBACP,EAAY,OAEZ;GAEJ,EAAW,QAAQ;GACnB,IAAM,IAAQ,OAAO,KACjB,IACA,aACA,4CACJ;GACA,IAAI,CAAC,GAAO;IACR,EAAW,QAAQ,EAAG,mBAAmB;IACzC;GACJ;GACA,GAAmB,CAAK;GACxB,IAAI;IACA,IAAM,IAAa,MAAM,EAAM,kBAAkB,EAAW,KAAK;IAEjE,AADA,EAAY,QAAQ,EAAW,aAC/B,EAAM,SAAS,OAAO,EAAW;GACrC,SAAS,GAAK;IAGV,AAFA,EAAa,GACb,EAAM,MAAM,GACZ,EAAW,QACP,aAAe,QAAQ,EAAI,UAAU;GAC7C;EACJ;SAKA,QAAgB,OAAO,iBAAiB,WAAW,CAAS,CAAC,GAC7D,QAAkB;GAEd,AADA,OAAO,oBAAoB,WAAW,CAAS,GAC/C,EAAa;EACjB,CAAC;;GAMD,OAAA,EAAA,GAAA,EAyFM,OAzFN,GAyFM,CAvFF,EAIM,OAJN,GAIM,CAFF,EAAoD,GAAA;IAA5C,MAAK;IAAY,OAAM;GAC/B,CAAA,GAAA,EAAkD,UAAlD,GAAkD,EAAtB,EAAA,KAAU,GAAA,CAAA,CAAA,CAAA,GAE1C,EAiFM,OAjFN,GAiFM,CA/Ec,EAAA,SACZ,EAAA,GAAA,EASM,OATN,GASM,CARF,EAA4D,GAAA;IAApD,MAAK;IAAgB,OAAM;GACnC,CAAA,GAAA,EAMS,UANT,IAMS,EAJD,EAAA,CAAA,CAAE,CAAA,6CAAA,EAAsF,MAAA,EAAA,MAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KASnF,EAAA,SACjB,EAAA,GAAA,EAKM,OALN,IAKM,CAJF,EAA8B,GAAA,EAAtB,MAAK,eAAc,CAAA,GAC3B,EAES,QAFT,IAES,EADL,EAAA,CAAA,CAAE,CAAA,oCAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAMO,EAAA,SACjB,EAAA,GAAA,EAiBM,OAjBN,IAiBM,CAhBF,EAKM,OALN,GAKM,CAJF,EAAmD,GAAA;IAA3C,MAAK;IAAgB,OAAM;GACnC,CAAA,GAAA,EAES,UAFT,GAES,EADF,EAAA,KAAU,GAAA,CAAA,CAAA,CAAA,GAIX,EAAA,SADV,EAAA,GAAA,EAS8B,GAAA;;IAP1B,WAAU;IACV,MAAK;IACJ,OAAoC,EAAA,CAAA,CAAE,CAAA,4CAAA,EAAqF,MAAA,EAAA,MAAA,CAAA;IAK3H,SAAO;GAKC,GAAA,MAAA,GAAA,CAAA,OAAA,CAAA,KAAA,EAAA,IAAA,EAAA,CAAA,CAAA,KAAA,EAAA,SAAwB,EAAA,SAA7C,EAAA,GAAA,EAmBW,GAAA,EAAA,KAAA,EAAA,GAAA,CAlBP,EAQM,OARN,GAQM,CAPF,EAMO,QAAA,MAAA,EAJC,EAAA,CAAA,CAAE,CAAA,4CAAA,EAAqF,MAAA,EAAA,MAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,GAMnG,EAQ8B,GAAA;IAP1B,WAAU;IACV,MAAK;IACJ,OAAgC,EAAA,CAAA,CAAE,CAAA,4CAAA,EAAiF,MAAA,EAAA,MAAA,CAAA;IAKnH,SAAO;GAIZ,GAAA,MAAA,GAAA,CAAA,OAAA,CAAA,CAAA,GAAA,EAAA,MAAA,EAAA,GAAA,EASM,OATN,GASM,CARF,EAA2B,GAAA,EAAnB,MAAK,YAAW,CAAA,GACxB,EAMO,QANP,GAMO,EAJC,EAAA,CAAA,CAAE,CAAA,0CAAA,EAAmF,MAAA,EAAA,MAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { t } from "./PkStreamingMarkdown-D8_LwZMR.js";
2
+ import { t } from "./PkStreamingMarkdown-D0IOaETI.js";
3
3
  import { VvButton as n } from "@volverjs/ui-vue/components";
4
4
  import { computed as r, createBlock as i, createElementBlock as a, createElementVNode as o, createTextVNode as s, createVNode as c, defineComponent as l, normalizeClass as u, openBlock as d, ref as f, toDisplayString as p, unref as m, watch as h } from "vue";
5
5
  import { useClipboard as g } from "@vueuse/core";
@@ -89,4 +89,4 @@ var _ = ["innerHTML"], v = /* @__PURE__ */ l({
89
89
  //#endregion
90
90
  export { T as n, v as r, E as t };
91
91
 
92
- //# sourceMappingURL=PkToolShowArtifact-CEXdfOGG.js.map
92
+ //# sourceMappingURL=PkToolShowArtifact-DHdJuzDi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowArtifact-CEXdfOGG.js","names":["$attrs","$t"],"sources":["../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PkToolShowArtifact-DHdJuzDi.js","names":["$attrs","$t"],"sources":["../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n defineOptions({\n inheritAttrs: false,\n })\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre\n :class=\"\n $attrs.class\n ? $attrs.class\n : 'font-mono leading-snug text-smaller bg-surface-1'\n \">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10 bg-surface\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -13,7 +13,7 @@ var v = {
13
13
  let u = e, { copy: C, copied: w } = _(), T = a(() => u.part), E = a(() => {
14
14
  let e = T.value.input?.items;
15
15
  return !e || e.length === 0 ? [] : Object.keys(e[0].values);
16
- }), D = () => {
16
+ }), D = (e) => e === "✓" ? "text-success" : e === "✗" ? "text-danger" : "text-word-2", O = () => {
17
17
  let e = T.value.input?.items;
18
18
  if (!e) return;
19
19
  let t = ["", ...e.map((e) => e.name)].join(" "), n = E.value.map((t) => [t.replace(/_/g, " "), ...e.map((e) => e.values[t] ?? "")].join(" "));
@@ -35,7 +35,7 @@ var v = {
35
35
  modifiers: "action-quiet-small",
36
36
  icon: h(w) ? "ri:check-line" : "ri:file-copy-line",
37
37
  label: h(w) ? e.$t("action.copied") : e.$t("action.copy"),
38
- onClick: D
38
+ onClick: O
39
39
  }, null, 8, ["icon", "label"])]),
40
40
  _: 1
41
41
  })
@@ -47,10 +47,10 @@ var v = {
47
47
  class: d({ "bg-surface-1": t % 2 != 0 })
48
48
  }, [c("td", { class: d(["text-word-3 font-medium p-8 whitespace-nowrap", { "border-b border-surface-3": t !== E.value.length - 1 }]) }, m(e.replace(/_/g, " ")), 3), (f(!0), s(i, null, p(T.value.input.items, (n) => (f(), s("td", {
49
49
  key: n.name,
50
- class: d(["text-center p-8 text-word-2", {
50
+ class: d(["text-center p-8", [D(n.values[e]), {
51
51
  "border-b border-surface-3": t !== E.value.length - 1,
52
52
  "bg-surface-1": n.highlighted
53
- }])
53
+ }]])
54
54
  }, m(n.values[e] ?? "-"), 3))), 128))], 2))), 128))])])])])) : o("", !0);
55
55
  };
56
56
  }
@@ -58,4 +58,4 @@ var v = {
58
58
  //#endregion
59
59
  export { w as n, T as t };
60
60
 
61
- //# sourceMappingURL=PkToolShowComparison-DMSjIpCR.js.map
61
+ //# sourceMappingURL=PkToolShowComparison-BLn4pkno.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowComparison-BLn4pkno.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowComparison.vue","../../../../packages/components/src/chat/PkToolShowComparison.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n // The tool contract asks for \"✓\" and \"✗\" on boolean features: the pair is\n // a verdict, so it wears one and the table reads by eye (DESIGN.md).\n const valueColorClass = (value?: string) => {\n if (value === '✓') {\n return 'text-success'\n }\n if (value === '✗') {\n return 'text-danger'\n }\n return 'text-word-2'\n }\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-12 border-collapse bg-surface\">\n <thead>\n <tr>\n <th\n class=\"text-left text-word-3 font-medium p-8 border-b border-surface-3 min-w-32\"></th>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center text-word-1 p-8 border-b border-surface-3 min-w-24\"\n :class=\"\n item.highlighted\n ? 'font-semibold bg-surface-1'\n : 'font-medium'\n \">\n {{ item.name }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(feature, fIdx) in features\"\n :key=\"feature\"\n :class=\"{ 'bg-surface-1': fIdx % 2 !== 0 }\">\n <td\n class=\"text-word-3 font-medium p-8 whitespace-nowrap\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n }\">\n {{ feature.replace(/_/g, ' ') }}\n </td>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center p-8\"\n :class=\"[\n valueColorClass(item.values[feature]),\n {\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n 'bg-surface-1': item.highlighted,\n },\n ]\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title?: string\n items: Array<{\n name: string\n values: Record<string, string>\n highlighted?: boolean\n }>\n }\n }\n return part\n })\n\n const features = computed(() => {\n const items = toolPart.value.input?.items\n if (!items || items.length === 0) {\n return []\n }\n return Object.keys(items[0].values)\n })\n\n // The tool contract asks for \"✓\" and \"✗\" on boolean features: the pair is\n // a verdict, so it wears one and the table reads by eye (DESIGN.md).\n const valueColorClass = (value?: string) => {\n if (value === '✓') {\n return 'text-success'\n }\n if (value === '✗') {\n return 'text-danger'\n }\n return 'text-word-2'\n }\n\n const copyTable = () => {\n const items = toolPart.value.input?.items\n if (!items) {\n return\n }\n const header = ['', ...items.map((i) => i.name)].join('\\t')\n const rows = features.value.map((f) =>\n [f.replace(/_/g, ' '), ...items.map((i) => i.values[f] ?? '')].join(\n '\\t',\n ),\n )\n copy([header, ...rows].join('\\n'))\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.items?.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:scales-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{\n toolPart.input.title ?? $t('label.comparison')\n }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyTable\" />\n </VvButtonGroup>\n </div>\n <div class=\"overflow-x-auto\">\n <table class=\"w-full text-12 border-collapse bg-surface\">\n <thead>\n <tr>\n <th\n class=\"text-left text-word-3 font-medium p-8 border-b border-surface-3 min-w-32\"></th>\n <th\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center text-word-1 p-8 border-b border-surface-3 min-w-24\"\n :class=\"\n item.highlighted\n ? 'font-semibold bg-surface-1'\n : 'font-medium'\n \">\n {{ item.name }}\n </th>\n </tr>\n </thead>\n <tbody>\n <tr\n v-for=\"(feature, fIdx) in features\"\n :key=\"feature\"\n :class=\"{ 'bg-surface-1': fIdx % 2 !== 0 }\">\n <td\n class=\"text-word-3 font-medium p-8 whitespace-nowrap\"\n :class=\"{\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n }\">\n {{ feature.replace(/_/g, ' ') }}\n </td>\n <td\n v-for=\"item in toolPart.input.items\"\n :key=\"item.name\"\n class=\"text-center p-8\"\n :class=\"[\n valueColorClass(item.values[feature]),\n {\n 'border-b border-surface-3':\n fIdx !== features.length - 1,\n 'bg-surface-1': item.highlighted,\n },\n ]\">\n {{ item.values[feature] ?? '-' }}\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;EAII,IAAM,IAAQ,GAIR,EAAE,SAAM,cAAW,EAAa,GAEhC,IAAW,QACA,EAAM,IAWtB,GAEK,IAAW,QAAe;GAC5B,IAAM,IAAQ,EAAS,MAAM,OAAO;GAIpC,OAHI,CAAC,KAAS,EAAM,WAAW,IACpB,CAAC,IAEL,OAAO,KAAK,EAAM,EAAE,CAAC,MAAM;EACtC,CAAC,GAIK,KAAmB,MACjB,MAAU,MACH,iBAEP,MAAU,MACH,gBAEJ,eAGL,UAAkB;GACpB,IAAM,IAAQ,EAAS,MAAM,OAAO;GACpC,IAAI,CAAC,GACD;GAEJ,IAAM,IAAS,CAAC,IAAI,GAAG,EAAM,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,GAAI,GACpD,IAAO,EAAS,MAAM,KAAK,MAC7B,CAAC,EAAE,QAAQ,MAAM,GAAG,GAAG,GAAG,EAAM,KAAK,MAAM,EAAE,OAAO,MAAM,EAAE,CAAC,CAAC,CAAC,KAC3D,GACJ,CACJ;GACA,EAAK,CAAC,GAAQ,GAAG,CAAI,CAAC,CAAC,KAAK,IAAI,CAAC;EACrC;;;GAKU,OAAA,EAAA,OAAU,OAAO,OAAO,UADlC,EAAA,GAAA,EAmEM,OAnEN,GAmEM,CAhEF,EAaM,OAbN,GAaM;IAXF,EAAgD,GAAA;KAAxC,MAAK;KAAiB,OAAM;;IACpC,EAEW,UAFX,GAEW,EADP,EAAA,MAAS,MAAM,SAASA,EAAAA,GAAE,kBAAA,CAAA,GAAA,CAAA;IAE9B,EAMgB,GAAA;KAND,WAAU;KAAU,OAAM;;KACrC,SAAA,QAIyB,CAJzB,EAIyB,GAAA;MAHrB,WAAU;MACT,MAAM,EAAA,CAAA,IAAM,kBAAA;MACZ,OAAO,EAAA,CAAA,IAASA,EAAAA,GAAE,eAAA,IAAoBA,EAAAA,GAAE,aAAA;MACxC,SAAO;;;;GAGpB,CAAA,GAAA,EAiDM,OAjDN,GAiDM,CAhDF,EA+CQ,SA/CR,GA+CQ,CA9CJ,EAgBQ,SAAA,MAAA,CAfJ,EAcK,MAAA,MAAA,CAbD,AAAA,EAAA,OAAA,EAC0F,MAAA,EAAtF,OAAM,2EAA0E,GAAA,MAAA,EAAA,IACpF,EAAA,EAAA,GAAA,EAUK,GAAA,MAAA,EATc,EAAA,MAAS,MAAM,QAAvB,OADX,EAAA,GAAA,EAUK,MAAA;IARA,KAAK,EAAK;IACX,OAAK,EAAA,CAAC,kEACmC,EAAK,cAAA,+BAAA,aAAA,CAAA;GAK3C,GAAA,EAAA,EAAK,IAAI,GAAA,CAAA,EAIxB,GAAA,GAAA,EAAA,CAAA,CAAA,CAAA,GAAA,EA4BQ,SAAA,MAAA,EA3BJ,EAAA,EAAA,GAAA,EA0BK,GAAA,MAAA,EAzByB,EAAA,QAAlB,GAAS,OADrB,EAAA,GAAA,EA0BK,MAAA;IAxBA,KAAK;IACL,OAAK,EAAA,EAAA,gBAAoB,IAAI,KAAA,EAAA,CAAA;GAC9B,GAAA,CAAA,EAOK,MAAA,EAND,OAAK,EAAA,CAAC,iDAA+C,EAAA,6BACsD,MAAS,EAAA,MAAS,SAAM,EAAA,CAAA,CAAA,EAIhI,GAAA,EAAA,EAAQ,QAAO,MAAA,GAAA,CAAA,GAAA,CAAA,IAEtB,EAAA,EAAA,GAAA,EAaK,GAAA,MAAA,EAZc,EAAA,MAAS,MAAM,QAAvB,OADX,EAAA,GAAA,EAaK,MAAA;IAXA,KAAK,EAAK;IACX,OAAK,EAAA,CAAC,mBAAiB,CACmB,EAAgB,EAAK,OAAO,EAAO,GAAA;KAA+I,6BAAA,MAAS,EAAA,MAAS,SAAM;KAA0D,gBAAA,EAAK;;GAQhT,GAAA,EAAA,EAAK,OAAO,MAAO,GAAA,GAAA,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
2
  import { _ as t, b as n, u as r } from "./schemas-DxbHVg3r.js";
3
- import { t as i } from "./PkStreamingMarkdown-D8_LwZMR.js";
3
+ import { t as i } from "./PkStreamingMarkdown-D0IOaETI.js";
4
4
  import { t as a } from "./useSafeLocalStorage-Ce3S1Ayn.js";
5
5
  import { t as o } from "./useLocalizedString-PfaKjIQY.js";
6
6
  import { t as s } from "./index.es-Cu5LTYt1.js";
@@ -54,7 +54,7 @@ var C = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
54
54
  }), p("strong", T, v(y(N)("label.contactUs")), 1)]), m(u, { mode: "out-in" }, {
55
55
  default: x(() => [U.value ? (_(), f("div", k, [p("div", A, [m(r, {
56
56
  name: "ri:check-line",
57
- class: "text-16 text-word-3"
57
+ class: "text-16 text-success"
58
58
  }), p("div", null, [p("strong", j, v(y(N)("message.leadSubmittedTitle")), 1), p("p", M, v(y(N)("message.leadSubmittedMessage")), 1)])])])) : (_(), f("div", E, [m(y(B), {
59
59
  modelValue: y(H),
60
60
  "onUpdate:modelValue": n[0] ||= (e) => g(H) ? H.value = e : null,
@@ -119,4 +119,4 @@ var C = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
119
119
  //#endregion
120
120
  export { P as n, F as t };
121
121
 
122
- //# sourceMappingURL=PkToolShowContactForm-DHmzAIVF.js.map
122
+ //# sourceMappingURL=PkToolShowContactForm-DceSyuX8.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowContactForm-DceSyuX8.js","names":[],"sources":["../../../../packages/components/src/chat/PkToolShowContactForm.vue","../../../../packages/components/src/chat/PkToolShowContactForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\n )\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact no-label\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <!-- One confirmation row across every tool card: a green\n check, the title in weight, the body quiet. The check is\n the outcome, so it alone carries the colour (DESIGN.md). -->\n <div class=\"flex items-center gap-sm\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div>\n <strong class=\"font-medium block text-word-1\">\n {{ $t('message.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import { useForm } from '@volverjs/form-vue'\n import * as z from 'zod'\n import { useSafeLocalStorage, useLocalizedString } from 'composables'\n import type { LocalizedString } from 'models'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { t: $t } = useI18n({ useScope: 'global' })\n\n const props = defineProps<{\n part: unknown\n submitted?: boolean\n loading?: boolean\n error?: string\n readonly?: boolean\n privacyPolicyNotice?: LocalizedString\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n type: string\n toolCallId: string\n input?: {\n name: string\n email: string\n phone?: string\n conversationContext?: Record<string, unknown>\n }\n }\n return part\n })\n\n const input = computed(() => toolPart.value.input)\n\n const localSubmitted = useSafeLocalStorage<boolean>(\n computed(\n () =>\n `${toolPart.value.toolCallId}-${toolPart.value.type}-submitted`,\n ),\n false,\n )\n\n const LeadFormSchema = z.object({\n name: z.string().min(1).max(255).default(''),\n email: z.email().max(255).default(''),\n phone: z\n .string()\n .max(50)\n .regex(/^[+0-9\\s\\-.()]*$/, $t('validation.invalidPhoneNumber'))\n .optional(),\n })\n\n const emit = defineEmits<{\n submit: [data: Record<string, unknown>]\n }>()\n\n const { VvForm, VvFormField, formData } = useForm(LeadFormSchema, {\n lazyLoad: true,\n })\n\n // Pre-populate form with input values\n watch(\n input,\n (newInput) => {\n formData.value = {\n name: newInput?.name || '',\n email: newInput?.email || '',\n phone: newInput?.phone || '',\n }\n },\n { immediate: true },\n )\n\n watch(\n () => props.submitted,\n (submitted) => {\n if (submitted) {\n localSubmitted.value = true\n }\n },\n { immediate: true },\n )\n\n const isSubmitted = computed(() => {\n return props.submitted || localSubmitted.value\n })\n\n const submitLead = async (data: Record<string, unknown>): Promise<void> => {\n emit('submit', { ...data, metadata: input.value?.conversationContext })\n }\n\n const privacyNotice = useLocalizedString(\n () => props.privacyPolicyNotice,\n 'message.defaultPrivacyPolicyNotice',\n )\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8 min-h-40\">\n <VvIcon name=\"ri:send-plane-2-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.contactUs') }}</strong>\n </div>\n\n <Transition mode=\"out-in\">\n <div v-if=\"!isSubmitted\" class=\"p-sm\">\n <VvForm v-model=\"formData\" :readonly @submit=\"submitLead\">\n <VvFormField\n name=\"name\"\n type=\"text\"\n :label=\"$t('label.name')\"\n :placeholder=\"$t('placeholder.name')\"\n icon=\"ri:user-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"email\"\n type=\"email\"\n :label=\"$t('label.email')\"\n :placeholder=\"$t('placeholder.email')\"\n icon=\"ri:mail-line\"\n modifiers=\"compact no-label\"\n class=\"mb-md\" />\n <VvFormField\n name=\"phone\"\n type=\"tel\"\n :label=\"$t('label.phone')\"\n :placeholder=\"$t('placeholder.phone')\"\n icon=\"ri:phone-line\"\n class=\"mb-md\"\n modifiers=\"compact no-label\" />\n\n <div class=\"flex justify-between items-center gap-16 mt-xs\">\n <div\n class=\"text-smaller text-word-3 flex items-center gap-8\">\n <VvIcon\n name=\"ri:shield-check-line\"\n class=\"text-16 shrink-0\" />\n <PkStreamingMarkdown\n :markdown=\"privacyNotice\"\n class=\"wysiwyg\" />\n </div>\n <VvButton\n type=\"submit\"\n modifiers=\"primary\"\n :loading\n :disabled=\"loading || readonly\"\n icon-position=\"right\"\n class=\"shrink-0\"\n :label=\"$t('action.submit')\" />\n </div>\n </VvForm>\n </div>\n <div v-else class=\"p-sm\">\n <!-- One confirmation row across every tool card: a green\n check, the title in weight, the body quiet. The check is\n the outcome, so it alone carries the colour (DESIGN.md). -->\n <div class=\"flex items-center gap-sm\">\n <VvIcon name=\"ri:check-line\" class=\"text-16 text-success\" />\n <div>\n <strong class=\"font-medium block text-word-1\">\n {{ $t('message.leadSubmittedTitle') }}\n </strong>\n <p class=\"text-word-3\">\n {{ $t('message.leadSubmittedMessage') }}\n </p>\n </div>\n </div>\n </div>\n </Transition>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;EASI,IAAM,EAAE,GAAG,MAAO,EAAQ,EAAE,UAAU,SAAS,CAAC,GAE1C,IAAQ,GASR,IAAW,QACA,EAAM,IAWtB,GAEK,IAAQ,QAAe,EAAS,MAAM,KAAK,GAE3C,IAAiB,EACnB,QAEQ,GAAG,EAAS,MAAM,WAAW,GAAG,EAAS,MAAM,KAAK,WAC5D,GACA,EACJ,GAEM,IAAiB,EAAS;GAC5B,MAAM,EAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE;GAC3C,OAAO,EAAQ,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE;GACpC,OAAO,EACK,CAAA,CACP,IAAI,EAAE,CAAA,CACN,MAAM,oBAAoB,EAAG,+BAA+B,CAAC,CAAA,CAC7D,SAAS;EAClB,CAAC,GAEK,IAAO,GAIP,EAAE,WAAQ,gBAAa,gBAAa,EAAQ,GAAgB,EAC9D,UAAU,GACd,CAAC;EAeD,AAZA,EACI,IACC,MAAa;GACV,EAAS,QAAQ;IACb,MAAM,GAAU,QAAQ;IACxB,OAAO,GAAU,SAAS;IAC1B,OAAO,GAAU,SAAS;GAC9B;EACJ,GACA,EAAE,WAAW,GAAK,CACtB,GAEA,QACU,EAAM,YACX,MAAc;GACX,AAAI,MACA,EAAe,QAAQ;EAE/B,GACA,EAAE,WAAW,GAAK,CACtB;EAEA,IAAM,IAAc,QACT,EAAM,aAAa,EAAe,KAC5C,GAEK,IAAa,OAAO,MAAiD;GACvE,EAAK,UAAU;IAAE,GAAG;IAAM,UAAU,EAAM,OAAO;GAAoB,CAAC;EAC1E,GAEM,IAAgB,QACZ,EAAM,qBACZ,oCACJ;;;GAIA,OAAA,EAAA,GAAA,EA0EM,OA1EN,GA0EM,CAxEF,EAIM,OAJN,GAIM,CAFF,EAAsD,GAAA;IAA9C,MAAK;IAAuB,OAAM;GAC1C,CAAA,GAAA,EAA8D,UAA9D,GAA8D,EAAjC,EAAA,CAAA,CAAE,CAAA,iBAAA,CAAA,GAAA,CAAA,CAAA,CAAA,GAGnC,EAiEa,GAAA,EAjED,MAAK,SAAQ,GAAA;IACrB,SAAA,QA+CM,CA/CM,EAAA,SAgDZ,EAAA,GAAA,EAeM,OAfN,GAeM,CAXF,EAUM,OAVN,GAUM,CATF,EAA4D,GAAA;KAApD,MAAK;KAAgB,OAAM;IACnC,CAAA,GAAA,EAOM,OAAA,MAAA,CANF,EAES,UAFT,GAES,EADF,EAAA,CAAA,CAAE,CAAA,4BAAA,CAAA,GAAA,CAAA,GAET,EAEI,KAFJ,GAEI,EADG,EAAA,CAAA,CAAE,CAAA,8BAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,MA3DrB,EAAA,GAAA,EA+CM,OA/CN,GA+CM,CA9CF,EA6CS,EAAA,CAAA,GAAA;KA7CQ,YAAA,EAAA,CAAA;KAAA,uBAAA,AAAA,EAAA,QAAA,MAAA,EAAA,CAAA,IAAA,EAAQ,QAAA,IAAA;KAAG,UAAA,EAAA;KAAU,UAAQ;;KAC1C,SAAA,QAOoB;MAPpB,EAOoB,EAAA,CAAA,GAAA;OANhB,MAAK;OACL,MAAK;OACJ,OAAO,EAAA,CAAA,CAAE,CAAA,YAAA;OACT,aAAa,EAAA,CAAA,CAAE,CAAA,kBAAA;OAChB,MAAK;OACL,WAAU;OACV,OAAM;;MACV,EAOoB,EAAA,CAAA,GAAA;OANhB,MAAK;OACL,MAAK;OACJ,OAAO,EAAA,CAAA,CAAE,CAAA,aAAA;OACT,aAAa,EAAA,CAAA,CAAE,CAAA,mBAAA;OAChB,MAAK;OACL,WAAU;OACV,OAAM;;MACV,EAOmC,EAAA,CAAA,GAAA;OAN/B,MAAK;OACL,MAAK;OACJ,OAAO,EAAA,CAAA,CAAE,CAAA,aAAA;OACT,aAAa,EAAA,CAAA,CAAE,CAAA,mBAAA;OAChB,MAAK;OACL,OAAM;OACN,WAAU;;MAEd,EAkBM,OAlBN,GAkBM,CAjBF,EAQM,OARN,GAQM,CANF,EAE+B,GAAA;OAD3B,MAAK;OACL,OAAM;MACV,CAAA,GAAA,EAEsB,GAAA;OADjB,UAAU,EAAA,CAAA;OACX,OAAM;MAEd,GAAA,MAAA,GAAA,CAAA,UAAA,CAAA,CAAA,CAAA,GAAA,EAOmC,GAAA;OAN/B,MAAK;OACL,WAAU;OACT,SAAA,EAAA;OACA,UAAU,EAAA,WAAW,EAAA;OACtB,iBAAc;OACd,OAAM;OACL,OAAO,EAAA,CAAA,CAAE,CAAA,eAAA;;;;;;;;IAI1B,GAAA,GAAA,CAAA,cAAA,UAAA,CAAA,CAAA,CAAA,EAWqB,CAAA"}
@@ -1,6 +1,6 @@
1
1
  import "./src-DT8FLE4_.js";
2
- import { a as e } from "./PkChatbotMessages-BFlU046I.js";
3
- import { t } from "./PkSvgViewer-DPpE9fiz.js";
2
+ import { a as e } from "./PkChatbotMessages-Bz5q8EtT.js";
3
+ import { t } from "./PkSvgViewer-D-0M5bqg.js";
4
4
  import { VvButton as n, VvButtonGroup as r, VvIcon as i } from "@volverjs/ui-vue/components";
5
5
  import { computed as a, createBlock as o, createCommentVNode as s, createElementBlock as c, createElementVNode as l, createVNode as u, defineComponent as d, onMounted as f, openBlock as p, ref as m, toDisplayString as h, unref as g, watch as _, withCtx as v } from "vue";
6
6
  import { useI18n as y } from "vue-i18n";
@@ -108,7 +108,7 @@ var x = {
108
108
  svg: I.value,
109
109
  title: P.value.input?.title
110
110
  }, null, 8, ["svg", "title"])) : (p(), c("div", E, [u(d, {
111
- name: "line-md:loading-loop",
111
+ name: "loading-loop",
112
112
  class: "w-24 h-24 text-word-5"
113
113
  })])),
114
114
  P.value.input.caption ? (p(), c("div", D, h(P.value.input.caption), 1)) : s("", !0)
@@ -119,4 +119,4 @@ var x = {
119
119
  //#endregion
120
120
  export { k as default };
121
121
 
122
- //# sourceMappingURL=PkToolShowDiagram-DuDp5EHd.js.map
122
+ //# sourceMappingURL=PkToolShowDiagram-pwc0wpNo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PkToolShowDiagram-pwc0wpNo.js","names":[],"sources":["../../../../packages/components/src/chat/PkToolShowDiagram.vue","../../../../packages/components/src/chat/PkToolShowDiagram.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, onMounted, ref, watch } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useI18n } from 'vue-i18n'\n import { toSnakeCase } from 'utils'\n import PkSvgViewer from '../PkSvgViewer.vue'\n\n const props = defineProps<{\n part: unknown\n isDark?: boolean\n }>()\n\n const { t: $t, te: $te } = useI18n({\n useScope: 'global',\n })\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n code: string\n title?: string\n caption?: string\n }\n }\n return part\n })\n\n const svgError = ref(false)\n\n // Serialized SVG content\n const svgContent = ref('')\n\n enum DiagramType {\n Sequence = 'sequenceDiagram',\n Class = 'classDiagram',\n State = 'stateDiagram',\n ER = 'erDiagram',\n XYChart = 'xychart',\n Flowchart = 'flowchart',\n Graph = 'graph',\n }\n\n const diagramType = computed<DiagramType | undefined>(() => {\n const code = toolPart.value.input?.code?.trimStart()\n if (!code) {\n return undefined\n }\n const firstWord = code.match(/^[A-Za-z-]+/)?.[0]\n switch (firstWord) {\n case 'sequenceDiagram':\n return DiagramType.Sequence\n case 'classDiagram':\n return DiagramType.Class\n case 'stateDiagram':\n return DiagramType.State\n case 'erDiagram':\n return DiagramType.ER\n case 'xychart-beta':\n return DiagramType.XYChart\n case 'flowchart':\n return DiagramType.Flowchart\n case 'graph':\n return DiagramType.Graph\n default:\n return undefined\n }\n })\n\n const diagramTypeLabel = computed(() => {\n if (!diagramType.value) {\n return ''\n }\n return $te(`diagram.${diagramType.value}`)\n ? $t(`diagram.${diagramType.value}`)\n : diagramType.value\n })\n\n const diagramTypeIcon = computed(() => {\n switch (diagramType.value) {\n case DiagramType.Sequence:\n return 'ri:timeline-view'\n case DiagramType.Class:\n return 'ri:organization-chart'\n case DiagramType.State:\n return 'ri:organization-chart'\n case DiagramType.ER:\n return 'ri:organization-chart'\n case DiagramType.XYChart:\n return 'ri:line-chart-line'\n case DiagramType.Flowchart:\n return 'ri:flow-chart'\n case DiagramType.Graph:\n return 'ri:flow-chart'\n default:\n return 'ri:flow-chart'\n }\n })\n\n async function renderDiagram() {\n const code = toolPart.value.input?.code\n if (!code) {\n return\n }\n\n svgError.value = false\n try {\n const { renderMermaidSVG, THEMES } =\n await import('beautiful-mermaid')\n const theme = props.isDark\n ? THEMES['github-dark']\n : THEMES['github-light']\n svgContent.value = renderMermaidSVG(code, theme)\n } catch {\n svgError.value = true\n }\n }\n\n watch([() => toolPart.value.input?.code, () => props.isDark], renderDiagram)\n onMounted(async () => {\n await renderDiagram()\n })\n\n const downloadSvg = () => {\n if (!svgContent.value) {\n return\n }\n const blob = new Blob([svgContent.value], {\n type: 'image/svg+xml;charset=utf-8',\n })\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = `${toSnakeCase(toolPart.value.input?.title || 'diagram')}.svg`\n document.body.appendChild(anchor)\n anchor.click()\n document.body.removeChild(anchor)\n URL.revokeObjectURL(url)\n }\n\n const copyCode = () => {\n const code = toolPart.value.input?.code\n if (code) {\n copy(code)\n }\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.code\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon :name=\"diagramTypeIcon\" class=\"text-16\" />\n <div class=\"flex flex-col items-start gap-2\">\n <strong class=\"font-bold\">{{\n diagramTypeLabel ?? $t('label.diagram')\n }}</strong>\n </div>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyCode\" />\n <VvButton\n v-if=\"svgContent\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:download-line\"\n :label=\"$t('action.download')\"\n @click=\"downloadSvg\" />\n </VvButtonGroup>\n </div>\n <div v-if=\"svgError\" class=\"text-12 text-danger py-8 px-sm\">\n {{ $t('message.diagramRenderError') }}\n </div>\n <PkSvgViewer\n v-else-if=\"svgContent\"\n class=\"pk-tool-show-diagram__stage\"\n :svg=\"svgContent\"\n :title=\"toolPart.input?.title\" />\n <div\n v-else\n class=\"pk-tool-show-diagram__stage flex justify-center items-center\">\n <VvIcon name=\"loading-loop\" class=\"w-24 h-24 text-word-5\" />\n </div>\n <div\n v-if=\"toolPart.input.caption\"\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-t border-surface-3 text-word-3\">\n {{ toolPart.input.caption }}\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-tool-show-diagram {\n // Fixed stage height: the diagram renders lazily (async chunk +\n // dynamic mermaid import), so the loader and the rendered SVG must\n // occupy the same space or the chat scroll position jumps around.\n // The SVG scales to fit; zoom/pan and the lightbox cover the rest.\n &__stage {\n height: 384px;\n\n .pk-svg-viewer__stage,\n .pk-svg-viewer__content {\n height: 100%;\n }\n }\n }\n</style>\n","<script setup lang=\"ts\">\n import { computed, onMounted, ref, watch } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useI18n } from 'vue-i18n'\n import { toSnakeCase } from 'utils'\n import PkSvgViewer from '../PkSvgViewer.vue'\n\n const props = defineProps<{\n part: unknown\n isDark?: boolean\n }>()\n\n const { t: $t, te: $te } = useI18n({\n useScope: 'global',\n })\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n code: string\n title?: string\n caption?: string\n }\n }\n return part\n })\n\n const svgError = ref(false)\n\n // Serialized SVG content\n const svgContent = ref('')\n\n enum DiagramType {\n Sequence = 'sequenceDiagram',\n Class = 'classDiagram',\n State = 'stateDiagram',\n ER = 'erDiagram',\n XYChart = 'xychart',\n Flowchart = 'flowchart',\n Graph = 'graph',\n }\n\n const diagramType = computed<DiagramType | undefined>(() => {\n const code = toolPart.value.input?.code?.trimStart()\n if (!code) {\n return undefined\n }\n const firstWord = code.match(/^[A-Za-z-]+/)?.[0]\n switch (firstWord) {\n case 'sequenceDiagram':\n return DiagramType.Sequence\n case 'classDiagram':\n return DiagramType.Class\n case 'stateDiagram':\n return DiagramType.State\n case 'erDiagram':\n return DiagramType.ER\n case 'xychart-beta':\n return DiagramType.XYChart\n case 'flowchart':\n return DiagramType.Flowchart\n case 'graph':\n return DiagramType.Graph\n default:\n return undefined\n }\n })\n\n const diagramTypeLabel = computed(() => {\n if (!diagramType.value) {\n return ''\n }\n return $te(`diagram.${diagramType.value}`)\n ? $t(`diagram.${diagramType.value}`)\n : diagramType.value\n })\n\n const diagramTypeIcon = computed(() => {\n switch (diagramType.value) {\n case DiagramType.Sequence:\n return 'ri:timeline-view'\n case DiagramType.Class:\n return 'ri:organization-chart'\n case DiagramType.State:\n return 'ri:organization-chart'\n case DiagramType.ER:\n return 'ri:organization-chart'\n case DiagramType.XYChart:\n return 'ri:line-chart-line'\n case DiagramType.Flowchart:\n return 'ri:flow-chart'\n case DiagramType.Graph:\n return 'ri:flow-chart'\n default:\n return 'ri:flow-chart'\n }\n })\n\n async function renderDiagram() {\n const code = toolPart.value.input?.code\n if (!code) {\n return\n }\n\n svgError.value = false\n try {\n const { renderMermaidSVG, THEMES } =\n await import('beautiful-mermaid')\n const theme = props.isDark\n ? THEMES['github-dark']\n : THEMES['github-light']\n svgContent.value = renderMermaidSVG(code, theme)\n } catch {\n svgError.value = true\n }\n }\n\n watch([() => toolPart.value.input?.code, () => props.isDark], renderDiagram)\n onMounted(async () => {\n await renderDiagram()\n })\n\n const downloadSvg = () => {\n if (!svgContent.value) {\n return\n }\n const blob = new Blob([svgContent.value], {\n type: 'image/svg+xml;charset=utf-8',\n })\n const url = URL.createObjectURL(blob)\n const anchor = document.createElement('a')\n anchor.href = url\n anchor.download = `${toSnakeCase(toolPart.value.input?.title || 'diagram')}.svg`\n document.body.appendChild(anchor)\n anchor.click()\n document.body.removeChild(anchor)\n URL.revokeObjectURL(url)\n }\n\n const copyCode = () => {\n const code = toolPart.value.input?.code\n if (code) {\n copy(code)\n }\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input?.code\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon :name=\"diagramTypeIcon\" class=\"text-16\" />\n <div class=\"flex flex-col items-start gap-2\">\n <strong class=\"font-bold\">{{\n diagramTypeLabel ?? $t('label.diagram')\n }}</strong>\n </div>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyCode\" />\n <VvButton\n v-if=\"svgContent\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:download-line\"\n :label=\"$t('action.download')\"\n @click=\"downloadSvg\" />\n </VvButtonGroup>\n </div>\n <div v-if=\"svgError\" class=\"text-12 text-danger py-8 px-sm\">\n {{ $t('message.diagramRenderError') }}\n </div>\n <PkSvgViewer\n v-else-if=\"svgContent\"\n class=\"pk-tool-show-diagram__stage\"\n :svg=\"svgContent\"\n :title=\"toolPart.input?.title\" />\n <div\n v-else\n class=\"pk-tool-show-diagram__stage flex justify-center items-center\">\n <VvIcon name=\"loading-loop\" class=\"w-24 h-24 text-word-5\" />\n </div>\n <div\n v-if=\"toolPart.input.caption\"\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-t border-surface-3 text-word-3\">\n {{ toolPart.input.caption }}\n </div>\n </div>\n</template>\n\n<style lang=\"scss\">\n .pk-tool-show-diagram {\n // Fixed stage height: the diagram renders lazily (async chunk +\n // dynamic mermaid import), so the loader and the rendered SVG must\n // occupy the same space or the chat scroll position jumps around.\n // The SVG scales to fit; zoom/pan and the lightbox cover the rest.\n &__stage {\n height: 384px;\n\n .pk-svg-viewer__stage,\n .pk-svg-viewer__content {\n height: 100%;\n }\n }\n }\n</style>\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { r as t } from "./PkStreamingMarkdown-D8_LwZMR.js";
2
+ import { r as t } from "./PkStreamingMarkdown-D0IOaETI.js";
3
3
  import { VvButton as n, VvButtonGroup as r, VvDropdown as i, VvDropdownAction as a, VvIcon as o } from "@volverjs/ui-vue/components";
4
4
  import { computed as s, createElementBlock as c, createElementVNode as l, createTextVNode as u, createVNode as d, defineComponent as f, guardReactiveProps as p, normalizeProps as m, openBlock as h, toDisplayString as g, unref as _, withCtx as v } from "vue";
5
5
  import { useClipboard as y } from "@vueuse/core";
@@ -87,4 +87,4 @@ var b = { class: "border border-surface-3 rounded-xl w-full overflow-hidden bg-s
87
87
  //#endregion
88
88
  export { A as n, j as t };
89
89
 
90
- //# sourceMappingURL=PkToolShowEmail-CavhsPvi.js.map
90
+ //# sourceMappingURL=PkToolShowEmail-DF__nKpR.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PkToolShowEmail-CavhsPvi.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowEmail.vue","../../../../packages/components/src/chat/PkToolShowEmail.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n subject: string\n body: string\n }\n }\n return part\n })\n\n // Emails leave the app (mailto/webmail/clipboard), so expand short urls to\n // their real target rather than keeping the fragile `/api/r/` redirect.\n const { resolveText } = useShortUrlResolver()\n const subject = resolveText(() => toolPart.value.input?.subject)\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInMailApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const mailtoLink = `mailto:?subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(mailtoLink)\n }\n\n const openInOutlook = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://outlook.office.com/mail/deeplink/compose?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInGmail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://mail.google.com/mail/u/0/?tf=cm&to=&su=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInYahooMail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://compose.mail.yahoo.com/?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:mail-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.email') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(`${subject}\\n\\n${body}`)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:mail-send-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInOutlook\">\n <VvIcon name=\"mdi:outlook\" />\n {{ $t('action.openInOutlook') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInGmail\">\n <VvIcon name=\"mdi:gmail\" />\n {{ $t('action.openInGmail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInYahooMail\">\n <VvIcon name=\"mdi:yahoo\" />\n {{ $t('action.openInYahooMail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInMailApp\">\n <VvIcon name=\"ri:mail-open-line\" />\n {{ $t('action.openInMailApp') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"border-b border-surface-3 p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.subject') }}\n </div>\n <div class=\"text-word-2 font-semibold\">\n {{ subject }}\n </div>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n subject: string\n body: string\n }\n }\n return part\n })\n\n // Emails leave the app (mailto/webmail/clipboard), so expand short urls to\n // their real target rather than keeping the fragile `/api/r/` redirect.\n const { resolveText } = useShortUrlResolver()\n const subject = resolveText(() => toolPart.value.input?.subject)\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInMailApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const mailtoLink = `mailto:?subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(mailtoLink)\n }\n\n const openInOutlook = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://outlook.office.com/mail/deeplink/compose?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInGmail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://mail.google.com/mail/u/0/?tf=cm&to=&su=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInYahooMail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://compose.mail.yahoo.com/?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:mail-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.email') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(`${subject}\\n\\n${body}`)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:mail-send-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInOutlook\">\n <VvIcon name=\"mdi:outlook\" />\n {{ $t('action.openInOutlook') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInGmail\">\n <VvIcon name=\"mdi:gmail\" />\n {{ $t('action.openInGmail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInYahooMail\">\n <VvIcon name=\"mdi:yahoo\" />\n {{ $t('action.openInYahooMail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInMailApp\">\n <VvIcon name=\"ri:mail-open-line\" />\n {{ $t('action.openInMailApp') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"border-b border-surface-3 p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.subject') }}\n </div>\n <div class=\"text-word-2 font-semibold\">\n {{ subject }}\n </div>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"PkToolShowEmail-DF__nKpR.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowEmail.vue","../../../../packages/components/src/chat/PkToolShowEmail.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n subject: string\n body: string\n }\n }\n return part\n })\n\n // Emails leave the app (mailto/webmail/clipboard), so expand short urls to\n // their real target rather than keeping the fragile `/api/r/` redirect.\n const { resolveText } = useShortUrlResolver()\n const subject = resolveText(() => toolPart.value.input?.subject)\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInMailApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const mailtoLink = `mailto:?subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(mailtoLink)\n }\n\n const openInOutlook = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://outlook.office.com/mail/deeplink/compose?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInGmail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://mail.google.com/mail/u/0/?tf=cm&to=&su=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInYahooMail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://compose.mail.yahoo.com/?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:mail-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.email') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(`${subject}\\n\\n${body}`)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:mail-send-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInOutlook\">\n <VvIcon name=\"mdi:outlook\" />\n {{ $t('action.openInOutlook') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInGmail\">\n <VvIcon name=\"mdi:gmail\" />\n {{ $t('action.openInGmail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInYahooMail\">\n <VvIcon name=\"mdi:yahoo\" />\n {{ $t('action.openInYahooMail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInMailApp\">\n <VvIcon name=\"ri:mail-open-line\" />\n {{ $t('action.openInMailApp') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"border-b border-surface-3 p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.subject') }}\n </div>\n <div class=\"text-word-2 font-semibold\">\n {{ subject }}\n </div>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { useShortUrlResolver } from 'composables'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n subject: string\n body: string\n }\n }\n return part\n })\n\n // Emails leave the app (mailto/webmail/clipboard), so expand short urls to\n // their real target rather than keeping the fragile `/api/r/` redirect.\n const { resolveText } = useShortUrlResolver()\n const subject = resolveText(() => toolPart.value.input?.subject)\n const body = resolveText(() => toolPart.value.input?.body)\n\n const openInMailApp = () => {\n if (!toolPart.value.input) {\n return\n }\n const mailtoLink = `mailto:?subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(mailtoLink)\n }\n\n const openInOutlook = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://outlook.office.com/mail/deeplink/compose?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInGmail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://mail.google.com/mail/u/0/?tf=cm&to=&su=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n\n const openInYahooMail = () => {\n if (!toolPart.value.input) {\n return\n }\n const url = `https://compose.mail.yahoo.com/?to=&subject=${encodeURIComponent(\n subject.value,\n )}&body=${encodeURIComponent(body.value)}`\n window.open(url, '_blank')\n }\n</script>\n\n<template>\n <div\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden bg-surface\">\n <div\n class=\"px-sm py-6 bg-surface-1 min-h-40 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:mail-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.email') }}\n </strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copy(`${subject}\\n\\n${body}`)\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n strategy: 'fixed',\n }\">\n <VvButton\n icon=\"ri:mail-send-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.send')\" />\n <template #items>\n <VvDropdownAction @click=\"openInOutlook\">\n <VvIcon name=\"mdi:outlook\" />\n {{ $t('action.openInOutlook') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInGmail\">\n <VvIcon name=\"mdi:gmail\" />\n {{ $t('action.openInGmail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInYahooMail\">\n <VvIcon name=\"mdi:yahoo\" />\n {{ $t('action.openInYahooMail') }}\n </VvDropdownAction>\n <VvDropdownAction @click=\"openInMailApp\">\n <VvIcon name=\"ri:mail-open-line\" />\n {{ $t('action.openInMailApp') }}\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div class=\"border-b border-surface-3 p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.subject') }}\n </div>\n <div class=\"text-word-2 font-semibold\">\n {{ subject }}\n </div>\n </div>\n <div class=\"p-sm\">\n <div class=\"text-12 text-word-4 mb-4\">\n {{ $t('label.body') }}\n </div>\n <pre class=\"text-word-2 whitespace-pre-wrap break-words\">{{\n body\n }}</pre>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { t as e } from "./rolldown-runtime-Dy4uBu1J.js";
2
- import { D as t } from "./Agent-C8BsTAxk.js";
3
- import { t as n } from "./PkStreamingMarkdown-D8_LwZMR.js";
4
- import { a as r, i } from "./utils-Coqik0XI.js";
2
+ import { D as t } from "./Agent-De2gFNjR.js";
3
+ import { t as n } from "./PkStreamingMarkdown-D0IOaETI.js";
4
+ import { a as r, o as i } from "./utils-C1666_6C.js";
5
5
  import { VvButton as a, VvCheckbox as o, VvCheckboxGroup as s, VvIcon as ee, VvInputText as te, VvRadio as c, VvRadioGroup as l } from "@volverjs/ui-vue/components";
6
6
  import { Fragment as u, computed as d, createBlock as f, createCommentVNode as p, createElementBlock as m, createElementVNode as h, createSlots as g, createTextVNode as _, createVNode as v, defineComponent as y, mergeModels as b, mergeProps as x, normalizeClass as ne, normalizeStyle as re, openBlock as S, reactive as ie, ref as C, renderList as w, renderSlot as T, toDisplayString as E, unref as D, useId as O, useModel as k, watch as A, withCtx as j, withKeys as ae, withModifiers as M } from "vue";
7
7
  import { useI18n as oe } from "vue-i18n";
@@ -198,7 +198,7 @@ var N = /* @__PURE__ */ y({
198
198
  return Array.isArray(t) ? t : void 0;
199
199
  }
200
200
  A(() => y.value.output, (e) => {
201
- e && !t(e) && Object.assign(K, i(z.value, e));
201
+ e && !t(e) && Object.assign(K, r(z.value, e));
202
202
  }, { immediate: !0 });
203
203
  let Me = d(() => {
204
204
  let e = y.value.output;
@@ -213,7 +213,7 @@ var N = /* @__PURE__ */ y({
213
213
  A(Me, (e) => {
214
214
  e && H.value && ((H.value.options ?? []).map((e) => e.label).includes(e) || (q.value = e));
215
215
  }, { immediate: !0 });
216
- let X = d(() => r(H.value));
216
+ let X = d(() => i(H.value));
217
217
  function Z() {
218
218
  if (q.value.trim()) {
219
219
  $();
@@ -354,7 +354,7 @@ var N = /* @__PURE__ */ y({
354
354
  class: "leading-normal"
355
355
  }, [h("div", Ee, E(e.question), 1), h("span", De, E(Fe(e, t)), 1)]))), 128))])]), h("div", Oe, [v(o, {
356
356
  name: "ri:check-line",
357
- class: "text-16 text-word-3"
357
+ class: "text-16 text-success"
358
358
  }), h("div", L, [h("span", ke, E(D(l)("showForm.completed")), 1)])])], 64))])) : p("", !0);
359
359
  };
360
360
  }
@@ -362,4 +362,4 @@ var N = /* @__PURE__ */ y({
362
362
  //#endregion
363
363
  export { N as i, z as n, P as r, B as t };
364
364
 
365
- //# sourceMappingURL=PkToolShowForm-CO5A_j9L.js.map
365
+ //# sourceMappingURL=PkToolShowForm-Dx10jOXm.js.map