@8wave/ai-elements 0.68.0 → 0.69.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{PkStreamingMarkdown-D3MJ5dfu.js → PkStreamingMarkdown-C0BpOvli.js} +2 -2
- package/dist/_chunks/{PkStreamingMarkdown-D3MJ5dfu.js.map → PkStreamingMarkdown-C0BpOvli.js.map} +1 -1
- package/dist/_chunks/{PkToolShowArtifact-BFe_MhNr.js → PkToolShowArtifact-DzNIkKvZ.js} +3 -3
- package/dist/_chunks/{PkToolShowArtifact-BFe_MhNr.js.map → PkToolShowArtifact-DzNIkKvZ.js.map} +1 -1
- package/dist/_chunks/{PkToolShowLocation-DN57lKN1.js → PkToolShowLocation-BsBiA4jV.js} +2 -2
- package/dist/_chunks/{PkToolShowLocation-DN57lKN1.js.map → PkToolShowLocation-BsBiA4jV.js.map} +1 -1
- package/dist/_chunks/src-BRYn66N3.js.map +1 -1
- package/dist/_chunks/{vue-leaflet.es-7LObg4WN.js → vue-leaflet.es-BT-uRmMx.js} +5 -5
- package/dist/_chunks/{vue-leaflet.es-7LObg4WN.js.map → vue-leaflet.es-BT-uRmMx.js.map} +1 -1
- package/dist/ai-elements.es.js +293 -299
- package/dist/ai-elements.es.js.map +1 -1
- package/dist-vue/PkChatbot.js +1 -1
- package/dist-vue/PkChatbotMessages.js +1 -1
- package/dist-vue/PkChatbotViewChat.js +1 -1
- package/dist-vue/PkChatbotViewConversations.js +1 -1
- package/dist-vue/PkChatbotViewProfile.js +1 -1
- package/dist-vue/_chunks/{PkChatbot-C_ASB2zq.js → PkChatbot-Cy7p5UI_.js} +5 -5
- package/dist-vue/_chunks/{PkChatbot-C_ASB2zq.js.map → PkChatbot-Cy7p5UI_.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotMessages-CQdxH86L.js → PkChatbotMessages-C7-ZtU0-.js} +11 -11
- package/dist-vue/_chunks/{PkChatbotMessages-CQdxH86L.js.map → PkChatbotMessages-C7-ZtU0-.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewChat-DHOeNxnR.js → PkChatbotViewChat-EWotdJkz.js} +3 -3
- package/dist-vue/_chunks/{PkChatbotViewChat-DHOeNxnR.js.map → PkChatbotViewChat-EWotdJkz.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewConversations-DFv_8-8K.js → PkChatbotViewConversations-Ct0TbDrg.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewConversations-DFv_8-8K.js.map → PkChatbotViewConversations-Ct0TbDrg.js.map} +1 -1
- package/dist-vue/_chunks/{PkChatbotViewProfile-BUj0YnIi.js → PkChatbotViewProfile-BhdCxVSX.js} +2 -2
- package/dist-vue/_chunks/{PkChatbotViewProfile-BUj0YnIi.js.map → PkChatbotViewProfile-BhdCxVSX.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowArtifact-DIw-_JPA.js → PkToolShowArtifact-pTS7wzhw.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowArtifact-DIw-_JPA.js.map → PkToolShowArtifact-pTS7wzhw.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowCalendarEvent-ZZM8p7wu.js → PkToolShowCalendarEvent-DQ--fzwb.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowCalendarEvent-ZZM8p7wu.js.map → PkToolShowCalendarEvent-DQ--fzwb.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowComparison-7akNsf1w.js → PkToolShowComparison-CzRUrjbP.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowComparison-7akNsf1w.js.map → PkToolShowComparison-CzRUrjbP.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowEmail-CpiAbmr0.js → PkToolShowEmail-htn0ivwY.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowEmail-CpiAbmr0.js.map → PkToolShowEmail-htn0ivwY.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowImageGallery-jY7iYqTv.js → PkToolShowImageGallery-CpU183SC.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowImageGallery-jY7iYqTv.js.map → PkToolShowImageGallery-CpU183SC.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowLocation-BeOkj0Q2.js → PkToolShowLocation-DSZvW68g.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowLocation-BeOkj0Q2.js.map → PkToolShowLocation-DSZvW68g.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowMessage-AS8VNcYP.js → PkToolShowMessage-DtGDm3pq.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowMessage-AS8VNcYP.js.map → PkToolShowMessage-DtGDm3pq.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowProductList-FEq8sFxW.js → PkToolShowProductList-BlkUdbtV.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowProductList-FEq8sFxW.js.map → PkToolShowProductList-BlkUdbtV.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowQrCode-DAt8tBHK.js → PkToolShowQrCode-BUyhM_MN.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowQrCode-DAt8tBHK.js.map → PkToolShowQrCode-BUyhM_MN.js.map} +1 -1
- package/dist-vue/_chunks/{PkToolShowWebPages-jA5eZRdi.js → PkToolShowWebPages-BQp9A4vb.js} +2 -2
- package/dist-vue/_chunks/{PkToolShowWebPages-jA5eZRdi.js.map → PkToolShowWebPages-BQp9A4vb.js.map} +1 -1
- package/dist-vue/_chunks/{dist-C-yeiSHm.js → dist-BHuX2VvC.js} +2 -2
- package/dist-vue/_chunks/{dist-C-yeiSHm.js.map → dist-BHuX2VvC.js.map} +1 -1
- package/dist-vue/_chunks/{dist-D2-23M8l.js → dist-BWXfA4NS.js} +4 -4
- package/dist-vue/_chunks/{dist-D2-23M8l.js.map → dist-BWXfA4NS.js.map} +1 -1
- package/dist-vue/_chunks/{dist-DJ_vDk0q.js → dist-CAXUIcdd.js} +3 -3
- package/dist-vue/_chunks/{dist-DJ_vDk0q.js.map → dist-CAXUIcdd.js.map} +1 -1
- package/dist-vue/_chunks/{dist-C38fHUMa.js → dist-D-VT7gvP.js} +2 -2
- package/dist-vue/_chunks/{dist-C38fHUMa.js.map → dist-D-VT7gvP.js.map} +1 -1
- package/dist-vue/_chunks/{dist-BrsWoii-.js → dist-DEe8jwtO.js} +2 -2
- package/dist-vue/_chunks/{dist-BrsWoii-.js.map → dist-DEe8jwtO.js.map} +1 -1
- package/dist-vue/_chunks/{dist-BmqFgHbN.js → dist-DV82RztV.js} +2 -2
- package/dist-vue/_chunks/{dist-BmqFgHbN.js.map → dist-DV82RztV.js.map} +1 -1
- package/dist-vue/_chunks/{dist-ByzpJpuj.js → dist-DVM_p-M1.js} +3 -3
- package/dist-vue/_chunks/{dist-ByzpJpuj.js.map → dist-DVM_p-M1.js.map} +1 -1
- package/dist-vue/_chunks/{dist-D3coexrW.js → dist-DfEAZDKB.js} +2 -2
- package/dist-vue/_chunks/{dist-D3coexrW.js.map → dist-DfEAZDKB.js.map} +1 -1
- package/dist-vue/_chunks/{dist-veLX58Me.js → dist-QbFF3eM_.js} +2 -2
- package/dist-vue/_chunks/{dist-veLX58Me.js.map → dist-QbFF3eM_.js.map} +1 -1
- package/dist-vue/_chunks/{dist-B65AhbTK.js → dist-bUGhZmKp.js} +3 -3
- package/dist-vue/_chunks/{dist-B65AhbTK.js.map → dist-bUGhZmKp.js.map} +1 -1
- package/dist-vue/_chunks/{dist-DmKzgdbO.js → dist-jVwgEJDw.js} +2 -2
- package/dist-vue/_chunks/{dist-DmKzgdbO.js.map → dist-jVwgEJDw.js.map} +1 -1
- package/dist-vue/_chunks/src-DjRNH9vV.js.map +1 -1
- package/dist-vue/_chunks/{useChatbotStore-B9BUWM4O.js → useChatbotStore-ys9uGP5v.js} +4 -10
- package/dist-vue/_chunks/{useChatbotStore-B9BUWM4O.js.map → useChatbotStore-ys9uGP5v.js.map} +1 -1
- package/dist-vue/composables.js +1 -1
- package/dist-vue/index.js +32 -32
- package/package.json +1 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Bt as e, C as t, E as n, Gt as r, Z as i, _ as a, ft as o, v as s, w as c, x as l, y as u, yt as d, z as f } from "./vue.runtime.esm-bundler-ljsQ8m_k.js";
|
|
2
2
|
import { i as p } from "./dist-BajHjEnz.js";
|
|
3
3
|
import { o as m } from "./index.es-D7jJWPne.js";
|
|
4
|
-
import { t as h } from "./PkStreamingMarkdown-
|
|
4
|
+
import { t as h } from "./PkStreamingMarkdown-C0BpOvli.js";
|
|
5
5
|
//#region ../../packages/components/src/chat/PkCode.vue?vue&type=script&setup=true&lang.ts
|
|
6
6
|
var g = { class: "font-mono leading-snug text-smaller bg-surface-1" }, _ = ["innerHTML"], v = /* @__PURE__ */ n({
|
|
7
7
|
__name: "PkCode",
|
|
@@ -13,7 +13,7 @@ var g = { class: "font-mono leading-snug text-smaller bg-surface-1" }, _ = ["inn
|
|
|
13
13
|
setup(n) {
|
|
14
14
|
let r = n, c = o(""), u = a(() => typeof r.code == "string" ? r.code : JSON.stringify(r.code, null, 2));
|
|
15
15
|
async function d() {
|
|
16
|
-
let e = (await import("https://cdn.jsdelivr.net/npm/highlight.js@11/
|
|
16
|
+
let e = (await import("https://cdn.jsdelivr.net/npm/highlight.js@11/es/common.js")).default;
|
|
17
17
|
try {
|
|
18
18
|
c.value = (r.language ? e.highlight(u.value, { language: r.language }) : e.highlightAuto(u.value)).value;
|
|
19
19
|
} catch {
|
|
@@ -86,4 +86,4 @@ var g = { class: "font-mono leading-snug text-smaller bg-surface-1" }, _ = ["inn
|
|
|
86
86
|
//#endregion
|
|
87
87
|
export { w as default };
|
|
88
88
|
|
|
89
|
-
//# sourceMappingURL=PkToolShowArtifact-
|
|
89
|
+
//# sourceMappingURL=PkToolShowArtifact-DzNIkKvZ.js.map
|
package/dist/_chunks/{PkToolShowArtifact-BFe_MhNr.js.map → PkToolShowArtifact-DzNIkKvZ.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkToolShowArtifact-BFe_MhNr.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre class=\"font-mono leading-snug text-smaller bg-surface-1\">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre class=\"font-mono leading-snug text-smaller bg-surface-1\">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre\n >\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre\n >\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PkToolShowArtifact-DzNIkKvZ.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkCode.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue","../../../../packages/components/src/chat/PkToolShowArtifact.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre class=\"font-mono leading-snug text-smaller bg-surface-1\">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed, ref, watch } from 'vue'\n\n const props = defineProps<{\n code: unknown\n language: string\n line?: boolean\n }>()\n\n const highlightedHtml = ref('')\n\n const hasCode = computed(() => {\n if (typeof props.code === 'string') {\n return props.code\n }\n return JSON.stringify(props.code, null, 2)\n })\n\n async function highlight() {\n const hljs = (await import('highlight.js/lib/common')).default\n try {\n const result = props.language\n ? hljs.highlight(hasCode.value, { language: props.language })\n : hljs.highlightAuto(hasCode.value)\n highlightedHtml.value = result.value\n } catch {\n highlightedHtml.value = hasCode.value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n }\n }\n\n watch(hasCode, highlight, { immediate: true })\n</script>\n\n<template>\n <pre class=\"font-mono leading-snug text-smaller bg-surface-1\">\n <code :class=\"['hljs', line ? 'whitespace-pre-line' : 'whitespace-pre', language]\" v-html=\"highlightedHtml\"></code>\n </pre>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre\n >\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import { computed } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import PkCode from './PkCode.vue'\n import PkStreamingMarkdown from './PkStreamingMarkdown.vue'\n\n const { copy, copied } = useClipboard()\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n title: string\n content: string\n artifactType: string\n language?: string\n }\n }\n return part\n })\n\n const artifactTypeLabel = computed(() => {\n const labels: Record<string, string> = {\n code: 'Code',\n document: 'Document',\n markdown: 'Markdown',\n json: 'JSON',\n xml: 'XML',\n csv: 'CSV',\n html: 'HTML',\n yaml: 'YAML',\n sql: 'SQL',\n text: 'Text',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'Artifact'\n }\n return labels[toolPart.value.input.artifactType] || 'Artifact'\n })\n\n const languageLabel = computed(() => {\n if (!toolPart.value.input?.language) {\n return ''\n }\n return ` (${toolPart.value.input.language})`\n })\n\n const isCodeType = computed(() => {\n return (\n toolPart.value.input?.artifactType === 'code' ||\n toolPart.value.input?.artifactType === 'json' ||\n toolPart.value.input?.artifactType === 'xml' ||\n toolPart.value.input?.artifactType === 'yaml' ||\n toolPart.value.input?.artifactType === 'html' ||\n toolPart.value.input?.artifactType === 'sql'\n )\n })\n\n const isMarkdownType = computed(() => {\n return toolPart.value.input?.artifactType === 'markdown'\n })\n\n const codeLanguage = computed(() => {\n if (toolPart.value.input?.language) {\n return toolPart.value.input.language\n }\n // Map artifact types to highlight.js languages\n const languageMap: Record<string, string> = {\n json: 'json',\n xml: 'xml',\n yaml: 'yaml',\n html: 'html',\n sql: 'sql',\n }\n if (!toolPart.value.input?.artifactType) {\n return 'plaintext'\n }\n return languageMap[toolPart.value.input.artifactType] || 'plaintext'\n })\n</script>\n\n<template>\n <div class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 font-bold bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex justify-between items-center\">\n <div class=\"flex flex-col items-start gap-4\">\n <span>{{ toolPart?.input?.title }}</span>\n <span class=\"text-10 opacity-60 font-normal\">\n {{ artifactTypeLabel }}{{ languageLabel }}\n </span>\n </div>\n <VvButton\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n modifiers=\"action-quiet-small\"\n :title=\"$t('action.copy')\"\n class=\"shrink-0\"\n @click=\"copy(toolPart?.input?.content || '')\" />\n </div>\n <div class=\"px-sm py-10\">\n <PkCode\n v-if=\"isCodeType\"\n :code=\"toolPart?.input?.content\"\n :language=\"codeLanguage\" />\n <PkStreamingMarkdown\n v-else-if=\"isMarkdownType\"\n :markdown=\"toolPart?.input?.content\"\n class=\"wysiwyg text-word-2\" />\n <pre\n v-else\n class=\"text-word-2 whitespace-pre-wrap break-words\"\n :class=\"{\n italic:\n toolPart?.input?.artifactType === 'document' ||\n toolPart?.input?.artifactType === 'text',\n }\"\n >{{ toolPart?.input?.content }}</pre\n >\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -16,7 +16,7 @@ var E = {
|
|
|
16
16
|
__name: "PkToolShowLocation",
|
|
17
17
|
props: { part: { type: null } },
|
|
18
18
|
setup(r) {
|
|
19
|
-
let P = import("./vue-leaflet.es-
|
|
19
|
+
let P = import("./vue-leaflet.es-BT-uRmMx.js"), F = c(() => P.then((e) => e.LMap)), I = c(() => P.then((e) => e.LTileLayer)), L = c(() => P.then((e) => e.LMarker)), R = c(() => P.then((e) => e.LPopup)), z = r, { copy: B, copied: V } = v(), H = u(() => z.part), U = f(null);
|
|
20
20
|
a(() => {
|
|
21
21
|
w("https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet.css", T(n()?.proxy?.$el));
|
|
22
22
|
}), s(async () => {
|
|
@@ -131,4 +131,4 @@ var E = {
|
|
|
131
131
|
//#endregion
|
|
132
132
|
export { P as default };
|
|
133
133
|
|
|
134
|
-
//# sourceMappingURL=PkToolShowLocation-
|
|
134
|
+
//# sourceMappingURL=PkToolShowLocation-BsBiA4jV.js.map
|
package/dist/_chunks/{PkToolShowLocation-DN57lKN1.js.map → PkToolShowLocation-BsBiA4jV.js.map}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PkToolShowLocation-DN57lKN1.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowLocation.vue","../../../../packages/components/src/chat/PkToolShowLocation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import {\n computed,\n ref,\n watchEffect,\n defineAsyncComponent,\n onMounted,\n getCurrentInstance,\n } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { loadCdnCss, getShadowRoot } from 'utils'\n\n const leafletModule = import('@maxel01/vue-leaflet')\n const LMap = defineAsyncComponent(() => leafletModule.then((m) => m.LMap))\n const LTileLayer = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LTileLayer),\n )\n const LMarker = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LMarker),\n )\n const LPopup = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LPopup),\n )\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n name: string\n address: string\n latitude?: number\n longitude?: number\n additionalInfo?: string\n }\n }\n return part\n })\n\n const geocodedCoords = ref<[number, number] | null>(null)\n\n onMounted(() => {\n loadCdnCss(\n 'https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet.css',\n getShadowRoot(getCurrentInstance()?.proxy?.$el),\n )\n })\n\n watchEffect(async () => {\n const input = toolPart.value.input\n if (!input || input.latitude != null || !input.address) {\n return\n }\n\n try {\n const response = await fetch(\n `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(input.address)}&format=json&limit=1`,\n { headers: { 'Accept-Language': 'en' } },\n )\n const results = (await response.json()) as {\n lat: string\n lon: string\n }[]\n if (results.length > 0) {\n geocodedCoords.value = [\n Number(results[0].lat),\n Number(results[0].lon),\n ]\n }\n } catch {\n // Geocoding failed — fallback to text-only card\n }\n })\n\n const hasCoords = computed(\n () =>\n (toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null) ||\n geocodedCoords.value != null,\n )\n\n const center = computed<[number, number]>(() => {\n if (\n toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null\n ) {\n return [\n toolPart.value.input.latitude,\n toolPart.value.input.longitude,\n ]\n }\n return geocodedCoords.value ?? [0, 0]\n })\n\n const openGoogleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openAppleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://maps.apple.com/?daddr=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openWaze = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n if (hasCoords.value) {\n window.open(\n `https://waze.com/ul?ll=${center.value[0]},${center.value[1]}&navigate=yes`,\n '_blank',\n )\n } else {\n window.open(\n `https://waze.com/ul?q=${encodeURIComponent(input.address)}&navigate=yes`,\n '_blank',\n )\n }\n }\n\n const copyLocation = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n copy(`${input.name}\\n${input.address}`)\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.location') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyLocation\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n icon=\"ri:direction-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.getDirections')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleMaps\">\n <VvIcon name=\"ri:map-2-line\" />\n Google Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openAppleMaps\">\n <VvIcon name=\"ri:map-line\" />\n Apple Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openWaze\">\n <VvIcon name=\"ri:navigation-line\" />\n Waze\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div v-if=\"hasCoords\" class=\"h-224 border-b border-surface-3\">\n <LMap\n :zoom=\"12\"\n :center\n :use-global-leaflet=\"false\"\n :options=\"{\n scrollWheelZoom: false,\n dragging: true,\n zoomControl: true,\n attributionControl: false,\n }\"\n style=\"height: 100%; width: 100%\">\n <LTileLayer\n url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\n layer-type=\"base\"\n name=\"OpenStreetMap\" />\n <LMarker :lat-lng=\"center\">\n <LPopup>{{ toolPart.input.name }}</LPopup>\n </LMarker>\n </LMap>\n </div>\n <div class=\"p-sm flex flex-col gap-4\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.name }}\n </p>\n <p class=\"text-12 text-word-3\">{{ toolPart.input.address }}</p>\n <p v-if=\"toolPart.input.additionalInfo\" class=\"text-12 text-word-4\">\n {{ toolPart.input.additionalInfo }}\n </p>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import {\n computed,\n ref,\n watchEffect,\n defineAsyncComponent,\n onMounted,\n getCurrentInstance,\n } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { loadCdnCss, getShadowRoot } from 'utils'\n\n const leafletModule = import('@maxel01/vue-leaflet')\n const LMap = defineAsyncComponent(() => leafletModule.then((m) => m.LMap))\n const LTileLayer = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LTileLayer),\n )\n const LMarker = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LMarker),\n )\n const LPopup = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LPopup),\n )\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n name: string\n address: string\n latitude?: number\n longitude?: number\n additionalInfo?: string\n }\n }\n return part\n })\n\n const geocodedCoords = ref<[number, number] | null>(null)\n\n onMounted(() => {\n loadCdnCss(\n 'https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet.css',\n getShadowRoot(getCurrentInstance()?.proxy?.$el),\n )\n })\n\n watchEffect(async () => {\n const input = toolPart.value.input\n if (!input || input.latitude != null || !input.address) {\n return\n }\n\n try {\n const response = await fetch(\n `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(input.address)}&format=json&limit=1`,\n { headers: { 'Accept-Language': 'en' } },\n )\n const results = (await response.json()) as {\n lat: string\n lon: string\n }[]\n if (results.length > 0) {\n geocodedCoords.value = [\n Number(results[0].lat),\n Number(results[0].lon),\n ]\n }\n } catch {\n // Geocoding failed — fallback to text-only card\n }\n })\n\n const hasCoords = computed(\n () =>\n (toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null) ||\n geocodedCoords.value != null,\n )\n\n const center = computed<[number, number]>(() => {\n if (\n toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null\n ) {\n return [\n toolPart.value.input.latitude,\n toolPart.value.input.longitude,\n ]\n }\n return geocodedCoords.value ?? [0, 0]\n })\n\n const openGoogleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openAppleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://maps.apple.com/?daddr=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openWaze = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n if (hasCoords.value) {\n window.open(\n `https://waze.com/ul?ll=${center.value[0]},${center.value[1]}&navigate=yes`,\n '_blank',\n )\n } else {\n window.open(\n `https://waze.com/ul?q=${encodeURIComponent(input.address)}&navigate=yes`,\n '_blank',\n )\n }\n }\n\n const copyLocation = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n copy(`${input.name}\\n${input.address}`)\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.location') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyLocation\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n icon=\"ri:direction-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.getDirections')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleMaps\">\n <VvIcon name=\"ri:map-2-line\" />\n Google Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openAppleMaps\">\n <VvIcon name=\"ri:map-line\" />\n Apple Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openWaze\">\n <VvIcon name=\"ri:navigation-line\" />\n Waze\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div v-if=\"hasCoords\" class=\"h-224 border-b border-surface-3\">\n <LMap\n :zoom=\"12\"\n :center\n :use-global-leaflet=\"false\"\n :options=\"{\n scrollWheelZoom: false,\n dragging: true,\n zoomControl: true,\n attributionControl: false,\n }\"\n style=\"height: 100%; width: 100%\">\n <LTileLayer\n url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\n layer-type=\"base\"\n name=\"OpenStreetMap\" />\n <LMarker :lat-lng=\"center\">\n <LPopup>{{ toolPart.input.name }}</LPopup>\n </LMarker>\n </LMap>\n </div>\n <div class=\"p-sm flex flex-col gap-4\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.name }}\n </p>\n <p class=\"text-12 text-word-3\">{{ toolPart.input.address }}</p>\n <p v-if=\"toolPart.input.additionalInfo\" class=\"text-12 text-word-4\">\n {{ toolPart.input.additionalInfo }}\n </p>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PkToolShowLocation-BsBiA4jV.js","names":["$t"],"sources":["../../../../packages/components/src/chat/PkToolShowLocation.vue","../../../../packages/components/src/chat/PkToolShowLocation.vue"],"sourcesContent":["<script setup lang=\"ts\">\n import {\n computed,\n ref,\n watchEffect,\n defineAsyncComponent,\n onMounted,\n getCurrentInstance,\n } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { loadCdnCss, getShadowRoot } from 'utils'\n\n const leafletModule = import('@maxel01/vue-leaflet')\n const LMap = defineAsyncComponent(() => leafletModule.then((m) => m.LMap))\n const LTileLayer = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LTileLayer),\n )\n const LMarker = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LMarker),\n )\n const LPopup = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LPopup),\n )\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n name: string\n address: string\n latitude?: number\n longitude?: number\n additionalInfo?: string\n }\n }\n return part\n })\n\n const geocodedCoords = ref<[number, number] | null>(null)\n\n onMounted(() => {\n loadCdnCss(\n 'https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet.css',\n getShadowRoot(getCurrentInstance()?.proxy?.$el),\n )\n })\n\n watchEffect(async () => {\n const input = toolPart.value.input\n if (!input || input.latitude != null || !input.address) {\n return\n }\n\n try {\n const response = await fetch(\n `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(input.address)}&format=json&limit=1`,\n { headers: { 'Accept-Language': 'en' } },\n )\n const results = (await response.json()) as {\n lat: string\n lon: string\n }[]\n if (results.length > 0) {\n geocodedCoords.value = [\n Number(results[0].lat),\n Number(results[0].lon),\n ]\n }\n } catch {\n // Geocoding failed — fallback to text-only card\n }\n })\n\n const hasCoords = computed(\n () =>\n (toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null) ||\n geocodedCoords.value != null,\n )\n\n const center = computed<[number, number]>(() => {\n if (\n toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null\n ) {\n return [\n toolPart.value.input.latitude,\n toolPart.value.input.longitude,\n ]\n }\n return geocodedCoords.value ?? [0, 0]\n })\n\n const openGoogleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openAppleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://maps.apple.com/?daddr=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openWaze = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n if (hasCoords.value) {\n window.open(\n `https://waze.com/ul?ll=${center.value[0]},${center.value[1]}&navigate=yes`,\n '_blank',\n )\n } else {\n window.open(\n `https://waze.com/ul?q=${encodeURIComponent(input.address)}&navigate=yes`,\n '_blank',\n )\n }\n }\n\n const copyLocation = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n copy(`${input.name}\\n${input.address}`)\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.location') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyLocation\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n icon=\"ri:direction-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.getDirections')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleMaps\">\n <VvIcon name=\"ri:map-2-line\" />\n Google Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openAppleMaps\">\n <VvIcon name=\"ri:map-line\" />\n Apple Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openWaze\">\n <VvIcon name=\"ri:navigation-line\" />\n Waze\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div v-if=\"hasCoords\" class=\"h-224 border-b border-surface-3\">\n <LMap\n :zoom=\"12\"\n :center\n :use-global-leaflet=\"false\"\n :options=\"{\n scrollWheelZoom: false,\n dragging: true,\n zoomControl: true,\n attributionControl: false,\n }\"\n style=\"height: 100%; width: 100%\">\n <LTileLayer\n url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\n layer-type=\"base\"\n name=\"OpenStreetMap\" />\n <LMarker :lat-lng=\"center\">\n <LPopup>{{ toolPart.input.name }}</LPopup>\n </LMarker>\n </LMap>\n </div>\n <div class=\"p-sm flex flex-col gap-4\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.name }}\n </p>\n <p class=\"text-12 text-word-3\">{{ toolPart.input.address }}</p>\n <p v-if=\"toolPart.input.additionalInfo\" class=\"text-12 text-word-4\">\n {{ toolPart.input.additionalInfo }}\n </p>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\n import {\n computed,\n ref,\n watchEffect,\n defineAsyncComponent,\n onMounted,\n getCurrentInstance,\n } from 'vue'\n import { useClipboard } from '@vueuse/core'\n import { loadCdnCss, getShadowRoot } from 'utils'\n\n const leafletModule = import('@maxel01/vue-leaflet')\n const LMap = defineAsyncComponent(() => leafletModule.then((m) => m.LMap))\n const LTileLayer = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LTileLayer),\n )\n const LMarker = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LMarker),\n )\n const LPopup = defineAsyncComponent(() =>\n leafletModule.then((m) => m.LPopup),\n )\n\n const props = defineProps<{\n part: unknown\n }>()\n\n const { copy, copied } = useClipboard()\n\n const toolPart = computed(() => {\n const part = props.part as {\n input?: {\n name: string\n address: string\n latitude?: number\n longitude?: number\n additionalInfo?: string\n }\n }\n return part\n })\n\n const geocodedCoords = ref<[number, number] | null>(null)\n\n onMounted(() => {\n loadCdnCss(\n 'https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet.css',\n getShadowRoot(getCurrentInstance()?.proxy?.$el),\n )\n })\n\n watchEffect(async () => {\n const input = toolPart.value.input\n if (!input || input.latitude != null || !input.address) {\n return\n }\n\n try {\n const response = await fetch(\n `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(input.address)}&format=json&limit=1`,\n { headers: { 'Accept-Language': 'en' } },\n )\n const results = (await response.json()) as {\n lat: string\n lon: string\n }[]\n if (results.length > 0) {\n geocodedCoords.value = [\n Number(results[0].lat),\n Number(results[0].lon),\n ]\n }\n } catch {\n // Geocoding failed — fallback to text-only card\n }\n })\n\n const hasCoords = computed(\n () =>\n (toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null) ||\n geocodedCoords.value != null,\n )\n\n const center = computed<[number, number]>(() => {\n if (\n toolPart.value.input?.latitude != null &&\n toolPart.value.input?.longitude != null\n ) {\n return [\n toolPart.value.input.latitude,\n toolPart.value.input.longitude,\n ]\n }\n return geocodedCoords.value ?? [0, 0]\n })\n\n const openGoogleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://www.google.com/maps/dir/?api=1&destination=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openAppleMaps = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n const destination = hasCoords.value\n ? `${center.value[0]},${center.value[1]}`\n : input.address\n window.open(\n `https://maps.apple.com/?daddr=${encodeURIComponent(destination)}`,\n '_blank',\n )\n }\n\n const openWaze = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n if (hasCoords.value) {\n window.open(\n `https://waze.com/ul?ll=${center.value[0]},${center.value[1]}&navigate=yes`,\n '_blank',\n )\n } else {\n window.open(\n `https://waze.com/ul?q=${encodeURIComponent(input.address)}&navigate=yes`,\n '_blank',\n )\n }\n }\n\n const copyLocation = () => {\n const input = toolPart.value.input\n if (!input) {\n return\n }\n copy(`${input.name}\\n${input.address}`)\n }\n</script>\n\n<template>\n <div\n v-if=\"toolPart?.input\"\n class=\"border border-surface-3 rounded-xl w-full overflow-hidden\">\n <div\n class=\"px-sm py-6 bg-surface-1 text-12 border-b border-surface-3 text-word-3 flex items-center gap-8\">\n <VvIcon name=\"ri:map-pin-line\" class=\"text-16\" />\n <strong class=\"font-bold\">{{ $t('label.location') }}</strong>\n <VvButtonGroup modifiers=\"compact\" class=\"ml-auto shrink-0\">\n <VvButton\n modifiers=\"action-quiet-small\"\n :icon=\"copied ? 'ri:check-line' : 'ri:file-copy-line'\"\n :label=\"copied ? $t('action.copied') : $t('action.copy')\"\n @click=\"copyLocation\" />\n <VvDropdown\n v-bind=\"{\n placement: 'bottom-end',\n modifiers: 'menu',\n flip: true,\n offset: 3,\n }\">\n <VvButton\n icon=\"ri:direction-line\"\n modifiers=\"action-quiet-small\"\n :label=\"$t('action.getDirections')\" />\n <template #items>\n <VvDropdownAction @click=\"openGoogleMaps\">\n <VvIcon name=\"ri:map-2-line\" />\n Google Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openAppleMaps\">\n <VvIcon name=\"ri:map-line\" />\n Apple Maps\n </VvDropdownAction>\n <VvDropdownAction @click=\"openWaze\">\n <VvIcon name=\"ri:navigation-line\" />\n Waze\n </VvDropdownAction>\n </template>\n </VvDropdown>\n </VvButtonGroup>\n </div>\n <div v-if=\"hasCoords\" class=\"h-224 border-b border-surface-3\">\n <LMap\n :zoom=\"12\"\n :center\n :use-global-leaflet=\"false\"\n :options=\"{\n scrollWheelZoom: false,\n dragging: true,\n zoomControl: true,\n attributionControl: false,\n }\"\n style=\"height: 100%; width: 100%\">\n <LTileLayer\n url=\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\"\n layer-type=\"base\"\n name=\"OpenStreetMap\" />\n <LMarker :lat-lng=\"center\">\n <LPopup>{{ toolPart.input.name }}</LPopup>\n </LMarker>\n </LMap>\n </div>\n <div class=\"p-sm flex flex-col gap-4\">\n <p class=\"font-semibold text-word-1 text-14\">\n {{ toolPart.input.name }}\n </p>\n <p class=\"text-12 text-word-3\">{{ toolPart.input.address }}</p>\n <p v-if=\"toolPart.input.additionalInfo\" class=\"text-12 text-word-4\">\n {{ toolPart.input.additionalInfo }}\n </p>\n </div>\n </div>\n</template>\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"src-BRYn66N3.js","names":[],"sources":["../../../../packages/utils/src/cdn-css.ts","../../../../packages/utils/src/device-context.ts","../../../../packages/utils/src/logger.ts","../../../../packages/utils/src/markdown.ts","../../../../packages/utils/src/message.ts","../../../../packages/utils/src/text.ts","../../../../packages/utils/src/url-validation.ts"],"sourcesContent":["const loaded = new WeakMap<Node, Set<string>>()\n\n/**\n * Injects a CDN stylesheet `<link>` once per URL per root.\n * When a `ShadowRoot` is passed, the link is appended there so that\n * custom-element (Shadow DOM) encapsulation is respected.\n * Falls back to `document.head` for regular DOM usage.\n */\nexport function loadCdnCss(href: string, root?: ShadowRoot) {\n const target: Node = root ?? document.head\n let set = loaded.get(target)\n if (!set) {\n set = new Set()\n loaded.set(target, set)\n }\n if (set.has(href)) {\n return\n }\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = href\n target.appendChild(link)\n set.add(href)\n}\n\n/** Returns the `ShadowRoot` ancestor of `el`, or `undefined` in regular DOM. */\nexport function getShadowRoot(el?: Element | null): ShadowRoot | undefined {\n const root = el?.getRootNode?.()\n return root instanceof ShadowRoot ? root : undefined\n}\n","interface NetworkInformation {\n type?: string\n effectiveType?: string\n downlink?: number\n rtt?: number\n saveData?: boolean\n}\n\ninterface NavigatorUAData {\n platform?: string\n}\n\n/**\n * Collects client-side device context information useful for chatbot interactions.\n * No additional permissions are required — all values are available by default in the browser.\n */\nexport function collectDeviceContext() {\n const connection = (\n navigator as Navigator & { connection?: NetworkInformation }\n ).connection\n\n const uaData = (\n navigator as Navigator & { userAgentData?: NavigatorUAData }\n ).userAgentData\n\n return {\n dateTime: new Date().toISOString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n language: navigator.language,\n languages: [...navigator.languages],\n url: window.location.href,\n pathname: window.location.pathname,\n pageTitle: document.title,\n referrer: document.referrer || undefined,\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n maxTouchPoints: navigator.maxTouchPoints,\n hardwareConcurrency: navigator.hardwareConcurrency,\n deviceMemory: (navigator as Navigator & { deviceMemory?: number })\n .deviceMemory,\n platform: uaData?.platform,\n connectionType: connection?.type,\n connectionEffectiveType: connection?.effectiveType,\n connectionDownlink: connection?.downlink,\n connectionRtt: connection?.rtt,\n saveData: connection?.saveData,\n darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,\n reducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)')\n .matches,\n historyLength: window.history.length,\n }\n}\n\nexport type GeolocationData = {\n geolocationLatitude: number\n geolocationLongitude: number\n geolocationAccuracy?: number\n geolocationCity?: string\n}\n\nexport type ReverseGeocodeFn = (\n lat: number,\n lon: number,\n) => Promise<string | undefined>\n\n/**\n * Collects geolocation data if the user has already granted permission.\n * Uses the Permissions API to avoid triggering a browser prompt.\n * Returns null if permission is not granted or geolocation is unavailable.\n * @param reverseGeocode - optional callback to resolve city name from coordinates (e.g. via backend proxy)\n */\nexport async function collectGeolocation(\n reverseGeocode?: ReverseGeocodeFn,\n): Promise<GeolocationData | null> {\n if (!navigator.geolocation || !navigator.permissions) {\n return null\n }\n\n try {\n const permission = await navigator.permissions.query({\n name: 'geolocation',\n })\n if (permission.state !== 'granted') {\n return null\n }\n\n const position = await new Promise<GeolocationPosition>(\n (resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n timeout: 10_000,\n })\n },\n )\n\n const { latitude, longitude, accuracy } = position.coords\n const city = reverseGeocode\n ? await reverseGeocode(latitude, longitude).catch(() => undefined)\n : undefined\n\n return {\n geolocationLatitude: latitude,\n geolocationLongitude: longitude,\n geolocationAccuracy: accuracy,\n geolocationCity: city,\n }\n } catch {\n return null\n }\n}\n","import type { Ref } from 'vue'\n\ntype ExceptionTracker = (\n error: Error,\n properties?: Record<string, string>,\n) => void\n\nlet _exceptionTracker: ExceptionTracker | undefined\n\n/**\n * Registers a callback invoked by error/warn/logError/logWarn to track exceptions\n * (e.g. Application Insights trackException).\n */\nexport const setExceptionTracker = (tracker: ExceptionTracker) => {\n _exceptionTracker = tracker\n}\n\nconst extractError = (params: unknown[]): Error => {\n const found = params.find((p): p is Error => p instanceof Error)\n if (found) {\n return found\n }\n return new Error(params.map(String).join(' '))\n}\n\nconst formatParam = (param: unknown): string => {\n if (param instanceof Error) {\n return param.stack ?? param.message\n }\n return String(param)\n}\n\nconst formatParams = (params: unknown[]): string => {\n return params.map(formatParam).join(' ')\n}\n\nconst isServerSide = typeof window === 'undefined'\nconst isLocal = isServerSide\n ? process?.env?.VITE_LOCAL === 'true'\n : import.meta.env?.VITE_LOCAL\n\nconst isLoggingEnabled = isLocal || isServerSide\n\nexport const log = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.log(...params)\n }\n}\n\nexport const error = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.error(formatParams(params))\n }\n}\nexport const info = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.info(...params)\n }\n}\nexport const debug = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.debug(...params)\n }\n}\nexport const warn = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.warn(formatParams(params))\n }\n}\nexport const assert = (condition: boolean | undefined, message: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.assert(condition, message)\n }\n}\nexport const clear = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.clear()\n }\n}\nexport const table = (table: unknown) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.table(table)\n }\n}\nexport const group = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.group(name)\n }\n}\nexport const groupEnd = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.groupEnd()\n }\n}\nexport const time = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.time(name)\n }\n}\nexport const timeEnd = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeEnd(name)\n }\n}\nexport const timeLog = (name: string, ...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeLog(name, ...params)\n }\n}\n\nexport const logger = {\n log,\n error,\n info,\n debug,\n warn,\n assert,\n clear,\n table,\n group,\n groupEnd,\n time,\n timeEnd,\n timeLog,\n}\n\nexport const useErrorsLogger = (errors: Ref<Error | null | undefined>[]) => {\n // Vue is an optional runtime dependency for the backend build.\n // Lazily import it only when running in a browser/Vue environment.\n if (typeof window === 'undefined') {\n return\n }\n\n void import('vue').then(({ watch }) => {\n errors.forEach((error) => {\n watch(error, (value) => {\n logger.error(value)\n })\n })\n })\n}\n","export const stripMarkdown = (text?: string | null) => {\n if (!text) {\n return undefined\n }\n return text\n .replace(/!\\[.*?\\]\\(.*?\\)/g, '') // images\n .replace(/\\[([^\\]]+)\\]\\(.*?\\)/g, '$1') // links\n .replace(/`{1,3}[^`]*`{1,3}/g, '') // inline code / code blocks\n .replace(/#{1,6}\\s/g, '') // headings\n .replace(/(\\*{1,3}|_{1,3})(.*?)\\1/g, '$2') // bold / italic\n .replace(/~~(.*?)~~/g, '$1') // strikethrough\n .replace(/^\\s*[-*+>]\\s+/gm, '') // lists and blockquotes\n .replace(/\\n+/g, ' ') // newlines\n .trim()\n}\n","import type { UIMessage } from 'ai'\n\ntype MessagePart = UIMessage['parts'][number]\n\nexport function isTextPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'text' }> {\n if (!part) return false\n return part.type === 'text'\n}\n\nexport function isToolPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: `tool-${string}` }> {\n if (!part) return false\n return part.type.startsWith('tool-')\n}\n\nexport function getToolPartName(part: MessagePart): string {\n if (!isToolPart(part)) return ''\n return part.type.slice('tool-'.length)\n}\n\nexport function isFilePart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'file' }> {\n if (!part) return false\n return part.type === 'file'\n}\n\nexport function isReasoningPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'reasoning' }> {\n if (!part) return false\n return part.type === 'reasoning'\n}\n\nexport function hasPartText(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { text: string }> {\n if (!part) return false\n if (isTextPart(part)) {\n return true\n }\n return (\n 'text' in part &&\n part.text !== undefined &&\n part.text !== null &&\n part.text !== ''\n )\n}\n\nexport function hasTextPart(message?: UIMessage): boolean {\n if (!message) return false\n return message.parts.some((part) => isTextPart(part))\n}\n\nexport function getTextPart(\n message: UIMessage | null | undefined,\n): string | undefined {\n if (!message) return undefined\n const textPart = message.parts.find((part) => isTextPart(part))\n return textPart?.text\n}\n\nexport function getMessageText(message: UIMessage | null | undefined): string {\n if (!message) return ''\n return message.parts\n .filter((p): p is Extract<MessagePart, { type: 'text' }> =>\n isTextPart(p),\n )\n .map((p) => p.text)\n .join('')\n}\n","export const removeAccents = (str: string) =>\n str.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n\nexport const toCamelCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toLowerCase()) as unknown as T\n}\n\nexport const fromCamelCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/([a-z])([A-Z])/g, '$1 $2')\n}\n\nexport const toPascalCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toUpperCase()) as unknown as T\n}\n\nexport const toKebabCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .toLowerCase() as unknown as T\n}\n\nexport const fromKebabCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/-/g, ' ')\n}\n\nexport const toSnakeCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .toLowerCase() as unknown as T\n}\n\nexport const capitalizeFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport const lowercaseFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n","/**\n * Check if URL points to an HTML page based on extension and content-type\n * @param url - The URL to check\n * @param contentType - Optional content-type header from response\n * @returns true if URL appears to be HTML, false otherwise\n */\nexport function isHtmlUrl(url: string, contentType?: string): boolean {\n // Check content-type if available\n if (contentType) {\n return contentType.includes('text/html')\n }\n\n // Check URL extension\n const urlObj = new URL(url)\n const pathname = urlObj.pathname.toLowerCase()\n\n // Exclude common non-HTML extensions\n const nonHtmlExtensions = [\n '.pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.ppt',\n '.pptx',\n '.zip',\n '.rar',\n '.tar',\n '.gz',\n '.jpg',\n '.jpeg',\n '.png',\n '.gif',\n '.svg',\n '.webp',\n '.mp4',\n '.avi',\n '.mov',\n '.mp3',\n '.wav',\n '.css',\n '.js',\n '.json',\n '.xml',\n '.txt',\n ]\n\n return !nonHtmlExtensions.some((ext) => pathname.endsWith(ext))\n}\n\n/**\n * Checks if a URL has an initial slash\n * @param url - The URL string to check\n * @returns true if URL has an initial slash, false otherwise\n */\nexport function hasInitialSlash(url: string): boolean {\n return url.startsWith('/')\n}\n\n/**\n * Adds an initial slash to a URL if it doesn't already have one\n * @param url - The URL string to modify\n * @returns The URL string with an initial slash\n */\nexport function addInitialSlash(url: string): string {\n return hasInitialSlash(url) ? url : `/${url}`\n}\n\n/**\n * Checks if a URL has a trailing slash\n * @param url - The URL string to check\n * @returns true if URL has a trailing slash, false otherwise\n */\nexport function hasTrailingSlash(url: string): boolean {\n return url.endsWith('/')\n}\n\n/**\n * Checks whether a URL belongs to the same site as the current page.\n * Relative URLs and malformed URLs are treated as same-site.\n * Comparison is based on hostname only, so http and https variants of\n * the same domain are considered the same site.\n * @param url - The URL to check\n * @returns true if the URL is same-site or relative/malformed, false otherwise\n */\nexport function isSameSite(url: string): boolean {\n try {\n const target = new URL(url, window.location.origin)\n return target.hostname === window.location.hostname\n } catch {\n return true\n }\n}\n\n/**\n * Removes the trailing slash from a URL if it exists\n * @param url - The URL string to modify\n * @returns The URL string without a trailing slash\n */\nexport function removeTrailingSlash(url: string): string {\n return hasTrailingSlash(url) ? url.slice(0, -1) : url\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"src-BRYn66N3.js","names":[],"sources":["../../../../packages/utils/src/cdn-css.ts","../../../../packages/utils/src/device-context.ts","../../../../packages/utils/src/logger.ts","../../../../packages/utils/src/markdown.ts","../../../../packages/utils/src/message.ts","../../../../packages/utils/src/text.ts","../../../../packages/utils/src/url-validation.ts"],"sourcesContent":["const loaded = new WeakMap<Node, Set<string>>()\n\n/**\n * Injects a CDN stylesheet `<link>` once per URL per root.\n * When a `ShadowRoot` is passed, the link is appended there so that\n * custom-element (Shadow DOM) encapsulation is respected.\n * Falls back to `document.head` for regular DOM usage.\n */\nexport function loadCdnCss(href: string, root?: ShadowRoot) {\n const target: Node = root ?? document.head\n let set = loaded.get(target)\n if (!set) {\n set = new Set()\n loaded.set(target, set)\n }\n if (set.has(href)) {\n return\n }\n const link = document.createElement('link')\n link.rel = 'stylesheet'\n link.href = href\n target.appendChild(link)\n set.add(href)\n}\n\n/** Returns the `ShadowRoot` ancestor of `el`, or `undefined` in regular DOM. */\nexport function getShadowRoot(el?: Element | null): ShadowRoot | undefined {\n const root = el?.getRootNode?.()\n return root instanceof ShadowRoot ? root : undefined\n}\n","interface NetworkInformation {\n type?: string\n effectiveType?: string\n downlink?: number\n rtt?: number\n saveData?: boolean\n}\n\ninterface NavigatorUAData {\n platform?: string\n}\n\n/**\n * Collects client-side device context information useful for chatbot interactions.\n * No additional permissions are required — all values are available by default in the browser.\n */\nexport function collectDeviceContext() {\n const connection = (\n navigator as Navigator & { connection?: NetworkInformation }\n ).connection\n\n const uaData = (\n navigator as Navigator & { userAgentData?: NavigatorUAData }\n ).userAgentData\n\n return {\n dateTime: new Date().toISOString(),\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n language: navigator.language,\n languages: [...navigator.languages],\n url: window.location.href,\n pathname: window.location.pathname,\n pageTitle: document.title,\n referrer: document.referrer || undefined,\n screenWidth: screen.width,\n screenHeight: screen.height,\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n devicePixelRatio: window.devicePixelRatio,\n maxTouchPoints: navigator.maxTouchPoints,\n hardwareConcurrency: navigator.hardwareConcurrency,\n deviceMemory: (navigator as Navigator & { deviceMemory?: number })\n .deviceMemory,\n platform: uaData?.platform,\n connectionType: connection?.type,\n connectionEffectiveType: connection?.effectiveType,\n connectionDownlink: connection?.downlink,\n connectionRtt: connection?.rtt,\n saveData: connection?.saveData,\n darkMode: window.matchMedia('(prefers-color-scheme: dark)').matches,\n reducedMotion: window.matchMedia('(prefers-reduced-motion: reduce)')\n .matches,\n historyLength: window.history.length,\n }\n}\n\nexport type GeolocationData = {\n geolocationLatitude: number\n geolocationLongitude: number\n geolocationAccuracy?: number\n geolocationCity?: string\n}\n\nexport type ReverseGeocodeFn = (\n lat: number,\n lon: number,\n) => Promise<string | undefined>\n\n/**\n * Collects geolocation data if the user has already granted permission.\n * Uses the Permissions API to avoid triggering a browser prompt.\n * Returns null if permission is not granted or geolocation is unavailable.\n * @param reverseGeocode - optional callback to resolve city name from coordinates (e.g. via backend proxy)\n */\nexport async function collectGeolocation(\n reverseGeocode?: ReverseGeocodeFn,\n): Promise<GeolocationData | null> {\n if (!navigator.geolocation || !navigator.permissions) {\n return null\n }\n\n try {\n const permission = await navigator.permissions.query({\n name: 'geolocation',\n })\n if (permission.state !== 'granted') {\n return null\n }\n\n const position = await new Promise<GeolocationPosition>(\n (resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject, {\n timeout: 10_000,\n })\n },\n )\n\n const { latitude, longitude, accuracy } = position.coords\n const city = reverseGeocode\n ? await reverseGeocode(latitude, longitude).catch(() => undefined)\n : undefined\n\n return {\n geolocationLatitude: latitude,\n geolocationLongitude: longitude,\n geolocationAccuracy: accuracy,\n geolocationCity: city,\n }\n } catch {\n return null\n }\n}\n","import type { Ref } from 'vue'\n\ntype ExceptionTracker = (\n error: Error,\n properties?: Record<string, string>,\n) => void\n\nlet _exceptionTracker: ExceptionTracker | undefined\n\n/**\n * Registers a callback invoked by error/warn/logError/logWarn to track exceptions\n * (e.g. Application Insights trackException).\n */\nexport const setExceptionTracker = (tracker: ExceptionTracker) => {\n _exceptionTracker = tracker\n}\n\nconst extractError = (params: unknown[]): Error => {\n const found = params.find((p): p is Error => p instanceof Error)\n if (found) {\n return found\n }\n return new Error(params.map(String).join(' '))\n}\n\nconst formatParam = (param: unknown): string => {\n if (param instanceof Error) {\n return param.stack ?? param.message\n }\n return String(param)\n}\n\nconst formatParams = (params: unknown[]): string => {\n return params.map(formatParam).join(' ')\n}\n\nconst isServerSide = typeof window === 'undefined'\nconst isLocal = isServerSide\n ? process?.env?.VITE_LOCAL === 'true'\n : import.meta.env?.VITE_LOCAL\n\nconst isLoggingEnabled = isLocal || isServerSide\n\nexport const log = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.log(...params)\n }\n}\n\nexport const error = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.error(formatParams(params))\n }\n}\nexport const info = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.info(...params)\n }\n}\nexport const debug = (...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.debug(...params)\n }\n}\nexport const warn = (...params: unknown[]) => {\n _exceptionTracker?.(extractError(params))\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.warn(formatParams(params))\n }\n}\nexport const assert = (condition: boolean | undefined, message: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.assert(condition, message)\n }\n}\nexport const clear = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.clear()\n }\n}\nexport const table = (table: unknown) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.table(table)\n }\n}\nexport const group = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.group(name)\n }\n}\nexport const groupEnd = () => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.groupEnd()\n }\n}\nexport const time = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.time(name)\n }\n}\nexport const timeEnd = (name: string) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeEnd(name)\n }\n}\nexport const timeLog = (name: string, ...params: unknown[]) => {\n if (isLoggingEnabled) {\n // eslint-disable-next-line no-console\n console.timeLog(name, ...params)\n }\n}\n\nexport const logger = {\n log,\n error,\n info,\n debug,\n warn,\n assert,\n clear,\n table,\n group,\n groupEnd,\n time,\n timeEnd,\n timeLog,\n}\n\nexport const useErrorsLogger = (errors: Ref<Error | null | undefined>[]) => {\n // Vue is an optional runtime dependency for the backend build.\n // Lazily import it only when running in a browser/Vue environment.\n if (typeof window === 'undefined') {\n return\n }\n\n void import('vue').then(({ watch }) => {\n errors.forEach((error) => {\n watch(error, (value) => {\n logger.error(value)\n })\n })\n })\n}\n","export const stripMarkdown = (text?: string | null) => {\n if (!text) {\n return undefined\n }\n return text\n .replace(/!\\[.*?\\]\\(.*?\\)/g, '') // images\n .replace(/\\[([^\\]]+)\\]\\(.*?\\)/g, '$1') // links\n .replace(/`{1,3}[^`]*`{1,3}/g, '') // inline code / code blocks\n .replace(/#{1,6}\\s/g, '') // headings\n .replace(/(\\*{1,3}|_{1,3})(.*?)\\1/g, '$2') // bold / italic\n .replace(/~~(.*?)~~/g, '$1') // strikethrough\n .replace(/^\\s*[-*+>]\\s+/gm, '') // lists and blockquotes\n .replace(/\\n+/g, ' ') // newlines\n .trim()\n}\n","import type { UIMessage } from 'ai'\n\ntype MessagePart = UIMessage['parts'][number]\n\nexport function isTextPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'text' }> {\n if (!part) return false\n return part.type === 'text'\n}\n\nexport function isToolPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: `tool-${string}` }> {\n if (!part) return false\n return part.type.startsWith('tool-')\n}\n\nexport function getToolPartName(part: MessagePart): string {\n if (!isToolPart(part)) return ''\n return part.type.slice('tool-'.length)\n}\n\nexport function isFilePart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'file' }> {\n if (!part) return false\n return part.type === 'file'\n}\n\nexport function isReasoningPart(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { type: 'reasoning' }> {\n if (!part) return false\n return part.type === 'reasoning'\n}\n\nexport function hasPartText(\n part: MessagePart | null | undefined,\n): part is Extract<MessagePart, { text: string }> {\n if (!part) return false\n if (isTextPart(part)) {\n return true\n }\n return (\n 'text' in part &&\n part.text !== undefined &&\n part.text !== null &&\n part.text !== ''\n )\n}\n\nexport function hasTextPart(message?: UIMessage): boolean {\n if (!message) return false\n return message.parts.some((part) => isTextPart(part))\n}\n\nexport function getTextPart(\n message: UIMessage | null | undefined,\n): string | undefined {\n if (!message) return undefined\n const textPart = message.parts.find((part) => isTextPart(part))\n return textPart?.text\n}\n\nexport function getMessageText(message: UIMessage | null | undefined): string {\n if (!message) return ''\n return message.parts\n .filter((p): p is Extract<MessagePart, { type: 'text' }> =>\n isTextPart(p),\n )\n .map((p) => p.text)\n .join('')\n}\n","export const removeAccents = (str: string) =>\n str.normalize('NFD').replace(/[\\u0300-\\u036f]/g, '')\n\nexport const toCamelCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toLowerCase()) as unknown as T\n}\n\nexport const fromCamelCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/([a-z])([A-Z])/g, '$1 $2')\n}\n\nexport const toPascalCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/[^a-zA-Z0-9]+(.)?/g, (_, c) => (c ? c.toUpperCase() : ''))\n .replace(/^(.)/, (match) => match.toUpperCase()) as unknown as T\n}\n\nexport const toKebabCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1-$2')\n .replace(/[^a-zA-Z0-9]+/g, '-')\n .toLowerCase() as unknown as T\n}\n\nexport const fromKebabCase = (str?: string): string => {\n if (!str) return ''\n return str.replace(/-/g, ' ')\n}\n\nexport const toSnakeCase = <T extends string>(str?: string): T => {\n if (!str) return '' as unknown as T\n return removeAccents(str)\n .replace(/([a-z0-9])([A-Z])/g, '$1_$2')\n .replace(/[^a-zA-Z0-9]+/g, '_')\n .toLowerCase() as unknown as T\n}\n\nexport const capitalizeFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toUpperCase() + str.slice(1)\n}\n\nexport const lowercaseFirstLetter = (str?: string) => {\n if (!str) return ''\n return str.charAt(0).toLowerCase() + str.slice(1)\n}\n","/**\n * Check if URL points to an HTML page based on extension and content-type\n * @param url - The URL to check\n * @param contentType - Optional content-type header from response\n * @returns true if URL appears to be HTML, false otherwise\n */\nexport function isHtmlUrl(url: string, contentType?: string): boolean {\n // Check content-type if available\n if (contentType) {\n return contentType.includes('text/html')\n }\n\n // Check URL extension\n let urlObj: URL\n try {\n urlObj = new URL(url)\n } catch {\n return false\n }\n const pathname = urlObj.pathname.toLowerCase()\n\n // Exclude common non-HTML extensions\n const nonHtmlExtensions = [\n '.pdf',\n '.doc',\n '.docx',\n '.xls',\n '.xlsx',\n '.ppt',\n '.pptx',\n '.zip',\n '.rar',\n '.tar',\n '.gz',\n '.jpg',\n '.jpeg',\n '.png',\n '.gif',\n '.svg',\n '.webp',\n '.mp4',\n '.avi',\n '.mov',\n '.mp3',\n '.wav',\n '.css',\n '.js',\n '.json',\n '.xml',\n '.txt',\n ]\n\n return !nonHtmlExtensions.some((ext) => pathname.endsWith(ext))\n}\n\n/**\n * Checks if a URL has an initial slash\n * @param url - The URL string to check\n * @returns true if URL has an initial slash, false otherwise\n */\nexport function hasInitialSlash(url: string): boolean {\n return url.startsWith('/')\n}\n\n/**\n * Adds an initial slash to a URL if it doesn't already have one\n * @param url - The URL string to modify\n * @returns The URL string with an initial slash\n */\nexport function addInitialSlash(url: string): string {\n return hasInitialSlash(url) ? url : `/${url}`\n}\n\n/**\n * Checks if a URL has a trailing slash\n * @param url - The URL string to check\n * @returns true if URL has a trailing slash, false otherwise\n */\nexport function hasTrailingSlash(url: string): boolean {\n return url.endsWith('/')\n}\n\n/**\n * Checks whether a URL belongs to the same site as the current page.\n * Relative URLs and malformed URLs are treated as same-site.\n * Comparison is based on hostname only, so http and https variants of\n * the same domain are considered the same site.\n * @param url - The URL to check\n * @returns true if the URL is same-site or relative/malformed, false otherwise\n */\nexport function isSameSite(url: string): boolean {\n try {\n const target = new URL(url, window.location.origin)\n return target.hostname === window.location.hostname\n } catch {\n return true\n }\n}\n\n/**\n * Removes the trailing slash from a URL if it exists\n * @param url - The URL string to modify\n * @returns The URL string without a trailing slash\n */\nexport function removeTrailingSlash(url: string): string {\n return hasTrailingSlash(url) ? url.slice(0, -1) : url\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { B as e, E as t, F as n, H as r, Ht as i, I as a, K as o, L as s, M as c, R as l, Y as u, Z as d, _ as f, b as p, ct as m, ft as h, h as g, j as _, k as ee, o as v, v as y, x as b, yt as x, z as S } from "./vue.runtime.esm-bundler-ljsQ8m_k.js";
|
|
2
|
-
import { Circle as te, CircleMarker as ne, Control as C, DivIcon as w, DomEvent as T, DomUtil as re, FeatureGroup as ie, GeoJSON as ae, GridLayer as oe, Icon as se, ImageOverlay as ce, LatLng as le, LatLngBounds as ue, LayerGroup as de, Map as fe, Marker as pe, Polygon as me, Polyline as he, Popup as ge, Rectangle as _e, SVGOverlay as ve, TileLayer as ye, Tooltip as be, Util as E, VideoOverlay as xe } from "https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1
|
|
2
|
+
import { Circle as te, CircleMarker as ne, Control as C, DivIcon as w, DomEvent as T, DomUtil as re, FeatureGroup as ie, GeoJSON as ae, GridLayer as oe, Icon as se, ImageOverlay as ce, LatLng as le, LatLngBounds as ue, LayerGroup as de, Map as fe, Marker as pe, Polygon as me, Polyline as he, Popup as ge, Rectangle as _e, SVGOverlay as ve, TileLayer as ye, Tooltip as be, Util as E, VideoOverlay as xe } from "https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet-src.js";
|
|
3
3
|
//#region ../../node_modules/.pnpm/@maxel01+vue-leaflet@1.0.0-beta.7_leaflet@2.0.0-alpha_vue@3.5.32_typescript@6.0.2_/node_modules/@maxel01/vue-leaflet/dist/vue-leaflet.es.js
|
|
4
4
|
var Se = /* @__PURE__ */ Symbol("getMapObject"), D = /* @__PURE__ */ Symbol("addLayer"), O = /* @__PURE__ */ Symbol("removeLayer"), k = /* @__PURE__ */ Symbol("registerControl"), Ce = /* @__PURE__ */ Symbol("registerLayerControl"), we = /* @__PURE__ */ Symbol("canSetParentHtml"), Te = /* @__PURE__ */ Symbol("setParentHtml"), Ee = /* @__PURE__ */ Symbol("setIcon"), A = /* @__PURE__ */ Symbol("bindPopup"), j = /* @__PURE__ */ Symbol("bindTooltip"), De = /* @__PURE__ */ Symbol("unbindPopup"), Oe = /* @__PURE__ */ Symbol("unbindTooltip"), M = { experimental: {
|
|
5
5
|
useResetWebpackIcon: !0,
|
|
@@ -48,9 +48,9 @@ var N = (e, t) => {
|
|
|
48
48
|
}, je = async (e) => {
|
|
49
49
|
if (!M.experimental.useResetWebpackIcon) return;
|
|
50
50
|
let t = await Promise.all([
|
|
51
|
-
import("https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1
|
|
52
|
-
import("https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1
|
|
53
|
-
import("https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1
|
|
51
|
+
import("https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet-src.js/dist/images/marker-icon-2x.png"),
|
|
52
|
+
import("https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet-src.js/dist/images/marker-icon.png"),
|
|
53
|
+
import("https://cdn.jsdelivr.net/npm/leaflet@2.0.0-alpha.1/dist/leaflet-src.js/dist/images/marker-shadow.png")
|
|
54
54
|
]);
|
|
55
55
|
delete e.Default.prototype._getIconUrl, e.Default.mergeOptions({
|
|
56
56
|
iconRetinaUrl: t[0].default,
|
|
@@ -1735,4 +1735,4 @@ var jt = {
|
|
|
1735
1735
|
//#endregion
|
|
1736
1736
|
export { D as AddLayerInjection, A as BindPopupInjection, j as BindTooltipInjection, we as CanSetParentHtmlInjection, _t as CreateVueGridLayer, Se as GetMapObjectInjection, Be as LCircle, He as LCircleMarker, We as LControl, qe as LControlAttribution, Xe as LControlLayers, $e as LControlScale, nt as LControlZoom, ut as LFeatureGroup, pt as LGeoJson, vt as LGridLayer, it as LIcon, ot as LImageOverlay, bt as LLayerGroup, wt as LMap, Mt as LMarker, Lt as LPolygon, zt as LPolyline, Wt as LPopup, Jt as LRectangle, Qt as LSVGOverlay, tn as LTileLayer, an as LTooltip, ln as LVideoOverlay, fn as LWmsTileLayer, k as RegisterControlInjection, Ce as RegisterLayerControlInjection, O as RemoveLayerInjection, Ee as SetIconInjection, Te as SetParentHtmlInjection, De as UnbindPopupInjection, Oe as UnbindTooltipInjection, V as assertInject, N as bindEventHandlers, P as cancelDebounces, Ae as capitalizeFirstLetter, Fe as circleMarkerPropsDefaults, Le as circlePropsDefaults, H as componentPropsDefaults, q as controlAbstractPropsDefaults, Ge as controlAttributionPropsDefaults, Je as controlLayersPropsDefaults, Ue as controlPropsDefaults, Ze as controlScalePropsDefaults, et as controlZoomPropsDefaults, st as featureGroupPropsDefaults, dt as geoJSONPropsDefaults, mt as gridLayerAbstractPropsDefaults, ht as gridLayerPropsDefaults, rt as iconPropsDefaults, Y as imageOverlayPropsDefaults, Me as interactiveLayerPropsDefaults, F as isFunction, Z as layerGroupPropsDefaults, W as layerPropsDefaults, St as mapPropsDefaults, Dt as markerPropsDefaults, K as pathPropsDefaults, $ as polygonPropsDefaults, Nt as polylinePropsDefaults, Bt as popperPropsDefaults, Ht as popupPropsDefaults, I as propsBinder, L as propsToLeafletOptions, z as provideLeafletWrapper, Gt as rectanglePropsDefaults, R as remapEvents, je as resetWebpackIcon, ke as setVueLeafletConfig, Re as setupCircle, Ie as setupCircleMarker, U as setupComponent, J as setupControl, Ke as setupControlAttribution, Ye as setupControlLayers, Qe as setupControlScale, tt as setupControlZoom, ct as setupFeatureGroup, ft as setupGeoJSON, gt as setupGridLayer, X as setupImageOverlay, Ne as setupInteractiveLayer, G as setupLayer, Q as setupLayerGroup, Ct as setupMap, Ot as setupMarker, Pe as setupPath, Ft as setupPolygon, Pt as setupPolyline, Vt as setupPopper, Ut as setupPopup, Kt as setupRectangle, Xt as setupSVGOverlay, en as setupTileLayer, rn as setupTooltip, sn as setupVideoOverlay, dn as setupWMSTileLayer, kt as shouldBlankIcon, Yt as svgOverlayPropsDefaults, $t as tileLayerPropsDefaults, nn as tooltipPropsDefaults, B as updateLeafletWrapper, on as videoOverlayPropsDefaults, M as vueLeafletConfig, un as wmsTileLayerPropsDefaults };
|
|
1737
1737
|
|
|
1738
|
-
//# sourceMappingURL=vue-leaflet.es-
|
|
1738
|
+
//# sourceMappingURL=vue-leaflet.es-BT-uRmMx.js.map
|