feat: 对接 Spark 大模型
This commit is contained in:
44
components/Markdown.vue
Normal file
44
components/Markdown.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<script setup lang="ts">
|
||||
import md from 'markdown-it'
|
||||
import hljs from "highlight.js";
|
||||
import 'highlight.js/styles/github-dark-dimmed.min.css';
|
||||
|
||||
const renderer = md({
|
||||
html: true,
|
||||
linkify: true,
|
||||
typographer: true,
|
||||
breaks: true,
|
||||
highlight: function (str, lang) {
|
||||
if (lang && hljs.getLanguage(lang)) {
|
||||
try {
|
||||
return (
|
||||
`<pre class="hljs" style="overflow-x: auto"><code>${
|
||||
hljs.highlight(str, {language: lang, ignoreIllegals: true}).value
|
||||
}</code></pre>`
|
||||
)
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
|
||||
return '<pre class="hljs"><code>' + md().utils.escapeHtml(str) + '</code></pre>';
|
||||
}
|
||||
})
|
||||
|
||||
const props = defineProps({
|
||||
source: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article
|
||||
class="prose dark:prose-invert max-w-none prose-sm prose-neutral"
|
||||
v-html="renderer.render(source.replaceAll('\t', ' '))"
|
||||
></article>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type {ChatSession} from "~/components/aigc/chat/index";
|
||||
import type {PropType} from "vue";
|
||||
import type {ChatSession} from "~/typings/llm";
|
||||
|
||||
const props = defineProps({
|
||||
active: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import type {PropType} from "vue";
|
||||
import type {ChatMessage} from "~/components/aigc/chat/index";
|
||||
import type {ChatMessage} from "~/typings/llm";
|
||||
import MessageResponding from "~/components/Icon/MessageResponding.vue";
|
||||
|
||||
const props = defineProps({
|
||||
@@ -24,6 +24,9 @@ const message_avatar = computed(() => {
|
||||
}
|
||||
})
|
||||
const message_background = computed(() => {
|
||||
if (props.message?.interrupted) {
|
||||
return 'bg-red-200/50 dark:bg-red-800/20 border-red-300 dark:!border-red-500/50'
|
||||
}
|
||||
switch (props.message?.role) {
|
||||
case 'user':
|
||||
return 'bg-primary-100 dark:bg-primary-800'
|
||||
@@ -47,15 +50,23 @@ const message_background = computed(() => {
|
||||
:class="message_background"
|
||||
:key="message.content"
|
||||
>
|
||||
<span v-if="message.content">
|
||||
{{ message.content }}
|
||||
</span>
|
||||
<div v-if="message.content">
|
||||
<!-- <span v-if="message.interrupted">-->
|
||||
<!-- <svg class="inline -mt-0.5 opacity-80" xmlns="http://www.w3.org/2000/svg" width="1.2em"-->
|
||||
<!-- height="1.2em" viewBox="0 0 24 24">-->
|
||||
<!-- <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"-->
|
||||
<!-- d="M12 9v4m-1.637-9.409L2.257 17.125a1.914 1.914 0 0 0 1.636 2.871h16.214a1.914 1.914 0 0 0 1.636-2.87L13.637 3.59a1.914 1.914 0 0 0-3.274 0zM12 16h.01"/>-->
|
||||
<!-- </svg>-->
|
||||
<!-- {{ message.content }}-->
|
||||
<!-- </span>-->
|
||||
<Markdown :source="message.content"/>
|
||||
</div>
|
||||
<span v-else>
|
||||
<MessageResponding class="text-xl text-neutral-500 dark:text-neutral-300 mx-2"/>
|
||||
</span>
|
||||
</div>
|
||||
</Transition>
|
||||
<div class="chat-inside-extra">
|
||||
<div v-if="message.create_at" class="chat-inside-extra">
|
||||
{{ dayjs(message.create_at * 1000).format('YYYY-MM-DD HH:mm:ss') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
20
components/aigc/chat/index.d.ts
vendored
20
components/aigc/chat/index.d.ts
vendored
@@ -1,20 +0,0 @@
|
||||
export type ChatSessionId = string
|
||||
export type ChatMessageId = string
|
||||
|
||||
export interface ChatSession {
|
||||
id: ChatSessionId
|
||||
subject: string
|
||||
create_at: number
|
||||
messages: ChatMessage[]
|
||||
last_input?: string
|
||||
}
|
||||
|
||||
export type MessageRole = 'user' | 'assistant' | 'system'
|
||||
|
||||
export interface ChatMessage {
|
||||
id: ChatMessageId
|
||||
role: MessageRole
|
||||
content: string
|
||||
create_at: number
|
||||
interrupted?: boolean
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {ResultBlockMeta} from '~/components/aigc/drawing';
|
||||
import type {ChatSession} from "~/components/aigc/chat";
|
||||
import type {ChatSession} from "~/typings/llm";
|
||||
|
||||
export interface HistoryItem {
|
||||
fid: string
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
export const useIdGenerator = () => {
|
||||
const generateUUID = () => {
|
||||
// noinspection SpellCheckingInspection
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8)
|
||||
return v.toString(16)
|
||||
})
|
||||
}
|
||||
|
||||
const generateMathRandom = () => {
|
||||
return Math.random().toString(36).slice(2)
|
||||
}
|
||||
|
||||
return {
|
||||
generateUUID,
|
||||
generateMathRandom
|
||||
}
|
||||
}
|
||||
31
composables/useLLM.ts
Normal file
31
composables/useLLM.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import {type ChatMessage, llmModels, type LLMSpark, type MessageRole, type ModelTag} from "~/typings/llm";
|
||||
import {useFetchWrapped} from "~/composables/useFetchWrapped";
|
||||
|
||||
export interface LLMRequestOptions {
|
||||
modelTag: ModelTag
|
||||
}
|
||||
|
||||
export const useLLM = (context: ChatMessage[], options: LLMRequestOptions): Promise<string> => new Promise((resolve, reject) => {
|
||||
const {modelTag} = options
|
||||
const model = llmModels.find(model => model.tag === modelTag)
|
||||
if (!model) return reject('model specified is not available')
|
||||
const loginState = useLoginState()
|
||||
useFetchWrapped<LLMSpark.request | AuthedRequest, BaseResponse<LLMSpark.response>>(
|
||||
model.endpoint,
|
||||
{
|
||||
token: loginState.token || '',
|
||||
user_id: loginState.user.id,
|
||||
prompt: JSON.stringify(context.filter(c => c.content && !c.interrupted).map(c => ({
|
||||
role: c.role,
|
||||
content: c.content
|
||||
})))
|
||||
}
|
||||
).then(res => {
|
||||
if (res.ret !== 200) return reject(res.msg || 'unknown error')
|
||||
if (res.data.request_msg) return resolve(res.data.request_msg)
|
||||
if (res.data.request_fail) return reject(res.data.request_fail?.header?.message || 'unknown error')
|
||||
return reject('unknown error')
|
||||
}).catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
@@ -15,7 +15,10 @@
|
||||
"@iconify-json/svg-spinners": "^1.1.2",
|
||||
"@iconify-json/tabler": "^1.1.105",
|
||||
"@nuxt/ui": "^2.14.1",
|
||||
"@uniiem/uuid": "^0.2.1",
|
||||
"highlight.js": "^11.9.0",
|
||||
"idb-keyval": "^6.2.1",
|
||||
"markdown-it": "^14.1.0",
|
||||
"nuxt": "^3.10.3",
|
||||
"radix-vue": "^1.4.9",
|
||||
"vue": "^3.4.19",
|
||||
@@ -26,6 +29,8 @@
|
||||
"@nuxtjs/google-fonts": "^3.2.0",
|
||||
"@pinia-plugin-persistedstate/nuxt": "^1.2.0",
|
||||
"@pinia/nuxt": "^0.5.1",
|
||||
"@tailwindcss/typography": "^0.5.12",
|
||||
"@types/markdown-it": "^13.0.7",
|
||||
"@vite-pwa/nuxt": "^0.5.0",
|
||||
"dayjs-nuxt": "^2.1.9",
|
||||
"sass": "^1.72.0"
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<script lang="ts" setup>
|
||||
import ChatItem from "~/components/aigc/chat/ChatItem.vue";
|
||||
import type {ChatMessage, ChatMessageId, ChatSessionId} from "~/components/aigc/chat";
|
||||
import Message from "~/components/aigc/chat/Message.vue";
|
||||
import {useIdGenerator} from "~/composables/useIdGenerator";
|
||||
import type {ChatMessage, ChatMessageId, ChatSessionId} from "~/typings/llm";
|
||||
import {useHistory} from "~/composables/useHistory";
|
||||
import {uuidv4} from "@uniiem/uuid";
|
||||
import {useLLM} from "~/composables/useLLM";
|
||||
|
||||
useHead({
|
||||
title: '聊天 | XSH AI'
|
||||
@@ -11,7 +12,6 @@ useHead({
|
||||
|
||||
const dayjs = useDayjs()
|
||||
const toast = useToast()
|
||||
const {generateUUID} = useIdGenerator()
|
||||
const historyStore = useHistory()
|
||||
const {chatSessions} = storeToRefs(historyStore)
|
||||
const {setChatSessions} = historyStore
|
||||
@@ -23,7 +23,15 @@ const messagesWrapperRef = ref<HTMLDivElement | null>(null)
|
||||
const user_input = ref('')
|
||||
const responding = ref(false)
|
||||
|
||||
/**
|
||||
* 获取指定 ID 的会话数据
|
||||
* @param chatSessionId
|
||||
*/
|
||||
const getSessionCopyById = (chatSessionId: ChatSessionId) => chatSessions.value.find(s => s.id === chatSessionId);
|
||||
/**
|
||||
* 切换当前会话
|
||||
* @param chatSessionId 指定会话 ID,不传则切换到列表中第一个会话
|
||||
*/
|
||||
const selectCurrentSessionId = (chatSessionId?: ChatSessionId) => {
|
||||
if (chatSessions.value.length > 0) {
|
||||
if (chatSessionId) { // 切换到指定 ID
|
||||
@@ -48,11 +56,17 @@ const selectCurrentSessionId = (chatSessionId?: ChatSessionId) => {
|
||||
} else {
|
||||
handleClickCreateSession()
|
||||
}
|
||||
nextTick(() => {
|
||||
scrollToMessageListBottom()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理新建会话操作
|
||||
*/
|
||||
const handleClickCreateSession = () => {
|
||||
// 生成一个新的会话 ID
|
||||
const sessionId = generateUUID()
|
||||
const sessionId = uuidv4()
|
||||
// 插入新会话数据
|
||||
setChatSessions([
|
||||
{
|
||||
@@ -67,6 +81,10 @@ const handleClickCreateSession = () => {
|
||||
selectCurrentSessionId(sessionId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理发送消息操作
|
||||
* @param event
|
||||
*/
|
||||
const handleClickSend = (event: any) => {
|
||||
if (event.ctrlKey) {
|
||||
return;
|
||||
@@ -84,7 +102,7 @@ const handleClickSend = (event: any) => {
|
||||
}
|
||||
// 插入用户消息
|
||||
insetMessage({
|
||||
id: generateUUID(),
|
||||
id: uuidv4(),
|
||||
role: 'user',
|
||||
content: user_input.value,
|
||||
create_at: dayjs().unix(),
|
||||
@@ -94,16 +112,20 @@ const handleClickSend = (event: any) => {
|
||||
responding.value = true
|
||||
// 插入空助手消息(加载状态)
|
||||
const assistantReplyId = insetMessage({
|
||||
id: generateUUID(),
|
||||
id: uuidv4(),
|
||||
role: 'assistant',
|
||||
content: '',
|
||||
create_at: dayjs().unix(),
|
||||
})
|
||||
// mock
|
||||
setTimeout(() => {
|
||||
modifyMessageContent(assistantReplyId, '草,走,忽略!ጿ ኈ ቼ ዽ ጿ')
|
||||
// 请求模型回复
|
||||
useLLM(getMessages(), {
|
||||
modelTag: 'spark3_5'
|
||||
}).then(reply => {
|
||||
modifyMessageContent(assistantReplyId, reply)
|
||||
}).catch(err => {
|
||||
modifyMessageContent(assistantReplyId, err, true)
|
||||
}).finally(() => {
|
||||
responding.value = false
|
||||
}, 1000)
|
||||
})
|
||||
}
|
||||
|
||||
const scrollToMessageListBottom = () => {
|
||||
@@ -127,12 +149,21 @@ const insetMessage = (message: ChatMessage): ChatMessageId => {
|
||||
return message.id
|
||||
}
|
||||
|
||||
const modifyMessageContent = (messageId: ChatMessageId, content: string) => {
|
||||
const getMessages = () => getSessionCopyById(currentSessionId.value!)?.messages || []
|
||||
|
||||
const modifyMessageContent = (
|
||||
messageId: ChatMessageId,
|
||||
content: string,
|
||||
interrupted: boolean = false,
|
||||
updateTime: boolean = true
|
||||
) => {
|
||||
setChatSessions(chatSessions.value.map(s => s.id === currentSessionId.value ? {
|
||||
...s,
|
||||
messages: s.messages.map(m => m.id === messageId ? {
|
||||
...m,
|
||||
content,
|
||||
interrupted,
|
||||
create_at: updateTime ? dayjs().unix() : m.create_at,
|
||||
} : m)
|
||||
} : s))
|
||||
scrollToMessageListBottom()
|
||||
@@ -188,7 +219,7 @@ onMounted(() => {
|
||||
<div class="flex flex-col gap-8 px-4 py-8">
|
||||
<TransitionGroup name="message">
|
||||
<Message
|
||||
v-for="message in getSessionCopyById(currentSessionId!)?.messages || []"
|
||||
v-for="message in getMessages() || []"
|
||||
:message="message"
|
||||
:key="message.id"
|
||||
/>
|
||||
@@ -234,8 +265,4 @@ onMounted(() => {
|
||||
.message-enter-from {
|
||||
@apply translate-y-4 opacity-0;
|
||||
}
|
||||
|
||||
.message-leave-to {
|
||||
@apply -translate-y-4 opacity-0;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
import type {Config} from 'tailwindcss'
|
||||
import defaultTheme from 'tailwindcss/defaultTheme'
|
||||
import typography from '@tailwindcss/typography'
|
||||
|
||||
export default <Partial<Config>>{
|
||||
theme: {
|
||||
@@ -19,6 +19,7 @@ export default <Partial<Config>>{
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [typography],
|
||||
safelist: [
|
||||
{
|
||||
pattern: /^bg-/,
|
||||
|
||||
83
typings/llm.ts
Normal file
83
typings/llm.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
export type ChatSessionId = string
|
||||
export type ChatMessageId = string
|
||||
|
||||
export type ModelTag =
|
||||
'spark1_5' |
|
||||
'spark3_0' |
|
||||
'spark3_5'
|
||||
|
||||
export interface LLMModal {
|
||||
tag: ModelTag
|
||||
name: string
|
||||
description: string
|
||||
endpoint: string
|
||||
}
|
||||
|
||||
export namespace LLMSpark {
|
||||
export interface request {
|
||||
prompt: string
|
||||
}
|
||||
export interface response {
|
||||
request_msg?: string
|
||||
request_fail?: {
|
||||
header?: {
|
||||
code: number
|
||||
message: string
|
||||
sid: string
|
||||
status: number
|
||||
}
|
||||
}
|
||||
// answer: string
|
||||
// last_data: {
|
||||
// payload: {
|
||||
// usage: {
|
||||
// text: {
|
||||
// completion_tokens: number
|
||||
// prompt_tokens: number
|
||||
// question_tokens: number
|
||||
// total_tokens: number
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
export const llmModels: Readonly<LLMModal[]> = Object.freeze([
|
||||
{
|
||||
tag: 'spark1_5',
|
||||
name: 'Spark 1.5',
|
||||
description: 'Spark 1.5',
|
||||
endpoint: 'App.Assistant_Spark.Chat_1_5'
|
||||
},
|
||||
{
|
||||
tag: 'spark3_0',
|
||||
name: 'Spark 3.0',
|
||||
description: 'Spark 3.0',
|
||||
endpoint: 'App.Assistant_Spark.Chat_3_0'
|
||||
},
|
||||
{
|
||||
tag: 'spark3_5',
|
||||
name: 'Spark 3.5',
|
||||
description: 'Spark 3.5',
|
||||
endpoint: 'App.Assistant_Spark.Chat_3_5'
|
||||
},
|
||||
])
|
||||
|
||||
export interface ChatSession {
|
||||
id: ChatSessionId
|
||||
subject: string
|
||||
create_at: number
|
||||
messages: ChatMessage[]
|
||||
last_input?: string
|
||||
}
|
||||
|
||||
export type MessageRole = 'user' | 'assistant' | 'system'
|
||||
|
||||
export interface ChatMessage {
|
||||
id: ChatMessageId
|
||||
role: MessageRole
|
||||
content: string
|
||||
create_at?: number
|
||||
interrupted?: boolean
|
||||
}
|
||||
105
yarn.lock
105
yarn.lock
@@ -2255,6 +2255,16 @@
|
||||
lodash.merge "^4.6.2"
|
||||
postcss-selector-parser "6.0.10"
|
||||
|
||||
"@tailwindcss/typography@^0.5.12":
|
||||
version "0.5.12"
|
||||
resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.12.tgz#c0532fd594427b7f4e8e38eff7bf272c63a1dca4"
|
||||
integrity sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==
|
||||
dependencies:
|
||||
lodash.castarray "^4.4.0"
|
||||
lodash.isplainobject "^4.0.6"
|
||||
lodash.merge "^4.6.2"
|
||||
postcss-selector-parser "6.0.10"
|
||||
|
||||
"@tanstack/virtual-core@3.1.2":
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmmirror.com/@tanstack/virtual-core/-/virtual-core-3.1.2.tgz#ca76f28f826fbd3310f88c3cd355d9c4aba80abb"
|
||||
@@ -2302,6 +2312,24 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/linkify-it@*":
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/linkify-it/-/linkify-it-3.0.5.tgz#1e78a3ac2428e6d7e6c05c1665c242023a4601d8"
|
||||
integrity sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==
|
||||
|
||||
"@types/markdown-it@^13.0.7":
|
||||
version "13.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-13.0.7.tgz#4a495115f470075bd4434a0438ac477a49c2e152"
|
||||
integrity sha512-U/CBi2YUUcTHBt5tjO2r5QV/x0Po6nsYwQU4Y04fBS6vfoImaiZ6f8bi3CjTCxBPQSO1LMyUqkByzi8AidyxfA==
|
||||
dependencies:
|
||||
"@types/linkify-it" "*"
|
||||
"@types/mdurl" "*"
|
||||
|
||||
"@types/mdurl@*":
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.5.tgz#3e0d2db570e9fb6ccb2dc8fde0be1d79ac810d39"
|
||||
integrity sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==
|
||||
|
||||
"@types/node@*":
|
||||
version "20.11.20"
|
||||
resolved "https://registry.npmmirror.com/@types/node/-/node-20.11.20.tgz#f0a2aee575215149a62784210ad88b3a34843659"
|
||||
@@ -2372,6 +2400,11 @@
|
||||
hookable "^5.5.3"
|
||||
unhead "1.8.10"
|
||||
|
||||
"@uniiem/uuid@^0.2.1":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@uniiem/uuid/-/uuid-0.2.1.tgz#2ffa44624968cda47ef744770b2b58f5e5e558f8"
|
||||
integrity sha512-p8DOA3BTkZgvgtOCtK5x7Y2l+GRTFhYrOua70YPiEEUomQFirwxpWrQBst+7oB/iPTeY1zHuF6MKl+mxi0R00A==
|
||||
|
||||
"@vercel/nft@^0.24.3":
|
||||
version "0.24.4"
|
||||
resolved "https://registry.npmmirror.com/@vercel/nft/-/nft-0.24.4.tgz#b8942340c7821e6ff7bdf943b559642dbc9cae78"
|
||||
@@ -3668,7 +3701,7 @@ enhanced-resolve@^5.14.1:
|
||||
graceful-fs "^4.2.4"
|
||||
tapable "^2.2.0"
|
||||
|
||||
entities@^4.2.0, entities@^4.5.0:
|
||||
entities@^4.2.0, entities@^4.4.0, entities@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
@@ -4372,6 +4405,11 @@ hasown@^2.0.0, hasown@^2.0.1:
|
||||
dependencies:
|
||||
function-bind "^1.1.2"
|
||||
|
||||
highlight.js@^11.9.0:
|
||||
version "11.9.0"
|
||||
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-11.9.0.tgz#04ab9ee43b52a41a047432c8103e2158a1b8b5b0"
|
||||
integrity sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==
|
||||
|
||||
hookable@^5.5.3:
|
||||
version "5.5.3"
|
||||
resolved "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d"
|
||||
@@ -5087,6 +5125,13 @@ lines-and-columns@^1.1.6:
|
||||
resolved "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
|
||||
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
|
||||
|
||||
linkify-it@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421"
|
||||
integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==
|
||||
dependencies:
|
||||
uc.micro "^2.0.0"
|
||||
|
||||
listhen@^1.5.5:
|
||||
version "1.7.2"
|
||||
resolved "https://registry.npmmirror.com/listhen/-/listhen-1.7.2.tgz#66b81740692269d5d8cafdc475020f2fc51afbae"
|
||||
@@ -5274,6 +5319,18 @@ make-fetch-happen@^13.0.0:
|
||||
promise-retry "^2.0.1"
|
||||
ssri "^10.0.0"
|
||||
|
||||
markdown-it@^14.1.0:
|
||||
version "14.1.0"
|
||||
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45"
|
||||
integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
entities "^4.4.0"
|
||||
linkify-it "^5.0.0"
|
||||
mdurl "^2.0.0"
|
||||
punycode.js "^2.3.1"
|
||||
uc.micro "^2.1.0"
|
||||
|
||||
mdn-data@2.0.28:
|
||||
version "2.0.28"
|
||||
resolved "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba"
|
||||
@@ -5284,6 +5341,11 @@ mdn-data@2.0.30:
|
||||
resolved "https://registry.npmmirror.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc"
|
||||
integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==
|
||||
|
||||
mdurl@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0"
|
||||
integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.npmmirror.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
@@ -6484,6 +6546,11 @@ protocols@^2.0.0, protocols@^2.0.1:
|
||||
resolved "https://registry.npmmirror.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86"
|
||||
integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==
|
||||
|
||||
punycode.js@^2.3.1:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7"
|
||||
integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||
@@ -7143,7 +7210,16 @@ streamx@^2.15.0:
|
||||
optionalDependencies:
|
||||
bare-events "^2.2.0"
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
"string-width-cjs@npm:string-width@^4.2.0":
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.1"
|
||||
|
||||
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@@ -7226,7 +7302,14 @@ stringify-object@^3.3.0:
|
||||
is-obj "^1.0.1"
|
||||
is-regexp "^1.0.0"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
@@ -7591,6 +7674,11 @@ typed-array-length@^1.0.4:
|
||||
is-typed-array "^1.1.13"
|
||||
possible-typed-array-names "^1.0.0"
|
||||
|
||||
uc.micro@^2.0.0, uc.micro@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee"
|
||||
integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==
|
||||
|
||||
ufo@^1.1.2, ufo@^1.2.0, ufo@^1.3.0, ufo@^1.3.1, ufo@^1.3.2, ufo@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmmirror.com/ufo/-/ufo-1.4.0.tgz#39845b31be81b4f319ab1d99fd20c56cac528d32"
|
||||
@@ -8263,7 +8351,16 @@ workbox-window@7.0.0, workbox-window@^7.0.0:
|
||||
"@types/trusted-types" "^2.0.2"
|
||||
workbox-core "7.0.0"
|
||||
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
|
||||
Reference in New Issue
Block a user