hexo-theme-redefine
Version:
Redefine your writing with Hexo Theme Redefine.
1 lines • 1.11 MB
Source Map (JSON)
{"version":3,"file":"waline.js","sources":["../../../node_modules/.pnpm/@waline+api@1.0.0-alpha.8/node_modules/@waline/api/dist/api.js","../src/config/default.ts","../src/config/highlighter.ts","../src/config/i18n/generate.ts","../src/config/i18n/en.ts","../src/config/i18n/fr.ts","../src/config/i18n/jp.ts","../src/config/i18n/pt-BR.ts","../src/config/i18n/ru.ts","../src/config/i18n/vi-VN.ts","../src/config/i18n/zh-CN.ts","../src/config/i18n/zh-TW.ts","../src/config/i18n/index.ts","../src/utils/path.ts","../src/utils/config.ts","../src/utils/type.ts","../src/utils/darkmode.ts","../src/utils/date.ts","../src/utils/email.ts","../../../node_modules/.pnpm/@vue+shared@3.4.27/node_modules/@vue/shared/dist/shared.esm-bundler.js","../../../node_modules/.pnpm/@vue+reactivity@3.4.27/node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js","../../../node_modules/.pnpm/@vue+runtime-core@3.4.27/node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js","../../../node_modules/.pnpm/@vue+runtime-dom@3.4.27/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js","../../../node_modules/.pnpm/@vueuse+shared@10.10.0_vue@3.4.27_typescript@5.4.5_/node_modules/@vueuse/shared/index.mjs","../../../node_modules/.pnpm/@vueuse+core@10.10.0_vue@3.4.27_typescript@5.4.5_/node_modules/@vueuse/core/index.mjs","../src/utils/emoji.ts","../src/utils/error.ts","../src/utils/getRoot.ts","../src/utils/image.ts","../../../node_modules/.pnpm/marked@12.0.2/node_modules/marked/lib/marked.esm.js","../../../node_modules/.pnpm/marked-highlight@2.1.1_marked@12.0.2/node_modules/marked-highlight/src/index.js","../src/utils/markedMathExtension.ts","../src/utils/markdown.ts","../src/utils/query.ts","../src/utils/wordCount.ts","../src/utils/userAgent.ts","../src/comment.ts","../src/components/Icons.ts","../src/composables/inputs.ts","../src/composables/like.ts","../src/composables/reaction.ts","../../../node_modules/.pnpm/recaptcha-v3@1.10.0/node_modules/recaptcha-v3/dist/ReCaptchaInstance.js","../../../node_modules/.pnpm/recaptcha-v3@1.10.0/node_modules/recaptcha-v3/dist/ReCaptchaLoader.js","../../../node_modules/.pnpm/recaptcha-v3@1.10.0/node_modules/recaptcha-v3/dist/ReCaptcha.js","../src/composables/recaptchaV3.ts","../src/composables/turnstile.ts","../src/composables/userInfo.ts","../src/components/ArticleReaction.vue","../../../node_modules/.pnpm/autosize@6.0.1/node_modules/autosize/dist/autosize.esm.js","../src/components/ImageWall.vue","../src/components/CommentBox.vue","../src/components/CommentCard.vue","../src/version.ts","../src/components/WalineComment.vue","../src/pageview.ts","../src/init.ts","../src/widgets/recentComments.ts","../src/widgets/userList.ts"],"sourcesContent":["const m={\"Content-Type\":\"application/json\"},s=e=>`${e.replace(/\\/?$/,\"/\")}api/`,c=(e,n=\"\")=>{if(typeof e==\"object\"&&e.errno)throw new TypeError(`${n} failed with ${e.errno}: ${e.errmsg}`);return e},p=({serverURL:e,lang:n,paths:o,type:a,signal:t})=>fetch(`${s(e)}article?path=${encodeURIComponent(o.join(\",\"))}&type=${encodeURIComponent(a.join(\",\"))}&lang=${n}`,{signal:t}).then(r=>r.json()).then(r=>c(r,\"Get counter\").data),d=({serverURL:e,lang:n,path:o,type:a,action:t})=>fetch(`${s(e)}article?lang=${n}`,{method:\"POST\",headers:m,body:JSON.stringify({path:o,type:a,action:t})}).then(r=>r.json()).then(r=>c(r,\"Update counter\").data),$=({serverURL:e,lang:n,path:o,page:a,pageSize:t,sortBy:r,signal:h,token:i})=>{const l={};return i&&(l.Authorization=`Bearer ${i}`),fetch(`${s(e)}comment?path=${encodeURIComponent(o)}&pageSize=${t}&page=${a}&lang=${n}&sortBy=${r}`,{signal:h,headers:l}).then(g=>g.json()).then(g=>c(g,\"Get comment data\").data)},u=({serverURL:e,lang:n,token:o,comment:a})=>{const t={\"Content-Type\":\"application/json\"};return o&&(t.Authorization=`Bearer ${o}`),fetch(`${s(e)}comment?lang=${n}`,{method:\"POST\",headers:t,body:JSON.stringify(a)}).then(r=>r.json())},y=({serverURL:e,lang:n,token:o,objectId:a})=>fetch(`${s(e)}comment/${a}?lang=${n}`,{method:\"DELETE\",headers:{Authorization:`Bearer ${o}`}}).then(t=>t.json()).then(t=>c(t,\"Delete comment\")),U=({serverURL:e,lang:n,token:o,objectId:a,comment:t})=>fetch(`${s(e)}comment/${a}?lang=${n}`,{method:\"PUT\",headers:{...m,Authorization:`Bearer ${o}`},body:JSON.stringify(t)}).then(r=>r.json()).then(r=>c(r,\"Update comment\")),f=({serverURL:e,lang:n,paths:o,signal:a})=>fetch(`${s(e)}comment?type=count&url=${encodeURIComponent(o.join(\",\"))}&lang=${n}`,{signal:a}).then(t=>t.json()).then(t=>c(t,\"Get comment count\").data),R=({lang:e,serverURL:n})=>{const o=(window.innerWidth-450)/2,a=(window.innerHeight-450)/2,t=window.open(`${n.replace(/\\/$/,\"\")}/ui/login?lng=${encodeURIComponent(e)}`,\"_blank\",`width=450,height=450,left=${o},top=${a},scrollbars=no,resizable=no,status=no,location=no,toolbar=no,menubar=no`);return t?.postMessage({type:\"TOKEN\",data:null},\"*\"),new Promise(r=>{const h=({data:i})=>{!i||typeof i!=\"object\"||i.type!==\"userInfo\"||i.data.token&&(t?.close(),window.removeEventListener(\"message\",h),r(i.data))};window.addEventListener(\"message\",h)})},j=({serverURL:e,lang:n,paths:o,signal:a})=>p({serverURL:e,lang:n,paths:o,type:[\"time\"],signal:a}),v=e=>d({...e,type:\"time\",action:\"inc\"}),w=({serverURL:e,lang:n,count:o,signal:a,token:t})=>{const r={};return t&&(r.Authorization=`Bearer ${t}`),fetch(`${s(e)}comment?type=recent&count=${o}&lang=${n}`,{signal:a,headers:r}).then(h=>h.json())},C=({serverURL:e,signal:n,pageSize:o,lang:a})=>fetch(`${s(e)}user?pageSize=${o}&lang=${a}`,{signal:n}).then(t=>t.json()).then(t=>c(t,\"user list\")).then(t=>t.data);export{u as addComment,y as deleteComment,f as fetchCommentCount,p as getArticleCounter,$ as getComment,j as getPageview,w as getRecentComment,C as getUserList,R as login,d as updateArticleCounter,U as updateComment,v as updatePageview};\n//# sourceMappingURL=api.js.map\n","import type { IGif } from '@giphy/js-types';\n\nimport type {\n WalineEmojiPresets,\n WalineMeta,\n WalineSearchOptions,\n WalineSearchResult,\n} from '../typings/index.js';\n\nconst AVAILABLE_META: WalineMeta[] = ['nick', 'mail', 'link'];\n\nexport const getMeta = (meta: WalineMeta[]): WalineMeta[] =>\n meta.filter((item) => AVAILABLE_META.includes(item));\n\nexport const DEFAULT_EMOJI: WalineEmojiPresets[] = [\n '//unpkg.com/@waline/emojis@1.1.0/weibo',\n];\n\nexport const DEFAULT_REACTION = [\n '//unpkg.com/@waline/emojis/tieba/tieba_agree.png',\n '//unpkg.com/@waline/emojis/tieba/tieba_look_down.png',\n '//unpkg.com/@waline/emojis/tieba/tieba_sunglasses.png',\n '//unpkg.com/@waline/emojis/tieba/tieba_pick_nose.png',\n '//unpkg.com/@waline/emojis/tieba/tieba_awkward.png',\n '//unpkg.com/@waline/emojis/tieba/tieba_sleep.png',\n];\n\nexport const defaultUploadImage = (file: File): Promise<string> =>\n new Promise((resolve, reject) => {\n if (file.size > 128 * 1000)\n return reject(new Error('File too large! File size limit 128KB'));\n\n const reader = new FileReader();\n\n reader.readAsDataURL(file);\n reader.onload = (): void => resolve(reader.result?.toString() ?? '');\n reader.onerror = reject;\n });\n\nexport const defaultTeXRenderer = (blockMode: boolean): string =>\n blockMode === true\n ? '<p class=\"wl-tex\">TeX is not available in preview</p>'\n : '<span class=\"wl-tex\">TeX is not available in preview</span>';\n\nexport const getDefaultSearchOptions = (lang: string): WalineSearchOptions => {\n interface GifResult {\n data: IGif[];\n meta: {\n msg: string;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n response_id: string;\n status: number;\n };\n pagination: {\n count: number;\n // eslint-disable-next-line @typescript-eslint/naming-convention\n total_count: number;\n offset: number;\n };\n }\n\n const fetchGiphy = async (\n url: string,\n params: Record<string, string> = {},\n ): Promise<WalineSearchResult> =>\n fetch(\n `https://api.giphy.com/v1/gifs/${url}?${new URLSearchParams({\n lang,\n limit: '20',\n rating: 'g',\n // eslint-disable-next-line @typescript-eslint/naming-convention\n api_key: '6CIMLkNMMOhRcXPoMCPkFy4Ybk2XUiMp',\n ...params,\n }).toString()}`,\n )\n .then((resp) => resp.json() as Promise<GifResult>)\n .then(({ data }) =>\n data.map((gif) => ({\n title: gif.title,\n src: gif.images.downsized_medium.url,\n })),\n );\n\n return {\n search: (word: string): Promise<WalineSearchResult> =>\n fetchGiphy('search', { q: word, offset: '0' }),\n default: (): Promise<WalineSearchResult> => fetchGiphy('trending', {}),\n more: (word: string, offset = 0): Promise<WalineSearchResult> =>\n fetchGiphy('search', { q: word, offset: offset.toString() }),\n };\n};\n","/**\n * The MIT License (MIT)\n *\n * Copyright (c) egoist <0x142857@gmail.com> (https://egoistian.com)\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n *\n */\n\nconst WORD_REGEXP =\n /[\\u4E00-\\u9FFF\\u3400-\\u4dbf\\uf900-\\ufaff\\u3040-\\u309f\\uac00-\\ud7af\\u0400-\\u04FF]+|\\w+/;\nconst LEFT_ANGLE_REGEXP = /</;\nconst LINE_COMMENT_REGEXP = /(?:^|\\s)\\/\\/(.+?)$/gm;\nconst BLOCK_COMMENT_REGEXP = /\\/\\*([\\S\\s]*?)\\*\\//gm;\nconst REGEXP = new RegExp(\n `(${WORD_REGEXP.source}|${LEFT_ANGLE_REGEXP.source})|((?:${LINE_COMMENT_REGEXP.source})|(?:${BLOCK_COMMENT_REGEXP.source}))`,\n 'gmi',\n);\n\nconst COLORS = [\n '23AC69',\n '91C132',\n 'F19726',\n 'E8552D',\n '1AAB8E',\n 'E1147F',\n '2980C1',\n '1BA1E6',\n '9FA0A0',\n 'F19726',\n 'E30B20',\n 'E30B20',\n 'A3338B',\n];\nconst cache: Record<string, string> = {};\n\nexport const defaultHighlighter = (input: string): string => {\n let index = 0;\n\n return input.replace(REGEXP, (_match, word: string, comment: string) => {\n if (comment) return `<span style=\"color: slategray\">${comment}</span>`;\n if (word === '<') return '<';\n\n let color: string;\n\n if (cache[word]) color = cache[word];\n else {\n color = COLORS[index];\n cache[word] = color;\n }\n\n const out = `<span style=\"color: #${color}\">${word}</span>`;\n\n index = ++index % COLORS.length;\n\n return out;\n });\n};\n","import type { WalineLocale } from '../../typings/index.js';\n\nconst localeKeys = [\n 'nick',\n 'nickError',\n 'mail',\n 'mailError',\n 'link',\n 'optional',\n 'placeholder',\n 'sofa',\n 'submit',\n 'like',\n 'cancelLike',\n 'reply',\n 'cancelReply',\n 'comment',\n 'refresh',\n 'more',\n 'preview',\n 'emoji',\n 'uploadImage',\n 'seconds',\n 'minutes',\n 'hours',\n 'days',\n 'now',\n 'uploading',\n 'login',\n 'logout',\n 'admin',\n 'sticky',\n 'word',\n 'wordHint',\n 'anonymous',\n 'level0',\n 'level1',\n 'level2',\n 'level3',\n 'level4',\n 'level5',\n 'gif',\n 'gifSearchPlaceholder',\n 'profile',\n 'approved',\n 'waiting',\n 'spam',\n 'unsticky',\n 'oldest',\n 'latest',\n 'hottest',\n 'reactionTitle',\n];\n\nexport const generateLocale = (locale: string[]): WalineLocale =>\n Object.fromEntries(\n locale.map((item, index) => [localeKeys[index], item]),\n ) as unknown as WalineLocale;\n","import { generateLocale } from './generate.js';\n\nexport default generateLocale([\n 'NickName',\n 'NickName cannot be less than 3 bytes.',\n 'E-Mail',\n 'Please confirm your email address.',\n 'Website',\n 'Optional',\n 'Comment here...',\n 'No comment yet.',\n 'Submit',\n 'Like',\n 'Cancel like',\n 'Reply',\n 'Cancel reply',\n 'Comments',\n 'Refresh',\n 'Load More...',\n 'Preview',\n 'Emoji',\n 'Upload Image',\n 'seconds ago',\n 'minutes ago',\n 'hours ago',\n 'days ago',\n 'just now',\n 'Uploading',\n 'Login',\n 'logout',\n 'Admin',\n 'Sticky',\n 'Words',\n 'Please input comments between $0 and $1 words!\\n Current word number: $2',\n 'Anonymous',\n 'Dwarves',\n 'Hobbits',\n 'Ents',\n 'Wizards',\n 'Elves',\n 'Maiar',\n 'GIF',\n 'Search GIF',\n 'Profile',\n 'Approved',\n 'Waiting',\n 'Spam',\n 'Unsticky',\n 'Oldest',\n 'Latest',\n 'Hottest',\n 'What do you think?',\n]);\n","/* fr.ts */\n\nimport { generateLocale } from './generate.js';\n\nexport default generateLocale([\n 'Pseudo',\n 'Le pseudo ne peut pas faire moins de 3 octets.',\n 'E-mail',\n 'Veuillez confirmer votre adresse e-mail.',\n 'Site Web',\n 'Optionnel',\n 'Commentez ici...',\n \"Aucun commentaire pour l'instant.\",\n 'Envoyer',\n \"J'aime\",\n \"Annuler le j'aime\",\n 'Répondre',\n 'Annuler la réponse',\n 'Commentaires',\n 'Actualiser',\n 'Charger plus...',\n 'Aperçu',\n 'Emoji',\n 'Télécharger une image',\n 'Il y a quelques secondes',\n 'Il y a quelques minutes',\n 'Il y a quelques heures',\n 'Il y a quelques jours',\n \"À l'instant\",\n 'Téléchargement en cours',\n 'Connexion',\n 'Déconnexion',\n 'Admin',\n 'Épinglé',\n 'Mots',\n 'Veuillez saisir des commentaires entre $0 et $1 mots !\\n Nombre actuel de mots : $2',\n 'Anonyme',\n 'Nains',\n 'Hobbits',\n 'Ents',\n 'Mages',\n 'Elfes',\n 'Maïar',\n 'GIF',\n 'Rechercher un GIF',\n 'Profil',\n 'Approuvé',\n 'En attente',\n 'Indésirable',\n 'Détacher',\n 'Le plus ancien',\n 'Dernier',\n 'Le plus populaire',\n \"Qu'en pensez-vous ?\",\n]);\n","import { generateLocale } from './generate.js';\n\nexport default generateLocale([\n 'ニックネーム',\n '3バイト以上のニックネームをご入力ください.',\n 'メールアドレス',\n 'メールアドレスをご確認ください.',\n 'サイト',\n 'オプション',\n 'ここにコメント',\n 'コメントしましょう~',\n '提出する',\n 'Like',\n 'Cancel like',\n '返信する',\n 'キャンセル',\n 'コメント',\n '更新',\n 'さらに読み込む',\n 'プレビュー',\n '絵文字',\n '画像をアップロード',\n '秒前',\n '分前',\n '時間前',\n '日前',\n 'たっだ今',\n 'アップロード',\n 'ログインする',\n 'ログアウト',\n '管理者',\n 'トップに置く',\n 'ワード',\n 'コメントは $0 から $1 ワードの間でなければなりません!\\n 現在の単語番号: $2',\n '匿名',\n 'うえにん',\n 'なかにん',\n 'しもおし',\n '特にしもおし',\n 'かげ',\n 'なぬし',\n 'GIF',\n '探す GIF',\n '個人情報',\n '承認済み',\n '待っている',\n 'スパム',\n 'べたつかない',\n '逆順',\n '正順',\n '人気順',\n 'どう思いますか?',\n]);\n","import { generateLocale } from './generate.js';\n\nexport default generateLocale([\n 'Apelido',\n 'Apelido não pode ser menor que 3 bytes.',\n 'E-Mail',\n 'Por favor, confirme seu endereço de e-mail.',\n 'Website',\n 'Opcional',\n 'Comente aqui...',\n 'Nenhum comentário, ainda.',\n 'Enviar',\n 'Like',\n 'Cancel like',\n 'Responder',\n 'Cancelar resposta',\n 'Comentários',\n 'Refrescar',\n 'Carregar Mais...',\n 'Visualizar',\n 'Emoji',\n 'Enviar Imagem',\n 'segundos atrás',\n 'minutos atrás',\n 'horas atrás',\n 'dias atrás',\n 'agora mesmo',\n 'Enviando',\n 'Entrar',\n 'Sair',\n 'Admin',\n 'Sticky',\n 'Palavras',\n 'Favor enviar comentário com $0 a $1 palavras!\\n Número de palavras atuais: $2',\n 'Anônimo',\n 'Dwarves',\n 'Hobbits',\n 'Ents',\n 'Wizards',\n 'Elves',\n 'Maiar',\n 'GIF',\n 'Pesquisar GIF',\n 'informação pessoal',\n 'Aprovado',\n 'Espera',\n 'Spam',\n 'Unsticky',\n 'Mais velho',\n 'Mais recentes',\n 'Mais quente',\n 'O que você acha?',\n]);\n","import { generateLocale } from './generate.js';\n\nexport default generateLocale([\n 'Псевдоним',\n 'Никнейм не может быть меньше 3 байт.',\n 'Эл. адрес',\n 'Пожалуйста, подтвердите адрес вашей электронной почты.',\n 'Веб-сайт',\n 'Необязательный',\n 'Комментарий здесь...',\n 'Пока нет комментариев.',\n 'Отправить',\n 'Like',\n 'Cancel like',\n 'Отвечать',\n 'Отменить ответ',\n 'Комментарии',\n 'Обновить',\n 'Загрузи больше...',\n 'Превью',\n 'эмодзи',\n 'Загрузить изображение',\n 'секунд назад',\n 'несколько минут назад',\n 'несколько часов назад',\n 'дней назад',\n 'прямо сейчас',\n 'Загрузка',\n 'Авторизоваться',\n 'Выход из системы',\n 'Админ',\n 'Липкий',\n 'Слова',\n 'Пожалуйста, введите комментарии от $0 до $1 слов!\\nНомер текущего слова: $2',\n 'Анонимный',\n 'Dwarves',\n 'Hobbits',\n 'Ents',\n 'Wizards',\n 'Elves',\n 'Maiar',\n 'GIF',\n 'Поиск GIF',\n 'Персональные данные',\n 'Одобренный',\n 'Ожидающий',\n 'Спам',\n 'Нелипкий',\n 'самый старый',\n 'последний',\n 'самый горячий',\n 'Что вы думаете?',\n]);\n","import { generateLocale } from './generate.js';\n\nexport default generateLocale([\n 'Tên',\n 'Tên không được nhỏ hơn 3 ký tự.',\n 'E-Mail',\n 'Vui lòng xác nhập địa chỉ email của bạn.',\n 'Website',\n 'Tùy chọn',\n 'Hãy bình luận có văn hoá!',\n 'Chưa có bình luận',\n 'Gửi',\n 'Thích',\n 'Bỏ thích',\n 'Trả lời',\n 'Hủy bỏ',\n 'bình luận',\n 'Làm mới',\n 'Tải thêm...',\n 'Xem trước',\n 'Emoji',\n 'Tải lên hình ảnh',\n 'giây trước',\n 'phút trước',\n 'giờ trước',\n 'ngày trước',\n 'Vừa xong',\n 'Đang tải lên',\n 'Đăng nhập',\n 'đăng xuất',\n 'Quản trị viên',\n 'Dính',\n 'từ',\n 'Bình luận phải có độ dài giữa $0 và $1 từ!\\n Số từ hiện tại: $2',\n 'Vô danh',\n 'Người lùn',\n 'Người tí hon',\n 'Thần rừng',\n 'Pháp sư',\n 'Tiên tộc',\n 'Maiar',\n 'Ảnh GIF',\n 'Tìm kiếm ảnh GIF',\n 'thông tin cá nhân',\n 'Đã được phê duyệt',\n 'Đang chờ đợi',\n 'Thư rác',\n 'Không dính',\n 'lâu đời nhất',\n 'muộn nhất',\n 'nóng nhất',\n 'What do you think?',\n]);\n","import { generateLocale } from './generate.js';\n\nexport default generateLocale([\n '昵称',\n '昵称不能少于3个字符',\n '邮箱',\n '请填写正确的邮件地址',\n '网址',\n '可选',\n '欢迎评论',\n '来发评论吧~',\n '提交',\n '喜欢',\n '取消喜欢',\n '回复',\n '取消回复',\n '评论',\n '刷新',\n '加载更多...',\n '预览',\n '表情',\n '上传图片',\n '秒前',\n '分钟前',\n '小时前',\n '天前',\n '刚刚',\n '正在上传',\n '登录',\n '退出',\n '博主',\n '置顶',\n '字',\n '评论字数应在 $0 到 $1 字之间!\\n当前字数:$2',\n '匿名',\n '潜水',\n '冒泡',\n '吐槽',\n '活跃',\n '话痨',\n '传说',\n '表情包',\n '搜索表情包',\n '个人资料',\n '通过',\n '待审核',\n '垃圾',\n '取消置顶',\n '按倒序',\n '按正序',\n '按热度',\n '你认为这篇文章怎么样?',\n]);\n","import { generateLocale } from './generate.js';\n\nexport default generateLocale([\n '暱稱',\n '暱稱不能少於3個字元',\n '郵箱',\n '請填寫正確的郵件地址',\n '網址',\n '可選',\n '歡迎留言',\n '來發留言吧~',\n '送出',\n '喜歡',\n '取消喜歡',\n '回覆',\n '取消回覆',\n '留言',\n '重整',\n '載入更多...',\n '預覽',\n '表情',\n '上傳圖片',\n '秒前',\n '分鐘前',\n '小時前',\n '天前',\n '剛剛',\n '正在上傳',\n '登入',\n '登出',\n '管理者',\n '置頂',\n '字',\n '留言字數應在 $0 到 $1 字之間!\\n目前字數:$2',\n '匿名',\n '潛水',\n '冒泡',\n '吐槽',\n '活躍',\n '多話',\n '傳說',\n '表情包',\n '搜尋表情包',\n '個人資料',\n '通過',\n '待審核',\n '垃圾',\n '取消置頂',\n '最早',\n '最新',\n '熱門',\n '你認為這篇文章怎麼樣?',\n]);\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport en from './en.js';\nimport fr from './fr.js';\nimport jp from './jp.js';\nimport ptBR from './pt-BR.js';\nimport ru from './ru.js';\nimport viVN from './vi-VN.js';\nimport zhCN from './zh-CN.js';\nimport zhTW from './zh-TW.js';\nimport type { WalineLocale } from '../../typings/index.js';\n\nexport type Locales = Record<string, WalineLocale>;\n\nexport const DEFAULT_LANG = 'en-US';\n\nexport const DEFAULT_LOCALES: Locales = {\n zh: zhCN,\n 'zh-cn': zhCN,\n 'zh-tw': zhTW,\n en,\n 'en-us': en,\n fr,\n 'fr-fr': fr,\n jp,\n 'jp-jp': jp,\n 'pt-br': ptBR,\n ru,\n 'ru-ru': ru,\n vi: viVN,\n 'vi-vn': viVN,\n};\n\nexport const getLocale = (lang: string): WalineLocale =>\n DEFAULT_LOCALES[lang.toLowerCase()] || DEFAULT_LOCALES[DEFAULT_LANG];\n\nexport const getLang = (lang: string): string =>\n Object.keys(DEFAULT_LOCALES).includes(lang.toLowerCase())\n ? lang\n : DEFAULT_LANG;\n","export const decodePath = (path: string): string => {\n try {\n path = decodeURI(path);\n } catch (err) {\n // ignore error\n }\n\n return path;\n};\n\nexport const removeEndingSplash = (content = ''): string =>\n content.replace(/\\/$/u, '');\n\nexport const isLinkHttp = (link: string): boolean =>\n /^(https?:)?\\/\\//.test(link);\n","import { decodePath, isLinkHttp, removeEndingSplash } from './path.js';\nimport {\n DEFAULT_EMOJI,\n DEFAULT_REACTION,\n defaultHighlighter,\n defaultTeXRenderer,\n defaultUploadImage,\n getDefaultSearchOptions,\n getLang,\n getLocale,\n getMeta,\n} from '../config/index.js';\nimport type {\n WalineEmojiInfo,\n WalineEmojiMaps,\n WalineLocale,\n WalineProps,\n} from '../typings/index.js';\n\nexport interface WalineEmojiConfig {\n tabs: Pick<WalineEmojiInfo, 'name' | 'icon' | 'items'>[];\n map: WalineEmojiMaps;\n}\n\nexport interface WalineConfig\n extends Required<\n Omit<\n WalineProps,\n | 'emoji'\n | 'imageUploader'\n | 'highlighter'\n | 'texRenderer'\n | 'wordLimit'\n | 'reaction'\n | 'search'\n >\n > {\n locale: WalineLocale;\n wordLimit: [number, number] | false;\n reaction: string[];\n emoji: Exclude<WalineProps['emoji'], boolean | undefined>;\n highlighter: Exclude<WalineProps['highlighter'], true | undefined>;\n imageUploader: Exclude<WalineProps['imageUploader'], true | undefined>;\n texRenderer: Exclude<WalineProps['texRenderer'], true | undefined>;\n search: Exclude<WalineProps['search'], true | undefined>;\n}\n\nexport const getServerURL = (serverURL: string): string => {\n const result = removeEndingSplash(serverURL);\n\n return isLinkHttp(result) ? result : `https://${result}`;\n};\n\nconst getWordLimit = (\n wordLimit: WalineProps['wordLimit'],\n): [number, number] | false =>\n Array.isArray(wordLimit) ? wordLimit : wordLimit ? [0, wordLimit] : false;\n\nconst fallback = <T = unknown>(\n value: T | boolean | undefined,\n fallback: T,\n): T | false =>\n typeof value === 'function' ? value : value === false ? false : fallback;\n\nexport const getConfig = ({\n serverURL,\n\n path = location.pathname,\n lang = typeof navigator === 'undefined' ? 'en-US' : navigator.language,\n locale,\n emoji = DEFAULT_EMOJI,\n meta = ['nick', 'mail', 'link'],\n requiredMeta = [],\n dark = false,\n pageSize = 10,\n wordLimit,\n imageUploader,\n highlighter,\n texRenderer,\n copyright = true,\n login = 'enable',\n search,\n reaction,\n recaptchaV3Key = '',\n turnstileKey = '',\n commentSorting = 'latest',\n ...more\n}: WalineProps): WalineConfig => ({\n serverURL: getServerURL(serverURL),\n path: decodePath(path),\n lang: getLang(lang),\n locale: {\n ...getLocale(lang),\n ...(typeof locale === 'object' ? locale : {}),\n } as WalineLocale,\n wordLimit: getWordLimit(wordLimit),\n meta: getMeta(meta),\n requiredMeta: getMeta(requiredMeta),\n imageUploader: fallback(imageUploader, defaultUploadImage),\n highlighter: fallback(highlighter, defaultHighlighter),\n texRenderer: fallback(texRenderer, defaultTeXRenderer),\n dark,\n emoji: typeof emoji === 'boolean' ? (emoji ? DEFAULT_EMOJI : []) : emoji,\n pageSize,\n login,\n copyright,\n search:\n search === false\n ? false\n : typeof search === 'object'\n ? search\n : getDefaultSearchOptions(lang),\n recaptchaV3Key,\n turnstileKey,\n reaction: Array.isArray(reaction)\n ? reaction\n : reaction === true\n ? DEFAULT_REACTION\n : [],\n commentSorting,\n ...more,\n});\n","export const isString = (val: unknown): val is string =>\n typeof val === 'string';\n","import { isString } from './type.js';\n\nconst DARK_VARIABLES = `{--waline-white:#000;--waline-light-grey:#666;--waline-dark-grey:#999;--waline-color:#888;--waline-bg-color:#1e1e1e;--waline-bg-color-light:#272727;--waline-bg-color-hover: #444;--waline-border-color:#333;--waline-disable-bg-color:#444;--waline-disable-color:#272727;--waline-bq-color:#272727;--waline-info-bg-color:#272727;--waline-info-color:#666}`;\n\nexport const getDarkStyle = (selector?: string | boolean): string =>\n isString(selector)\n ? selector === 'auto'\n ? `@media(prefers-color-scheme:dark){body${DARK_VARIABLES}}`\n : `${selector}${DARK_VARIABLES}`\n : selector === true\n ? `:root${DARK_VARIABLES}`\n : '';\n","import { isString } from './type.js';\nimport type { WalineDateLocale } from '../typings/index.js';\n\nconst padWithZeros = (vNumber: number, width: number): string => {\n let numAsString = vNumber.toString();\n\n while (numAsString.length < width) {\n numAsString = '0' + numAsString;\n }\n\n return numAsString;\n};\n\nexport const dateFormat = (date: Date): string => {\n const vDay = padWithZeros(date.getDate(), 2);\n const vMonth = padWithZeros(date.getMonth() + 1, 2);\n const vYear = padWithZeros(date.getFullYear(), 2);\n\n return `${vYear}-${vMonth}-${vDay}`;\n};\n\nexport const getTimeAgo = (\n date: Date | string,\n now: Date,\n locale: WalineDateLocale,\n): string => {\n if (!date) return '';\n\n const time = isString(date)\n ? new Date(date.indexOf(' ') !== -1 ? date.replace(/-/g, '/') : date)\n : date;\n\n const timePassed = now.getTime() - time.getTime();\n\n const days = Math.floor(timePassed / (24 * 3600 * 1000));\n\n if (days === 0) {\n // 计算相差小时数\n\n // 计算天数后剩余的毫秒数\n const leave1 = timePassed % (24 * 3600 * 1000);\n const hours = Math.floor(leave1 / (3600 * 1000));\n\n if (hours === 0) {\n //计算相差分钟数\n\n // 计算小时数后剩余的毫秒数\n const leave2 = leave1 % (3600 * 1000);\n const minutes = Math.floor(leave2 / (60 * 1000));\n\n // 计算相差秒数\n if (minutes === 0) {\n // 计算分钟数后剩余的毫秒数\n const leave3 = leave2 % (60 * 1000);\n const seconds = Math.round(leave3 / 1000);\n\n return `${seconds} ${locale.seconds}`;\n }\n\n return `${minutes} ${locale.minutes}`;\n }\n\n return `${hours} ${locale.hours}`;\n }\n\n if (days < 0) return locale.now;\n\n if (days < 8) return `${days} ${locale.days}`;\n\n return dateFormat(time);\n};\n","/**\n * @ref https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address\n */\nconst EMAIL_REG_EXP =\n /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;\n\nexport const isValidEmail = (email: string): boolean =>\n EMAIL_REG_EXP.test(email);\n","/**\n* @vue/shared v3.4.27\n* (c) 2018-present Yuxi (Evan) You and Vue contributors\n* @license MIT\n**/\n/*! #__NO_SIDE_EFFECTS__ */\n// @__NO_SIDE_EFFECTS__\nfunction makeMap(str, expectsLowerCase) {\n const set = new Set(str.split(\",\"));\n return expectsLowerCase ? (val) => set.has(val.toLowerCase()) : (val) => set.has(val);\n}\n\nconst EMPTY_OBJ = !!(process.env.NODE_ENV !== \"production\") ? Object.freeze({}) : {};\nconst EMPTY_ARR = !!(process.env.NODE_ENV !== \"production\") ? Object.freeze([]) : [];\nconst NOOP = () => {\n};\nconst NO = () => false;\nconst isOn = (key) => key.charCodeAt(0) === 111 && key.charCodeAt(1) === 110 && // uppercase letter\n(key.charCodeAt(2) > 122 || key.charCodeAt(2) < 97);\nconst isModelListener = (key) => key.startsWith(\"onUpdate:\");\nconst extend = Object.assign;\nconst remove = (arr, el) => {\n const i = arr.indexOf(el);\n if (i > -1) {\n arr.splice(i, 1);\n }\n};\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst hasOwn = (val, key) => hasOwnProperty.call(val, key);\nconst isArray = Array.isArray;\nconst isMap = (val) => toTypeString(val) === \"[object Map]\";\nconst isSet = (val) => toTypeString(val) === \"[object Set]\";\nconst isDate = (val) => toTypeString(val) === \"[object Date]\";\nconst isRegExp = (val) => toTypeString(val) === \"[object RegExp]\";\nconst isFunction = (val) => typeof val === \"function\";\nconst isString = (val) => typeof val === \"string\";\nconst isSymbol = (val) => typeof val === \"symbol\";\nconst isObject = (val) => val !== null && typeof val === \"object\";\nconst isPromise = (val) => {\n return (isObject(val) || isFunction(val)) && isFunction(val.then) && isFunction(val.catch);\n};\nconst objectToString = Object.prototype.toString;\nconst toTypeString = (value) => objectToString.call(value);\nconst toRawType = (value) => {\n return toTypeString(value).slice(8, -1);\n};\nconst isPlainObject = (val) => toTypeString(val) === \"[object Object]\";\nconst isIntegerKey = (key) => isString(key) && key !== \"NaN\" && key[0] !== \"-\" && \"\" + parseInt(key, 10) === key;\nconst isReservedProp = /* @__PURE__ */ makeMap(\n // the leading comma is intentional so empty string \"\" is also included\n \",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted\"\n);\nconst isBuiltInDirective = /* @__PURE__ */ makeMap(\n \"bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo\"\n);\nconst cacheStringFunction = (fn) => {\n const cache = /* @__PURE__ */ Object.create(null);\n return (str) => {\n const hit = cache[str];\n return hit || (cache[str] = fn(str));\n };\n};\nconst camelizeRE = /-(\\w)/g;\nconst camelize = cacheStringFunction((str) => {\n return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : \"\");\n});\nconst hyphenateRE = /\\B([A-Z])/g;\nconst hyphenate = cacheStringFunction(\n (str) => str.replace(hyphenateRE, \"-$1\").toLowerCase()\n);\nconst capitalize = cacheStringFunction((str) => {\n return str.charAt(0).toUpperCase() + str.slice(1);\n});\nconst toHandlerKey = cacheStringFunction((str) => {\n const s = str ? `on${capitalize(str)}` : ``;\n return s;\n});\nconst hasChanged = (value, oldValue) => !Object.is(value, oldValue);\nconst invokeArrayFns = (fns, arg) => {\n for (let i = 0; i < fns.length; i++) {\n fns[i](arg);\n }\n};\nconst def = (obj, key, value, writable = false) => {\n Object.defineProperty(obj, key, {\n configurable: true,\n enumerable: false,\n writable,\n value\n });\n};\nconst looseToNumber = (val) => {\n const n = parseFloat(val);\n return isNaN(n) ? val : n;\n};\nconst toNumber = (val) => {\n const n = isString(val) ? Number(val) : NaN;\n return isNaN(n) ? val : n;\n};\nlet _globalThis;\nconst getGlobalThis = () => {\n return _globalThis || (_globalThis = typeof globalThis !== \"undefined\" ? globalThis : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n};\nconst identRE = /^[_$a-zA-Z\\xA0-\\uFFFF][_$a-zA-Z0-9\\xA0-\\uFFFF]*$/;\nfunction genPropsAccessExp(name) {\n return identRE.test(name) ? `__props.${name}` : `__props[${JSON.stringify(name)}]`;\n}\n\nconst PatchFlags = {\n \"TEXT\": 1,\n \"1\": \"TEXT\",\n \"CLASS\": 2,\n \"2\": \"CLASS\",\n \"STYLE\": 4,\n \"4\": \"STYLE\",\n \"PROPS\": 8,\n \"8\": \"PROPS\",\n \"FULL_PROPS\": 16,\n \"16\": \"FULL_PROPS\",\n \"NEED_HYDRATION\": 32,\n \"32\": \"NEED_HYDRATION\",\n \"STABLE_FRAGMENT\": 64,\n \"64\": \"STABLE_FRAGMENT\",\n \"KEYED_FRAGMENT\": 128,\n \"128\": \"KEYED_FRAGMENT\",\n \"UNKEYED_FRAGMENT\": 256,\n \"256\": \"UNKEYED_FRAGMENT\",\n \"NEED_PATCH\": 512,\n \"512\": \"NEED_PATCH\",\n \"DYNAMIC_SLOTS\": 1024,\n \"1024\": \"DYNAMIC_SLOTS\",\n \"DEV_ROOT_FRAGMENT\": 2048,\n \"2048\": \"DEV_ROOT_FRAGMENT\",\n \"HOISTED\": -1,\n \"-1\": \"HOISTED\",\n \"BAIL\": -2,\n \"-2\": \"BAIL\"\n};\nconst PatchFlagNames = {\n [1]: `TEXT`,\n [2]: `CLASS`,\n [4]: `STYLE`,\n [8]: `PROPS`,\n [16]: `FULL_PROPS`,\n [32]: `NEED_HYDRATION`,\n [64]: `STABLE_FRAGMENT`,\n [128]: `KEYED_FRAGMENT`,\n [256]: `UNKEYED_FRAGMENT`,\n [512]: `NEED_PATCH`,\n [1024]: `DYNAMIC_SLOTS`,\n [2048]: `DEV_ROOT_FRAGMENT`,\n [-1]: `HOISTED`,\n [-2]: `BAIL`\n};\n\nconst ShapeFlags = {\n \"ELEMENT\": 1,\n \"1\": \"ELEMENT\",\n \"FUNCTIONAL_COMPONENT\": 2,\n \"2\": \"FUNCTIONAL_COMPONENT\",\n \"STATEFUL_COMPONENT\": 4,\n \"4\": \"STATEFUL_COMPONENT\",\n \"TEXT_CHILDREN\": 8,\n \"8\": \"TEXT_CHILDREN\",\n \"ARRAY_CHILDREN\": 16,\n \"16\": \"ARRAY_CHILDREN\",\n \"SLOTS_CHILDREN\": 32,\n \"32\": \"SLOTS_CHILDREN\",\n \"TELEPORT\": 64,\n \"64\": \"TELEPORT\",\n \"SUSPENSE\": 128,\n \"128\": \"SUSPENSE\",\n \"COMPONENT_SHOULD_KEEP_ALIVE\": 256,\n \"256\": \"COMPONENT_SHOULD_KEEP_ALIVE\",\n \"COMPONENT_KEPT_ALIVE\": 512,\n \"512\": \"COMPONENT_KEPT_ALIVE\",\n \"COMPONENT\": 6,\n \"6\": \"COMPONENT\"\n};\n\nconst SlotFlags = {\n \"STABLE\": 1,\n \"1\": \"STABLE\",\n \"DYNAMIC\": 2,\n \"2\": \"DYNAMIC\",\n \"FORWARDED\": 3,\n \"3\": \"FORWARDED\"\n};\nconst slotFlagsText = {\n [1]: \"STABLE\",\n [2]: \"DYNAMIC\",\n [3]: \"FORWARDED\"\n};\n\nconst GLOBALS_ALLOWED = \"Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error\";\nconst isGloballyAllowed = /* @__PURE__ */ makeMap(GLOBALS_ALLOWED);\nconst isGloballyWhitelisted = isGloballyAllowed;\n\nconst range = 2;\nfunction generateCodeFrame(source, start = 0, end = source.length) {\n let lines = source.split(/(\\r?\\n)/);\n const newlineSequences = lines.filter((_, idx) => idx % 2 === 1);\n lines = lines.filter((_, idx) => idx % 2 === 0);\n let count = 0;\n const res = [];\n for (let i = 0; i < lines.length; i++) {\n count += lines[i].length + (newlineSequences[i] && newlineSequences[i].length || 0);\n if (count >= start) {\n for (let j = i - range; j <= i + range || end > count; j++) {\n if (j < 0 || j >= lines.length)\n continue;\n const line = j + 1;\n res.push(\n `${line}${\" \".repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`\n );\n const lineLength = lines[j].length;\n const newLineSeqLength = newlineSequences[j] && newlineSequences[j].length || 0;\n if (j === i) {\n const pad = start - (count - (lineLength + newLineSeqLength));\n const length = Math.max(\n 1,\n end > count ? lineLength - pad : end - start\n );\n res.push(` | ` + \" \".repeat(pad) + \"^\".repeat(length));\n } else if (j > i) {\n if (end > count) {\n const length = Math.max(Math.min(end - count, lineLength), 1);\n res.push(` | ` + \"^\".repeat(length));\n }\n count += lineLength + newLineSeqLength;\n }\n }\n break;\n }\n }\n return res.join(\"\\n\");\n}\n\nfunction normalizeStyle(value) {\n if (isArray(value)) {\n const res = {};\n for (let i = 0; i < value.length; i++) {\n const item = value[i];\n const normalized = isString(item) ? parseStringStyle(item) : normalizeStyle(item);\n if (normalized) {\n for (const key in normalized) {\n res[key] = normalized[key];\n }\n }\n }\n return res;\n } else if (isString(value) || isObject(value)) {\n return value;\n }\n}\nconst listDelimiterRE = /;(?![^(]*\\))/g;\nconst propertyDelimiterRE = /:([^]+)/;\nconst styleCommentRE = /\\/\\*[^]*?\\*\\//g;\nfunction parseStringStyle(cssText) {\n const ret = {};\n cssText.replace(styleCommentRE, \"\").split(listDelimiterRE).forEach((item) => {\n if (item) {\n const tmp = item.split(propertyDelimiterRE);\n tmp.length > 1 && (ret[tmp[0].trim()] = tmp[1].trim());\n }\n });\n return ret;\n}\nfunction stringifyStyle(styles) {\n let ret = \"\";\n if (!styles || isString(styles)) {\n return ret;\n }\n for (const key in styles) {\n const value = styles[key];\n if (isString(value) || typeof value === \"number\") {\n const normalizedKey = key.startsWith(`--`) ? key : hyphenate(key);\n ret += `${normalizedKey}:${value};`;\n }\n }\n return ret;\n}\nfunction normalizeClass(value) {\n let res = \"\";\n if (isString(value)) {\n res = value;\n } else if (isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n const normalized = normalizeClass(value[i]);\n if (normalized) {\n res += normalized + \" \";\n }\n }\n } else if (isObject(value)) {\n for (const name in value) {\n if (value[name]) {\n res += name + \" \";\n }\n }\n }\n return res.trim();\n}\nfunction normalizeProps(props) {\n if (!props)\n return null;\n let { class: klass, style } = props;\n if (klass && !isString(klass)) {\n props.class = normalizeClass(klass);\n }\n if (style) {\n props.style = normalizeStyle(style);\n }\n return props;\n}\n\nconst HTML_TAGS = \"html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot\";\nconst SVG_TAGS = \"svg,animate,animateMotion,animateTransform,circle,clipPath,color-profile,defs,desc,discard,ellipse,feBlend,feColorMatrix,feComponentTransfer,feComposite,feConvolveMatrix,feDiffuseLighting,feDisplacementMap,feDistantLight,feDropShadow,feFlood,feFuncA,feFuncB,feFuncG,feFuncR,feGaussianBlur,feImage,feMerge,feMergeNode,feMorphology,feOffset,fePointLight,feSpecularLighting,feSpotLight,feTile,feTurbulence,filter,foreignObject,g,hatch,hatchpath,image,line,linearGradient,marker,mask,mesh,meshgradient,meshpatch,meshrow,metadata,mpath,path,pattern,polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,text,textPath,title,tspan,unknown,use,view\";\nconst MATH_TAGS = \"annotation,annotation-xml,maction,maligngroup,malignmark,math,menclose,merror,mfenced,mfrac,mfraction,mglyph,mi,mlabeledtr,mlongdiv,mmultiscripts,mn,mo,mover,mpadded,mphantom,mprescripts,mroot,mrow,ms,mscarries,mscarry,msgroup,msline,mspace,msqrt,msrow,mstack,mstyle,msub,msubsup,msup,mtable,mtd,mtext,mtr,munder,munderover,none,semantics\";\nconst VOID_TAGS = \"area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr\";\nconst isHTMLTag = /* @__PURE__ */ makeMap(HTML_TAGS);\nconst isSVGTag = /* @__PURE__ */ makeMap(SVG_TAGS);\nconst isMathMLTag = /* @__PURE__ */ makeMap(MATH_TAGS);\nconst isVoidTag = /* @__PURE__ */ makeMap(VOID_TAGS);\n\nconst specialBooleanAttrs = `itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly`;\nconst isSpecialBooleanAttr = /* @__PURE__ */ makeMap(specialBooleanAttrs);\nconst isBooleanAttr = /* @__PURE__ */ makeMap(\n specialBooleanAttrs + `,async,autofocus,autoplay,controls,default,defer,disabled,hidden,inert,loop,open,required,reversed,scoped,seamless,checked,muted,multiple,selected`\n);\nfunction includeBooleanAttr(value) {\n return !!value || value === \"\";\n}\nconst unsafeAttrCharRE = /[>/=\"'\\u0009\\u000a\\u000c\\u0020]/;\nconst attrValidationCache = {};\nfunction isSSRSafeAttrName(name) {\n if (attrValidationCache.hasOwnProperty(name)) {\n return attrValidationCache[name];\n }\n const isUnsafe = unsafeAttrCharRE.test(name);\n if (isUnsafe) {\n console.error(`unsafe attribute name: ${name}`);\n }\n return attrValidationCache[name] = !isUnsafe;\n}\nconst propsToAttrMap = {\n acceptCharset: \"accept-charset\",\n className: \"class\",\n htmlFor: \"for\",\n httpEquiv: \"http-equiv\"\n};\nconst isKnownHtmlAttr = /* @__PURE__ */ makeMap(\n `accept,accept-charset,accesskey,action,align,allow,alt,async,autocapitalize,autocomplete,autofocus,autoplay,background,bgcolor,border,buffered,capture,challenge,charset,checked,cite,class,code,codebase,color,cols,colspan,content,contenteditable,contextmenu,controls,coords,crossorigin,csp,data,datetime,decoding,default,defer,dir,dirname,disabled,download,draggable,dropzone,enctype,enterkeyhint,for,form,formaction,formenctype,formmethod,formnovalidate,formtarget,headers,height,hidden,high,href,hreflang,http-equiv,icon,id,importance,inert,integrity,ismap,itemprop,keytype,kind,label,lang,language,loading,list,loop,low,manifest,max,maxlength,minlength,media,min,multiple,muted,name,novalidate,open,optimum,pattern,ping,placeholder,poster,preload,radiogroup,readonly,referrerpolicy,rel,required,reversed,rows,rowspan,sandbox,scope,scoped,selected,shape,size,sizes,slot,span,spellcheck,src,srcdoc,srclang,srcset,start,step,style,summary,tabindex,target,title,translate,type,usemap,value,width,wrap`\n);\nconst isKnownSvgAttr = /* @__PURE__ */ makeMap(\n `xmlns,accent-height,accumulate,additive,alignment-baseline,alphabetic,amplitude,arabic-form,ascent,attributeName,attributeType,azimuth,baseFrequency,baseline-shift,baseProfile,bbox,begin,bias,by,calcMode,cap-height,class,clip,clipPathUnits,clip-path,clip-rule,color,color-interpolation,color-interpolation-filters,color-profile,color-rendering,contentScriptType,contentStyleType,crossorigin,cursor,cx,cy,d,decelerate,descent,diffuseConstant,direction,display,divisor,dominant-baseline,dur,dx,dy,edgeMode,elevation,enable-background,end,exponent,fill,fill-opacity,fill-rule,filter,filterRes,filterUnits,flood-color,flood-opacity,font-family,font-size,font-size-adjust,font-stretch,font-style,font-variant,font-weight,format,from,fr,fx,fy,g1,g2,glyph-name,glyph-orientation-horizontal,glyph-orientation-vertical,glyphRef,gradientTransform,gradientUnits,hanging,height,href,hreflang,horiz-adv-x,horiz-origin-x,id,ideographic,image-rendering,in,in2,intercept,k,k1,k2,k3,k4,kernelMatrix,kernelUnitLength,kerning,keyPoints,keySplines,keyTimes,lang,lengthAdjust,letter-spacing,lighting-color,limitingConeAngle,local,marker-end,marker-mid,marker-start,markerHeight,markerUnits,markerWidth,mask,maskContentUnits,maskUnits,mathematical,max,media,method,min,mode,name,numOctaves,offset,opacity,operator,order,orient,orientation,origin,overflow,overline-position,overline-thickness,panose-1,paint-order,path,pathLength,patternContentUnits,patternTransform,patternUnits,ping,pointer-events,points,pointsAtX,pointsAtY,pointsAtZ,preserveAlpha,preserveAspectRatio,primitiveUnits,r,radius,referrerPolicy,refX,refY,rel,rendering-intent,repeatCount,repeatDur,requiredExtensions,requiredFeatures,restart,result,rotate,rx,ry,scale,seed,shape-rendering,slope,spacing,specularConstant,specularExponent,speed,spreadMethod,startOffset,stdDeviation,stemh,stemv,stitchTiles,stop-color,stop-opacity,strikethrough-position,strikethrough-thickness,string,stroke,stroke-dasharray,stroke-dashoffset,stroke-linecap,stroke-linejoin,stroke-miterlimit,stroke-opacity,stroke-width,style,surfaceScale,systemLanguage,tabindex,tableValues,target,targetX,targetY,text-anchor,text-decoration,text-rendering,textLength,to,transform,transform-origin,type,u1,u2,underline-position,underline-thickness,unicode,unicode-bidi,unicode-range,units-per-em,v-alphabetic,v-hanging,v-ideographic,v-mathematical,values,vector-effect,version,vert-adv-y,vert-origin-x,vert-origin-y,viewBox,viewTarget,visibility,width,widths,word-spacing,writing-mode,x,x-height,x1,x2,xChannelSelector,xlink:actuate,xlink:arcrole,xlink:href,xlink:role,xlink:show,xlink:title,xlink:type,xmlns:xlink,xml:base,xml:lang,xml:space,y,y1,y2,yChannelSelector,z,zoomAndPan`\n);\nfunction isRenderableAttrValue(value) {\n if (value == null) {\n return false;\n }\n const type = typeof value;\n return type === \"string\" || type === \"number\" || type === \"boolean\";\n}\n\nconst escapeRE = /[\"'&<>]/;\nfunction escapeHtml(string) {\n const str = \"\" + string;\n const match = escapeRE.exec(str);\n if (!match) {\n return str;\n }\n let html = \"\";\n let escaped;\n let index;\n let lastIndex = 0;\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34:\n escaped = \""\";\n break;\n case 38:\n escaped = \"&\";\n break;\n case 39:\n escaped = \"'\";\n break;\n case 60:\n escaped = \"<\";\n break;\n case 62:\n escaped = \">\";\n break;\n default:\n continue;\n }\n if (lastIndex !== index) {\n html += str.slice(lastIndex, index);\n }\n lastIndex = index + 1;\n html += escaped;\n }\n return lastIndex !== index ? html + str.slice(lastIndex, index) : html;\n}\nconst commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g;\nfunction escapeHtmlComment(src) {\n return src.replace(commentStripRE, \"\");\n}\n\nfunction looseCompareArrays(a, b) {\n if (a.length !== b.length)\n return false;\n let equal = true;\n for (let i = 0; equal && i < a.length; i++) {\n equal = looseEqual(a[i], b[i]);\n }\n return equal;\n}\nfunction looseEqual(a, b) {\n if (a === b)\n return true;\n let aValidType = isDate(a);\n let bValidType = isDate(b);\n if (aValidType || bValidType) {\n return aValidType && bValidType ? a.getTime() === b.getTime() : false;\n }\n aValidType = isSymbol(a);\n bValidType = isSymbol(b);\n if (aValidType || bValidType) {\n return a === b;\n }\n aValidType = isArray(a);\n bValidType = isArray(b);\n if (aValidType || bValidType) {\n return aValidType && bValidType ? looseCompareArrays(a, b) : false;\n }\n aValidType = isObject(a);\n bValidType = isObject(b);\n if (aValidType || bValidType) {\n if (!aValidType || !bValidType) {\n return false;\n }\n const aKeysCount = Object.keys(a).length;\n const bKeysCount = Object.keys(b).length;\n if (aKeysCount !== bKeysCount) {\n return false;\n }\n for (const key in a) {\n const aHasKey = a.hasOwnProperty(key);\n const bHasKey = b.hasOwnProperty(key);\n if (aHasKey && !bHasKey || !aHasKey && bHasKey || !looseEqual(a[key], b[key])) {\n return false;\n }\n }\n }\n return String(a) === String(b);\n}\nfunction looseIndexOf(arr, val) {\n return arr.findIndex((item) => looseEqual(item, val));\n}\n\nconst toDisplayString = (val) => {\n return isString(val) ? val : val == null ? \"\" : isArray(val) || isObject(val) && (val.toString === objectToString || !isFunction(val.toString)) ? JSON.stringify(val, replacer, 2) : String(val);\n};\nconst replacer = (_key, val) => {\n if (val && val.__v_isRef) {\n return replacer(_key, val.value);\n } else if (isMap(val)) {\n return {\n [`Map(${val.size})`]: [...val.entries()].reduce(\n (entries, [key, val2], i) => {\n entries[stringifySymbol(key, i) + \" =>\"] = val2;\n return entries;\n },\n {}\n )\n };\n } else if (isSet(val)) {\n return {\n [`Set(${val.size})`]: [...val.values()].map((v) => stringifySymbol(v))\n };\n } else if (isSymbol(val)) {\n return stringifySymbol(val);\n } else if (isObject(val) && !isArray(val) && !isPlainObject(val)) {\n return String(val);\n }\n return val;\n};\nconst stringifySymbol = (v, i = \"\") => {\n var _a;\n return (\n // Symbol.description in es2019+ so we need to cast here to pass\n // the lib: es2016 check\n isSymbol(v) ? `Symbol(${(_a = v.description) != null ? _a : i})` : v\n );\n};\n\nexport { EMPTY_ARR, EMPTY_OBJ, NO, NOOP, PatchFlagNames, PatchFlags, ShapeFlags, SlotFlags, camelize, capitalize, def, escapeHtml, escapeHtmlComment, extend, genPropsAccessExp, generateCodeFrame, getGlobalThis, hasChanged, hasOwn, hyphenate, includeBooleanAttr, invokeArrayFns, isArray, isBooleanAttr, isBuiltInDirective, isDate, isFunction, isGloballyAllowed, isGloballyWhitelisted, isHTMLTag, isIntegerKey, isKnownHtmlAttr, isKnownSvgAttr, isMap, isMathMLTag, isModelListener, isObject, isOn, isPlainObject, isPromise, isRegExp, isRenderableAttrValue, isReservedProp, isSSRSafeAttrName, isSVGTag, isSet, isSpecialBooleanAttr, isString, isSymbol, isVoidTag, looseEqual, looseIndexOf, looseToNumber, makeMap, normalizeClass, normalizeProps, normalizeStyle, objectToString, parseStringStyle, propsToAttrMap, remove, slotFlagsText, stringifyStyle, toDisplayString, toHandlerKey, toNumber, toRawType, toTypeString };\n","/**\n* @vue/reactivity v3.4.27\n* (c) 2018-present Yuxi (Evan) You and Vue contributors\n* @license MIT\n**/\nimport { NOOP, extend, isArray, isSymbol, isMap, isIntegerKey, hasOwn, hasChanged, isObject, makeMap, capitalize, toRawType, def, isFunction } from '@vue/shared';\n\nfunction warn(msg, ...args) {\n console.warn(`[Vue warn] ${msg}`, ...args);\n}\n\nlet activeEffectScope;\nclass EffectScope {\n constructor(detached = false) {\n this.detached = detached;\n /**\n * @internal\n */\n this._active = true;\n /**\n * @internal\n */\n this.effects = [];\n /**\n * @internal\n */\n this.cleanups = [];\n this.parent = activeEffectScope;\n if (!detached && activeEffectScope) {\n this.index = (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(\n this\n ) - 1;\n }\n }\n get active() {\n return this._active;\n }\n run(fn) {\n if (this._active) {\n const currentEffectScope = activeEffectScope;\n try {\n activeEffectScope = this;\n return fn();\n } finally {\n activeEffectScope = currentEffectScope;\n }\n } else if (!!(process.env.NODE_ENV !== \"production\")) {\n warn(`cannot run an inactive effect scope.`);\n }\n }\n /**\n * This should only be called on non-detach