@8wave/ai-elements 0.99.0-beta.1 → 0.99.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{dist-vue/_chunks/PkStreamingMarkdown-DEhbK-3c.js → dist/_chunks/PkStreamingMarkdown-6Xx9n1ue.js} +379 -362
- package/dist/_chunks/PkStreamingMarkdown-6Xx9n1ue.js.map +1 -0
- package/dist/_chunks/{PkToolRequestGeolocation-BJ9NJZIg.js → PkToolRequestGeolocation-B73evGBg.js} +2 -2
- package/dist/_chunks/{PkToolRequestGeolocation-BJ9NJZIg.js.map → PkToolRequestGeolocation-B73evGBg.js.map} +1 -1
- package/dist/_chunks/{PkToolRequestOAuthConnection-DdvJ6n1K.js → PkToolRequestOAuthConnection-BWP5dsK_.js} +3 -3
- package/dist/_chunks/{PkToolRequestOAuthConnection-DdvJ6n1K.js.map → PkToolRequestOAuthConnection-BWP5dsK_.js.map} +1 -1
- package/dist/_chunks/{PkToolShowArtifact-BaGEr7O9.js → PkToolShowArtifact-bYYaMGxq.js} +7 -7
- package/dist/_chunks/{PkToolShowArtifact-BaGEr7O9.js.map → PkToolShowArtifact-bYYaMGxq.js.map} +1 -1
- package/dist/_chunks/{PkToolShowCalendarEvent-BYnhl2er.js → PkToolShowCalendarEvent-DdEWaTj-.js} +4 -4
- package/dist/_chunks/{PkToolShowCalendarEvent-BYnhl2er.js.map → PkToolShowCalendarEvent-DdEWaTj-.js.map} +1 -1
- package/dist/_chunks/{PkToolShowComparison-DahL5vHr.js → PkToolShowComparison-Dcar7HPW.js} +4 -4
- package/dist/_chunks/{PkToolShowComparison-DahL5vHr.js.map → PkToolShowComparison-Dcar7HPW.js.map} +1 -1
- package/dist/_chunks/{PkToolShowContactForm-upUNZtId.js → PkToolShowContactForm-DtjVW-n6.js} +13 -13
- package/dist/_chunks/{PkToolShowContactForm-upUNZtId.js.map → PkToolShowContactForm-DtjVW-n6.js.map} +1 -1
- package/dist/_chunks/{PkToolShowDiagram-Jq_4KWiK.js → PkToolShowDiagram-X35nsoIY.js} +8 -8
- package/dist/_chunks/{PkToolShowDiagram-Jq_4KWiK.js.map → PkToolShowDiagram-X35nsoIY.js.map} +1 -1
- package/dist/_chunks/{PkToolShowEmail-CtmpDS1B.js → PkToolShowEmail-jVoK8qEh.js} +4 -4
- package/dist/_chunks/{PkToolShowEmail-CtmpDS1B.js.map → PkToolShowEmail-jVoK8qEh.js.map} +1 -1
- package/dist/_chunks/{PkToolShowForm-dFuoqTPs.js → PkToolShowForm-BP8asXtz.js} +101 -79
- package/dist/_chunks/PkToolShowForm-BP8asXtz.js.map +1 -0
- package/dist/_chunks/{PkToolShowImageGallery-mLq2p3aH.js → PkToolShowImageGallery-WQL3T4Hr.js} +2 -2
- package/dist/_chunks/{PkToolShowImageGallery-mLq2p3aH.js.map → PkToolShowImageGallery-WQL3T4Hr.js.map} +1 -1
- package/dist/_chunks/{PkToolShowLocation-SbgTbuGu.js → PkToolShowLocation-w2t7lKpb.js} +4 -4
- package/dist/_chunks/{PkToolShowLocation-SbgTbuGu.js.map → PkToolShowLocation-w2t7lKpb.js.map} +1 -1
- package/dist/_chunks/{PkToolShowMessage-CAVpDTzd.js → PkToolShowMessage-BPo7WPim.js} +4 -4
- package/dist/_chunks/{PkToolShowMessage-CAVpDTzd.js.map → PkToolShowMessage-BPo7WPim.js.map} +1 -1
- package/dist/_chunks/{PkToolShowProductList-puiPFItN.js → PkToolShowProductList-BbY4ni7Y.js} +2 -2
- package/dist/_chunks/{PkToolShowProductList-puiPFItN.js.map → PkToolShowProductList-BbY4ni7Y.js.map} +1 -1
- package/dist/_chunks/{PkToolShowQrCode-CctXvRyG.js → PkToolShowQrCode-CN0ms27N.js} +4 -4
- package/dist/_chunks/{PkToolShowQrCode-CctXvRyG.js.map → PkToolShowQrCode-CN0ms27N.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSources-DwB6VXrK.js → PkToolShowSources-D2tBcx7n.js} +18 -18
- package/dist/_chunks/{PkToolShowSources-DwB6VXrK.js.map → PkToolShowSources-D2tBcx7n.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSuggestedReply-QEcIhSxa.js → PkToolShowSuggestedReply-Cdh_elSh.js} +2 -2
- package/dist/_chunks/{PkToolShowSuggestedReply-QEcIhSxa.js.map → PkToolShowSuggestedReply-Cdh_elSh.js.map} +1 -1
- package/dist/_chunks/{PkToolShowVideo-DoLoI8_N.js → PkToolShowVideo-D3aU5FMO.js} +2 -2
- package/dist/_chunks/{PkToolShowVideo-DoLoI8_N.js.map → PkToolShowVideo-D3aU5FMO.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWeather-C2rPCQ_K.js → PkToolShowWeather-CzanXIJp.js} +3 -3
- package/dist/_chunks/{PkToolShowWeather-C2rPCQ_K.js.map → PkToolShowWeather-CzanXIJp.js.map} +1 -1
- package/dist/_chunks/{PkToolShowWebPages-BBJYzF8V.js → PkToolShowWebPages-DkMJrWmT.js} +2 -2
- package/dist/_chunks/{PkToolShowWebPages-BBJYzF8V.js.map → PkToolShowWebPages-DkMJrWmT.js.map} +1 -1
- package/dist/_chunks/{VvCheckbox.es-D5d8k9yP.js → VvCheckbox.es-CRhIKQNR.js} +2 -2
- package/dist/_chunks/{VvCheckbox.es-D5d8k9yP.js.map → VvCheckbox.es-CRhIKQNR.js.map} +1 -1
- package/dist/_chunks/{VvCheckboxGroup.es-DVnsOjX0.js → VvCheckboxGroup.es-gOy2kM1Y.js} +5 -5
- package/dist/_chunks/{VvCheckboxGroup.es-DVnsOjX0.js.map → VvCheckboxGroup.es-gOy2kM1Y.js.map} +1 -1
- package/dist/_chunks/{VvCombobox.es-CFA-K-cQ.js → VvCombobox.es-BOwH3LmO.js} +9 -9
- package/dist/_chunks/VvCombobox.es-BOwH3LmO.js.map +1 -0
- package/dist/_chunks/{VvInputText.es-csEQ-bSG.js → VvInputText.es-D8nXroKO.js} +536 -513
- package/dist/_chunks/VvInputText.es-D8nXroKO.js.map +1 -0
- package/dist/_chunks/{VvRadio.es-BpymhC73.js → VvRadio.es-Djy5J33A.js} +2 -2
- package/dist/_chunks/{VvRadio.es-BpymhC73.js.map → VvRadio.es-Djy5J33A.js.map} +1 -1
- package/dist/_chunks/{VvRadioGroup.es-CSNzOJKx.js → VvRadioGroup.es-DQq3JYCR.js} +5 -5
- package/dist/_chunks/VvRadioGroup.es-DQq3JYCR.js.map +1 -0
- package/dist/_chunks/{VvSelect.es-CjKMd0nH.js → VvSelect.es-CE4x1ww0.js} +4 -4
- package/dist/_chunks/{VvSelect.es-CjKMd0nH.js.map → VvSelect.es-CE4x1ww0.js.map} +1 -1
- package/dist/_chunks/VvTextarea.es-BU2vqdEQ.js +1129 -0
- package/dist/_chunks/VvTextarea.es-BU2vqdEQ.js.map +1 -0
- package/dist/_chunks/{dist-BNET2z7b.js → dist-CvMCBce7.js} +39 -21
- package/dist/_chunks/dist-CvMCBce7.js.map +1 -0
- package/dist/_chunks/dot-prop-CObyt75F.js +141 -0
- package/dist/_chunks/dot-prop-CObyt75F.js.map +1 -0
- package/dist/_chunks/{floating-ui.vue-CIKvCpTA.js → floating-ui.vue-BacoFpVq.js} +278 -305
- package/dist/_chunks/floating-ui.vue-BacoFpVq.js.map +1 -0
- package/dist/_chunks/{index.es-u1dF1xg2.js → index.es-DpqfagWZ.js} +12 -12
- package/dist/_chunks/{index.es-u1dF1xg2.js.map → index.es-DpqfagWZ.js.map} +1 -1
- package/dist/_chunks/{index.es-BYny0uhz.js → index.es-_oXVRjHy.js} +2352 -2329
- package/dist/_chunks/index.es-_oXVRjHy.js.map +1 -0
- package/dist/ai-elements.es.js +4087 -5205
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotAuth.js +1 -1
- package/dist-vue/PkChatbotEmptyState.js +1 -1
- package/dist-vue/PkChatbotFeedbackForm.js +1 -1
- package/dist-vue/PkChatbotInput.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotSteps.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/PkChatbotViewConversations.js +1 -1
- package/dist-vue/PkChatbotViewFiles.js +1 -1
- package/dist-vue/PkChatbotViewProfile.js +1 -1
- package/dist-vue/_chunks/PkChatbot-Bf5uY3cO.js +236 -0
- package/dist-vue/_chunks/{PkChatbot-BlG1WlAO.js.map → PkChatbot-Bf5uY3cO.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotAuth-C_L2xWuD.js → PkChatbotAuth-BGn2MDYD.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotAuth-C_L2xWuD.js.map → PkChatbotAuth-BGn2MDYD.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotEmptyState-BGOC6vxr.js → PkChatbotEmptyState-CPqLqXek.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotEmptyState-BGOC6vxr.js.map → PkChatbotEmptyState-CPqLqXek.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotFeedbackForm-BSe40qlc.js → PkChatbotFeedbackForm-C_y__RH8.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotFeedbackForm-BSe40qlc.js.map → PkChatbotFeedbackForm-C_y__RH8.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotInput-DTazYlPd.js → PkChatbotInput-jvb0vuak.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotInput-DTazYlPd.js.map → PkChatbotInput-jvb0vuak.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotMessages-BrufA7o1.js → PkChatbotMessages-B3G12zah.js} +246 -246
- package/dist-vue/_chunks/{PkChatbotMessages-BrufA7o1.js.map → PkChatbotMessages-B3G12zah.js.map} +1 -1
- package/dist-vue/_chunks/PkChatbotSteps-BdU6YC_N.js +172 -0
- package/dist-vue/_chunks/{PkChatbotSteps-Dv9NkYER.js.map → PkChatbotSteps-BdU6YC_N.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewChat-CAqvbbfN.js → PkChatbotViewChat-c0Ecpzoc.js} +6 -6
- package/dist-vue/_chunks/{PkChatbotViewChat-CAqvbbfN.js.map → PkChatbotViewChat-c0Ecpzoc.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewConversations-Cq41H-tc.js → PkChatbotViewConversations-BfhRCA_1.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewConversations-Cq41H-tc.js.map → PkChatbotViewConversations-BfhRCA_1.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewFiles-DNuzmBJc.js → PkChatbotViewFiles-BipRoidH.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewFiles-DNuzmBJc.js.map → PkChatbotViewFiles-BipRoidH.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewProfile-C0BXIY2N.js → PkChatbotViewProfile-DuLwYpGZ.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewProfile-C0BXIY2N.js.map → PkChatbotViewProfile-DuLwYpGZ.js.map} +1 -1
- package/{dist/_chunks/PkStreamingMarkdown-Djw604Ny.js → dist-vue/_chunks/PkStreamingMarkdown-CjBMQ18U.js} +344 -347
- package/dist-vue/_chunks/PkStreamingMarkdown-CjBMQ18U.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowArtifact-CTBwt4DN.js → PkToolShowArtifact-COwSXmF4.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowArtifact-CTBwt4DN.js.map → PkToolShowArtifact-COwSXmF4.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowContactForm-B6-MsExL.js → PkToolShowContactForm-DRRtCCxB.js} +10 -10
- package/dist-vue/_chunks/{PkToolShowContactForm-B6-MsExL.js.map → PkToolShowContactForm-DRRtCCxB.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowForm-CQuX08lk.js → PkToolShowForm-j7Ha-0X3.js} +109 -87
- package/dist-vue/_chunks/PkToolShowForm-j7Ha-0X3.js.map +1 -0
- package/dist-vue/_chunks/{PkToolShowSources-CFh-i60o.js → PkToolShowSources-BVLw4W5l.js} +43 -43
- package/dist-vue/_chunks/{PkToolShowSources-CFh-i60o.js.map → PkToolShowSources-BVLw4W5l.js.map} +1 -1
- package/dist-vue/_chunks/{createChatbotApiClient-BMZltBLh.js → createChatbotApiClient-IH6wBh4s.js} +365 -381
- package/dist-vue/_chunks/createChatbotApiClient-IH6wBh4s.js.map +1 -0
- package/dist-vue/_chunks/{index.es-XfWQ82pb.js → index.es-Bk1O0p8N.js} +166 -156
- package/dist-vue/_chunks/index.es-Bk1O0p8N.js.map +1 -0
- package/dist-vue/_chunks/{useChatbotStore-DZiorgLW.js → useChatbotStore-C3uKi2FS.js} +3 -5
- package/dist-vue/_chunks/useChatbotStore-C3uKi2FS.js.map +1 -0
- package/dist-vue/api.js +1 -1
- package/dist-vue/composables.js +2 -2
- package/dist-vue/index.js +4430 -4221
- package/dist-vue/index.js.map +1 -1
- package/dist-vue/locales.js +27 -7
- package/dist-vue/packages/components/src/PkCheckboxField.d.ts +1 -1
- package/dist-vue/packages/components/src/PkOfflineScreen.d.ts +18 -0
- package/dist-vue/packages/components/src/PkPwaNotices.d.ts +19 -0
- package/dist-vue/packages/components/src/chat/PkAgentSettingsPanel.d.ts +9 -3
- package/dist-vue/packages/components/src/index.d.ts +3 -3
- package/dist-vue/packages/composable/src/chatbot/useChatbotStore.d.ts +36 -0
- package/dist-vue/packages/composable/src/index.d.ts +1 -0
- package/dist-vue/packages/composable/src/useConnectivity.d.ts +28 -0
- package/dist-vue/packages/models/src/schema/Agent.d.ts +81 -0
- package/dist-vue/packages/models/src/schema/ReasoningChat.d.ts +24 -0
- package/dist-vue/packages/models/src/schema/SubAgent.d.ts +24 -0
- package/dist-vue/style.css +1 -1
- package/package.json +3 -3
- package/dist/_chunks/PkStreamingMarkdown-Djw604Ny.js.map +0 -1
- package/dist/_chunks/PkToolShowForm-dFuoqTPs.js.map +0 -1
- package/dist/_chunks/VvCombobox.es-CFA-K-cQ.js.map +0 -1
- package/dist/_chunks/VvInputText.es-csEQ-bSG.js.map +0 -1
- package/dist/_chunks/VvRadioGroup.es-CSNzOJKx.js.map +0 -1
- package/dist/_chunks/VvTextarea.es-eEyRRpuT.js +0 -1109
- package/dist/_chunks/VvTextarea.es-eEyRRpuT.js.map +0 -1
- package/dist/_chunks/dist-BNET2z7b.js.map +0 -1
- package/dist/_chunks/dot-prop-BXrC9bAX.js +0 -131
- package/dist/_chunks/dot-prop-BXrC9bAX.js.map +0 -1
- package/dist/_chunks/floating-ui.vue-CIKvCpTA.js.map +0 -1
- package/dist/_chunks/index.es-BYny0uhz.js.map +0 -1
- package/dist-vue/_chunks/PkChatbot-BlG1WlAO.js +0 -236
- package/dist-vue/_chunks/PkChatbotSteps-Dv9NkYER.js +0 -172
- package/dist-vue/_chunks/PkStreamingMarkdown-DEhbK-3c.js.map +0 -1
- package/dist-vue/_chunks/PkToolShowForm-CQuX08lk.js.map +0 -1
- package/dist-vue/_chunks/createChatbotApiClient-BMZltBLh.js.map +0 -1
- package/dist-vue/_chunks/index.es-XfWQ82pb.js.map +0 -1
- package/dist-vue/_chunks/useChatbotStore-DZiorgLW.js.map +0 -1
- package/dist-vue/packages/components/src/PkPwaInstallPrompt.d.ts +0 -4
- package/dist-vue/packages/components/src/PkPwaOfflineNotice.d.ts +0 -4
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A as e, C as t, H as n, Ht as r, J as i, N as a, P as o, Q as s, S as c, T as l, V as u, Wt as ee, _ as d, at as f, b as p, d as te, et as m, f as h, ft as ne, g, i as _, kt as v, mt as y, p as b, qt as x, v as S, x as C, xt as w, y as T, z as E } from "./vue.runtime.esm-bundler-DbhD_IvR.js";
|
|
2
2
|
import { r as re } from "./vue-i18n-kZs9Hfey.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { t as ie } from "./PkStreamingMarkdown-6Xx9n1ue.js";
|
|
4
|
+
import { c as D, d as ae, f as oe, n as O, o as se, p as k, s as A } from "./index.es-_oXVRjHy.js";
|
|
5
5
|
e(), v();
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region ../../packages/components/src/PkEditorRadioButtons.vue
|
|
@@ -28,7 +28,7 @@ var ce = /* @__PURE__ */ l({
|
|
|
28
28
|
setup(e) {
|
|
29
29
|
let t = e, r = i(e, "modelValue"), a = g(() => [...t.modifiers ? Array.isArray(t.modifiers) ? t.modifiers : [t.modifiers] : [], "button"]);
|
|
30
30
|
return (t, i) => {
|
|
31
|
-
let s =
|
|
31
|
+
let s = D, l = O;
|
|
32
32
|
return E(), S(l, {
|
|
33
33
|
modelValue: r.value,
|
|
34
34
|
"onUpdate:modelValue": i[0] ||= (e) => r.value = e,
|
|
@@ -118,22 +118,22 @@ var ue = {
|
|
|
118
118
|
}, fe = {
|
|
119
119
|
key: 1,
|
|
120
120
|
class: "flex flex-col gap-4 p-sm"
|
|
121
|
-
}, pe = { class: "flex justify-between text-10 text-word-3" },
|
|
121
|
+
}, pe = { class: "flex justify-between text-10 text-word-3" }, me = { class: "h-4 bg-surface-3 rounded-full overflow-hidden" }, j = { class: "px-sm py-16 flex flex-col gap-12" }, M = { class: "leading-normal text-12" }, N = { class: "font-semibold" }, P = { class: "text-12" }, F = { class: "font-semibold" }, I = {
|
|
122
122
|
key: 0,
|
|
123
123
|
class: "text-word-3"
|
|
124
|
-
},
|
|
124
|
+
}, L = { class: "text-12" }, R = { class: "font-semibold" }, z = {
|
|
125
125
|
key: 0,
|
|
126
126
|
class: "text-word-3"
|
|
127
|
-
},
|
|
127
|
+
}, he = {
|
|
128
128
|
key: 2,
|
|
129
129
|
class: "flex flex-col gap-6 w-full"
|
|
130
|
-
},
|
|
130
|
+
}, B = {
|
|
131
131
|
key: 0,
|
|
132
132
|
class: "px-sm pb-sm border-t border-surface-3"
|
|
133
|
-
},
|
|
133
|
+
}, ge = {
|
|
134
134
|
key: 1,
|
|
135
135
|
class: "px-sm py-10 bg-surface border-t border-surface-3 flex justify-between gap-12"
|
|
136
|
-
},
|
|
136
|
+
}, _e = { key: 1 }, ve = { class: "px-sm py-12 bg-surface space-y-10" }, ye = { class: "flex flex-col gap-8" }, be = { class: "text-12 text-word-3" }, xe = { class: "text-12 text-word-2 font-semibold" }, Se = { class: "px-sm py-12 bg-surface border-t border-surface-3 flex items-center gap-10" }, Ce = { class: "w-20 h-20 rounded-full border border-success text-success flex items-center justify-center" }, we = { class: "flex flex-col" }, Te = { class: "font-semibold text-12 text-word-1 leading-tight" }, V = /* @__PURE__ */ l({
|
|
137
137
|
__name: "PkToolShowForm",
|
|
138
138
|
props: {
|
|
139
139
|
part: { type: null },
|
|
@@ -142,143 +142,164 @@ var ue = {
|
|
|
142
142
|
emits: ["select"],
|
|
143
143
|
setup(e, { emit: n }) {
|
|
144
144
|
let i = e, a = n, { t: o, d: c } = re({ useScope: "global" }), l = g(() => JSON.parse(JSON.stringify(i.part))), f = g(() => l.value.toolName === "showMultipleChoice" || l.value.type === "tool-showMultipleChoice"), _ = g(() => l.value.state === "input-available"), v = g(() => {
|
|
145
|
-
let e =
|
|
145
|
+
let e = V.value;
|
|
146
146
|
return e ? k.value.length === 1 && !e.allowFreeformInput && !i.allowCustomAnswer : !1;
|
|
147
|
-
}), D = g(() => f.value && k.value.length === 1 && !
|
|
147
|
+
}), D = g(() => f.value && k.value.length === 1 && !V.value?.multiSelect), O = g(() => !!V.value?.options && !V.value?.multiSelect && (v.value || D.value)), k = g(() => {
|
|
148
148
|
let e = l.value.input;
|
|
149
149
|
return e?.steps?.length ? e.steps : e?.question && e?.options ? [{
|
|
150
150
|
id: "legacy",
|
|
151
151
|
question: e.question,
|
|
152
152
|
options: e.options.map((e) => typeof e == "string" ? { label: e } : e)
|
|
153
153
|
}] : [];
|
|
154
|
-
}), A = y(0),
|
|
154
|
+
}), A = y(0), V = g(() => k.value[A.value]), H = g(() => A.value > 0), U = g(() => A.value < k.value.length - 1), Ee = g(() => k.value.length > 1), W = g(() => Ee.value ? Math.round((A.value + 1) / k.value.length * 100) : null), G = ne({}), K = y("");
|
|
155
|
+
s(A, () => {
|
|
156
|
+
K.value = "";
|
|
157
|
+
});
|
|
158
|
+
let q = g({
|
|
155
159
|
get: () => {
|
|
156
|
-
let e =
|
|
160
|
+
let e = V.value ? G[V.value.id] : void 0;
|
|
157
161
|
if (!(e == null || Array.isArray(e))) return e;
|
|
158
162
|
},
|
|
159
163
|
set: (e) => {
|
|
160
|
-
|
|
164
|
+
V.value && (G[V.value.id] = e ?? null);
|
|
161
165
|
}
|
|
162
|
-
}),
|
|
166
|
+
}), J = g({
|
|
163
167
|
get: () => {
|
|
164
|
-
let e =
|
|
168
|
+
let e = V.value ? G[V.value.id] : void 0;
|
|
165
169
|
return Array.isArray(e) ? e : [];
|
|
166
170
|
},
|
|
167
171
|
set: (e) => {
|
|
168
|
-
|
|
172
|
+
V.value && (G[V.value.id] = e ?? []);
|
|
169
173
|
}
|
|
170
174
|
});
|
|
175
|
+
function Y(e) {
|
|
176
|
+
if (!e || typeof e == "string") return;
|
|
177
|
+
let t = e.answers;
|
|
178
|
+
return Array.isArray(t) ? t : void 0;
|
|
179
|
+
}
|
|
171
180
|
s(() => l.value.output, (e) => {
|
|
172
|
-
if (e)
|
|
173
|
-
|
|
174
|
-
|
|
181
|
+
if (!e) return;
|
|
182
|
+
if (typeof e == "string") {
|
|
183
|
+
k.value.length === 1 && (G[k.value[0].id] = e);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
let t = Y(e);
|
|
187
|
+
if (t) {
|
|
188
|
+
for (let e of t) G[e.id] = e.value;
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
let n = e;
|
|
192
|
+
for (let e of k.value) {
|
|
193
|
+
let t = n[e.id];
|
|
194
|
+
t !== void 0 && (G[e.id] = t);
|
|
175
195
|
}
|
|
176
196
|
}, { immediate: !0 }), s(g(() => {
|
|
177
197
|
let e = l.value.output;
|
|
178
|
-
if (e)
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
198
|
+
if (!e) return;
|
|
199
|
+
if (typeof e == "string") return e;
|
|
200
|
+
let t = Y(e);
|
|
201
|
+
if (t?.length === 1) {
|
|
202
|
+
let e = t[0].value;
|
|
203
|
+
return Array.isArray(e) ? e.join(", ") : String(e);
|
|
184
204
|
}
|
|
185
205
|
}), (e) => {
|
|
186
|
-
!e || !
|
|
206
|
+
!e || !V.value || (V.value.options ?? []).map((e) => e.label).includes(e) || (K.value = e);
|
|
187
207
|
}, { immediate: !0 });
|
|
188
|
-
let X = g(() =>
|
|
208
|
+
let X = g(() => V.value?.options ? V.value.options.map((e) => ({
|
|
189
209
|
label: e.label,
|
|
190
210
|
value: e.label,
|
|
191
211
|
description: e.description
|
|
192
212
|
})) : []);
|
|
193
213
|
function Z() {
|
|
194
|
-
if (
|
|
214
|
+
if (K.value.trim()) {
|
|
195
215
|
$();
|
|
196
216
|
return;
|
|
197
217
|
}
|
|
198
|
-
|
|
218
|
+
U.value ? A.value++ : Q();
|
|
199
219
|
}
|
|
200
|
-
function
|
|
201
|
-
|
|
220
|
+
function De() {
|
|
221
|
+
H.value && A.value--;
|
|
202
222
|
}
|
|
203
223
|
function Q() {
|
|
204
224
|
if (!_.value) return;
|
|
205
225
|
let e = k.value.map((e) => ({
|
|
206
226
|
id: e.id,
|
|
207
|
-
value:
|
|
227
|
+
value: G[e.id] ?? null
|
|
208
228
|
}));
|
|
209
|
-
if (D.value && !
|
|
229
|
+
if (D.value && !V.value?.allowFreeformInput) {
|
|
210
230
|
let t = e[0].value;
|
|
211
231
|
a("select", Array.isArray(t) ? t[0] : t);
|
|
212
232
|
} else a("select", { answers: e });
|
|
213
233
|
}
|
|
214
234
|
function $() {
|
|
215
|
-
let e =
|
|
216
|
-
e && (
|
|
235
|
+
let e = K.value.trim();
|
|
236
|
+
e && (G[V.value.id] = e, K.value = "", k.value.length === 1 ? Q() : Z());
|
|
217
237
|
}
|
|
218
|
-
function
|
|
238
|
+
function Oe() {
|
|
219
239
|
_.value && (v.value || D.value) && Q();
|
|
220
240
|
}
|
|
221
|
-
function
|
|
222
|
-
let t =
|
|
241
|
+
function ke(e) {
|
|
242
|
+
let t = G[e.id];
|
|
223
243
|
return t == null ? "—" : Array.isArray(t) ? t.join(", ") : e.type === "date" ? c(new Date(t), "short") : t;
|
|
224
244
|
}
|
|
225
245
|
return (e, n) => {
|
|
226
|
-
let i =
|
|
246
|
+
let i = se, a = ae, s = oe;
|
|
227
247
|
return k.value.length ? (E(), p("div", ue, [l.value.input?.title || _.value && k.value.length > 1 ? (E(), p("div", de, [l.value.input?.title ? (E(), p("div", {
|
|
228
248
|
key: 0,
|
|
229
249
|
class: r(["px-sm py-10 font-bold", { "border-b border-surface-3": _.value && k.value.length > 1 }])
|
|
230
250
|
}, x(l.value.input?.title), 3)) : T("", !0), _.value && k.value.length > 1 ? (E(), p("div", fe, [d("div", pe, [d("span", null, x(w(o)("showForm.step", {
|
|
231
251
|
current: A.value + 1,
|
|
232
252
|
total: k.value.length
|
|
233
|
-
})), 1), d("span", null, x(
|
|
253
|
+
})), 1), d("span", null, x(W.value) + "%", 1)]), d("div", me, [d("div", {
|
|
234
254
|
class: "h-full bg-word-4 transition-all duration-300",
|
|
235
|
-
style: ee({ width: `${
|
|
255
|
+
style: ee({ width: `${W.value}%` })
|
|
236
256
|
}, null, 4)])])) : T("", !0)])) : T("", !0), _.value ? (E(), p(b, { key: 1 }, [
|
|
237
|
-
d("div",
|
|
257
|
+
d("div", j, [d("div", M, [d("strong", N, x(V.value.question), 1), V.value.message ? (E(), S(ie, {
|
|
238
258
|
key: 0,
|
|
239
|
-
markdown:
|
|
259
|
+
markdown: V.value.message,
|
|
240
260
|
class: "text-word-2 mt-4"
|
|
241
|
-
}, null, 8, ["markdown"])) : T("", !0)]),
|
|
261
|
+
}, null, 8, ["markdown"])) : T("", !0)]), V.value.options && V.value.multiSelect ? (E(), S(le, {
|
|
242
262
|
key: 0,
|
|
243
|
-
modelValue:
|
|
244
|
-
"onUpdate:modelValue": n[0] ||= (e) =>
|
|
245
|
-
name:
|
|
263
|
+
modelValue: J.value,
|
|
264
|
+
"onUpdate:modelValue": n[0] ||= (e) => J.value = e,
|
|
265
|
+
name: V.value.id,
|
|
246
266
|
options: X.value,
|
|
247
267
|
readonly: !_.value,
|
|
248
268
|
class: "mb-0",
|
|
249
269
|
vertical: ""
|
|
250
270
|
}, C({ _: 2 }, [u(X.value, (e) => ({
|
|
251
271
|
name: e.value,
|
|
252
|
-
fn: m(() => [d("div",
|
|
272
|
+
fn: m(() => [d("div", P, [d("div", F, x(e.label), 1), e.description ? (E(), p("div", I, x(e.description), 1)) : T("", !0)])])
|
|
253
273
|
}))]), 1032, [
|
|
254
274
|
"modelValue",
|
|
255
275
|
"name",
|
|
256
276
|
"options",
|
|
257
277
|
"readonly"
|
|
258
|
-
])) :
|
|
278
|
+
])) : V.value.options && !V.value.multiSelect ? (E(), S(ce, {
|
|
259
279
|
key: 1,
|
|
260
|
-
modelValue:
|
|
261
|
-
"onUpdate:modelValue": [n[1] ||= (e) =>
|
|
262
|
-
name:
|
|
280
|
+
modelValue: q.value,
|
|
281
|
+
"onUpdate:modelValue": [n[1] ||= (e) => q.value = e, Oe],
|
|
282
|
+
name: V.value.id,
|
|
263
283
|
options: X.value,
|
|
264
284
|
readonly: !_.value,
|
|
265
285
|
vertical: "",
|
|
266
286
|
class: "mb-0"
|
|
267
287
|
}, C({ _: 2 }, [u(X.value, (e) => ({
|
|
268
288
|
name: e.value,
|
|
269
|
-
fn: m(() => [d("div",
|
|
289
|
+
fn: m(() => [d("div", L, [d("div", R, x(e.label), 1), e.description ? (E(), p("div", z, x(e.description), 1)) : T("", !0)])])
|
|
270
290
|
}))]), 1032, [
|
|
271
291
|
"modelValue",
|
|
272
292
|
"name",
|
|
273
293
|
"options",
|
|
274
294
|
"readonly"
|
|
275
|
-
])) :
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
295
|
+
])) : V.value.options ? T("", !0) : (E(), p("div", he, [(E(), S(i, {
|
|
296
|
+
key: V.value.id,
|
|
297
|
+
modelValue: q.value,
|
|
298
|
+
"onUpdate:modelValue": n[2] ||= (e) => q.value = e,
|
|
299
|
+
placeholder: V.value.placeholder || w(o)("placeholder.insert"),
|
|
300
|
+
type: V.value.type,
|
|
280
301
|
class: "w-full",
|
|
281
|
-
name:
|
|
302
|
+
name: V.value.id,
|
|
282
303
|
modifiers: "compact rounded",
|
|
283
304
|
disabled: !_.value,
|
|
284
305
|
onKeyup: te(Z, ["enter"])
|
|
@@ -288,52 +309,53 @@ var ue = {
|
|
|
288
309
|
"type",
|
|
289
310
|
"name",
|
|
290
311
|
"disabled"
|
|
291
|
-
])]))]),
|
|
292
|
-
|
|
312
|
+
]))]))]),
|
|
313
|
+
V.value.allowFreeformInput && V.value.options ? (E(), p("div", B, [d("form", {
|
|
293
314
|
class: "flex gap-xs pt-sm",
|
|
294
315
|
onSubmit: h($, ["prevent"])
|
|
295
|
-
}, [
|
|
296
|
-
|
|
297
|
-
|
|
316
|
+
}, [(E(), S(i, {
|
|
317
|
+
key: `${V.value.id}-custom`,
|
|
318
|
+
modelValue: K.value,
|
|
319
|
+
"onUpdate:modelValue": n[3] ||= (e) => K.value = e,
|
|
298
320
|
class: "flex-1",
|
|
299
|
-
name: `${
|
|
321
|
+
name: `${V.value.id}-custom`,
|
|
300
322
|
modifiers: "compact rounded",
|
|
301
323
|
disabled: !_.value,
|
|
302
|
-
placeholder:
|
|
324
|
+
placeholder: V.value.placeholder || w(o)("showForm.otherPlaceholder")
|
|
303
325
|
}, null, 8, [
|
|
304
326
|
"modelValue",
|
|
305
327
|
"name",
|
|
306
328
|
"disabled",
|
|
307
329
|
"placeholder"
|
|
308
|
-
])], 32)])) : T("", !0),
|
|
309
|
-
O.value ? T("", !0) : (E(), p("div",
|
|
330
|
+
]))], 32)])) : T("", !0),
|
|
331
|
+
O.value ? T("", !0) : (E(), p("div", ge, [H.value ? (E(), S(a, {
|
|
310
332
|
key: 0,
|
|
311
333
|
modifiers: "action-quiet",
|
|
312
334
|
icon: "ri:arrow-left-s-line",
|
|
313
335
|
label: w(o)("action.back"),
|
|
314
|
-
onClick: h(
|
|
315
|
-
}, null, 8, ["label"])) : (E(), p("div",
|
|
316
|
-
modifiers:
|
|
317
|
-
icon:
|
|
336
|
+
onClick: h(De, ["stop"])
|
|
337
|
+
}, null, 8, ["label"])) : (E(), p("div", _e)), t(a, {
|
|
338
|
+
modifiers: U.value ? "action-quiet" : "action-primary",
|
|
339
|
+
icon: U.value ? "ri:arrow-right-s-line" : "ri:send-plane-2-line",
|
|
318
340
|
"icon-position": "right",
|
|
319
|
-
label:
|
|
341
|
+
label: U.value ? w(o)("action.next") : w(o)("action.submit"),
|
|
320
342
|
onClick: h(Z, ["stop"])
|
|
321
343
|
}, null, 8, [
|
|
322
344
|
"modifiers",
|
|
323
345
|
"icon",
|
|
324
346
|
"label"
|
|
325
347
|
])]))
|
|
326
|
-
], 64)) : (E(), p(b, { key: 2 }, [d("div",
|
|
348
|
+
], 64)) : (E(), p(b, { key: 2 }, [d("div", ve, [d("ul", ye, [(E(!0), p(b, null, u(k.value, (e) => (E(), p("li", {
|
|
327
349
|
key: e.id,
|
|
328
350
|
class: "leading-normal"
|
|
329
|
-
}, [d("div",
|
|
351
|
+
}, [d("div", be, x(e.question), 1), d("span", xe, x(ke(e)), 1)]))), 128))])]), d("div", Se, [d("div", Ce, [t(s, {
|
|
330
352
|
name: "ri:check-line",
|
|
331
353
|
class: "text-12"
|
|
332
|
-
})]), d("div",
|
|
354
|
+
})]), d("div", we, [d("span", Te, x(w(o)("showForm.completed")), 1)])])], 64))])) : T("", !0);
|
|
333
355
|
};
|
|
334
356
|
}
|
|
335
357
|
});
|
|
336
358
|
//#endregion
|
|
337
|
-
export {
|
|
359
|
+
export { V as default };
|
|
338
360
|
|
|
339
|
-
//# sourceMappingURL=PkToolShowForm-
|
|
361
|
+
//# sourceMappingURL=PkToolShowForm-BP8asXtz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PkToolShowForm-BP8asXtz.js","names":[],"sources":["../../../../packages/components/src/PkEditorRadioButtons.vue","../../../../packages/components/src/PkEditorRadioButtons.vue","../../../../packages/components/src/PkEditorCheckboxButtons.vue","../../../../packages/components/src/PkEditorCheckboxButtons.vue","../../../../packages/components/src/chat/PkToolShowForm.vue","../../../../packages/components/src/chat/PkToolShowForm.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n import { computed } from 'vue'\n\n const props = defineProps<{\n name: string\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n modifiers?: string | string[]\n }>()\n\n const modelValue = defineModel<\n string | number | boolean | symbol | unknown[] | undefined\n >()\n\n const radioModifiers = computed(() => {\n const toReturn = props.modifiers\n ? Array.isArray(props.modifiers)\n ? props.modifiers\n : [props.modifiers]\n : []\n return [...toReturn, 'button']\n })\n</script>\n\n<template>\n <VvRadioGroup v-model=\"modelValue\" :name modifiers=\"buttons\">\n <VvRadio\n v-for=\"(option, key) in options\"\n :key\n :name\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n :modifiers=\"radioModifiers\">\n <slot :name=\"option.value\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvRadio>\n </VvRadioGroup>\n</template>\n","<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n import { computed } from 'vue'\n\n const props = defineProps<{\n name: string\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n modifiers?: string | string[]\n }>()\n\n const modelValue = defineModel<\n string | number | boolean | symbol | unknown[] | undefined\n >()\n\n const radioModifiers = computed(() => {\n const toReturn = props.modifiers\n ? Array.isArray(props.modifiers)\n ? props.modifiers\n : [props.modifiers]\n : []\n return [...toReturn, 'button']\n })\n</script>\n\n<template>\n <VvRadioGroup v-model=\"modelValue\" :name modifiers=\"buttons\">\n <VvRadio\n v-for=\"(option, key) in options\"\n :key\n :name\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n :modifiers=\"radioModifiers\">\n <slot :name=\"option.value\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvRadio>\n </VvRadioGroup>\n</template>\n","<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n\n defineProps<{\n name: string\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n }>()\n\n const modelValue = defineModel<unknown[] | undefined>()\n</script>\n\n<template>\n <VvCheckboxGroup v-model=\"modelValue\" :name modifiers=\"buttons\">\n <VvCheckbox\n v-for=\"(option, key) in options\"\n :key\n :name\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n modifiers=\"button\">\n <slot :name=\"String(option.value)\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvCheckbox>\n </VvCheckboxGroup>\n</template>\n","<script setup lang=\"ts\">\n import type { Option } from '@volverjs/ui-vue'\n\n defineProps<{\n name: string\n required?: boolean\n options: Option[]\n readonly?: boolean\n disabled?: boolean\n }>()\n\n const modelValue = defineModel<unknown[] | undefined>()\n</script>\n\n<template>\n <VvCheckboxGroup v-model=\"modelValue\" :name modifiers=\"buttons\">\n <VvCheckbox\n v-for=\"(option, key) in options\"\n :key\n :name\n :required\n :readonly\n :disabled\n :value=\"option.value\"\n modifiers=\"button\">\n <slot :name=\"String(option.value)\" v-bind=\"{ option }\">\n {{ option.label }}\n </slot>\n </VvCheckbox>\n </VvCheckboxGroup>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkEditorRadioButtons from '../PkEditorRadioButtons.vue'\n import PkEditorCheckboxButtons from '../PkEditorCheckboxButtons.vue'\n\n // --- Types ---\n\n interface FormOption {\n label: string\n description?: string\n }\n\n interface FormStep {\n id: string\n question: string\n message?: string\n type?: 'text' | 'number' | 'date'\n options?: FormOption[]\n multiSelect?: boolean\n allowFreeformInput?: boolean\n placeholder?: string\n }\n\n interface FormAnswer {\n id: string\n value: string | string[] | number | null\n }\n\n interface ToolPartShape {\n state?: 'input-available' | 'output-available'\n toolCallId?: string\n // AI SDK v5 encodes the tool name in `type` (e.g. 'tool-showMultipleChoice').\n // `toolName` is kept for backward compatibility but is normally absent.\n type?: string\n toolName?: string\n input?: {\n title?: string\n steps?: FormStep[]\n // Legacy showMultipleChoice fields\n question?: string\n options?: (string | FormOption)[]\n }\n // The web card submits `{ answers: [...] }`; the platform channels\n // (Teams modal) submit a flat record keyed by step id.\n output?: string | { answers: FormAnswer[] } | Record<string, unknown>\n }\n\n type AnswerValue = string | string[] | number | null\n\n // --- Props & Emits ---\n\n const props = defineProps<{\n part: unknown\n allowCustomAnswer?: boolean\n }>()\n\n const emit = defineEmits<{\n select: [answer: string | { answers: FormAnswer[] }]\n }>()\n\n const { t: $t, d: $d } = useI18n({ useScope: 'global' })\n\n // --- Parsed tool part ---\n\n const toolPart = computed(\n () => JSON.parse(JSON.stringify(props.part)) as ToolPartShape,\n )\n\n const isLegacy = computed(\n () =>\n toolPart.value.toolName === 'showMultipleChoice' ||\n toolPart.value.type === 'tool-showMultipleChoice',\n )\n\n const isInteractive = computed(\n () => toolPart.value.state === 'input-available',\n )\n\n /** Single-step with no custom-answer and no freeform → auto-submit on option pick */\n const isAutoSubmitStep = computed(() => {\n const step = currentStep.value\n if (!step) return false\n return (\n steps.value.length === 1 &&\n !step.allowFreeformInput &&\n !props.allowCustomAnswer\n )\n })\n\n /** Legacy tool should auto-submit on option pick regardless of allowCustomAnswer */\n const isLegacyAutoSubmit = computed(\n () =>\n isLegacy.value &&\n steps.value.length === 1 &&\n !currentStep.value?.multiSelect,\n )\n\n /**\n * True only for the steps that send themselves as soon as an option is\n * picked: the single case where the footer button would be redundant.\n * Every other shape needs it, single-step forms included: with\n * `allowFreeformInput` (or `allowCustomAnswer`) the radio pick no longer\n * auto-submits, so without the footer the user was left with a chosen\n * option and no way to send it.\n */\n const isSelfSubmitting = computed(\n () =>\n Boolean(currentStep.value?.options) &&\n !currentStep.value?.multiSelect &&\n (isAutoSubmitStep.value || isLegacyAutoSubmit.value),\n )\n\n // --- Steps ---\n\n const steps = computed<FormStep[]>(() => {\n const input = toolPart.value.input\n if (input?.steps?.length) {\n return input.steps\n }\n // Legacy showMultipleChoice → normalize into a single step\n if (input?.question && input?.options) {\n return [\n {\n id: 'legacy',\n question: input.question,\n options: input.options.map((o) =>\n typeof o === 'string' ? { label: o } : o,\n ),\n },\n ]\n }\n return []\n })\n\n // --- Navigation state ---\n\n const currentStepIndex = ref(0)\n const currentStep = computed(() => steps.value[currentStepIndex.value])\n const canGoBack = computed(() => currentStepIndex.value > 0)\n const canGoNext = computed(\n () => currentStepIndex.value < steps.value.length - 1,\n )\n const isMultiStep = computed(() => steps.value.length > 1)\n\n const progress = computed(() => {\n if (!isMultiStep.value) return null\n return Math.round(\n ((currentStepIndex.value + 1) / steps.value.length) * 100,\n )\n })\n\n // --- Answers ---\n\n const answers = reactive<Record<string, AnswerValue>>({})\n const customAnswer = ref('')\n\n // The freeform field belongs to the step showing it: text left behind\n // (unsubmitted, or arriving from a late input update) must not follow the\n // user to the next or previous question.\n watch(currentStepIndex, () => {\n customAnswer.value = ''\n })\n\n // Single scalar answer shared by radio buttons and freeform text/number/date inputs.\n const scalarValue = computed<string | number | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStep.value.id]\n : undefined\n if (val == null || Array.isArray(val)) return undefined\n return val\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStep.value.id] = val ?? null\n }\n },\n })\n\n const activeCheckboxValue = computed<unknown[] | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStep.value.id]\n : undefined\n return Array.isArray(val) ? val : []\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStep.value.id] = (val as string[]) ?? []\n }\n },\n })\n\n // --- Initialize answers from existing output ---\n\n /** The `{ answers: [...] }` list, when the output carries one. */\n function outputAnswers(output: ToolPartShape['output']) {\n if (!output || typeof output === 'string') return undefined\n const list = (output as { answers?: unknown }).answers\n return Array.isArray(list) ? (list as FormAnswer[]) : undefined\n }\n\n watch(\n () => toolPart.value.output,\n (output) => {\n if (!output) return\n if (typeof output === 'string') {\n if (steps.value.length === 1) {\n answers[steps.value[0].id] = output\n }\n return\n }\n const list = outputAnswers(output)\n if (list) {\n for (const a of list) {\n answers[a.id] = a.value\n }\n return\n }\n // Forms answered on a platform channel come back as a flat record\n // keyed by step id: without this the read-only summary showed every\n // answer as a placeholder.\n const record = output as Record<string, unknown>\n for (const step of steps.value) {\n const value = record[step.id]\n if (value !== undefined) {\n answers[step.id] = value as AnswerValue\n }\n }\n },\n { immediate: true },\n )\n\n // --- Restore custom answer from output when it doesn't match any option ---\n\n const normalizedOutput = computed(() => {\n const out = toolPart.value.output\n if (!out) return undefined\n if (typeof out === 'string') return out\n const list = outputAnswers(out)\n if (list?.length === 1) {\n const val = list[0].value\n return Array.isArray(val) ? val.join(', ') : String(val)\n }\n return undefined\n })\n\n watch(\n normalizedOutput,\n (value) => {\n if (!value || !currentStep.value) return\n const optionLabels = (currentStep.value.options ?? []).map(\n (o) => o.label,\n )\n if (!optionLabels.includes(value)) {\n customAnswer.value = value\n }\n },\n { immediate: true },\n )\n\n // --- Option mapping for radio/checkbox components ---\n\n const radioOptions = computed(() => {\n if (!currentStep.value?.options) return []\n return currentStep.value.options.map((option) => ({\n label: option.label,\n value: option.label,\n description: option.description,\n }))\n })\n\n // --- Navigation & Submission ---\n\n /** Footer button, and Enter on a pure freeform step. */\n function goNext() {\n // A typed freeform answer wins over the picked option: it is the more\n // recent intent, and the footer button is now the visible way to send\n // it (the freeform field only submits on Enter).\n if (customAnswer.value.trim()) {\n submitCustomAnswer()\n return\n }\n if (canGoNext.value) {\n currentStepIndex.value++\n } else {\n submitForm()\n }\n }\n\n function goBack() {\n if (canGoBack.value) {\n currentStepIndex.value--\n }\n }\n\n function submitForm() {\n if (!isInteractive.value) return\n\n const finalAnswers: FormAnswer[] = steps.value.map((step) => ({\n id: step.id,\n value: answers[step.id] ?? null,\n }))\n\n // Legacy backward compatibility: single-step, single-select → return plain string\n if (\n isLegacyAutoSubmit.value &&\n !currentStep.value?.allowFreeformInput\n ) {\n const val = finalAnswers[0].value\n emit('select', Array.isArray(val) ? val[0] : (val as string))\n } else {\n emit('select', { answers: finalAnswers })\n }\n }\n\n /** Enter inside the freeform field shown alongside the options. */\n function submitCustomAnswer() {\n const value = customAnswer.value.trim()\n if (!value) return\n\n answers[currentStep.value.id] = value\n // Cleared before navigating: `goNext()` reads it back to route a typed\n // answer here, so leaving it set would recurse.\n customAnswer.value = ''\n if (steps.value.length === 1) {\n submitForm()\n } else {\n goNext()\n }\n }\n\n function onRadioChange() {\n if (!isInteractive.value) return\n if (isAutoSubmitStep.value || isLegacyAutoSubmit.value) {\n submitForm()\n }\n }\n\n // --- Summary helpers ---\n\n function getSummaryValue(step: FormStep) {\n const val = answers[step.id]\n if (val == null) return '—'\n if (Array.isArray(val)) return val.join(', ')\n if (step.type === 'date') return $d(new Date(val), 'short')\n return val\n }\n</script>\n\n<template>\n <div\n v-if=\"steps.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden flex flex-col transition-all bg-surface\">\n <!-- Header -->\n <div\n v-if=\"toolPart.input?.title || (isInteractive && steps.length > 1)\"\n class=\"text-12 border-b border-surface-3 text-word-3 bg-surface-1\">\n <div\n v-if=\"toolPart.input?.title\"\n class=\"px-sm py-10 font-bold\"\n :class=\"{\n 'border-b border-surface-3':\n isInteractive && steps.length > 1,\n }\">\n {{ toolPart.input?.title }}\n </div>\n <!-- Progress for multi-step -->\n <div\n v-if=\"isInteractive && steps.length > 1\"\n class=\"flex flex-col gap-4 p-sm\">\n <div class=\"flex justify-between text-10 text-word-3\">\n <span>\n {{\n $t('showForm.step', {\n current: currentStepIndex + 1,\n total: steps.length,\n })\n }}\n </span>\n <span>{{ progress }}%</span>\n </div>\n <div class=\"h-4 bg-surface-3 rounded-full overflow-hidden\">\n <div\n class=\"h-full bg-word-4 transition-all duration-300\"\n :style=\"{ width: `${progress}%` }\"></div>\n </div>\n </div>\n </div>\n\n <!-- Input Available State -->\n <template v-if=\"isInteractive\">\n <!-- Current Step Content -->\n <div class=\"px-sm py-16 flex flex-col gap-12\">\n <div class=\"leading-normal text-12\">\n <strong class=\"font-semibold\">\n {{ currentStep.question }}\n </strong>\n <PkStreamingMarkdown\n v-if=\"currentStep.message\"\n :markdown=\"currentStep.message\"\n class=\"text-word-2 mt-4\" />\n </div>\n\n <!-- Checkbox list for multi-select -->\n <PkEditorCheckboxButtons\n v-if=\"currentStep.options && currentStep.multiSelect\"\n v-model=\"activeCheckboxValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n class=\"mb-0\"\n vertical>\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorCheckboxButtons>\n\n <!-- Radio buttons for single-select -->\n <PkEditorRadioButtons\n v-else-if=\"currentStep.options && !currentStep.multiSelect\"\n v-model=\"scalarValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n vertical\n class=\"mb-0\"\n @update:model-value=\"onRadioChange\">\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorRadioButtons>\n\n <!-- Pure Freeform Input (text, number, date) -->\n <div\n v-else-if=\"!currentStep.options\"\n class=\"flex flex-col gap-6 w-full\">\n <VvInputText\n :key=\"currentStep.id\"\n v-model=\"scalarValue\"\n :placeholder=\"\n currentStep.placeholder || $t('placeholder.insert')\n \"\n :type=\"currentStep.type\"\n class=\"w-full\"\n :name=\"currentStep.id\"\n modifiers=\"compact rounded\"\n :disabled=\"!isInteractive\"\n @keyup.enter=\"goNext\" />\n </div>\n </div>\n\n <!-- Custom footer freeform input (shown alongside options when allowFreeformInput) -->\n <div\n v-if=\"currentStep.allowFreeformInput && currentStep.options\"\n class=\"px-sm pb-sm border-t border-surface-3\">\n <form\n class=\"flex gap-xs pt-sm\"\n @submit.prevent=\"submitCustomAnswer\">\n <VvInputText\n :key=\"`${currentStep.id}-custom`\"\n v-model=\"customAnswer\"\n class=\"flex-1\"\n :name=\"`${currentStep.id}-custom`\"\n modifiers=\"compact rounded\"\n :disabled=\"!isInteractive\"\n :placeholder=\"\n currentStep.placeholder ||\n $t('showForm.otherPlaceholder')\n \" />\n </form>\n </div>\n\n <!-- Footer navigation: shown for every step that does not submit\n itself on option pick (see `isSelfSubmitting`). -->\n <div\n v-if=\"!isSelfSubmitting\"\n class=\"px-sm py-10 bg-surface border-t border-surface-3 flex justify-between gap-12\">\n <VvButton\n v-if=\"canGoBack\"\n modifiers=\"action-quiet\"\n icon=\"ri:arrow-left-s-line\"\n :label=\"$t('action.back')\"\n @click.stop=\"goBack\" />\n <div v-else></div>\n\n <VvButton\n :modifiers=\"canGoNext ? 'action-quiet' : 'action-primary'\"\n :icon=\"\n canGoNext\n ? 'ri:arrow-right-s-line'\n : 'ri:send-plane-2-line'\n \"\n icon-position=\"right\"\n :label=\"canGoNext ? $t('action.next') : $t('action.submit')\"\n @click.stop=\"goNext\" />\n </div>\n </template>\n\n <!-- Output Available State (Multi-step Summary) -->\n <template v-else>\n <div class=\"px-sm py-12 bg-surface space-y-10\">\n <ul class=\"flex flex-col gap-8\">\n <li\n v-for=\"step in steps\"\n :key=\"step.id\"\n class=\"leading-normal\">\n <div class=\"text-12 text-word-3\">\n {{ step.question }}\n </div>\n <span class=\"text-12 text-word-2 font-semibold\">\n {{ getSummaryValue(step) }}\n </span>\n </li>\n </ul>\n </div>\n <div\n class=\"px-sm py-12 bg-surface border-t border-surface-3 flex items-center gap-10\">\n <div\n class=\"w-20 h-20 rounded-full border border-success text-success flex items-center justify-center\">\n <VvIcon name=\"ri:check-line\" class=\"text-12\" />\n </div>\n <div class=\"flex flex-col\">\n <span\n class=\"font-semibold text-12 text-word-1 leading-tight\">\n {{ $t('showForm.completed') }}\n </span>\n </div>\n </div>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive, watch } from 'vue'\n import { useI18n } from 'vue-i18n'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkEditorRadioButtons from '../PkEditorRadioButtons.vue'\n import PkEditorCheckboxButtons from '../PkEditorCheckboxButtons.vue'\n\n // --- Types ---\n\n interface FormOption {\n label: string\n description?: string\n }\n\n interface FormStep {\n id: string\n question: string\n message?: string\n type?: 'text' | 'number' | 'date'\n options?: FormOption[]\n multiSelect?: boolean\n allowFreeformInput?: boolean\n placeholder?: string\n }\n\n interface FormAnswer {\n id: string\n value: string | string[] | number | null\n }\n\n interface ToolPartShape {\n state?: 'input-available' | 'output-available'\n toolCallId?: string\n // AI SDK v5 encodes the tool name in `type` (e.g. 'tool-showMultipleChoice').\n // `toolName` is kept for backward compatibility but is normally absent.\n type?: string\n toolName?: string\n input?: {\n title?: string\n steps?: FormStep[]\n // Legacy showMultipleChoice fields\n question?: string\n options?: (string | FormOption)[]\n }\n // The web card submits `{ answers: [...] }`; the platform channels\n // (Teams modal) submit a flat record keyed by step id.\n output?: string | { answers: FormAnswer[] } | Record<string, unknown>\n }\n\n type AnswerValue = string | string[] | number | null\n\n // --- Props & Emits ---\n\n const props = defineProps<{\n part: unknown\n allowCustomAnswer?: boolean\n }>()\n\n const emit = defineEmits<{\n select: [answer: string | { answers: FormAnswer[] }]\n }>()\n\n const { t: $t, d: $d } = useI18n({ useScope: 'global' })\n\n // --- Parsed tool part ---\n\n const toolPart = computed(\n () => JSON.parse(JSON.stringify(props.part)) as ToolPartShape,\n )\n\n const isLegacy = computed(\n () =>\n toolPart.value.toolName === 'showMultipleChoice' ||\n toolPart.value.type === 'tool-showMultipleChoice',\n )\n\n const isInteractive = computed(\n () => toolPart.value.state === 'input-available',\n )\n\n /** Single-step with no custom-answer and no freeform → auto-submit on option pick */\n const isAutoSubmitStep = computed(() => {\n const step = currentStep.value\n if (!step) return false\n return (\n steps.value.length === 1 &&\n !step.allowFreeformInput &&\n !props.allowCustomAnswer\n )\n })\n\n /** Legacy tool should auto-submit on option pick regardless of allowCustomAnswer */\n const isLegacyAutoSubmit = computed(\n () =>\n isLegacy.value &&\n steps.value.length === 1 &&\n !currentStep.value?.multiSelect,\n )\n\n /**\n * True only for the steps that send themselves as soon as an option is\n * picked: the single case where the footer button would be redundant.\n * Every other shape needs it, single-step forms included: with\n * `allowFreeformInput` (or `allowCustomAnswer`) the radio pick no longer\n * auto-submits, so without the footer the user was left with a chosen\n * option and no way to send it.\n */\n const isSelfSubmitting = computed(\n () =>\n Boolean(currentStep.value?.options) &&\n !currentStep.value?.multiSelect &&\n (isAutoSubmitStep.value || isLegacyAutoSubmit.value),\n )\n\n // --- Steps ---\n\n const steps = computed<FormStep[]>(() => {\n const input = toolPart.value.input\n if (input?.steps?.length) {\n return input.steps\n }\n // Legacy showMultipleChoice → normalize into a single step\n if (input?.question && input?.options) {\n return [\n {\n id: 'legacy',\n question: input.question,\n options: input.options.map((o) =>\n typeof o === 'string' ? { label: o } : o,\n ),\n },\n ]\n }\n return []\n })\n\n // --- Navigation state ---\n\n const currentStepIndex = ref(0)\n const currentStep = computed(() => steps.value[currentStepIndex.value])\n const canGoBack = computed(() => currentStepIndex.value > 0)\n const canGoNext = computed(\n () => currentStepIndex.value < steps.value.length - 1,\n )\n const isMultiStep = computed(() => steps.value.length > 1)\n\n const progress = computed(() => {\n if (!isMultiStep.value) return null\n return Math.round(\n ((currentStepIndex.value + 1) / steps.value.length) * 100,\n )\n })\n\n // --- Answers ---\n\n const answers = reactive<Record<string, AnswerValue>>({})\n const customAnswer = ref('')\n\n // The freeform field belongs to the step showing it: text left behind\n // (unsubmitted, or arriving from a late input update) must not follow the\n // user to the next or previous question.\n watch(currentStepIndex, () => {\n customAnswer.value = ''\n })\n\n // Single scalar answer shared by radio buttons and freeform text/number/date inputs.\n const scalarValue = computed<string | number | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStep.value.id]\n : undefined\n if (val == null || Array.isArray(val)) return undefined\n return val\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStep.value.id] = val ?? null\n }\n },\n })\n\n const activeCheckboxValue = computed<unknown[] | undefined>({\n get: () => {\n const val = currentStep.value\n ? answers[currentStep.value.id]\n : undefined\n return Array.isArray(val) ? val : []\n },\n set: (val) => {\n if (currentStep.value) {\n answers[currentStep.value.id] = (val as string[]) ?? []\n }\n },\n })\n\n // --- Initialize answers from existing output ---\n\n /** The `{ answers: [...] }` list, when the output carries one. */\n function outputAnswers(output: ToolPartShape['output']) {\n if (!output || typeof output === 'string') return undefined\n const list = (output as { answers?: unknown }).answers\n return Array.isArray(list) ? (list as FormAnswer[]) : undefined\n }\n\n watch(\n () => toolPart.value.output,\n (output) => {\n if (!output) return\n if (typeof output === 'string') {\n if (steps.value.length === 1) {\n answers[steps.value[0].id] = output\n }\n return\n }\n const list = outputAnswers(output)\n if (list) {\n for (const a of list) {\n answers[a.id] = a.value\n }\n return\n }\n // Forms answered on a platform channel come back as a flat record\n // keyed by step id: without this the read-only summary showed every\n // answer as a placeholder.\n const record = output as Record<string, unknown>\n for (const step of steps.value) {\n const value = record[step.id]\n if (value !== undefined) {\n answers[step.id] = value as AnswerValue\n }\n }\n },\n { immediate: true },\n )\n\n // --- Restore custom answer from output when it doesn't match any option ---\n\n const normalizedOutput = computed(() => {\n const out = toolPart.value.output\n if (!out) return undefined\n if (typeof out === 'string') return out\n const list = outputAnswers(out)\n if (list?.length === 1) {\n const val = list[0].value\n return Array.isArray(val) ? val.join(', ') : String(val)\n }\n return undefined\n })\n\n watch(\n normalizedOutput,\n (value) => {\n if (!value || !currentStep.value) return\n const optionLabels = (currentStep.value.options ?? []).map(\n (o) => o.label,\n )\n if (!optionLabels.includes(value)) {\n customAnswer.value = value\n }\n },\n { immediate: true },\n )\n\n // --- Option mapping for radio/checkbox components ---\n\n const radioOptions = computed(() => {\n if (!currentStep.value?.options) return []\n return currentStep.value.options.map((option) => ({\n label: option.label,\n value: option.label,\n description: option.description,\n }))\n })\n\n // --- Navigation & Submission ---\n\n /** Footer button, and Enter on a pure freeform step. */\n function goNext() {\n // A typed freeform answer wins over the picked option: it is the more\n // recent intent, and the footer button is now the visible way to send\n // it (the freeform field only submits on Enter).\n if (customAnswer.value.trim()) {\n submitCustomAnswer()\n return\n }\n if (canGoNext.value) {\n currentStepIndex.value++\n } else {\n submitForm()\n }\n }\n\n function goBack() {\n if (canGoBack.value) {\n currentStepIndex.value--\n }\n }\n\n function submitForm() {\n if (!isInteractive.value) return\n\n const finalAnswers: FormAnswer[] = steps.value.map((step) => ({\n id: step.id,\n value: answers[step.id] ?? null,\n }))\n\n // Legacy backward compatibility: single-step, single-select → return plain string\n if (\n isLegacyAutoSubmit.value &&\n !currentStep.value?.allowFreeformInput\n ) {\n const val = finalAnswers[0].value\n emit('select', Array.isArray(val) ? val[0] : (val as string))\n } else {\n emit('select', { answers: finalAnswers })\n }\n }\n\n /** Enter inside the freeform field shown alongside the options. */\n function submitCustomAnswer() {\n const value = customAnswer.value.trim()\n if (!value) return\n\n answers[currentStep.value.id] = value\n // Cleared before navigating: `goNext()` reads it back to route a typed\n // answer here, so leaving it set would recurse.\n customAnswer.value = ''\n if (steps.value.length === 1) {\n submitForm()\n } else {\n goNext()\n }\n }\n\n function onRadioChange() {\n if (!isInteractive.value) return\n if (isAutoSubmitStep.value || isLegacyAutoSubmit.value) {\n submitForm()\n }\n }\n\n // --- Summary helpers ---\n\n function getSummaryValue(step: FormStep) {\n const val = answers[step.id]\n if (val == null) return '—'\n if (Array.isArray(val)) return val.join(', ')\n if (step.type === 'date') return $d(new Date(val), 'short')\n return val\n }\n</script>\n\n<template>\n <div\n v-if=\"steps.length\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden flex flex-col transition-all bg-surface\">\n <!-- Header -->\n <div\n v-if=\"toolPart.input?.title || (isInteractive && steps.length > 1)\"\n class=\"text-12 border-b border-surface-3 text-word-3 bg-surface-1\">\n <div\n v-if=\"toolPart.input?.title\"\n class=\"px-sm py-10 font-bold\"\n :class=\"{\n 'border-b border-surface-3':\n isInteractive && steps.length > 1,\n }\">\n {{ toolPart.input?.title }}\n </div>\n <!-- Progress for multi-step -->\n <div\n v-if=\"isInteractive && steps.length > 1\"\n class=\"flex flex-col gap-4 p-sm\">\n <div class=\"flex justify-between text-10 text-word-3\">\n <span>\n {{\n $t('showForm.step', {\n current: currentStepIndex + 1,\n total: steps.length,\n })\n }}\n </span>\n <span>{{ progress }}%</span>\n </div>\n <div class=\"h-4 bg-surface-3 rounded-full overflow-hidden\">\n <div\n class=\"h-full bg-word-4 transition-all duration-300\"\n :style=\"{ width: `${progress}%` }\"></div>\n </div>\n </div>\n </div>\n\n <!-- Input Available State -->\n <template v-if=\"isInteractive\">\n <!-- Current Step Content -->\n <div class=\"px-sm py-16 flex flex-col gap-12\">\n <div class=\"leading-normal text-12\">\n <strong class=\"font-semibold\">\n {{ currentStep.question }}\n </strong>\n <PkStreamingMarkdown\n v-if=\"currentStep.message\"\n :markdown=\"currentStep.message\"\n class=\"text-word-2 mt-4\" />\n </div>\n\n <!-- Checkbox list for multi-select -->\n <PkEditorCheckboxButtons\n v-if=\"currentStep.options && currentStep.multiSelect\"\n v-model=\"activeCheckboxValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n class=\"mb-0\"\n vertical>\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorCheckboxButtons>\n\n <!-- Radio buttons for single-select -->\n <PkEditorRadioButtons\n v-else-if=\"currentStep.options && !currentStep.multiSelect\"\n v-model=\"scalarValue\"\n :name=\"currentStep.id\"\n :options=\"radioOptions\"\n :readonly=\"!isInteractive\"\n vertical\n class=\"mb-0\"\n @update:model-value=\"onRadioChange\">\n <template\n v-for=\"option in radioOptions\"\n :key=\"option.value\"\n #[option.value]>\n <!-- Shared option layout: label + optional description -->\n <div class=\"text-12\">\n <div class=\"font-semibold\">{{ option.label }}</div>\n <div v-if=\"option.description\" class=\"text-word-3\">\n {{ option.description }}\n </div>\n </div>\n </template>\n </PkEditorRadioButtons>\n\n <!-- Pure Freeform Input (text, number, date) -->\n <div\n v-else-if=\"!currentStep.options\"\n class=\"flex flex-col gap-6 w-full\">\n <VvInputText\n :key=\"currentStep.id\"\n v-model=\"scalarValue\"\n :placeholder=\"\n currentStep.placeholder || $t('placeholder.insert')\n \"\n :type=\"currentStep.type\"\n class=\"w-full\"\n :name=\"currentStep.id\"\n modifiers=\"compact rounded\"\n :disabled=\"!isInteractive\"\n @keyup.enter=\"goNext\" />\n </div>\n </div>\n\n <!-- Custom footer freeform input (shown alongside options when allowFreeformInput) -->\n <div\n v-if=\"currentStep.allowFreeformInput && currentStep.options\"\n class=\"px-sm pb-sm border-t border-surface-3\">\n <form\n class=\"flex gap-xs pt-sm\"\n @submit.prevent=\"submitCustomAnswer\">\n <VvInputText\n :key=\"`${currentStep.id}-custom`\"\n v-model=\"customAnswer\"\n class=\"flex-1\"\n :name=\"`${currentStep.id}-custom`\"\n modifiers=\"compact rounded\"\n :disabled=\"!isInteractive\"\n :placeholder=\"\n currentStep.placeholder ||\n $t('showForm.otherPlaceholder')\n \" />\n </form>\n </div>\n\n <!-- Footer navigation: shown for every step that does not submit\n itself on option pick (see `isSelfSubmitting`). -->\n <div\n v-if=\"!isSelfSubmitting\"\n class=\"px-sm py-10 bg-surface border-t border-surface-3 flex justify-between gap-12\">\n <VvButton\n v-if=\"canGoBack\"\n modifiers=\"action-quiet\"\n icon=\"ri:arrow-left-s-line\"\n :label=\"$t('action.back')\"\n @click.stop=\"goBack\" />\n <div v-else></div>\n\n <VvButton\n :modifiers=\"canGoNext ? 'action-quiet' : 'action-primary'\"\n :icon=\"\n canGoNext\n ? 'ri:arrow-right-s-line'\n : 'ri:send-plane-2-line'\n \"\n icon-position=\"right\"\n :label=\"canGoNext ? $t('action.next') : $t('action.submit')\"\n @click.stop=\"goNext\" />\n </div>\n </template>\n\n <!-- Output Available State (Multi-step Summary) -->\n <template v-else>\n <div class=\"px-sm py-12 bg-surface space-y-10\">\n <ul class=\"flex flex-col gap-8\">\n <li\n v-for=\"step in steps\"\n :key=\"step.id\"\n class=\"leading-normal\">\n <div class=\"text-12 text-word-3\">\n {{ step.question }}\n </div>\n <span class=\"text-12 text-word-2 font-semibold\">\n {{ getSummaryValue(step) }}\n </span>\n </li>\n </ul>\n </div>\n <div\n class=\"px-sm py-12 bg-surface border-t border-surface-3 flex items-center gap-10\">\n <div\n class=\"w-20 h-20 rounded-full border border-success text-success flex items-center justify-center\">\n <VvIcon name=\"ri:check-line\" class=\"text-12\" />\n </div>\n <div class=\"flex flex-col\">\n <span\n class=\"font-semibold text-12 text-word-1 leading-tight\">\n {{ $t('showForm.completed') }}\n </span>\n </div>\n </div>\n </template>\n </div>\n</template>\n"],"mappings":"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"}
|
package/dist/_chunks/{PkToolShowImageGallery-mLq2p3aH.js → PkToolShowImageGallery-WQL3T4Hr.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { A as e, C as t, Ht as n, L as r, T as i, V as a, _ as o, at as s, b as c, g as l, kt as u, mt as d, p as f, qt as p, xt as m, y as h, z as g } from "./vue.runtime.esm-bundler-DbhD_IvR.js";
|
|
2
2
|
import "./src-BGqVtumX.js";
|
|
3
3
|
import { n as _ } from "./url-validation-uLMZ5-AU.js";
|
|
4
|
-
import {
|
|
4
|
+
import { f as v } from "./index.es-_oXVRjHy.js";
|
|
5
5
|
import { n as y, t as b } from "./useLightbox-WFuKhn8l.js";
|
|
6
6
|
e(), u(), s();
|
|
7
7
|
var x = {
|
|
@@ -70,4 +70,4 @@ var x = {
|
|
|
70
70
|
//#endregion
|
|
71
71
|
export { k as default };
|
|
72
72
|
|
|
73
|
-
//# sourceMappingURL=PkToolShowImageGallery-
|
|
73
|
+
//# sourceMappingURL=PkToolShowImageGallery-WQL3T4Hr.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkToolShowImageGallery-mLq2p3aH.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowImageGallery.vue","../../../../packages/components/src/chat/PkToolShowImageGallery.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, onMounted } from 'vue'\n import { isSameSite } from 'utils'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n images: Array<{\n url: string\n caption?: string\n alt?: string\n }>\n }\n }\n return part\n })\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n\n const images = computed(() => toolPart.value.input?.images ?? [])\n\n const failed = ref(new Set<string>())\n const onError = (url: string) => failed.value.add(url)\n\n const gridCols = computed(() => {\n const count = images.value.length\n if (count === 1) {\n return 'grid-cols-1 justify-items-center'\n }\n if (count === 2) {\n return 'grid-cols-2'\n }\n return 'grid-cols-3'\n })\n\n const { init } = useLightbox({ gallery: galleryRef })\n\n onMounted(async () => {\n preload(images.value)\n await init()\n })\n</script>\n\n<template>\n <div\n v-if=\"images.length\"\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:image-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.gallery', { count: images.length }) }}\n </strong>\n </div>\n <div class=\"p-sm\">\n <div ref=\"galleryRef\" class=\"grid gap-8\" :class=\"gridCols\">\n <a\n v-for=\"image in images\"\n :key=\"image.url\"\n :href=\"failed.has(image.url) ? undefined : image.url\"\n :data-pswp-src=\"\n failed.has(image.url) ? undefined : image.url\n \"\n :data-pswp-width=\"getSize(image.url).width\"\n :data-pswp-height=\"getSize(image.url).height\"\n :data-pswp-caption=\"image.caption ?? image.alt ?? ''\"\n :data-cropped=\"true\"\n class=\"relative block aspect-square overflow-hidden rounded-xl group max-h-384\"\n :class=\"[\n { 'w-384 max-w-full': images.length === 1 },\n failed.has(image.url)\n ? 'pointer-events-none'\n : 'cursor-pointer',\n ]\"\n :title=\"image.caption ?? image.alt ?? ''\"\n :target=\"isSameSite(image.url) ? undefined : '_blank'\"\n :rel=\"\n isSameSite(image.url)\n ? undefined\n : 'noopener noreferrer'\n \">\n <img\n v-if=\"!failed.has(image.url)\"\n :src=\"image.url\"\n :alt=\"image.alt ?? image.caption ?? ''\"\n class=\"w-full h-full object-cover transition-opacity group-hover:opacity-80\"\n @error=\"onError(image.url)\" />\n <div\n v-else\n class=\"w-full h-full flex flex-col items-center justify-center gap-4 bg-surface-1 text-word-3\">\n <VvIcon name=\"ri:camera-off-line\" class=\"text-24\" />\n <span class=\"text-12\">{{\n $t('label.imageLoadError')\n }}</span>\n </div>\n </a>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, onMounted } from 'vue'\n import { isSameSite } from 'utils'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n images: Array<{\n url: string\n caption?: string\n alt?: string\n }>\n }\n }\n return part\n })\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n\n const images = computed(() => toolPart.value.input?.images ?? [])\n\n const failed = ref(new Set<string>())\n const onError = (url: string) => failed.value.add(url)\n\n const gridCols = computed(() => {\n const count = images.value.length\n if (count === 1) {\n return 'grid-cols-1 justify-items-center'\n }\n if (count === 2) {\n return 'grid-cols-2'\n }\n return 'grid-cols-3'\n })\n\n const { init } = useLightbox({ gallery: galleryRef })\n\n onMounted(async () => {\n preload(images.value)\n await init()\n })\n</script>\n\n<template>\n <div\n v-if=\"images.length\"\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:image-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.gallery', { count: images.length }) }}\n </strong>\n </div>\n <div class=\"p-sm\">\n <div ref=\"galleryRef\" class=\"grid gap-8\" :class=\"gridCols\">\n <a\n v-for=\"image in images\"\n :key=\"image.url\"\n :href=\"failed.has(image.url) ? undefined : image.url\"\n :data-pswp-src=\"\n failed.has(image.url) ? undefined : image.url\n \"\n :data-pswp-width=\"getSize(image.url).width\"\n :data-pswp-height=\"getSize(image.url).height\"\n :data-pswp-caption=\"image.caption ?? image.alt ?? ''\"\n :data-cropped=\"true\"\n class=\"relative block aspect-square overflow-hidden rounded-xl group max-h-384\"\n :class=\"[\n { 'w-384 max-w-full': images.length === 1 },\n failed.has(image.url)\n ? 'pointer-events-none'\n : 'cursor-pointer',\n ]\"\n :title=\"image.caption ?? image.alt ?? ''\"\n :target=\"isSameSite(image.url) ? undefined : '_blank'\"\n :rel=\"\n isSameSite(image.url)\n ? undefined\n : 'noopener noreferrer'\n \">\n <img\n v-if=\"!failed.has(image.url)\"\n :src=\"image.url\"\n :alt=\"image.alt ?? image.caption ?? ''\"\n class=\"w-full h-full object-cover transition-opacity group-hover:opacity-80\"\n @error=\"onError(image.url)\" />\n <div\n v-else\n class=\"w-full h-full flex flex-col items-center justify-center gap-4 bg-surface-1 text-word-3\">\n <VvIcon name=\"ri:camera-off-line\" class=\"text-24\" />\n <span class=\"text-12\">{{\n $t('label.imageLoadError')\n }}</span>\n </div>\n </a>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKI,IAAM,IAAQ,GAIR,IAAW,QACA,EAAM,IAUtB,GAEK,IAAa,EAAiB,GAC9B,EAAE,YAAS,eAAY,EAAc,GAErC,IAAS,QAAe,EAAS,MAAM,OAAO,UAAU,CAAC,CAAC,GAE1D,IAAS,kBAAI,IAAI,IAAY,CAAC,GAC9B,KAAW,MAAgB,EAAO,MAAM,IAAI,CAAG,GAE/C,IAAW,QAAe;GAC5B,IAAM,IAAQ,EAAO,MAAM;GAO3B,OANI,MAAU,IACH,qCAEP,MAAU,IACH,gBAEJ;EACX,CAAC,GAEK,EAAE,YAAS,EAAY,EAAE,SAAS,EAAW,CAAC;SAEpD,EAAU,YAAY;GAElB,AADA,EAAQ,EAAO,KAAK,GACpB,MAAM,EAAK;EACf,CAAC;;UAKS,EAAA,MAAO,UAAA,EAAA,GADjB,EAsDM,OAtDN,GAsDM,CAnDF,EAMM,OANN,GAMM,CAJF,EAA+C,GAAA;IAAvC,MAAK;IAAgB,OAAM;OACnC,EAES,UAFT,GAES,EADFA,EAAAA,GAAE,iBAAA,EAAA,OAA2B,EAAA,MAAO,OAAM,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,GAGrD,EA2CM,OA3CN,GA2CM,CA1CF,EAyCM,OAAA;aAzCG;IAAJ,KAAI;IAAa,OAAK,EAAA,CAAC,cAAqB,EAAA,KAAQ,CAAA;eACrD,EAuCI,GAAA,MAAA,EAtCgB,EAAA,QAAT,YADX,EAuCI,KAAA;IArCC,KAAK,EAAM;IACX,MAAM,EAAA,MAAO,IAAI,EAAM,GAAG,IAAI,KAAA,IAAY,EAAM;IAChD,iBAAwC,EAAA,MAAO,IAAI,EAAM,GAAG,IAAI,KAAA,IAAY,EAAM;IAGlF,mBAAiB,EAAA,CAAA,CAAO,CAAC,EAAM,GAAG,CAAA,CAAE;IACpC,oBAAkB,EAAA,CAAA,CAAO,CAAC,EAAM,GAAG,CAAA,CAAE;IACrC,qBAAmB,EAAM,WAAW,EAAM,OAAG;IAC7C,gBAAc;IACf,OAAK,EAAA,CAAC,2EAAyE,CAAA,EAAA,oBACvB,EAAA,MAAO,WAAM,EAAA,GAAkC,EAAA,MAAO,IAAI,EAAM,GAAG,IAAA,wBAAA,gBAAA,CAAA,CAAA;IAM1H,OAAO,EAAM,WAAW,EAAM,OAAG;IACjC,QAAQ,EAAA,CAAA,CAAU,CAAC,EAAM,GAAG,IAAI,KAAA,IAAS;IACzC,KAA8B,EAAA,CAAA,CAAU,CAAC,EAAM,GAAG,IAAgC,KAAA,IAAA;OAMxE,EAAA,MAAO,IAAI,EAAM,GAAG,UAK/B,EAOM,OAPN,GAOM,CAJF,EAAoD,GAAA;IAA5C,MAAK;IAAqB,OAAM;OACxC,EAES,QAFT,GAES,EADLA,EAAAA,GAAE,sBAAA,CAAA,GAAA,CAAA,CAAA,CAAA,MAVqB,EAAA,GAD/B,EAKkC,OAAA;;IAH7B,KAAK,EAAM;IACX,KAAK,EAAM,OAAO,EAAM,WAAO;IAChC,OAAM;IACL,UAAK,MAAE,EAAQ,EAAM,GAAG;mBAMnB,GAAA,IAAA,CAAA"}
|
|
1
|
+
{"version":3,"file":"PkToolShowImageGallery-WQL3T4Hr.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowImageGallery.vue","../../../../packages/components/src/chat/PkToolShowImageGallery.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, onMounted } from 'vue'\n import { isSameSite } from 'utils'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n images: Array<{\n url: string\n caption?: string\n alt?: string\n }>\n }\n }\n return part\n })\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n\n const images = computed(() => toolPart.value.input?.images ?? [])\n\n const failed = ref(new Set<string>())\n const onError = (url: string) => failed.value.add(url)\n\n const gridCols = computed(() => {\n const count = images.value.length\n if (count === 1) {\n return 'grid-cols-1 justify-items-center'\n }\n if (count === 2) {\n return 'grid-cols-2'\n }\n return 'grid-cols-3'\n })\n\n const { init } = useLightbox({ gallery: galleryRef })\n\n onMounted(async () => {\n preload(images.value)\n await init()\n })\n</script>\n\n<template>\n <div\n v-if=\"images.length\"\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:image-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.gallery', { count: images.length }) }}\n </strong>\n </div>\n <div class=\"p-sm\">\n <div ref=\"galleryRef\" class=\"grid gap-8\" :class=\"gridCols\">\n <a\n v-for=\"image in images\"\n :key=\"image.url\"\n :href=\"failed.has(image.url) ? undefined : image.url\"\n :data-pswp-src=\"\n failed.has(image.url) ? undefined : image.url\n \"\n :data-pswp-width=\"getSize(image.url).width\"\n :data-pswp-height=\"getSize(image.url).height\"\n :data-pswp-caption=\"image.caption ?? image.alt ?? ''\"\n :data-cropped=\"true\"\n class=\"relative block aspect-square overflow-hidden rounded-xl group max-h-384\"\n :class=\"[\n { 'w-384 max-w-full': images.length === 1 },\n failed.has(image.url)\n ? 'pointer-events-none'\n : 'cursor-pointer',\n ]\"\n :title=\"image.caption ?? image.alt ?? ''\"\n :target=\"isSameSite(image.url) ? undefined : '_blank'\"\n :rel=\"\n isSameSite(image.url)\n ? undefined\n : 'noopener noreferrer'\n \">\n <img\n v-if=\"!failed.has(image.url)\"\n :src=\"image.url\"\n :alt=\"image.alt ?? image.caption ?? ''\"\n class=\"w-full h-full object-cover transition-opacity group-hover:opacity-80\"\n @error=\"onError(image.url)\" />\n <div\n v-else\n class=\"w-full h-full flex flex-col items-center justify-center gap-4 bg-surface-1 text-word-3\">\n <VvIcon name=\"ri:camera-off-line\" class=\"text-24\" />\n <span class=\"text-12\">{{\n $t('label.imageLoadError')\n }}</span>\n </div>\n </a>\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, onMounted } from 'vue'\n import { isSameSite } from 'utils'\n import { useLightbox, useImageSizes } from '../composables/useLightbox'\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n images: Array<{\n url: string\n caption?: string\n alt?: string\n }>\n }\n }\n return part\n })\n\n const galleryRef = ref<HTMLElement>()\n const { preload, getSize } = useImageSizes()\n\n const images = computed(() => toolPart.value.input?.images ?? [])\n\n const failed = ref(new Set<string>())\n const onError = (url: string) => failed.value.add(url)\n\n const gridCols = computed(() => {\n const count = images.value.length\n if (count === 1) {\n return 'grid-cols-1 justify-items-center'\n }\n if (count === 2) {\n return 'grid-cols-2'\n }\n return 'grid-cols-3'\n })\n\n const { init } = useLightbox({ gallery: galleryRef })\n\n onMounted(async () => {\n preload(images.value)\n await init()\n })\n</script>\n\n<template>\n <div\n v-if=\"images.length\"\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:image-line\" class=\"text-16\" />\n <strong class=\"font-bold\">\n {{ $t('label.gallery', { count: images.length }) }}\n </strong>\n </div>\n <div class=\"p-sm\">\n <div ref=\"galleryRef\" class=\"grid gap-8\" :class=\"gridCols\">\n <a\n v-for=\"image in images\"\n :key=\"image.url\"\n :href=\"failed.has(image.url) ? undefined : image.url\"\n :data-pswp-src=\"\n failed.has(image.url) ? undefined : image.url\n \"\n :data-pswp-width=\"getSize(image.url).width\"\n :data-pswp-height=\"getSize(image.url).height\"\n :data-pswp-caption=\"image.caption ?? image.alt ?? ''\"\n :data-cropped=\"true\"\n class=\"relative block aspect-square overflow-hidden rounded-xl group max-h-384\"\n :class=\"[\n { 'w-384 max-w-full': images.length === 1 },\n failed.has(image.url)\n ? 'pointer-events-none'\n : 'cursor-pointer',\n ]\"\n :title=\"image.caption ?? image.alt ?? ''\"\n :target=\"isSameSite(image.url) ? undefined : '_blank'\"\n :rel=\"\n isSameSite(image.url)\n ? undefined\n : 'noopener noreferrer'\n \">\n <img\n v-if=\"!failed.has(image.url)\"\n :src=\"image.url\"\n :alt=\"image.alt ?? image.caption ?? ''\"\n class=\"w-full h-full object-cover transition-opacity group-hover:opacity-80\"\n @error=\"onError(image.url)\" />\n <div\n v-else\n class=\"w-full h-full flex flex-col items-center justify-center gap-4 bg-surface-1 text-word-3\">\n <VvIcon name=\"ri:camera-off-line\" class=\"text-24\" />\n <span class=\"text-12\">{{\n $t('label.imageLoadError')\n }}</span>\n </div>\n </a>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKI,IAAM,IAAQ,GAIR,IAAW,QACA,EAAM,IAUtB,GAEK,IAAa,EAAiB,GAC9B,EAAE,YAAS,eAAY,EAAc,GAErC,IAAS,QAAe,EAAS,MAAM,OAAO,UAAU,CAAC,CAAC,GAE1D,IAAS,kBAAI,IAAI,IAAY,CAAC,GAC9B,KAAW,MAAgB,EAAO,MAAM,IAAI,CAAG,GAE/C,IAAW,QAAe;GAC5B,IAAM,IAAQ,EAAO,MAAM;GAO3B,OANI,MAAU,IACH,qCAEP,MAAU,IACH,gBAEJ;EACX,CAAC,GAEK,EAAE,YAAS,EAAY,EAAE,SAAS,EAAW,CAAC;SAEpD,EAAU,YAAY;GAElB,AADA,EAAQ,EAAO,KAAK,GACpB,MAAM,EAAK;EACf,CAAC;;UAKS,EAAA,MAAO,UAAA,EAAA,GADjB,EAsDM,OAtDN,GAsDM,CAnDF,EAMM,OANN,GAMM,CAJF,EAA+C,GAAA;IAAvC,MAAK;IAAgB,OAAM;OACnC,EAES,UAFT,GAES,EADFA,EAAAA,GAAE,iBAAA,EAAA,OAA2B,EAAA,MAAO,OAAM,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,GAGrD,EA2CM,OA3CN,GA2CM,CA1CF,EAyCM,OAAA;aAzCG;IAAJ,KAAI;IAAa,OAAK,EAAA,CAAC,cAAqB,EAAA,KAAQ,CAAA;eACrD,EAuCI,GAAA,MAAA,EAtCgB,EAAA,QAAT,YADX,EAuCI,KAAA;IArCC,KAAK,EAAM;IACX,MAAM,EAAA,MAAO,IAAI,EAAM,GAAG,IAAI,KAAA,IAAY,EAAM;IAChD,iBAAwC,EAAA,MAAO,IAAI,EAAM,GAAG,IAAI,KAAA,IAAY,EAAM;IAGlF,mBAAiB,EAAA,CAAA,CAAO,CAAC,EAAM,GAAG,CAAA,CAAE;IACpC,oBAAkB,EAAA,CAAA,CAAO,CAAC,EAAM,GAAG,CAAA,CAAE;IACrC,qBAAmB,EAAM,WAAW,EAAM,OAAG;IAC7C,gBAAc;IACf,OAAK,EAAA,CAAC,2EAAyE,CAAA,EAAA,oBACvB,EAAA,MAAO,WAAM,EAAA,GAAkC,EAAA,MAAO,IAAI,EAAM,GAAG,IAAA,wBAAA,gBAAA,CAAA,CAAA;IAM1H,OAAO,EAAM,WAAW,EAAM,OAAG;IACjC,QAAQ,EAAA,CAAA,CAAU,CAAC,EAAM,GAAG,IAAI,KAAA,IAAS;IACzC,KAA8B,EAAA,CAAA,CAAU,CAAC,EAAM,GAAG,IAAgC,KAAA,IAAA;OAMxE,EAAA,MAAO,IAAI,EAAM,GAAG,UAK/B,EAOM,OAPN,GAOM,CAJF,EAAoD,GAAA;IAA5C,MAAK;IAAqB,OAAM;OACxC,EAES,QAFT,GAES,EADLA,EAAAA,GAAE,sBAAA,CAAA,GAAA,CAAA,CAAA,CAAA,MAVqB,EAAA,GAD/B,EAKkC,OAAA;;IAH7B,KAAK,EAAM;IACX,KAAK,EAAM,OAAO,EAAM,WAAO;IAChC,OAAM;IACL,UAAK,MAAE,EAAQ,EAAM,GAAG;mBAMnB,GAAA,IAAA,CAAA"}
|
|
@@ -2,8 +2,8 @@ import { t as e } from "./rolldown-runtime-DY7j01NX.js";
|
|
|
2
2
|
import { $ as t, A as n, B as r, C as i, D as a, E as o, F as s, I as c, L as l, O as u, Q as d, S as f, T as p, Ut as m, Z as h, _ as g, at as _, b as v, et as y, ft as b, g as x, gt as S, j as C, kt as w, lt as T, m as E, mt as D, qt as O, ut as k, xt as A, y as j, z as ee } from "./vue.runtime.esm-bundler-DbhD_IvR.js";
|
|
3
3
|
import { n as M, t as te } from "./cdn-css-JUUNhyQ6.js";
|
|
4
4
|
import "./src-BGqVtumX.js";
|
|
5
|
-
import { i as ne } from "./dist-
|
|
6
|
-
import { d as re,
|
|
5
|
+
import { i as ne } from "./dist-CvMCBce7.js";
|
|
6
|
+
import { d as re, f as ie, i as ae, l as oe, t as se } from "./index.es-_oXVRjHy.js";
|
|
7
7
|
//#region ../../node_modules/.pnpm/maplibre-gl@5.24.0/node_modules/maplibre-gl/dist/maplibre-gl.js
|
|
8
8
|
var ce = /* @__PURE__ */ e(((e, t) => {
|
|
9
9
|
(function(n, r) {
|
|
@@ -34669,7 +34669,7 @@ var Ue = {
|
|
|
34669
34669
|
e && r(`${e.name}\n${e.address}`);
|
|
34670
34670
|
};
|
|
34671
34671
|
return (t, n) => {
|
|
34672
|
-
let r = ie, o =
|
|
34672
|
+
let r = ie, o = re, l = se, u = oe, d = ae;
|
|
34673
34673
|
return c.value?.input ? (ee(), v("div", Ue, [
|
|
34674
34674
|
g("div", We, [
|
|
34675
34675
|
i(r, {
|
|
@@ -34756,4 +34756,4 @@ var Ue = {
|
|
|
34756
34756
|
//#endregion
|
|
34757
34757
|
export { $e as default };
|
|
34758
34758
|
|
|
34759
|
-
//# sourceMappingURL=PkToolShowLocation-
|
|
34759
|
+
//# sourceMappingURL=PkToolShowLocation-w2t7lKpb.js.map
|