@8wave/ai-elements 0.118.0 → 0.119.0-beta.1
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/_chunks/{PkStreamingMarkdown--CcBvs19.js → PkStreamingMarkdown-kpEBZA4d.js} +789 -780
- package/dist/_chunks/PkStreamingMarkdown-kpEBZA4d.js.map +1 -0
- package/dist/_chunks/{PkToolShowArtifact-BVGN7hV2.js → PkToolShowArtifact-B8TOTS6A.js} +2 -2
- package/dist/_chunks/{PkToolShowArtifact-BVGN7hV2.js.map → PkToolShowArtifact-B8TOTS6A.js.map} +1 -1
- package/dist/_chunks/{PkToolShowContactForm-Blrwqpl0.js → PkToolShowContactForm-B89p05XM.js} +2 -2
- package/dist/_chunks/{PkToolShowContactForm-Blrwqpl0.js.map → PkToolShowContactForm-B89p05XM.js.map} +1 -1
- package/dist/_chunks/{PkToolShowForm-BpGHaN6x.js → PkToolShowForm-DTKQtFij.js} +4 -4
- package/dist/_chunks/{PkToolShowForm-BpGHaN6x.js.map → PkToolShowForm-DTKQtFij.js.map} +1 -1
- package/dist/_chunks/{PkToolShowSources-8c9RvGV1.js → PkToolShowSources-CbwixpOb.js} +2 -2
- package/dist/_chunks/{PkToolShowSources-8c9RvGV1.js.map → PkToolShowSources-CbwixpOb.js.map} +1 -1
- package/dist/ai-elements.es.js +1888 -1863
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotEmptyState.js +1 -1
- package/dist-vue/PkChatbotInput.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotStepPayload.js +1 -1
- package/dist-vue/PkChatbotStepToolDetail.js +1 -1
- package/dist-vue/PkChatbotSteps.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/PkChatbotViewProfile.js +1 -1
- package/dist-vue/_chunks/PkAvatar-BTqu8tn9.js +44 -0
- package/dist-vue/_chunks/PkAvatar-BTqu8tn9.js.map +1 -0
- package/dist-vue/_chunks/PkChatbot-C_OzxC0s.js +276 -0
- package/dist-vue/_chunks/PkChatbot-C_OzxC0s.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotEmptyState-D2dhInfG.js → PkChatbotEmptyState-BEQCnqui.js} +3 -3
- package/dist-vue/_chunks/{PkChatbotEmptyState-D2dhInfG.js.map → PkChatbotEmptyState-BEQCnqui.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotInput-CQdxFbBR.js → PkChatbotInput-KJxWrDIT.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotInput-CQdxFbBR.js.map → PkChatbotInput-KJxWrDIT.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotMessages-coscJcpy.js → PkChatbotMessages-Zhuxom46.js} +283 -283
- package/dist-vue/_chunks/{PkChatbotMessages-coscJcpy.js.map → PkChatbotMessages-Zhuxom46.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotStepPayload-DnqFluQZ.js → PkChatbotStepPayload-Da4N5CKa.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotStepPayload-DnqFluQZ.js.map → PkChatbotStepPayload-Da4N5CKa.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotStepToolDetail-BMslY_BG.js → PkChatbotStepToolDetail-rrtImvq5.js} +3 -3
- package/dist-vue/_chunks/{PkChatbotStepToolDetail-BMslY_BG.js.map → PkChatbotStepToolDetail-rrtImvq5.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotSteps-7FT6Ju6_.js → PkChatbotSteps-LEfOolAc.js} +38 -38
- package/dist-vue/_chunks/{PkChatbotSteps-7FT6Ju6_.js.map → PkChatbotSteps-LEfOolAc.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewChat-Cko-Cw6c.js → PkChatbotViewChat-BJ0YHCvA.js} +7 -7
- package/dist-vue/_chunks/PkChatbotViewChat-BJ0YHCvA.js.map +1 -0
- package/dist-vue/_chunks/{PkChatbotViewProfile-B57VRVaO.js → PkChatbotViewProfile-CyzRxE3D.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewProfile-B57VRVaO.js.map → PkChatbotViewProfile-CyzRxE3D.js.map} +1 -1
- package/dist-vue/_chunks/{PkStreamingMarkdown-BtyWXY2k.js → PkStreamingMarkdown-BWEvuFZm.js} +2 -2
- package/dist-vue/_chunks/{PkStreamingMarkdown-BtyWXY2k.js.map → PkStreamingMarkdown-BWEvuFZm.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowArtifact-Ritx54_X.js → PkToolShowArtifact-tNEG6-r_.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowArtifact-Ritx54_X.js.map → PkToolShowArtifact-tNEG6-r_.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowContactForm-D30IsZGy.js → PkToolShowContactForm-DBC6f9gR.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowContactForm-D30IsZGy.js.map → PkToolShowContactForm-DBC6f9gR.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowDiagram-PEozSAqU.js → PkToolShowDiagram-Bbq0ETt1.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowDiagram-PEozSAqU.js.map → PkToolShowDiagram-Bbq0ETt1.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowForm-ZmdM9J9x.js → PkToolShowForm-BG-8aTHy.js} +5 -5
- package/dist-vue/_chunks/{PkToolShowForm-ZmdM9J9x.js.map → PkToolShowForm-BG-8aTHy.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowImageGallery-Dkjf7Tw_.js → PkToolShowImageGallery-DXn-bxHv.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowImageGallery-Dkjf7Tw_.js.map → PkToolShowImageGallery-DXn-bxHv.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowProductList-CsHYM8vl.js → PkToolShowProductList-BZ_fDRCq.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowProductList-CsHYM8vl.js.map → PkToolShowProductList-BZ_fDRCq.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowSources-CKZkcPLA.js → PkToolShowSources-CUURb0PG.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowSources-CKZkcPLA.js.map → PkToolShowSources-CUURb0PG.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowVideo-CKm1fVQs.js → PkToolShowVideo-FNlPjswi.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowVideo-CKm1fVQs.js.map → PkToolShowVideo-FNlPjswi.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowWebPages-DLEC9cuh.js → PkToolShowWebPages-CWV79tsb.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowWebPages-DLEC9cuh.js.map → PkToolShowWebPages-CWV79tsb.js.map} +1 -1
- package/dist-vue/_chunks/{utils-fxHiCnzf.js → utils-Dk2jFXR_.js} +40 -31
- package/dist-vue/_chunks/utils-Dk2jFXR_.js.map +1 -0
- package/dist-vue/apps/web-component/src/composables/useChatbotAgent.d.ts +1 -4
- package/dist-vue/composables.js +132 -113
- package/dist-vue/composables.js.map +1 -1
- package/dist-vue/index.js +23 -23
- package/dist-vue/index.js.map +1 -1
- package/dist-vue/packages/components/src/chat/PkAvatar.d.ts +7 -0
- package/dist-vue/packages/components/src/chat/utils.d.ts +10 -0
- package/dist-vue/style.css +1 -1
- package/package.json +1 -1
- package/dist/_chunks/PkStreamingMarkdown--CcBvs19.js.map +0 -1
- package/dist-vue/_chunks/PkAvatar-ZgCsoO-p.js +0 -42
- package/dist-vue/_chunks/PkAvatar-ZgCsoO-p.js.map +0 -1
- package/dist-vue/_chunks/PkChatbot-Cm45hwYw.js +0 -275
- package/dist-vue/_chunks/PkChatbot-Cm45hwYw.js.map +0 -1
- package/dist-vue/_chunks/PkChatbotViewChat-Cko-Cw6c.js.map +0 -1
- package/dist-vue/_chunks/utils-fxHiCnzf.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { $ as e, C as t, Ct as n, Dt as r, L as i, O as a, St as o, _ as s, b as c, d as l, ft as u, g as d, h as f, it as p, m, mt as h, r as g, t as _, v, wt as y, x as b, z as x } from "./vue.runtime.esm-bundler-DKVd2gci.js";
|
|
2
|
-
import { t as S } from "./PkStreamingMarkdown
|
|
2
|
+
import { t as S } from "./PkStreamingMarkdown-kpEBZA4d.js";
|
|
3
3
|
import { r as C, t as w } from "./markdown-c59ir6tw.js";
|
|
4
4
|
import "./src-Dt4rhhPN.js";
|
|
5
5
|
import { r as ee, t as T } from "./index.es-dTcgyeM4.js";
|
|
@@ -267,4 +267,4 @@ var F = {
|
|
|
267
267
|
//#endregion
|
|
268
268
|
export { $ as default };
|
|
269
269
|
|
|
270
|
-
//# sourceMappingURL=PkToolShowSources-
|
|
270
|
+
//# sourceMappingURL=PkToolShowSources-CbwixpOb.js.map
|
package/dist/_chunks/{PkToolShowSources-8c9RvGV1.js.map → PkToolShowSources-CbwixpOb.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkToolShowSources-8c9RvGV1.js","names":["_hoisted_1","_hoisted_2","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_createElementVNode","_toDisplayString","_unref","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","PkUrl","_sfc_main","$t","__unplugin_components_0","__unplugin_components_1","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_createTextVNode","_toDisplayString","_Fragment","_renderList","PkDocumentHeader","_createCommentVNode","_createBlock","PkStreamingMarkdown","PkChunkPreview","_Transition","_withCtx","_normalizeClass","_sfc_main","withCtx","defineComponent","init_shared_esm_bundler","toDisplayString","openBlock","init_runtime_core_esm_bundler","unref","createCommentVNode","createTextVNode","Fragment","reactive","createBlock","createBaseVNode","init_reactivity_esm_bundler","ref","init_runtime_dom_esm_bundler","Transition","normalizeClass","createVNode","renderList","PkStreamingMarkdown_default","getTypeIcon","stripMarkdown","Ca","Ae","PkUrl_default","_hoisted_1$2","_hoisted_2$2","PkChunkPreview_default","props","__props","similarityPercent","computed","max","_component_VvIcon","createElementBlock","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","_hoisted_4$1","PkDocumentHeader_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","PkToolShowSources_default","toolPart","sources","groupedSources","groups","source","existing","maxSimilarity","s","expandedDocuments","expandedChunks","contextData","loadingContext","toggleDocument","documentId","toggleChunk","chunkId","handleExpandContext","content","clearContext","showMore","visibleGroups","hasMore","_component_VvButton","_ctx","group","chunk","_cache"],"sources":["../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkToolShowSources.vue","../../../../packages/components/src/chat/PkToolShowSources.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n /**\n * The address as text, not a link: for a header drawn inside a button,\n * where a link is invalid HTML and its click also toggles the row\n */\n mutedUrl?: boolean\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" :muted=\"mutedUrl\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n /**\n * The address as text, not a link: for a header drawn inside a button,\n * where a link is invalid HTML and its click also toggles the row\n */\n mutedUrl?: boolean\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" :muted=\"mutedUrl\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header: the toggle, and beside it the link to\n the source, because a link inside a button is invalid\n HTML and its click also toggled the row -->\n <div\n class=\"flex items-center hover:bg-surface-1 transition-colors\">\n <button\n type=\"button\"\n class=\"flex items-center gap-8 p-8 flex-1 min-w-0 text-left cursor-pointer\"\n :aria-expanded=\"\n expandedDocuments.has(group.document.documentId)\n \"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\"\n muted-url />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(\n group.document.documentId,\n )\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n <VvButton\n v-if=\"group.document.sourceUrl\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:external-link-line\"\n class=\"text-10 shrink-0 mr-8\"\n :href=\"group.document.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :title=\"$t('action.open')\"\n :aria-label=\"$t('action.open')\" />\n </div>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header: the toggle, and beside it the link to\n the source, because a link inside a button is invalid\n HTML and its click also toggled the row -->\n <div\n class=\"flex items-center hover:bg-surface-1 transition-colors\">\n <button\n type=\"button\"\n class=\"flex items-center gap-8 p-8 flex-1 min-w-0 text-left cursor-pointer\"\n :aria-expanded=\"\n expandedDocuments.has(group.document.documentId)\n \"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\"\n muted-url />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(\n group.document.documentId,\n )\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n <VvButton\n v-if=\"group.document.sourceUrl\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:external-link-line\"\n class=\"text-10 shrink-0 mr-8\"\n :href=\"group.document.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :title=\"$t('action.open')\"\n :aria-label=\"$t('action.open')\" />\n </div>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PkToolShowSources-CbwixpOb.js","names":["_hoisted_1","_hoisted_2","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_createElementVNode","_toDisplayString","_unref","_createCommentVNode","_sfc_main","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","__unplugin_components_0","_openBlock","_createElementBlock","_Fragment","_createVNode","_unref","_createElementVNode","_toDisplayString","_createCommentVNode","PkUrl","_sfc_main","$t","__unplugin_components_0","__unplugin_components_1","_openBlock","_createElementBlock","_createElementVNode","_createVNode","_createTextVNode","_toDisplayString","_Fragment","_renderList","PkDocumentHeader","_createCommentVNode","_createBlock","PkStreamingMarkdown","PkChunkPreview","_Transition","_withCtx","_normalizeClass","_sfc_main","withCtx","defineComponent","init_shared_esm_bundler","toDisplayString","openBlock","init_runtime_core_esm_bundler","unref","createCommentVNode","createTextVNode","Fragment","reactive","createBlock","createBaseVNode","init_reactivity_esm_bundler","ref","init_runtime_dom_esm_bundler","Transition","normalizeClass","createVNode","renderList","PkStreamingMarkdown_default","getTypeIcon","stripMarkdown","Ca","Ae","PkUrl_default","_hoisted_1$2","_hoisted_2$2","PkChunkPreview_default","props","__props","similarityPercent","computed","max","_component_VvIcon","createElementBlock","_hoisted_1$1","_hoisted_2$1","_hoisted_3$1","_hoisted_4$1","PkDocumentHeader_default","_hoisted_1","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","_hoisted_9","_hoisted_10","_hoisted_11","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_hoisted_16","_hoisted_17","_hoisted_18","PkToolShowSources_default","toolPart","sources","groupedSources","groups","source","existing","maxSimilarity","s","expandedDocuments","expandedChunks","contextData","loadingContext","toggleDocument","documentId","toggleChunk","chunkId","handleExpandContext","content","clearContext","showMore","visibleGroups","hasMore","_component_VvButton","_ctx","group","chunk","_cache"],"sources":["../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkChunkPreview.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkDocumentHeader.vue","../../../../packages/components/src/chat/PkToolShowSources.vue","../../../../packages/components/src/chat/PkToolShowSources.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { stripMarkdown } from 'utils'\n\n const props = defineProps<{\n content: string\n similarity?: number\n maxSimilarity?: number\n expanded: boolean\n }>()\n\n const similarityPercent = computed(() => {\n if (props.similarity == null) {\n return null\n }\n const max =\n props.maxSimilarity && props.maxSimilarity > 0\n ? props.maxSimilarity\n : 1\n return Math.round((props.similarity / max) * 100)\n })\n</script>\n\n<template>\n <VvIcon name=\"ri:text-snippet\" class=\"shrink-0 text-12 text-word-4\" />\n <span class=\"text-10 text-word-2 truncate flex-1\" :title=\"content\">\n {{ stripMarkdown(content) }}\n </span>\n <span v-if=\"similarityPercent != null\" class=\"text-10 text-word-4 shrink-0\">\n {{ similarityPercent }}%\n </span>\n <VvIcon\n :name=\"expanded ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-14 text-word-4 shrink-0\" />\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n /**\n * The address as text, not a link: for a header drawn inside a button,\n * where a link is invalid HTML and its click also toggles the row\n */\n mutedUrl?: boolean\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" :muted=\"mutedUrl\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import type { DocumentType } from 'models'\n import { getTypeIcon } from 'models'\n import PkUrl from '../PkUrl.vue'\n\n defineProps<{\n type: string\n name: string\n url?: string\n filename?: string\n /**\n * The address as text, not a link: for a header drawn inside a button,\n * where a link is invalid HTML and its click also toggles the row\n */\n mutedUrl?: boolean\n }>()\n</script>\n\n<template>\n <VvIcon\n :name=\"getTypeIcon(type as DocumentType)\"\n class=\"shrink-0 text-14 text-word-3\" />\n <div class=\"flex flex-col gap-2 min-w-0 flex-1\">\n <strong class=\"font-bold text-12 text-word-1 truncate block\">\n {{ name }}\n </strong>\n <span v-if=\"filename\" class=\"text-10 text-word-4 truncate\">\n {{ filename }}\n </span>\n <span\n v-if=\"url\"\n class=\"text-10 text-word-4 truncate flex items-center gap-4\">\n <VvIcon name=\"ri:link\" class=\"shrink-0 text-10\" />\n <PkUrl :url=\"url\" :muted=\"mutedUrl\" />\n </span>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header: the toggle, and beside it the link to\n the source, because a link inside a button is invalid\n HTML and its click also toggled the row -->\n <div\n class=\"flex items-center hover:bg-surface-1 transition-colors\">\n <button\n type=\"button\"\n class=\"flex items-center gap-8 p-8 flex-1 min-w-0 text-left cursor-pointer\"\n :aria-expanded=\"\n expandedDocuments.has(group.document.documentId)\n \"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\"\n muted-url />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(\n group.document.documentId,\n )\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n <VvButton\n v-if=\"group.document.sourceUrl\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:external-link-line\"\n class=\"text-10 shrink-0 mr-8\"\n :href=\"group.document.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :title=\"$t('action.open')\"\n :aria-label=\"$t('action.open')\" />\n </div>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, reactive } from 'vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n import PkChunkPreview from './PkChunkPreview.vue'\n import PkDocumentHeader from './PkDocumentHeader.vue'\n\n interface SourceItem {\n chunkId: string\n documentId: string\n documentName: string\n documentType: string\n language: string\n content: string\n chunkIndex?: number | null\n similarity?: number\n sourceUrl?: string\n sourceFilename?: string\n sourceDescription?: string\n sourceImageUrl?: string\n }\n\n const props = defineProps<{\n part: unknown\n onExpandContext?: (payload: {\n documentId: string\n chunkIndex: number\n }) => Promise<string>\n onDownload?: (documentId: string) => void\n }>()\n\n const toolPart = computed(() => {\n return props.part as {\n input?: {\n sources: SourceItem[]\n }\n }\n })\n\n const sources = computed(() => toolPart.value.input?.sources || [])\n\n const groupedSources = computed(() => {\n const groups = new Map<\n string,\n { document: SourceItem; chunks: SourceItem[] }\n >()\n for (const source of sources.value) {\n const existing = groups.get(source.documentId)\n if (existing) {\n existing.chunks.push(source)\n } else {\n groups.set(source.documentId, {\n document: source,\n chunks: [source],\n })\n }\n }\n return [...groups.values()]\n })\n\n const maxSimilarity = computed(() => {\n return Math.max(...sources.value.map((s) => s.similarity ?? 0), 0)\n })\n\n const expandedDocuments = reactive(new Set<string>())\n const expandedChunks = reactive(new Set<string>())\n const contextData = reactive(new Map<string, string>())\n const loadingContext = reactive(new Set<string>())\n\n const toggleDocument = (documentId: string) => {\n if (expandedDocuments.has(documentId)) {\n expandedDocuments.delete(documentId)\n } else {\n expandedDocuments.add(documentId)\n }\n }\n\n const toggleChunk = (chunkId: string) => {\n if (expandedChunks.has(chunkId)) {\n expandedChunks.delete(chunkId)\n } else {\n expandedChunks.add(chunkId)\n }\n }\n\n const handleExpandContext = async (source: SourceItem) => {\n if (source.chunkIndex == null || !props.onExpandContext) {\n return\n }\n loadingContext.add(source.chunkId)\n try {\n const content = await props.onExpandContext({\n documentId: source.documentId,\n chunkIndex: source.chunkIndex,\n })\n contextData.set(source.chunkId, content)\n } finally {\n loadingContext.delete(source.chunkId)\n }\n }\n\n const clearContext = (chunkId: string) => {\n contextData.delete(chunkId)\n }\n\n const showMore = ref(false)\n const visibleGroups = computed(() => {\n if (showMore.value) {\n return groupedSources.value\n }\n return groupedSources.value.slice(0, 3)\n })\n const hasMore = computed(() => groupedSources.value.length > 3)\n</script>\n\n<template>\n <div v-if=\"sources.length\" class=\"flex flex-col gap-xs w-full\">\n <div class=\"flex items-center gap-4 text-12 text-word-3 font-semibold\">\n <VvIcon name=\"ri:article-line\" class=\"text-14\" />\n {{ $t('label.sources') }}\n <span class=\"text-word-4 font-normal\">\n ({{ groupedSources.length }})\n </span>\n </div>\n\n <ul class=\"flex flex-col gap-xs\">\n <li\n v-for=\"group in visibleGroups\"\n :key=\"group.document.documentId\"\n class=\"border border-surface-3 rounded-xl overflow-hidden\">\n <!-- Document header: the toggle, and beside it the link to\n the source, because a link inside a button is invalid\n HTML and its click also toggled the row -->\n <div\n class=\"flex items-center hover:bg-surface-1 transition-colors\">\n <button\n type=\"button\"\n class=\"flex items-center gap-8 p-8 flex-1 min-w-0 text-left cursor-pointer\"\n :aria-expanded=\"\n expandedDocuments.has(group.document.documentId)\n \"\n @click=\"toggleDocument(group.document.documentId)\">\n <PkDocumentHeader\n :type=\"group.document.documentType\"\n :name=\"group.document.documentName\"\n :url=\"group.document.sourceUrl\"\n :filename=\"group.document.sourceFilename\"\n muted-url />\n <div class=\"flex items-center gap-4 shrink-0\">\n <span\n v-if=\"group.chunks.length > 1\"\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2\">\n {{ group.chunks.length }}\n </span>\n <span\n class=\"text-10 text-word-4 bg-surface-2 rounded px-4 py-2 uppercase\">\n {{ group.document.language }}\n </span>\n <VvIcon\n :name=\"\n expandedDocuments.has(\n group.document.documentId,\n )\n ? 'ri:arrow-up-s-line'\n : 'ri:arrow-down-s-line'\n \"\n class=\"text-16 text-word-3\" />\n </div>\n </button>\n <VvButton\n v-if=\"group.document.sourceUrl\"\n modifiers=\"action-quiet-small\"\n icon=\"ri:external-link-line\"\n class=\"text-10 shrink-0 mr-8\"\n :href=\"group.document.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n :title=\"$t('action.open')\"\n :aria-label=\"$t('action.open')\" />\n </div>\n\n <!-- Expanded content -->\n <div\n v-if=\"expandedDocuments.has(group.document.documentId)\"\n class=\"border-t border-surface-3\">\n <PkStreamingMarkdown\n v-if=\"group.document.sourceDescription\"\n :markdown=\"group.document.sourceDescription\"\n class=\"px-8 py-4 text-10 text-word-3 bg-surface-1 border-b border-surface-3\" />\n\n <!-- Chunk excerpts -->\n <div\n v-for=\"chunk in group.chunks\"\n :key=\"chunk.chunkId\"\n class=\"border-b border-surface-3 last:border-b-0\">\n <button\n class=\"flex items-center gap-8 px-8 py-6 w-full text-left hover:bg-surface-1 transition-colors cursor-pointer\"\n @click=\"toggleChunk(chunk.chunkId)\">\n <PkChunkPreview\n :content=\"chunk.content\"\n :similarity=\"chunk.similarity\"\n :max-similarity=\"maxSimilarity\"\n :expanded=\"expandedChunks.has(chunk.chunkId)\" />\n </button>\n\n <!-- Expanded chunk content -->\n <div\n v-if=\"expandedChunks.has(chunk.chunkId)\"\n class=\"bg-surface-1 border-t border-surface-3\">\n <div class=\"p-8 text-10 text-word-3\">\n <transition mode=\"out-in\">\n <!-- Context expansion -->\n <PkStreamingMarkdown\n v-if=\"contextData.has(chunk.chunkId)\"\n :markdown=\"\n contextData.get(chunk.chunkId)!\n \"\n class=\"wysiwyg\" />\n\n <!-- Chunk content -->\n <PkStreamingMarkdown\n v-else\n :markdown=\"chunk.content\"\n class=\"wysiwyg\" />\n </transition>\n </div>\n\n <!-- Actions bar -->\n <div\n class=\"flex items-center gap-8 px-8 py-6 border-t border-surface-3 bg-surface\">\n <!-- Expand / collapse context -->\n <button\n v-if=\"\n onExpandContext &&\n chunk.chunkIndex != null &&\n !contextData.has(chunk.chunkId)\n \"\n class=\"text-10 text-word-3 hover:text-word flex items-center gap-4 cursor-pointer\"\n :disabled=\"\n loadingContext.has(chunk.chunkId)\n \"\n @click=\"handleExpandContext(chunk)\">\n <VvIcon\n :name=\"\n loadingContext.has(chunk.chunkId)\n ? 'loading-loop'\n : 'ri:expand-up-down-line'\n \"\n class=\"text-12\" />\n {{ $t('label.expandContext') }}\n </button>\n <button\n v-else-if=\"contextData.has(chunk.chunkId)\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n @click=\"clearContext(chunk.chunkId)\">\n <VvIcon\n name=\"ri:collapse-vertical-line\"\n class=\"text-12\" />\n {{ $t('label.collapseContext') }}\n </button>\n\n <!-- Open source URL -->\n <a\n v-if=\"chunk.sourceUrl\"\n :href=\"chunk.sourceUrl\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 ml-auto\">\n <VvIcon\n name=\"ri:external-link-line\"\n class=\"text-12\" />\n {{ $t('label.openSource') }}\n </a>\n\n <!-- Download file -->\n <button\n v-if=\"\n onDownload &&\n chunk.documentType === 'file'\n \"\n class=\"text-10 text-word-3 hover:text-word-1 flex items-center gap-4 cursor-pointer\"\n :class=\"{\n 'ml-auto': !chunk.sourceUrl,\n }\"\n @click=\"onDownload(chunk.documentId)\">\n <VvIcon\n name=\"ri:download-line\"\n class=\"text-12\" />\n {{ $t('label.downloadFile') }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </li>\n </ul>\n\n <!-- Show more -->\n <button\n v-if=\"hasMore\"\n class=\"text-12 text-word-3 cursor-pointer hover:underline flex items-center gap-4 mx-auto\"\n @click=\"showMore = !showMore\">\n <VvIcon\n :name=\"showMore ? 'ri:arrow-up-s-line' : 'ri:arrow-down-s-line'\"\n class=\"text-16\" />\n {{\n showMore\n ? $t('action.showLess')\n : $t('action.showMore', {\n count: groupedSources.length - 3,\n })\n }}\n </button>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;EAII,IAAM4E,IAAQC,GAORC,IAAoBC,QAAe;GACrC,IAAIH,EAAM,cAAc,MACpB,OAAO;GAEX,IAAMI,IACFJ,EAAM,iBAAiBA,EAAM,gBAAgB,IACvCA,EAAM,gBACN;GACV,OAAO,KAAK,MAAOA,EAAM,aAAaI,IAAO,GAAG;EACpD,CAAC;;;;IAID1E,EAAsE2E,GAAA;KAA9D,MAAK;KAAkB,OAAM;;IACrC1E,EAEO,QAAA;KAFD,OAAM;KAAuC,OAAOsE,EAAA;IACnD,GAAArE,EAAAC,EAAA4D,CAAA,CAAa,CAACQ,EAAA,OAAO,CAAA,GAAA,GAAA7E,CAAA;IAEhB8E,EAAA,SAAiB,OAE7BxB,EAAA,IAAA,EAAA,KAFAnD,EAAA,GAAAC,EAEO,QAFPH,GAEOO,EADAsE,EAAA,KAAiB,IAAG,MAC3B,CAAA;IACAxE,EAE2C2E,GAAA;KADtC,MAAMJ,EAAA,WAAQ,uBAAA;KACf,OAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;GEdVzD,OAAAA,EAAAA,GAAAA,EAAAA,GAAAA,MAAAA,CAAAA,EAE2C6D,GAAA;IADtC,MAAM5D,EAAA+C,CAAA,CAAW,CAACS,EAAA,IAAI;IACvB,OAAM;GACVvD,GAAAA,MAAAA,GAAAA,CAAAA,MAAAA,CAAAA,GAAAA,EAaM,OAbNV,GAaM;IAZFU,EAES,UAFTT,GAESU,EADFsD,EAAA,IAAI,GAAA,CAAA;IAECA,EAAA,YAAZ5D,EAAA,GAAAC,EAEO,QAFPJ,GAEOS,EADAsD,EAAA,QAAQ,GAAA,CAAA,KAAAvB,EAAA,IAAA,EAAA;IAGLuB,EAAA,OADV5D,EAAA,GAAAC,EAKO,QALPH,GAKO,CAFHK,EAAkD6D,GAAA;KAA1C,MAAK;KAAU,OAAM;IAC7B7D,CAAAA,GAAAA,EAAsCK,GAAA;KAA9B,KAAKoD,EAAA;KAAM,OAAOA,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EEZlC,IAAMD,IAAQC,GASR8B,IAAW5B,QACNH,EAAM,IAKhB,GAEKgC,IAAU7B,QAAe4B,EAAS,MAAM,OAAO,WAAW,CAAC,CAAC,GAE5DE,IAAiB9B,QAAe;GAClC,IAAM+B,oBAAS,IAAI,IAGjB;GACF,KAAK,IAAMC,KAAUH,EAAQ,OAAO;IAChC,IAAMI,IAAWF,EAAO,IAAIC,EAAO,UAAU;IAC7C,AAAIC,IACAA,EAAS,OAAO,KAAKD,CAAM,IAE3BD,EAAO,IAAIC,EAAO,YAAY;KAC1B,UAAUA;KACV,QAAQ,CAACA,CAAM;IACnB,CAAC;GAET;GACA,OAAO,CAAC,GAAGD,EAAO,OAAO,CAAC;EAC9B,CAAC,GAEKG,IAAgBlC,QACX,KAAK,IAAI,GAAG6B,EAAQ,MAAM,KAAK,MAAMM,EAAE,cAAc,CAAC,GAAG,CAAC,CACpE,GAEKC,IAAoB1D,kBAAS,IAAI,IAAY,CAAC,GAC9C2D,IAAiB3D,kBAAS,IAAI,IAAY,CAAC,GAC3C4D,IAAc5D,kBAAS,IAAI,IAAoB,CAAC,GAChD6D,IAAiB7D,kBAAS,IAAI,IAAY,CAAC,GAE3C8D,KAAkB,MAAuB;GAC3C,AAAIJ,EAAkB,IAAIK,CAAU,IAChCL,EAAkB,OAAOK,CAAU,IAEnCL,EAAkB,IAAIK,CAAU;EAExC,GAEMC,KAAe,MAAoB;GACrC,AAAIL,EAAe,IAAIM,CAAO,IAC1BN,EAAe,OAAOM,CAAO,IAE7BN,EAAe,IAAIM,CAAO;EAElC,GAEMC,IAAsB,OAAO,MAAuB;GACtD,IAAIZ,EAAO,cAAc,QAASnC,EAAM,iBAGxC;MAAe,IAAImC,EAAO,OAAO;IACjC,IAAI;KACA,IAAMa,IAAU,MAAMhD,EAAM,gBAAgB;MACxC,YAAYmC,EAAO;MACnB,YAAYA,EAAO;KACvB,CAAC;KACD,EAAY,IAAIA,EAAO,SAASa,CAAO;IAC3C,UAAU;KACN,EAAe,OAAOb,EAAO,OAAO;IACxC;GATiC;EAUrC,GAEMc,KAAgB,MAAoB;GACtC,EAAY,OAAOH,CAAO;EAC9B,GAEMI,IAAWjE,EAAI,EAAK,GACpBkE,IAAgBhD,QACd+C,EAAS,QACFjB,EAAe,QAEnBA,EAAe,MAAM,MAAM,GAAG,CAAC,CACzC,GACKmB,KAAUjD,QAAe8B,EAAe,MAAM,SAAS,CAAC;;;GAInD,OAAAD,EAAA,MAAQ,UAAnB9E,EAAA,GAAAC,EAqMM,OArMNyD,GAqMM;IApMFxD,EAMM,OANNyD,GAMM;KALFxD,EAAiDgD,GAAA;MAAzC,MAAK;MAAkB,OAAM;;KAAY/C,EAAA,MACjDC,EAAGR,EAAAA,GAAE,eAAA,CAAA,IAAoB,KACzB,CAAA;KAAAK,EAEO,QAFP0D,GAAsC,OACjCvD,EAAG0E,EAAA,MAAe,MAAM,IAAG,MAChC,CAAA;;IAGJ7E,EA0KK,MA1KL2D,GA0KK,EAzKD7D,EAAA,EAAA,GAAAC,EAwKKK,GAAA,MAAAC,EAvKe0F,EAAA,QAAT,OADXjG,EAAA,GAAAC,EAwKK,MAAA;KAtKA,KAAKoG,EAAM,SAAS;KACrB,OAAM;IAINnG,GAAAA,CAAAA,EA8CM,OA9CN4D,GA8CM,CA5CF5D,EAiCS,UAAA;KAhCL,MAAK;KACL,OAAM;KACL,iBAA4CmF,EAAkB,IAAIgB,EAAM,SAAS,UAAU;KAG3F,UAAK,MAAEZ,EAAeY,EAAM,SAAS,UAAU;IAChDlG,GAAAA,CAAAA,EAKgBK,GAAA;KAJX,MAAM6F,EAAM,SAAS;KACrB,MAAMA,EAAM,SAAS;KACrB,KAAKA,EAAM,SAAS;KACpB,UAAUA,EAAM,SAAS;KAC1B,aAAA;;;;;;IACJnG,CAAAA,GAAAA,EAmBM,OAnBN8D,GAmBM;KAjBQqC,EAAM,OAAO,SAAM,KAD7BrG,EAAA,GAAAC,EAIO,QAJPgE,GAIO5D,EADAgG,EAAM,OAAO,MAAM,GAAA,CAAA,KAAA7E,EAAA,IAAA,EAAA;KAE1BtB,EAGO,QAHPgE,GAGO7D,EADAgG,EAAM,SAAS,QAAQ,GAAA,CAAA;KAE9BlG,EAQkCgD,GAAA;MAP7B,MAA2CkC,EAAkB,IAA6CgB,EAAM,SAAS,UAAA,IAAA,uBAAA;MAO1H,OAAM;;IAIR,CAAA,CAAA,GAAA,GAAAtC,CAAA,GAAAsC,EAAM,SAAS,aADzBrG,EAAA,GAAAU,EASsCyF,GAAA;;KAPlC,WAAU;KACV,MAAK;KACL,OAAM;KACL,MAAME,EAAM,SAAS;KACtB,QAAO;KACP,KAAI;KACH,OAAOxG,EAAAA,GAAE,aAAA;KACT,cAAYA,EAAAA,GAAE,aAAA;;;;;IAKb,CAAA,KAAA2B,EAAA,IAAA,EAAA,CAAA,CAAA,GAAA6D,EAAkB,IAAIgB,EAAM,SAAS,UAAU,KADzDrG,EAAA,GAAAC,EA+GM,OA/GNkE,GA+GM,CA3GQkC,EAAM,SAAS,qBADzBrG,EAAA,GAAAU,EAGmFC,GAAA;;KAD9E,UAAU0F,EAAM,SAAS;KAC1B,OAAM;IAGVrG,GAAAA,MAAAA,GAAAA,CAAAA,UAAAA,CAAAA,KAAAA,EAAAA,IAAAA,EAAAA,IAAAA,EAAA,EAAA,GAAAC,EAqGMK,GAAA,MAAAC,EApGc8F,EAAM,SAAf,OADXrG,EAAA,GAAAC,EAqGM,OAAA;KAnGD,KAAKqG,EAAM;KACZ,OAAM;IACNpG,GAAAA,CAAAA,EAQS,UAAA;KAPL,OAAM;KACL,UAAK,MAAEyF,EAAYW,EAAM,OAAO;IACjCnG,GAAAA,CAAAA,EAIoDS,GAAA;KAH/C,SAAS0F,EAAM;KACf,YAAYA,EAAM;KAClB,kBAAgBnB,EAAA;KAChB,UAAUG,EAAe,IAAIgB,EAAM,OAAO;;;;;;IAKzC,CAAA,CAAA,GAAA,GAAAlC,CAAA,GAAAkB,EAAe,IAAIgB,EAAM,OAAO,KAD1CtG,EAAA,GAAAC,EAqFM,OArFNoE,GAqFM,CAlFFnE,EAgBM,OAhBNoE,GAgBM,CAfFnE,EAcaU,GAAA,EAdD,MAAK,SAAQ,GAAA;KAErB,SAAAC,QAKsB,CAJZyE,EAAY,IAAIe,EAAM,OAAO,KADvCtG,EAAA,GAAAU,EAKsBC,GAAA;;MAHjB,UAAuD4E,EAAY,IAAIe,EAAM,OAAO;MAGrF,OAAM;KAGVtG,GAAAA,MAAAA,GAAAA,CAAAA,UAAAA,CAAAA,MAAAA,EAAA,GAAAU,EAGsBC,GAAA;;MADjB,UAAU2F,EAAM;MACjB,OAAM;;;IAKlBpG,GAAAA,IAAAA,CAAAA,CAAAA,GAAAA,EA8DM,OA9DNqE,GA8DM;KA1DiDxB,EAAA,mBAA2DuD,EAAM,cAAU,QAAqD,CAAAf,EAAY,IAAIe,EAAM,OAAO,KADhNtG,EAAA,GAAAC,EAmBS,UAAA;;MAbL,OAAM;MACL,UAAmDuF,EAAe,IAAIc,EAAM,OAAO;MAGnF,UAAK,MAAET,EAAoBS,CAAK;KACjCnG,GAAAA,CAAAA,EAMsBgD,GAAA;MALjB,MAAmDqC,EAAe,IAAIc,EAAM,OAAO,IAAA,iBAAA;MAKpF,OAAM;KAAYlG,GAAAA,MAAAA,GAAAA,CAAAA,MAAAA,CAAAA,GAAAA,EAAA,MACtBC,EAAGR,EAAAA,GAAE,qBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,GAAA2E,CAAA,KAGMe,EAAY,IAAIe,EAAM,OAAO,KAD5CtG,EAAA,GAAAC,EAQS,UAAA;;MANL,OAAM;MACL,UAAK,MAAE8F,EAAaO,EAAM,OAAO;KAClCnG,GAAAA,CAAAA,EAEsBgD,GAAA;MADlB,MAAK;MACL,OAAM;KAAY/C,CAAAA,GAAAA,EAAA,MACtBC,EAAGR,EAAAA,GAAE,uBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,GAAA4E,CAAA,KAAAjD,EAAA,IAAA,EAAA;KAKC8E,EAAM,aADhBtG,EAAA,GAAAC,EAUI,KAAA;;MARC,MAAMqG,EAAM;MACb,QAAO;MACP,KAAI;MACJ,OAAM;KACNnG,GAAAA,CAAAA,EAEsBgD,GAAA;MADlB,MAAK;MACL,OAAM;KAAY/C,CAAAA,GAAAA,EAAA,MACtBC,EAAGR,EAAAA,GAAE,kBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,GAAA6E,CAAA,KAAAlD,EAAA,IAAA,EAAA;KAK0CuB,EAAA,cAAsDuD,EAAM,iBAAY,UAD3HtG,EAAA,GAAAC,EAcS,UAAA;;MATL,OAAKc,EAAA,CAAC,gFAA8E,EACtB,WAAA,CAAAuF,EAAM,UAAA,CAAA,CAAA;MAGnE,UAAK,MAAEvD,EAAA,WAAWuD,EAAM,UAAU;KACnCnG,GAAAA,CAAAA,EAEsBgD,GAAA;MADlB,MAAK;MACL,OAAM;KAAY/C,CAAAA,GAAAA,EAAA,MACtBC,EAAGR,EAAAA,GAAE,oBAAA,CAAA,GAAA,CAAA,CAAA,GAAA,IAAA8E,CAAA,KAAAnD,EAAA,IAAA,EAAA;;IAWvB0E,GAAA,SADVlG,EAAA,GAAAC,EAcS,UAAA;;KAZL,OAAM;KACL,SAAK,AAAAsG,EAAA,QAAA,MAAE,EAAA,QAAQ,CAAIP,EAAA;IACpB7F,GAAAA,CAAAA,EAEsBgD,GAAA;KADjB,MAAM6C,EAAA,QAAQ,uBAAA;KACf,OAAM;IAAY5F,GAAAA,MAAAA,GAAAA,CAAAA,MAAAA,CAAAA,GAAAA,EAAA,MACtBC,EACI2F,EAAA,QAA+BnG,EAAAA,GAAE,iBAAA,IAA0CA,EAAAA,GAAE,mBAAA,EAAuD,OAAAkF,EAAA,MAAe,SAAM,EAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,KAAAvD,EAAA,IAAA,EAAA"}
|