first commit

main
NoahLan 1 year ago
commit 98098c75a4

@ -0,0 +1,2 @@
node_modules
dist

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

17
.env

@ -0,0 +1,17 @@
# Whether to open mock
VITE_USE_MOCK=false
# public path
VITE_PUBLIC_PATH=/
VITE_TITLE=N-Admin
VITE_DESCRIPTION=N-Admin-UI template
# Basic interface address SPA
VITE_API_URL=/api
# File upload address optional
VITE_UPLOAD_URL=/api/upload
# Interface prefix
VITE_API_URL_PREFIX=

@ -0,0 +1,6 @@
{
"extends": [
"@antfu",
"@unocss"
]
}

@ -0,0 +1 @@
github: antfu

@ -0,0 +1,96 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v3
with:
node-version: 16.x
cache: pnpm
- name: Install
run: pnpm install
- name: Lint
run: pnpm run lint
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- uses: actions/setup-node@v3
with:
node-version: 16.x
cache: pnpm
- name: Install
run: pnpm install
- name: Typecheck
run: pnpm run typecheck
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
node-version: [16.x, 18.x]
os: [ubuntu-latest]
fail-fast: false
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
cache: pnpm
- run: pnpm install
- run: pnpm run test:unit
test-e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/cache@v3
with:
path: |
~/.cache
key: cypress-cache-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
- uses: pnpm/action-setup@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
cache: pnpm
- run: pnpm install
- name: Cypress PNPM Patch
run: cp pnpm-lock.yaml package-lock.json
- name: Cypress
uses: cypress-io/github-action@v4
with:
install-command: echo
build: pnpm run build
start: npx vite --port 3333

10
.gitignore vendored

@ -0,0 +1,10 @@
.DS_Store
.vite-ssg-dist
.vite-ssg-temp
*.local
dist
dist-ssr
node_modules
.idea/
*.log
cypress/downloads

@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false

@ -0,0 +1,13 @@
{
"recommendations": [
"antfu.iconify",
"antfu.unocss",
"antfu.vite",
"antfu.goto-alias",
"csstools.postcss",
"dbaeumer.vscode-eslint",
"vue.volar",
"lokalise.i18n-ally",
"streetsidesoftware.code-spell-checker"
]
}

@ -0,0 +1,15 @@
{
"cSpell.words": ["Vitesse", "Vite", "unocss", "vitest", "vueuse", "pinia", "demi", "antfu", "iconify", "intlify", "vitejs", "unplugin", "pnpm"],
"i18n-ally.sourceLanguage": "en",
"i18n-ally.keystyle": "nested",
"i18n-ally.localesPaths": "locales",
"i18n-ally.sortKeys": true,
"prettier.enable": false,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"files.associations": {
"*.css": "postcss"
},
"editor.formatOnSave": false
}

@ -0,0 +1,18 @@
FROM node:16-alpine as build-stage
WORKDIR /app
RUN corepack enable
COPY .npmrc package.json pnpm-lock.yaml ./
RUN --mount=type=cache,id=pnpm-store,target=/root/.pnpm-store \
pnpm install --frozen-lockfile
COPY . .
RUN pnpm build
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020-PRESENT Anthony Fu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -0,0 +1 @@
# N-Admin-UI-Vitesse

@ -0,0 +1,14 @@
import { defineConfig } from 'cypress'
import vitePreprocessor from 'cypress-vite'
export default defineConfig({
e2e: {
baseUrl: 'http://localhost:3333',
chromeWebSecurity: false,
specPattern: 'cypress/e2e/**/*.spec.*',
supportFile: false,
setupNodeEvents(on) {
on('file:preprocessor', vitePreprocessor())
},
},
})

@ -0,0 +1,36 @@
context('Basic', () => {
beforeEach(() => {
cy.visit('/')
})
it('basic nav', () => {
cy.url()
.should('eq', 'http://localhost:3333/')
cy.contains('[Home Layout]')
.should('exist')
cy.get('#input')
.type('Vitesse{Enter}')
.url()
.should('eq', 'http://localhost:3333/hi/Vitesse')
cy.contains('[Default Layout]')
.should('exist')
cy.get('[btn]')
.click()
.url()
.should('eq', 'http://localhost:3333/')
})
it('markdown', () => {
cy.get('[title="About"]')
.click()
.url()
.should('eq', 'http://localhost:3333/about')
cy.get('.shiki')
.should('exist')
})
})

@ -0,0 +1,12 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"types": [
"cypress"
]
},
"exclude": [],
"include": [
"**/*.ts"
]
}

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="apple-touch-icon" href="/pwa-192x192.png">
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#00aba9">
<meta name="msapplication-TileColor" content="#00aba9">
<script>
(function () {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
const setting = localStorage.getItem('vueuse-color-scheme') || 'auto'
if (setting === 'dark' || (prefersDark && setting !== 'light'))
document.documentElement.classList.toggle('dark', true)
})()
</script>
</head>
<body class="font-sans">
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<noscript>This website requires JavaScript to function properly. Please enable JavaScript to continue.</noscript>
</body>
</html>

@ -0,0 +1,7 @@
## i18n
This directory is to serve your locale translation files. YAML under this folder would be loaded automatically and register with their filenames as locale code.
Check out [`vue-i18n`](https://github.com/intlify/vue-i18n-next) for more details.
If you are using VS Code, [`i18n Ally`](https://github.com/lokalise/i18n-ally) is recommended to make the i18n experience better.

@ -0,0 +1,14 @@
button:
about: حول
back: رجوع
go: تجربة
home: الرئيسية
toggle_dark: التغيير إلى الوضع المظلم
toggle_langs: تغيير اللغة
intro:
desc: vite مثال لتطبيق
dynamic-route: عرض لتوجيهات ديناميكية
hi: مرحبا {name}
aka: معروف أيضا تحت مسمى
whats-your-name: ما إسمك؟
not-found: صفحة غير موجودة

@ -0,0 +1,14 @@
button:
about: Über
back: Zurück
go: Los
home: Startseite
toggle_dark: Dunkelmodus umschalten
toggle_langs: Sprachen ändern
intro:
desc: Vite Startvorlage mit Vorlieben
dynamic-route: Demo einer dynamischen Route
hi: Hi, {name}!
aka: Auch bekannt als
whats-your-name: Wie heißt du?
not-found: Nicht gefunden

@ -0,0 +1,14 @@
button:
about: About
back: Back
go: GO
home: Home
toggle_dark: Toggle dark mode
toggle_langs: Change languages
intro:
desc: Opinionated Vite Starter Template
dynamic-route: Demo of dynamic route
hi: Hi, {name}!
aka: Also known as
whats-your-name: What's your name?
not-found: Not found

@ -0,0 +1,14 @@
button:
about: Acerca de
back: Atrás
go: Ir
home: Inicio
toggle_dark: Alternar modo oscuro
toggle_langs: Cambiar idiomas
intro:
desc: Plantilla de Inicio de Vite Dogmática
dynamic-route: Demo de ruta dinámica
hi: ¡Hola, {name}!
aka: También conocido como
whats-your-name: ¿Cómo te llamas?
not-found: No se ha encontrado

@ -0,0 +1,14 @@
button:
about: À propos
back: Retour
go: Essayer
home: Accueil
toggle_dark: Basculer en mode sombre
toggle_langs: Changer de langue
intro:
desc: Exemple d'application Vite
dynamic-route: Démo de route dynamique
hi: Salut, {name}!
aka: Aussi connu sous le nom de
whats-your-name: Comment t'appelles-tu ?
not-found: Page non trouvée

@ -0,0 +1,14 @@
button:
about: Tentang
back: Kembali
go: Pergi
home: Beranda
toggle_dark: Ubah ke mode gelap
toggle_langs: Ubah bahasa
intro:
desc: Template awal vite
dynamic-route: Contoh rute dinamik
hi: Halo, {name}!
aka: Juga diketahui sebagai
whats-your-name: Siapa nama anda?
not-found: Tidak ditemukan

@ -0,0 +1,13 @@
button:
about: Su di me
back: Indietro
go: Vai
home: Home
toggle_dark: Attiva/disattiva modalità scura
toggle_langs: Cambia lingua
intro:
desc: Modello per una Applicazione Vite
dynamic-route: Demo di rotta dinamica
hi: Ciao, {name}!
whats-your-name: Come ti chiami?
not-found: Non trovato

@ -0,0 +1,13 @@
button:
about: これは?
back: 戻る
go: 進む
home: ホーム
toggle_dark: ダークモード切り替え
toggle_langs: 言語切り替え
intro:
desc: 固執された Vite スターターテンプレート
dynamic-route: 動的ルートのデモ
hi: こんにちは、{name}!
whats-your-name: 君の名は。
not-found: 見つかりませんでした

@ -0,0 +1,14 @@
button:
about: შესახებ
back: უკან
go: დაწყება
home: მთავარი
toggle_dark: გადართე მუქი რეჟიმი
toggle_langs: ენის შეცვლა
intro:
desc: Opinionated Vite Starter Template
dynamic-route: დინამიური როუტინგის დემო
hi: გამარჯობა, {name}!
aka: ასევე ცნობილი როგორც
whats-your-name: რა გქვია?
not-found: ვერ მოიძებნა

@ -0,0 +1,13 @@
button:
about: 소개
back: 뒤로가기
go: 이동
home:
toggle_dark: 다크모드 토글
toggle_langs: 언어 변경
intro:
desc: Vite 애플리케이션 템플릿
dynamic-route: 다이나믹 라우트 데모
hi: 안녕, {name}!
whats-your-name: 이름이 뭐예요?
not-found: 찾을 수 없습니다

@ -0,0 +1,14 @@
button:
about: O nas
back: Wróć
go: WEJDŹ
home: Strona główna
toggle_dark: Ustaw tryb nocny
toggle_langs: Zmień język
intro:
desc: Opiniowany szablon startowy Vite
dynamic-route: Demonstracja dynamicznego route
hi: Cześć, {name}!
aka: Znany też jako
whats-your-name: Jak masz na imię?
not-found: Nie znaleziono

@ -0,0 +1,14 @@
button:
about: Sobre
back: Voltar
go: Ir
home: Início
toggle_dark: Alternar modo escuro
toggle_langs: Mudar de idioma
intro:
desc: Modelo Opinativo de Partida de Vite
dynamic-route: Demonstração de rota dinâmica
hi: Olá, {name}!
aka: Também conhecido como
whats-your-name: Qual é o seu nome?
not-found: Não encontrado

@ -0,0 +1,13 @@
button:
about: О шаблоне
back: Назад
go: Перейти
home: Главная
toggle_dark: Включить темный режим
toggle_langs: Сменить язык
intro:
desc: Самостоятельный начальный шаблон Vite
dynamic-route: Демо динамического маршрута
hi: Привет, {name}!
whats-your-name: Как тебя зовут?
not-found: Не найден

@ -0,0 +1,14 @@
button:
about: Hakkımda
back: Geri
go: İLERİ
home: Anasayfa
toggle_dark: Karanlık modu değiştir
toggle_langs: Dilleri değiştir
intro:
desc: Görüşlü Vite Başlangıç Şablonu
dynamic-route: Dinamik rota demosu
hi: Merhaba, {name}!
aka: Ayrıca şöyle bilinir
whats-your-name: Adınız nedir?
not-found: Bulunamadı

@ -0,0 +1,13 @@
button:
about: Про шаблон
back: Назад
go: Перейти
home: Головна
toggle_dark: Переключити темний режим
toggle_langs: Змінити мову
intro:
desc: Самостійний початковий шаблон Vite
dynamic-route: Демо динамічного маршруту
hi: Привіт, {name}!
whats-your-name: Як тебе звати?
not-found: Не знайдено

@ -0,0 +1,14 @@
button:
about: Haqida
back: Orqaga
go: Kettik
home: Bosh sahifa
toggle_dark: Qorongi rejimga otish
toggle_langs: Tilni ozgartirish
intro:
desc: Oylangan boshlangich Vite shabloni
dynamic-route: Dynamic route demo'si
hi: Assalomu alaykum, {name}!
aka: shuningdek
whats-your-name: Ismingiz nima?
not-found: Topilmadi

@ -0,0 +1,13 @@
button:
about: Về
back: Quay lại
go: Đi
home: Khởi đầu
toggle_dark: Chuyển đổi chế độ tối
toggle_langs: Thay đổi ngôn ngữ
intro:
desc: Ý kiến cá nhân Vite Template để bắt đầu
dynamic-route: Bản giới thiệu về dynamic route
hi: Hi, {name}!
whats-your-name: Tên bạn là gì?
not-found: Không tìm thấy

@ -0,0 +1,14 @@
button:
about: 关于
back: 返回
go: 确定
home: 首页
toggle_dark: 切换深色模式
toggle_langs: 切换语言
intro:
desc: 固执己见的 Vite 项目模板
dynamic-route: 动态路由演示
hi: 你好,{name}
aka: 也叫
whats-your-name: 输入你的名字
not-found: 未找到页面

@ -0,0 +1,16 @@
[build.environment]
NODE_VERSION = "16"
[build]
publish = "dist"
command = "pnpm run build"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/manifest.webmanifest"
[headers.values]
Content-Type = "application/manifest+json"

@ -0,0 +1,87 @@
{
"type": "module",
"private": true,
"packageManager": "pnpm@8.5.1",
"scripts": {
"build": "vite build",
"build:ssg": "vite-ssg build",
"dev": "vite --port 3333 --open",
"lint": "eslint .",
"preview": "vite preview",
"preview-https": "serve dist",
"test": "vitest",
"test:e2e": "cypress open",
"test:unit": "vitest",
"typecheck": "vue-tsc --noEmit",
"up": "taze major -I",
"postinstall": "npx simple-git-hooks",
"sizecheck": "npx vite-bundle-visualizer"
},
"dependencies": {
"@unhead/vue": "^1.1.27",
"@unocss/reset": "^0.52.2",
"@vueuse/core": "^10.1.2",
"@vueuse/head": "^1.1.26",
"nprogress": "^0.2.0",
"pinia": "^2.1.3",
"vue": "^3.3.4",
"vue-demi": "^0.14.5",
"vue-i18n": "^9.2.2",
"vue-router": "^4.2.1"
},
"devDependencies": {
"@antfu/eslint-config": "^0.39.3",
"@iconify-json/carbon": "^1.1.16",
"@intlify/unplugin-vue-i18n": "^0.10.0",
"@types/markdown-it-link-attributes": "^3.0.1",
"@types/nprogress": "^0.2.0",
"@types/qs": "^6.9.7",
"@unocss/eslint-config": "^0.52.2",
"@vitejs/plugin-vue": "^4.2.3",
"@vue-macros/reactivity-transform": "^0.3.9",
"@vue-macros/short-vmodel": "^1.2.8",
"@vue-macros/volar": "^0.9.8",
"@vue/test-utils": "^2.3.2",
"critters": "^0.0.16",
"cross-env": "^7.0.3",
"cypress": "^12.12.0",
"cypress-vite": "^1.4.0",
"eslint": "^8.41.0",
"eslint-plugin-cypress": "^2.13.3",
"https-localhost": "^4.7.1",
"lint-staged": "^13.2.2",
"markdown-it-link-attributes": "^4.0.1",
"markdown-it-shiki": "^0.9.0",
"naive-ui": "^2.34.4",
"pnpm": "^8.5.1",
"shiki": "^0.14.2",
"simple-git-hooks": "^2.8.1",
"taze": "^0.10.1",
"typescript": "^5.0.4",
"unocss": "^0.52.2",
"unplugin-auto-import": "^0.16.2",
"unplugin-vue-components": "^0.24.1",
"unplugin-vue-macros": "^2.1.7",
"vite": "^4.3.8",
"vite-bundle-visualizer": "^0.7.0",
"vite-plugin-inspect": "^0.7.28",
"vite-plugin-pages": "^0.30.1",
"vite-plugin-pwa": "^0.15.0",
"vite-plugin-vue-component-preview": "^1.1.6",
"vite-plugin-vue-devtools": "^0.0.16",
"vite-plugin-vue-layouts": "^0.8.0",
"vite-plugin-vue-markdown": "^0.23.5",
"vite-plugin-webfont-dl": "^3.7.4",
"vite-ssg": "^0.22.2",
"vite-ssg-sitemap": "^0.5.1",
"vitest": "^0.31.1",
"vue-request": "^2.0.1",
"vue-tsc": "^1.6.5"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
},
"lint-staged": {
"*": "eslint --fix"
}
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,3 @@
/assets/*
cache-control: max-age=31536000
cache-control: immutable

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64px" height="64px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
<g><path style="opacity:0.8" fill="#95df84" d="M 39.5,6.5 C 38.791,7.40397 37.791,7.73731 36.5,7.5C 35.828,6.73261 34.9947,6.06594 34,5.5C 31.1745,7.82928 28.0078,9.49595 24.5,10.5C 23.8333,10.5 23.1667,10.5 22.5,10.5C 26.0359,7.80907 29.8692,5.47573 34,3.5C 36.1204,4.14024 37.9537,5.14024 39.5,6.5 Z"/></g>
<g><path style="opacity:0.694" fill="#8ddd81" d="M 39.5,6.5 C 41.921,11.8085 40.2543,15.1418 34.5,16.5C 33.8333,16.5 33.5,16.1667 33.5,15.5C 34.8484,14.3994 36.3484,13.3994 38,12.5C 38.7494,11.365 38.5827,10.365 37.5,9.5C 35.3021,11.0981 32.9687,12.4314 30.5,13.5C 29.5084,13.6716 28.8417,13.3382 28.5,12.5C 31.1305,10.8474 33.7972,9.1807 36.5,7.5C 37.791,7.73731 38.791,7.40397 39.5,6.5 Z"/></g>
<g><path style="opacity:0.804" fill="#98e08d" d="M 22.5,10.5 C 23.1667,10.5 23.8333,10.5 24.5,10.5C 23.0552,12.0627 21.3885,13.396 19.5,14.5C 18.791,13.596 17.791,13.2627 16.5,13.5C 18.1815,11.9925 20.1815,10.9925 22.5,10.5 Z"/></g>
<g><path style="opacity:0.976" fill="#84db7e" d="M 28.5,12.5 C 28.8417,13.3382 29.5084,13.6716 30.5,13.5C 28.3649,15.0709 26.0316,16.4043 23.5,17.5C 23.5,16.8333 23.5,16.1667 23.5,15.5C 24.9649,14.2632 26.6316,13.2632 28.5,12.5 Z"/></g>
<g><path style="opacity:0.87" fill="#83d87f" d="M 16.5,13.5 C 17.791,13.2627 18.791,13.596 19.5,14.5C 16.4604,15.6803 13.7937,17.347 11.5,19.5C 10.5,19.5 9.5,19.5 8.5,19.5C 8.78448,21.4147 8.45115,23.0813 7.5,24.5C 7.33788,22.4727 7.50454,20.4727 8,18.5C 10.6141,16.4436 13.4475,14.7769 16.5,13.5 Z"/></g>
<g><path style="opacity:0.785" fill="#74d278" d="M 11.5,19.5 C 13.674,19.7497 15.3406,20.7497 16.5,22.5C 16.5,23.1667 16.1667,23.5 15.5,23.5C 13.9557,23.2969 12.6223,22.6302 11.5,21.5C 11.1667,22 10.8333,22.5 10.5,23C 13.0216,25.4166 15.6883,27.5833 18.5,29.5C 17.5084,29.3284 16.8417,29.6618 16.5,30.5C 13.2911,28.7349 10.2911,26.7349 7.5,24.5C 8.45115,23.0813 8.78448,21.4147 8.5,19.5C 9.5,19.5 10.5,19.5 11.5,19.5 Z"/></g>
<g><path style="opacity:0.812" fill="#7ed77d" d="M 23.5,15.5 C 23.5,16.1667 23.5,16.8333 23.5,17.5C 20.8662,18.6584 21.0329,19.6584 24,20.5C 27.0756,18.5743 30.2423,16.9076 33.5,15.5C 33.5,16.1667 33.8333,16.5 34.5,16.5C 31.8333,18.5 29.1667,20.5 26.5,22.5C 26.5,23.1667 26.1667,23.5 25.5,23.5C 22.7261,22.2774 20.0594,20.7774 17.5,19C 19.0634,17.0527 21.0634,15.886 23.5,15.5 Z"/></g>
<g><path style="opacity:0.9" fill="#75c97a" d="M 16.5,22.5 C 18.8185,22.9925 20.8185,23.9925 22.5,25.5C 22.1667,26.1667 21.8333,26.8333 21.5,27.5C 19.4632,26.1535 17.4632,24.8202 15.5,23.5C 16.1667,23.5 16.5,23.1667 16.5,22.5 Z"/></g>
<g><path style="opacity:0.936" fill="#71d079" d="M 26.5,22.5 C 29.3311,23.0787 31.6644,24.412 33.5,26.5C 32.8333,26.5 32.1667,26.5 31.5,26.5C 29.1815,26.0075 27.1815,25.0075 25.5,23.5C 26.1667,23.5 26.5,23.1667 26.5,22.5 Z"/></g>
<g><path style="opacity:0.845" fill="#79cb7f" d="M 22.5,25.5 C 25.0316,26.5957 27.3649,27.9291 29.5,29.5C 28.209,29.2627 27.209,29.596 26.5,30.5C 24.9991,29.2485 23.3325,28.2485 21.5,27.5C 21.8333,26.8333 22.1667,26.1667 22.5,25.5 Z"/></g>
<g><path style="opacity:0.816" fill="#66c974" d="M 16.5,30.5 C 16.8417,29.6618 17.5084,29.3284 18.5,29.5C 20.2838,29.8925 21.9505,30.5592 23.5,31.5C 23.5,32.1667 23.5,32.8333 23.5,33.5C 21.0462,32.7729 18.7128,31.7729 16.5,30.5 Z"/></g>
<g><path style="opacity:0.895" fill="#6ac877" d="M 31.5,26.5 C 32.1667,26.5 32.8333,26.5 33.5,26.5C 39.165,28.9969 44.4984,31.9969 49.5,35.5C 48.5,35.5 47.5,35.5 46.5,35.5C 40.9946,33.2513 35.9946,30.2513 31.5,26.5 Z"/></g>
<g><path style="opacity:0.763" fill="#63c775" d="M 26.5,30.5 C 27.209,29.596 28.209,29.2627 29.5,29.5C 33.2009,31.0116 36.5342,33.0116 39.5,35.5C 38.5,35.5 37.5,35.5 36.5,35.5C 33.1932,33.8466 29.8599,32.1799 26.5,30.5 Z"/></g>
<g><path style="opacity:0.86" fill="#5ac571" d="M 36.5,39.5 C 35.1667,39.5 33.8333,39.5 32.5,39.5C 31.8333,39.1667 31.1667,38.8333 30.5,38.5C 29.8333,38.8333 29.1667,39.1667 28.5,39.5C 28.5,38.1667 28.5,36.8333 28.5,35.5C 31.4422,36.3045 34.1089,37.6378 36.5,39.5 Z"/></g>
<g><path style="opacity:0.88" fill="#58c76e" d="M 36.5,35.5 C 37.5,35.5 38.5,35.5 39.5,35.5C 41.2554,36.0722 42.9221,36.9055 44.5,38C 45.7383,38.69 45.7383,39.19 44.5,39.5C 43.5,39.5 42.5,39.5 41.5,39.5C 39.8333,38.1667 38.1667,36.8333 36.5,35.5 Z"/></g>
<g><path style="opacity:0.758" fill="#5dc773" d="M 46.5,35.5 C 47.5,35.5 48.5,35.5 49.5,35.5C 51.8525,36.3403 53.8525,37.6736 55.5,39.5C 54.0357,38.5946 52.7024,38.5946 51.5,39.5C 49.8333,38.1667 48.1667,36.8333 46.5,35.5 Z"/></g>
<g><path style="opacity:0.899" fill="#54ba6a" d="M 32.5,39.5 C 33.8333,39.5 35.1667,39.5 36.5,39.5C 38.2341,40.562 39.9008,40.562 41.5,39.5C 42.5,39.5 43.5,39.5 44.5,39.5C 43.1007,40.8897 41.4341,41.8897 39.5,42.5C 38.391,42.4431 37.391,42.1098 36.5,41.5C 35.8333,41.5 35.5,41.8333 35.5,42.5C 33.9519,42.8212 33.2852,43.8212 33.5,45.5C 33.5,47.1667 33.5,48.8333 33.5,50.5C 32.5184,47.0381 32.185,43.3714 32.5,39.5 Z"/></g>
<g><path style="opacity:0.774" fill="#4dc16b" d="M 36.5,41.5 C 37.391,42.1098 38.391,42.4431 39.5,42.5C 38.5637,43.9744 37.2303,44.9744 35.5,45.5C 34.8333,45.5 34.1667,45.5 33.5,45.5C 33.2852,43.8212 33.9519,42.8212 35.5,42.5C 36.1667,42.5 36.5,42.1667 36.5,41.5 Z"/></g>
<g><path style="opacity:0.74" fill="#4ebe6f" d="M 48.5,41.5 C 49.4916,41.3284 50.1583,41.6618 50.5,42.5C 46.9934,44.754 43.3267,46.754 39.5,48.5C 38.5084,48.6716 37.8417,48.3382 37.5,47.5C 41.0337,45.2336 44.7004,43.2336 48.5,41.5 Z"/></g>
<g><path style="opacity:0.735" fill="#54bf70" d="M 23.5,31.5 C 24.1174,31.6107 24.6174,31.944 25,32.5C 25.4988,36.4862 25.6655,40.4862 25.5,44.5C 24.8333,44.8333 24.1667,45.1667 23.5,45.5C 23.5,41.5 23.5,37.5 23.5,33.5C 23.5,32.8333 23.5,32.1667 23.5,31.5 Z"/></g>
<g><path style="opacity:0.703" fill="#51bd71" d="M 55.5,39.5 C 55.7947,41.7354 55.4614,43.7354 54.5,45.5C 53.8333,45.5 53.5,45.1667 53.5,44.5C 53.5983,41.7524 52.5983,41.0857 50.5,42.5C 50.1583,41.6618 49.4916,41.3284 48.5,41.5C 49.2905,40.5987 50.2905,39.9321 51.5,39.5C 52.7024,38.5946 54.0357,38.5946 55.5,39.5 Z"/></g>
<g><path style="opacity:0.718" fill="#4bbe6d" d="M 53.5,44.5 C 53.5,45.1667 53.8333,45.5 54.5,45.5C 52.5368,46.8202 50.5368,48.1535 48.5,49.5C 48.1583,48.6618 47.4916,48.3284 46.5,48.5C 48.3356,46.412 50.6689,45.0787 53.5,44.5 Z"/></g>
<g><path style="opacity:0.797" fill="#43b86d" d="M 33.5,45.5 C 34.1667,45.5 34.8333,45.5 35.5,45.5C 35.1307,47.9935 35.7973,48.6602 37.5,47.5C 37.8417,48.3382 38.5084,48.6716 39.5,48.5C 37.6841,50.4414 35.6841,51.1081 33.5,50.5C 33.5,48.8333 33.5,47.1667 33.5,45.5 Z"/></g>
<g><path style="opacity:0.696" fill="#47b96c" d="M 30.5,38.5 C 30.5,43.1667 30.5,47.8333 30.5,52.5C 29.8333,52.1667 29.1667,51.8333 28.5,51.5C 28.5,47.5 28.5,43.5 28.5,39.5C 29.1667,39.1667 29.8333,38.8333 30.5,38.5 Z"/></g>
<g><path style="opacity:0.915" fill="#41b76b" d="M 46.5,48.5 C 47.4916,48.3284 48.1583,48.6618 48.5,49.5C 46.4832,50.5294 44.4832,51.5294 42.5,52.5C 41.5084,52.6716 40.8417,52.3382 40.5,51.5C 42.2163,49.9752 44.2163,48.9752 46.5,48.5 Z"/></g>
<g><path style="opacity:0.669" fill="#3fb46a" d="M 25.5,44.5 C 25.5,47.8333 25.5,51.1667 25.5,54.5C 24.8333,54.8333 24.1667,55.1667 23.5,55.5C 23.5,52.1667 23.5,48.8333 23.5,45.5C 24.1667,45.1667 24.8333,44.8333 25.5,44.5 Z"/></g>
<g><path style="opacity:0.756" fill="#36af69" d="M 28.5,51.5 C 29.1667,51.8333 29.8333,52.1667 30.5,52.5C 30.238,53.9778 30.5713,55.3112 31.5,56.5C 34.6884,55.0748 37.6884,53.4081 40.5,51.5C 40.8417,52.3382 41.5084,52.6716 42.5,52.5C 38.3979,55.3921 34.0645,58.0588 29.5,60.5C 26.5737,59.7349 24.5737,58.0683 23.5,55.5C 24.1667,55.1667 24.8333,54.8333 25.5,54.5C 25.7496,55.9221 26.583,56.9221 28,57.5C 28.4955,55.5273 28.6621,53.5273 28.5,51.5 Z"/></g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64px" height="64px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
<g><path style="opacity:0.8" fill="#95df84" d="M 39.5,6.5 C 38.791,7.40397 37.791,7.73731 36.5,7.5C 35.828,6.73261 34.9947,6.06594 34,5.5C 31.1745,7.82928 28.0078,9.49595 24.5,10.5C 23.8333,10.5 23.1667,10.5 22.5,10.5C 26.0359,7.80907 29.8692,5.47573 34,3.5C 36.1204,4.14024 37.9537,5.14024 39.5,6.5 Z"/></g>
<g><path style="opacity:0.694" fill="#8ddd81" d="M 39.5,6.5 C 41.921,11.8085 40.2543,15.1418 34.5,16.5C 33.8333,16.5 33.5,16.1667 33.5,15.5C 34.8484,14.3994 36.3484,13.3994 38,12.5C 38.7494,11.365 38.5827,10.365 37.5,9.5C 35.3021,11.0981 32.9687,12.4314 30.5,13.5C 29.5084,13.6716 28.8417,13.3382 28.5,12.5C 31.1305,10.8474 33.7972,9.1807 36.5,7.5C 37.791,7.73731 38.791,7.40397 39.5,6.5 Z"/></g>
<g><path style="opacity:0.804" fill="#98e08d" d="M 22.5,10.5 C 23.1667,10.5 23.8333,10.5 24.5,10.5C 23.0552,12.0627 21.3885,13.396 19.5,14.5C 18.791,13.596 17.791,13.2627 16.5,13.5C 18.1815,11.9925 20.1815,10.9925 22.5,10.5 Z"/></g>
<g><path style="opacity:0.976" fill="#84db7e" d="M 28.5,12.5 C 28.8417,13.3382 29.5084,13.6716 30.5,13.5C 28.3649,15.0709 26.0316,16.4043 23.5,17.5C 23.5,16.8333 23.5,16.1667 23.5,15.5C 24.9649,14.2632 26.6316,13.2632 28.5,12.5 Z"/></g>
<g><path style="opacity:0.87" fill="#83d87f" d="M 16.5,13.5 C 17.791,13.2627 18.791,13.596 19.5,14.5C 16.4604,15.6803 13.7937,17.347 11.5,19.5C 10.5,19.5 9.5,19.5 8.5,19.5C 8.78448,21.4147 8.45115,23.0813 7.5,24.5C 7.33788,22.4727 7.50454,20.4727 8,18.5C 10.6141,16.4436 13.4475,14.7769 16.5,13.5 Z"/></g>
<g><path style="opacity:0.785" fill="#74d278" d="M 11.5,19.5 C 13.674,19.7497 15.3406,20.7497 16.5,22.5C 16.5,23.1667 16.1667,23.5 15.5,23.5C 13.9557,23.2969 12.6223,22.6302 11.5,21.5C 11.1667,22 10.8333,22.5 10.5,23C 13.0216,25.4166 15.6883,27.5833 18.5,29.5C 17.5084,29.3284 16.8417,29.6618 16.5,30.5C 13.2911,28.7349 10.2911,26.7349 7.5,24.5C 8.45115,23.0813 8.78448,21.4147 8.5,19.5C 9.5,19.5 10.5,19.5 11.5,19.5 Z"/></g>
<g><path style="opacity:0.812" fill="#7ed77d" d="M 23.5,15.5 C 23.5,16.1667 23.5,16.8333 23.5,17.5C 20.8662,18.6584 21.0329,19.6584 24,20.5C 27.0756,18.5743 30.2423,16.9076 33.5,15.5C 33.5,16.1667 33.8333,16.5 34.5,16.5C 31.8333,18.5 29.1667,20.5 26.5,22.5C 26.5,23.1667 26.1667,23.5 25.5,23.5C 22.7261,22.2774 20.0594,20.7774 17.5,19C 19.0634,17.0527 21.0634,15.886 23.5,15.5 Z"/></g>
<g><path style="opacity:0.9" fill="#75c97a" d="M 16.5,22.5 C 18.8185,22.9925 20.8185,23.9925 22.5,25.5C 22.1667,26.1667 21.8333,26.8333 21.5,27.5C 19.4632,26.1535 17.4632,24.8202 15.5,23.5C 16.1667,23.5 16.5,23.1667 16.5,22.5 Z"/></g>
<g><path style="opacity:0.936" fill="#71d079" d="M 26.5,22.5 C 29.3311,23.0787 31.6644,24.412 33.5,26.5C 32.8333,26.5 32.1667,26.5 31.5,26.5C 29.1815,26.0075 27.1815,25.0075 25.5,23.5C 26.1667,23.5 26.5,23.1667 26.5,22.5 Z"/></g>
<g><path style="opacity:0.845" fill="#79cb7f" d="M 22.5,25.5 C 25.0316,26.5957 27.3649,27.9291 29.5,29.5C 28.209,29.2627 27.209,29.596 26.5,30.5C 24.9991,29.2485 23.3325,28.2485 21.5,27.5C 21.8333,26.8333 22.1667,26.1667 22.5,25.5 Z"/></g>
<g><path style="opacity:0.816" fill="#66c974" d="M 16.5,30.5 C 16.8417,29.6618 17.5084,29.3284 18.5,29.5C 20.2838,29.8925 21.9505,30.5592 23.5,31.5C 23.5,32.1667 23.5,32.8333 23.5,33.5C 21.0462,32.7729 18.7128,31.7729 16.5,30.5 Z"/></g>
<g><path style="opacity:0.895" fill="#6ac877" d="M 31.5,26.5 C 32.1667,26.5 32.8333,26.5 33.5,26.5C 39.165,28.9969 44.4984,31.9969 49.5,35.5C 48.5,35.5 47.5,35.5 46.5,35.5C 40.9946,33.2513 35.9946,30.2513 31.5,26.5 Z"/></g>
<g><path style="opacity:0.763" fill="#63c775" d="M 26.5,30.5 C 27.209,29.596 28.209,29.2627 29.5,29.5C 33.2009,31.0116 36.5342,33.0116 39.5,35.5C 38.5,35.5 37.5,35.5 36.5,35.5C 33.1932,33.8466 29.8599,32.1799 26.5,30.5 Z"/></g>
<g><path style="opacity:0.86" fill="#5ac571" d="M 36.5,39.5 C 35.1667,39.5 33.8333,39.5 32.5,39.5C 31.8333,39.1667 31.1667,38.8333 30.5,38.5C 29.8333,38.8333 29.1667,39.1667 28.5,39.5C 28.5,38.1667 28.5,36.8333 28.5,35.5C 31.4422,36.3045 34.1089,37.6378 36.5,39.5 Z"/></g>
<g><path style="opacity:0.88" fill="#58c76e" d="M 36.5,35.5 C 37.5,35.5 38.5,35.5 39.5,35.5C 41.2554,36.0722 42.9221,36.9055 44.5,38C 45.7383,38.69 45.7383,39.19 44.5,39.5C 43.5,39.5 42.5,39.5 41.5,39.5C 39.8333,38.1667 38.1667,36.8333 36.5,35.5 Z"/></g>
<g><path style="opacity:0.758" fill="#5dc773" d="M 46.5,35.5 C 47.5,35.5 48.5,35.5 49.5,35.5C 51.8525,36.3403 53.8525,37.6736 55.5,39.5C 54.0357,38.5946 52.7024,38.5946 51.5,39.5C 49.8333,38.1667 48.1667,36.8333 46.5,35.5 Z"/></g>
<g><path style="opacity:0.899" fill="#54ba6a" d="M 32.5,39.5 C 33.8333,39.5 35.1667,39.5 36.5,39.5C 38.2341,40.562 39.9008,40.562 41.5,39.5C 42.5,39.5 43.5,39.5 44.5,39.5C 43.1007,40.8897 41.4341,41.8897 39.5,42.5C 38.391,42.4431 37.391,42.1098 36.5,41.5C 35.8333,41.5 35.5,41.8333 35.5,42.5C 33.9519,42.8212 33.2852,43.8212 33.5,45.5C 33.5,47.1667 33.5,48.8333 33.5,50.5C 32.5184,47.0381 32.185,43.3714 32.5,39.5 Z"/></g>
<g><path style="opacity:0.774" fill="#4dc16b" d="M 36.5,41.5 C 37.391,42.1098 38.391,42.4431 39.5,42.5C 38.5637,43.9744 37.2303,44.9744 35.5,45.5C 34.8333,45.5 34.1667,45.5 33.5,45.5C 33.2852,43.8212 33.9519,42.8212 35.5,42.5C 36.1667,42.5 36.5,42.1667 36.5,41.5 Z"/></g>
<g><path style="opacity:0.74" fill="#4ebe6f" d="M 48.5,41.5 C 49.4916,41.3284 50.1583,41.6618 50.5,42.5C 46.9934,44.754 43.3267,46.754 39.5,48.5C 38.5084,48.6716 37.8417,48.3382 37.5,47.5C 41.0337,45.2336 44.7004,43.2336 48.5,41.5 Z"/></g>
<g><path style="opacity:0.735" fill="#54bf70" d="M 23.5,31.5 C 24.1174,31.6107 24.6174,31.944 25,32.5C 25.4988,36.4862 25.6655,40.4862 25.5,44.5C 24.8333,44.8333 24.1667,45.1667 23.5,45.5C 23.5,41.5 23.5,37.5 23.5,33.5C 23.5,32.8333 23.5,32.1667 23.5,31.5 Z"/></g>
<g><path style="opacity:0.703" fill="#51bd71" d="M 55.5,39.5 C 55.7947,41.7354 55.4614,43.7354 54.5,45.5C 53.8333,45.5 53.5,45.1667 53.5,44.5C 53.5983,41.7524 52.5983,41.0857 50.5,42.5C 50.1583,41.6618 49.4916,41.3284 48.5,41.5C 49.2905,40.5987 50.2905,39.9321 51.5,39.5C 52.7024,38.5946 54.0357,38.5946 55.5,39.5 Z"/></g>
<g><path style="opacity:0.718" fill="#4bbe6d" d="M 53.5,44.5 C 53.5,45.1667 53.8333,45.5 54.5,45.5C 52.5368,46.8202 50.5368,48.1535 48.5,49.5C 48.1583,48.6618 47.4916,48.3284 46.5,48.5C 48.3356,46.412 50.6689,45.0787 53.5,44.5 Z"/></g>
<g><path style="opacity:0.797" fill="#43b86d" d="M 33.5,45.5 C 34.1667,45.5 34.8333,45.5 35.5,45.5C 35.1307,47.9935 35.7973,48.6602 37.5,47.5C 37.8417,48.3382 38.5084,48.6716 39.5,48.5C 37.6841,50.4414 35.6841,51.1081 33.5,50.5C 33.5,48.8333 33.5,47.1667 33.5,45.5 Z"/></g>
<g><path style="opacity:0.696" fill="#47b96c" d="M 30.5,38.5 C 30.5,43.1667 30.5,47.8333 30.5,52.5C 29.8333,52.1667 29.1667,51.8333 28.5,51.5C 28.5,47.5 28.5,43.5 28.5,39.5C 29.1667,39.1667 29.8333,38.8333 30.5,38.5 Z"/></g>
<g><path style="opacity:0.915" fill="#41b76b" d="M 46.5,48.5 C 47.4916,48.3284 48.1583,48.6618 48.5,49.5C 46.4832,50.5294 44.4832,51.5294 42.5,52.5C 41.5084,52.6716 40.8417,52.3382 40.5,51.5C 42.2163,49.9752 44.2163,48.9752 46.5,48.5 Z"/></g>
<g><path style="opacity:0.669" fill="#3fb46a" d="M 25.5,44.5 C 25.5,47.8333 25.5,51.1667 25.5,54.5C 24.8333,54.8333 24.1667,55.1667 23.5,55.5C 23.5,52.1667 23.5,48.8333 23.5,45.5C 24.1667,45.1667 24.8333,44.8333 25.5,44.5 Z"/></g>
<g><path style="opacity:0.756" fill="#36af69" d="M 28.5,51.5 C 29.1667,51.8333 29.8333,52.1667 30.5,52.5C 30.238,53.9778 30.5713,55.3112 31.5,56.5C 34.6884,55.0748 37.6884,53.4081 40.5,51.5C 40.8417,52.3382 41.5084,52.6716 42.5,52.5C 38.3979,55.3921 34.0645,58.0588 29.5,60.5C 26.5737,59.7349 24.5737,58.0683 23.5,55.5C 24.1667,55.1667 24.8333,54.8333 25.5,54.5C 25.7496,55.9221 26.583,56.9221 28,57.5C 28.4955,55.5273 28.6621,53.5273 28.5,51.5 Z"/></g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="64px" height="64px" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd" xmlns:xlink="http://www.w3.org/1999/xlink">
<g><path style="opacity:0.8" fill="#95df84" d="M 39.5,6.5 C 38.791,7.40397 37.791,7.73731 36.5,7.5C 35.828,6.73261 34.9947,6.06594 34,5.5C 31.1745,7.82928 28.0078,9.49595 24.5,10.5C 23.8333,10.5 23.1667,10.5 22.5,10.5C 26.0359,7.80907 29.8692,5.47573 34,3.5C 36.1204,4.14024 37.9537,5.14024 39.5,6.5 Z"/></g>
<g><path style="opacity:0.694" fill="#8ddd81" d="M 39.5,6.5 C 41.921,11.8085 40.2543,15.1418 34.5,16.5C 33.8333,16.5 33.5,16.1667 33.5,15.5C 34.8484,14.3994 36.3484,13.3994 38,12.5C 38.7494,11.365 38.5827,10.365 37.5,9.5C 35.3021,11.0981 32.9687,12.4314 30.5,13.5C 29.5084,13.6716 28.8417,13.3382 28.5,12.5C 31.1305,10.8474 33.7972,9.1807 36.5,7.5C 37.791,7.73731 38.791,7.40397 39.5,6.5 Z"/></g>
<g><path style="opacity:0.804" fill="#98e08d" d="M 22.5,10.5 C 23.1667,10.5 23.8333,10.5 24.5,10.5C 23.0552,12.0627 21.3885,13.396 19.5,14.5C 18.791,13.596 17.791,13.2627 16.5,13.5C 18.1815,11.9925 20.1815,10.9925 22.5,10.5 Z"/></g>
<g><path style="opacity:0.976" fill="#84db7e" d="M 28.5,12.5 C 28.8417,13.3382 29.5084,13.6716 30.5,13.5C 28.3649,15.0709 26.0316,16.4043 23.5,17.5C 23.5,16.8333 23.5,16.1667 23.5,15.5C 24.9649,14.2632 26.6316,13.2632 28.5,12.5 Z"/></g>
<g><path style="opacity:0.87" fill="#83d87f" d="M 16.5,13.5 C 17.791,13.2627 18.791,13.596 19.5,14.5C 16.4604,15.6803 13.7937,17.347 11.5,19.5C 10.5,19.5 9.5,19.5 8.5,19.5C 8.78448,21.4147 8.45115,23.0813 7.5,24.5C 7.33788,22.4727 7.50454,20.4727 8,18.5C 10.6141,16.4436 13.4475,14.7769 16.5,13.5 Z"/></g>
<g><path style="opacity:0.785" fill="#74d278" d="M 11.5,19.5 C 13.674,19.7497 15.3406,20.7497 16.5,22.5C 16.5,23.1667 16.1667,23.5 15.5,23.5C 13.9557,23.2969 12.6223,22.6302 11.5,21.5C 11.1667,22 10.8333,22.5 10.5,23C 13.0216,25.4166 15.6883,27.5833 18.5,29.5C 17.5084,29.3284 16.8417,29.6618 16.5,30.5C 13.2911,28.7349 10.2911,26.7349 7.5,24.5C 8.45115,23.0813 8.78448,21.4147 8.5,19.5C 9.5,19.5 10.5,19.5 11.5,19.5 Z"/></g>
<g><path style="opacity:0.812" fill="#7ed77d" d="M 23.5,15.5 C 23.5,16.1667 23.5,16.8333 23.5,17.5C 20.8662,18.6584 21.0329,19.6584 24,20.5C 27.0756,18.5743 30.2423,16.9076 33.5,15.5C 33.5,16.1667 33.8333,16.5 34.5,16.5C 31.8333,18.5 29.1667,20.5 26.5,22.5C 26.5,23.1667 26.1667,23.5 25.5,23.5C 22.7261,22.2774 20.0594,20.7774 17.5,19C 19.0634,17.0527 21.0634,15.886 23.5,15.5 Z"/></g>
<g><path style="opacity:0.9" fill="#75c97a" d="M 16.5,22.5 C 18.8185,22.9925 20.8185,23.9925 22.5,25.5C 22.1667,26.1667 21.8333,26.8333 21.5,27.5C 19.4632,26.1535 17.4632,24.8202 15.5,23.5C 16.1667,23.5 16.5,23.1667 16.5,22.5 Z"/></g>
<g><path style="opacity:0.936" fill="#71d079" d="M 26.5,22.5 C 29.3311,23.0787 31.6644,24.412 33.5,26.5C 32.8333,26.5 32.1667,26.5 31.5,26.5C 29.1815,26.0075 27.1815,25.0075 25.5,23.5C 26.1667,23.5 26.5,23.1667 26.5,22.5 Z"/></g>
<g><path style="opacity:0.845" fill="#79cb7f" d="M 22.5,25.5 C 25.0316,26.5957 27.3649,27.9291 29.5,29.5C 28.209,29.2627 27.209,29.596 26.5,30.5C 24.9991,29.2485 23.3325,28.2485 21.5,27.5C 21.8333,26.8333 22.1667,26.1667 22.5,25.5 Z"/></g>
<g><path style="opacity:0.816" fill="#66c974" d="M 16.5,30.5 C 16.8417,29.6618 17.5084,29.3284 18.5,29.5C 20.2838,29.8925 21.9505,30.5592 23.5,31.5C 23.5,32.1667 23.5,32.8333 23.5,33.5C 21.0462,32.7729 18.7128,31.7729 16.5,30.5 Z"/></g>
<g><path style="opacity:0.895" fill="#6ac877" d="M 31.5,26.5 C 32.1667,26.5 32.8333,26.5 33.5,26.5C 39.165,28.9969 44.4984,31.9969 49.5,35.5C 48.5,35.5 47.5,35.5 46.5,35.5C 40.9946,33.2513 35.9946,30.2513 31.5,26.5 Z"/></g>
<g><path style="opacity:0.763" fill="#63c775" d="M 26.5,30.5 C 27.209,29.596 28.209,29.2627 29.5,29.5C 33.2009,31.0116 36.5342,33.0116 39.5,35.5C 38.5,35.5 37.5,35.5 36.5,35.5C 33.1932,33.8466 29.8599,32.1799 26.5,30.5 Z"/></g>
<g><path style="opacity:0.86" fill="#5ac571" d="M 36.5,39.5 C 35.1667,39.5 33.8333,39.5 32.5,39.5C 31.8333,39.1667 31.1667,38.8333 30.5,38.5C 29.8333,38.8333 29.1667,39.1667 28.5,39.5C 28.5,38.1667 28.5,36.8333 28.5,35.5C 31.4422,36.3045 34.1089,37.6378 36.5,39.5 Z"/></g>
<g><path style="opacity:0.88" fill="#58c76e" d="M 36.5,35.5 C 37.5,35.5 38.5,35.5 39.5,35.5C 41.2554,36.0722 42.9221,36.9055 44.5,38C 45.7383,38.69 45.7383,39.19 44.5,39.5C 43.5,39.5 42.5,39.5 41.5,39.5C 39.8333,38.1667 38.1667,36.8333 36.5,35.5 Z"/></g>
<g><path style="opacity:0.758" fill="#5dc773" d="M 46.5,35.5 C 47.5,35.5 48.5,35.5 49.5,35.5C 51.8525,36.3403 53.8525,37.6736 55.5,39.5C 54.0357,38.5946 52.7024,38.5946 51.5,39.5C 49.8333,38.1667 48.1667,36.8333 46.5,35.5 Z"/></g>
<g><path style="opacity:0.899" fill="#54ba6a" d="M 32.5,39.5 C 33.8333,39.5 35.1667,39.5 36.5,39.5C 38.2341,40.562 39.9008,40.562 41.5,39.5C 42.5,39.5 43.5,39.5 44.5,39.5C 43.1007,40.8897 41.4341,41.8897 39.5,42.5C 38.391,42.4431 37.391,42.1098 36.5,41.5C 35.8333,41.5 35.5,41.8333 35.5,42.5C 33.9519,42.8212 33.2852,43.8212 33.5,45.5C 33.5,47.1667 33.5,48.8333 33.5,50.5C 32.5184,47.0381 32.185,43.3714 32.5,39.5 Z"/></g>
<g><path style="opacity:0.774" fill="#4dc16b" d="M 36.5,41.5 C 37.391,42.1098 38.391,42.4431 39.5,42.5C 38.5637,43.9744 37.2303,44.9744 35.5,45.5C 34.8333,45.5 34.1667,45.5 33.5,45.5C 33.2852,43.8212 33.9519,42.8212 35.5,42.5C 36.1667,42.5 36.5,42.1667 36.5,41.5 Z"/></g>
<g><path style="opacity:0.74" fill="#4ebe6f" d="M 48.5,41.5 C 49.4916,41.3284 50.1583,41.6618 50.5,42.5C 46.9934,44.754 43.3267,46.754 39.5,48.5C 38.5084,48.6716 37.8417,48.3382 37.5,47.5C 41.0337,45.2336 44.7004,43.2336 48.5,41.5 Z"/></g>
<g><path style="opacity:0.735" fill="#54bf70" d="M 23.5,31.5 C 24.1174,31.6107 24.6174,31.944 25,32.5C 25.4988,36.4862 25.6655,40.4862 25.5,44.5C 24.8333,44.8333 24.1667,45.1667 23.5,45.5C 23.5,41.5 23.5,37.5 23.5,33.5C 23.5,32.8333 23.5,32.1667 23.5,31.5 Z"/></g>
<g><path style="opacity:0.703" fill="#51bd71" d="M 55.5,39.5 C 55.7947,41.7354 55.4614,43.7354 54.5,45.5C 53.8333,45.5 53.5,45.1667 53.5,44.5C 53.5983,41.7524 52.5983,41.0857 50.5,42.5C 50.1583,41.6618 49.4916,41.3284 48.5,41.5C 49.2905,40.5987 50.2905,39.9321 51.5,39.5C 52.7024,38.5946 54.0357,38.5946 55.5,39.5 Z"/></g>
<g><path style="opacity:0.718" fill="#4bbe6d" d="M 53.5,44.5 C 53.5,45.1667 53.8333,45.5 54.5,45.5C 52.5368,46.8202 50.5368,48.1535 48.5,49.5C 48.1583,48.6618 47.4916,48.3284 46.5,48.5C 48.3356,46.412 50.6689,45.0787 53.5,44.5 Z"/></g>
<g><path style="opacity:0.797" fill="#43b86d" d="M 33.5,45.5 C 34.1667,45.5 34.8333,45.5 35.5,45.5C 35.1307,47.9935 35.7973,48.6602 37.5,47.5C 37.8417,48.3382 38.5084,48.6716 39.5,48.5C 37.6841,50.4414 35.6841,51.1081 33.5,50.5C 33.5,48.8333 33.5,47.1667 33.5,45.5 Z"/></g>
<g><path style="opacity:0.696" fill="#47b96c" d="M 30.5,38.5 C 30.5,43.1667 30.5,47.8333 30.5,52.5C 29.8333,52.1667 29.1667,51.8333 28.5,51.5C 28.5,47.5 28.5,43.5 28.5,39.5C 29.1667,39.1667 29.8333,38.8333 30.5,38.5 Z"/></g>
<g><path style="opacity:0.915" fill="#41b76b" d="M 46.5,48.5 C 47.4916,48.3284 48.1583,48.6618 48.5,49.5C 46.4832,50.5294 44.4832,51.5294 42.5,52.5C 41.5084,52.6716 40.8417,52.3382 40.5,51.5C 42.2163,49.9752 44.2163,48.9752 46.5,48.5 Z"/></g>
<g><path style="opacity:0.669" fill="#3fb46a" d="M 25.5,44.5 C 25.5,47.8333 25.5,51.1667 25.5,54.5C 24.8333,54.8333 24.1667,55.1667 23.5,55.5C 23.5,52.1667 23.5,48.8333 23.5,45.5C 24.1667,45.1667 24.8333,44.8333 25.5,44.5 Z"/></g>
<g><path style="opacity:0.756" fill="#36af69" d="M 28.5,51.5 C 29.1667,51.8333 29.8333,52.1667 30.5,52.5C 30.238,53.9778 30.5713,55.3112 31.5,56.5C 34.6884,55.0748 37.6884,53.4081 40.5,51.5C 40.8417,52.3382 41.5084,52.6716 42.5,52.5C 38.3979,55.3921 34.0645,58.0588 29.5,60.5C 26.5737,59.7349 24.5737,58.0683 23.5,55.5C 24.1667,55.1667 24.8333,54.8333 25.5,54.5C 25.7496,55.9221 26.583,56.9221 28,57.5C 28.4955,55.5273 28.6621,53.5273 28.5,51.5 Z"/></g>
</svg>

After

Width:  |  Height:  |  Size: 7.9 KiB

@ -0,0 +1,74 @@
<script setup lang="ts">
import type { GlobalThemeOverrides } from 'naive-ui'
import { darkTheme, dateZhCN, zhCN } from 'naive-ui'
// https://github.com/vueuse/head
// you can use this to manipulate the document head in any components,
// they will be rendered correctly in the html results with vite-ssg
useHead({
title: `${import.meta.env.VITE_TITLE}`,
meta: [
{ name: 'description', content: `${import.meta.env.VITE_DESCRIPTION}` },
{
name: 'theme-color',
content: () => isDark.value ? '#00aba9' : '#ffffff',
},
],
link: [
{
rel: 'icon',
type: 'image/svg+xml',
href: () => preferredDark.value ? '/favicon-dark.svg' : '/favicon.svg',
},
],
})
const theme = computed(() => {
return isDark.value ? darkTheme : null
})
// const i18n = useI18n()
// createLocale({ name: i18n.locale }, zhCN)
const themeOverrides: GlobalThemeOverrides = {
common: {
primaryColor: '#0052D9',
primaryColorHover: '#366ef4',
primaryColorPressed: '#003cab',
primaryColorSuppl: '#003ccc',
},
}
</script>
<template>
<n-config-provider
class="h-full w-full"
:theme="theme"
:theme-overrides="themeOverrides"
:locale="zhCN"
:date-locale="dateZhCN"
>
<n-loading-bar-provider>
<n-message-provider>
<n-notification-provider>
<n-dialog-provider>
<n-watermark
content="TODO 水印"
cross
fullscreen
:font-size="12"
:line-height="16"
:width="384"
:height="384"
:x-offset="12"
:y-offset="60"
:rotate="-15"
/>
<RouterView />
</n-dialog-provider>
</n-notification-provider>
</n-message-provider>
</n-loading-bar-provider>
<n-global-style />
</n-config-provider>
</template>

@ -0,0 +1,919 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-auto-import
export {}
declare global {
const $: typeof import('vue/macros')['$']
const $$: typeof import('vue/macros')['$$']
const $computed: typeof import('vue/macros')['$computed']
const $customRef: typeof import('vue/macros')['$customRef']
const $ref: typeof import('vue/macros')['$ref']
const $shallowRef: typeof import('vue/macros')['$shallowRef']
const $toRef: typeof import('vue/macros')['$toRef']
const EffectScope: typeof import('vue')['EffectScope']
const asyncComputed: typeof import('@vueuse/core')['asyncComputed']
const autoResetRef: typeof import('@vueuse/core')['autoResetRef']
const computed: typeof import('vue')['computed']
const computedAsync: typeof import('@vueuse/core')['computedAsync']
const computedEager: typeof import('@vueuse/core')['computedEager']
const computedInject: typeof import('@vueuse/core')['computedInject']
const computedWithControl: typeof import('@vueuse/core')['computedWithControl']
const controlledComputed: typeof import('@vueuse/core')['controlledComputed']
const controlledRef: typeof import('@vueuse/core')['controlledRef']
const createApp: typeof import('vue')['createApp']
const createEventHook: typeof import('@vueuse/core')['createEventHook']
const createGlobalState: typeof import('@vueuse/core')['createGlobalState']
const createInjectionState: typeof import('@vueuse/core')['createInjectionState']
const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn']
const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate']
const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable']
const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise']
const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn']
const customRef: typeof import('vue')['customRef']
const debouncedRef: typeof import('@vueuse/core')['debouncedRef']
const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const eagerComputed: typeof import('@vueuse/core')['eagerComputed']
const effectScope: typeof import('vue')['effectScope']
const envD: typeof import('./types/env.d')['default']
const extendRef: typeof import('@vueuse/core')['extendRef']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
const inject: typeof import('vue')['inject']
const isDark: typeof import('./composables/dark')['isDark']
const isDefined: typeof import('@vueuse/core')['isDefined']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave']
const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onClickOutside: typeof import('@vueuse/core')['onClickOutside']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke']
const onLongPress: typeof import('@vueuse/core')['onLongPress']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onStartTyping: typeof import('@vueuse/core')['onStartTyping']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const pausableWatch: typeof import('@vueuse/core')['pausableWatch']
const preferredDark: typeof import('./composables/dark')['preferredDark']
const provide: typeof import('vue')['provide']
const reactify: typeof import('@vueuse/core')['reactify']
const reactifyObject: typeof import('@vueuse/core')['reactifyObject']
const reactive: typeof import('vue')['reactive']
const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed']
const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit']
const reactivePick: typeof import('@vueuse/core')['reactivePick']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const refAutoReset: typeof import('@vueuse/core')['refAutoReset']
const refDebounced: typeof import('@vueuse/core')['refDebounced']
const refDefault: typeof import('@vueuse/core')['refDefault']
const refThrottled: typeof import('@vueuse/core')['refThrottled']
const refWithControl: typeof import('@vueuse/core')['refWithControl']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveRef: typeof import('@vueuse/core')['resolveRef']
const resolveUnref: typeof import('@vueuse/core')['resolveUnref']
const setGlobalOptions: typeof import('./composables/request')['setGlobalOptions']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const syncRef: typeof import('@vueuse/core')['syncRef']
const syncRefs: typeof import('@vueuse/core')['syncRefs']
const templateRef: typeof import('@vueuse/core')['templateRef']
const throttledRef: typeof import('@vueuse/core')['throttledRef']
const throttledWatch: typeof import('@vueuse/core')['throttledWatch']
const toRaw: typeof import('vue')['toRaw']
const toReactive: typeof import('@vueuse/core')['toReactive']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const toggleDark: typeof import('./composables/dark')['toggleDark']
const triggerRef: typeof import('vue')['triggerRef']
const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount']
const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount']
const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted']
const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose']
const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted']
const unref: typeof import('vue')['unref']
const unrefElement: typeof import('@vueuse/core')['unrefElement']
const until: typeof import('@vueuse/core')['until']
const useActiveElement: typeof import('@vueuse/core')['useActiveElement']
const useAnimate: typeof import('@vueuse/core')['useAnimate']
const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference']
const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery']
const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter']
const useArrayFind: typeof import('@vueuse/core')['useArrayFind']
const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex']
const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast']
const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes']
const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin']
const useArrayMap: typeof import('@vueuse/core')['useArrayMap']
const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce']
const useArraySome: typeof import('@vueuse/core')['useArraySome']
const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique']
const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue']
const useAsyncState: typeof import('@vueuse/core')['useAsyncState']
const useAttrs: typeof import('vue')['useAttrs']
const useBase64: typeof import('@vueuse/core')['useBase64']
const useBattery: typeof import('@vueuse/core')['useBattery']
const useBluetooth: typeof import('@vueuse/core')['useBluetooth']
const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints']
const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel']
const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation']
const useCached: typeof import('@vueuse/core')['useCached']
const useClipboard: typeof import('@vueuse/core')['useClipboard']
const useCloned: typeof import('@vueuse/core')['useCloned']
const useColorMode: typeof import('@vueuse/core')['useColorMode']
const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog']
const useCounter: typeof import('@vueuse/core')['useCounter']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVar: typeof import('@vueuse/core')['useCssVar']
const useCssVars: typeof import('vue')['useCssVars']
const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement']
const useCycleList: typeof import('@vueuse/core')['useCycleList']
const useDark: typeof import('@vueuse/core')['useDark']
const useDateFormat: typeof import('@vueuse/core')['useDateFormat']
const useDebounce: typeof import('@vueuse/core')['useDebounce']
const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn']
const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory']
const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion']
const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation']
const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio']
const useDevicesList: typeof import('@vueuse/core')['useDevicesList']
const useDialog: typeof import('naive-ui')['useDialog']
const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia']
const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility']
const useDraggable: typeof import('@vueuse/core')['useDraggable']
const useDropZone: typeof import('@vueuse/core')['useDropZone']
const useElementBounding: typeof import('@vueuse/core')['useElementBounding']
const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint']
const useElementHover: typeof import('@vueuse/core')['useElementHover']
const useElementSize: typeof import('@vueuse/core')['useElementSize']
const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility']
const useEventBus: typeof import('@vueuse/core')['useEventBus']
const useEventListener: typeof import('@vueuse/core')['useEventListener']
const useEventSource: typeof import('@vueuse/core')['useEventSource']
const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper']
const useFavicon: typeof import('@vueuse/core')['useFavicon']
const useFetch: typeof import('@vueuse/core')['useFetch']
const useFileDialog: typeof import('@vueuse/core')['useFileDialog']
const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess']
const useFocus: typeof import('@vueuse/core')['useFocus']
const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin']
const useFps: typeof import('@vueuse/core')['useFps']
const useFullscreen: typeof import('@vueuse/core')['useFullscreen']
const useGamepad: typeof import('@vueuse/core')['useGamepad']
const useGeolocation: typeof import('@vueuse/core')['useGeolocation']
const useHead: typeof import('@vueuse/head')['useHead']
const useI18n: typeof import('vue-i18n')['useI18n']
const useIdle: typeof import('@vueuse/core')['useIdle']
const useImage: typeof import('@vueuse/core')['useImage']
const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll']
const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver']
const useInterval: typeof import('@vueuse/core')['useInterval']
const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn']
const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier']
const useLastChanged: typeof import('@vueuse/core')['useLastChanged']
const useLink: typeof import('vue-router')['useLink']
const useLoadMore: typeof import('./composables/request')['useLoadMore']
const useLoadingBar: typeof import('naive-ui')['useLoadingBar']
const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage']
const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys']
const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory']
const useMediaControls: typeof import('@vueuse/core')['useMediaControls']
const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery']
const useMemoize: typeof import('@vueuse/core')['useMemoize']
const useMemory: typeof import('@vueuse/core')['useMemory']
const useMessage: typeof import('naive-ui')['useMessage']
const useMounted: typeof import('@vueuse/core')['useMounted']
const useMouse: typeof import('@vueuse/core')['useMouse']
const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement']
const useMousePressed: typeof import('@vueuse/core')['useMousePressed']
const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver']
const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage']
const useNetwork: typeof import('@vueuse/core')['useNetwork']
const useNotification: typeof import('naive-ui')['useNotification']
const useNow: typeof import('@vueuse/core')['useNow']
const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl']
const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination']
const useOnline: typeof import('@vueuse/core')['useOnline']
const usePageLeave: typeof import('@vueuse/core')['usePageLeave']
const usePagination: typeof import('./composables/request')['usePagination']
const useParallax: typeof import('@vueuse/core')['useParallax']
const useParentElement: typeof import('@vueuse/core')['useParentElement']
const usePerformanceObserver: typeof import('@vueuse/core')['usePerformanceObserver']
const usePermission: typeof import('@vueuse/core')['usePermission']
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']
const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark']
const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages']
const usePreferredReducedMotion: typeof import('@vueuse/core')['usePreferredReducedMotion']
const usePrevious: typeof import('@vueuse/core')['usePrevious']
const useRafFn: typeof import('@vueuse/core')['useRafFn']
const useRefHistory: typeof import('@vueuse/core')['useRefHistory']
const useRequest: typeof import('./composables/request')['useRequest']
const useRequestProvider: typeof import('./composables/request')['useRequestProvider']
const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver']
const useRoute: typeof import('vue-router')['useRoute']
const useRouter: typeof import('vue-router')['useRouter']
const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation']
const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea']
const useScriptTag: typeof import('@vueuse/core')['useScriptTag']
const useScroll: typeof import('@vueuse/core')['useScroll']
const useScrollLock: typeof import('@vueuse/core')['useScrollLock']
const useSeoMeta: typeof import('@vueuse/head')['useSeoMeta']
const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage']
const useShare: typeof import('@vueuse/core')['useShare']
const useSlots: typeof import('vue')['useSlots']
const useSorted: typeof import('@vueuse/core')['useSorted']
const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition']
const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis']
const useStepper: typeof import('@vueuse/core')['useStepper']
const useStorage: typeof import('@vueuse/core')['useStorage']
const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync']
const useStyleTag: typeof import('@vueuse/core')['useStyleTag']
const useSupported: typeof import('@vueuse/core')['useSupported']
const useSwipe: typeof import('@vueuse/core')['useSwipe']
const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
const useTextDirection: typeof import('@vueuse/core')['useTextDirection']
const useTextSelection: typeof import('@vueuse/core')['useTextSelection']
const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize']
const useThrottle: typeof import('@vueuse/core')['useThrottle']
const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn']
const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory']
const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo']
const useTimeout: typeof import('@vueuse/core')['useTimeout']
const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn']
const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll']
const useTimestamp: typeof import('@vueuse/core')['useTimestamp']
const useTitle: typeof import('@vueuse/core')['useTitle']
const useToNumber: typeof import('@vueuse/core')['useToNumber']
const useToString: typeof import('@vueuse/core')['useToString']
const useToggle: typeof import('@vueuse/core')['useToggle']
const useTransition: typeof import('@vueuse/core')['useTransition']
const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
const useUserStore: typeof import('./stores/user')['useUserStore']
const useVModel: typeof import('@vueuse/core')['useVModel']
const useVModels: typeof import('@vueuse/core')['useVModels']
const useVibrate: typeof import('@vueuse/core')['useVibrate']
const useVirtualList: typeof import('@vueuse/core')['useVirtualList']
const useWakeLock: typeof import('@vueuse/core')['useWakeLock']
const useWebNotification: typeof import('@vueuse/core')['useWebNotification']
const useWebSocket: typeof import('@vueuse/core')['useWebSocket']
const useWebWorker: typeof import('@vueuse/core')['useWebWorker']
const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn']
const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
const watch: typeof import('vue')['watch']
const watchArray: typeof import('@vueuse/core')['watchArray']
const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
const watchDebounced: typeof import('@vueuse/core')['watchDebounced']
const watchDeep: typeof import('@vueuse/core')['watchDeep']
const watchEffect: typeof import('vue')['watchEffect']
const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable']
const watchImmediate: typeof import('@vueuse/core')['watchImmediate']
const watchOnce: typeof import('@vueuse/core')['watchOnce']
const watchPausable: typeof import('@vueuse/core')['watchPausable']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
const watchThrottled: typeof import('@vueuse/core')['watchThrottled']
const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable']
const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter']
const whenever: typeof import('@vueuse/core')['whenever']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
interface ComponentCustomProperties {
readonly $$: UnwrapRef<typeof import('vue/macros')['$$']>
readonly $: UnwrapRef<typeof import('vue/macros')['$']>
readonly $computed: UnwrapRef<typeof import('vue/macros')['$computed']>
readonly $customRef: UnwrapRef<typeof import('vue/macros')['$customRef']>
readonly $ref: UnwrapRef<typeof import('vue/macros')['$ref']>
readonly $shallowRef: UnwrapRef<typeof import('vue/macros')['$shallowRef']>
readonly $toRef: UnwrapRef<typeof import('vue/macros')['$toRef']>
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
readonly computedEager: UnwrapRef<typeof import('@vueuse/core')['computedEager']>
readonly computedInject: UnwrapRef<typeof import('@vueuse/core')['computedInject']>
readonly computedWithControl: UnwrapRef<typeof import('@vueuse/core')['computedWithControl']>
readonly controlledComputed: UnwrapRef<typeof import('@vueuse/core')['controlledComputed']>
readonly controlledRef: UnwrapRef<typeof import('@vueuse/core')['controlledRef']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly createEventHook: UnwrapRef<typeof import('@vueuse/core')['createEventHook']>
readonly createGlobalState: UnwrapRef<typeof import('@vueuse/core')['createGlobalState']>
readonly createInjectionState: UnwrapRef<typeof import('@vueuse/core')['createInjectionState']>
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
readonly createReusableTemplate: UnwrapRef<typeof import('@vueuse/core')['createReusableTemplate']>
readonly createSharedComposable: UnwrapRef<typeof import('@vueuse/core')['createSharedComposable']>
readonly createTemplatePromise: UnwrapRef<typeof import('@vueuse/core')['createTemplatePromise']>
readonly createUnrefFn: UnwrapRef<typeof import('@vueuse/core')['createUnrefFn']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly debouncedRef: UnwrapRef<typeof import('@vueuse/core')['debouncedRef']>
readonly debouncedWatch: UnwrapRef<typeof import('@vueuse/core')['debouncedWatch']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly eagerComputed: UnwrapRef<typeof import('@vueuse/core')['eagerComputed']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly envD: UnwrapRef<typeof import('./types/env.d')['default']>
readonly extendRef: UnwrapRef<typeof import('@vueuse/core')['extendRef']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isDark: UnwrapRef<typeof import('./composables/dark')['isDark']>
readonly isDefined: UnwrapRef<typeof import('@vueuse/core')['isDefined']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onClickOutside: UnwrapRef<typeof import('@vueuse/core')['onClickOutside']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onKeyStroke: UnwrapRef<typeof import('@vueuse/core')['onKeyStroke']>
readonly onLongPress: UnwrapRef<typeof import('@vueuse/core')['onLongPress']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onStartTyping: UnwrapRef<typeof import('@vueuse/core')['onStartTyping']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly pausableWatch: UnwrapRef<typeof import('@vueuse/core')['pausableWatch']>
readonly preferredDark: UnwrapRef<typeof import('./composables/dark')['preferredDark']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactify: UnwrapRef<typeof import('@vueuse/core')['reactify']>
readonly reactifyObject: UnwrapRef<typeof import('@vueuse/core')['reactifyObject']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly reactiveComputed: UnwrapRef<typeof import('@vueuse/core')['reactiveComputed']>
readonly reactiveOmit: UnwrapRef<typeof import('@vueuse/core')['reactiveOmit']>
readonly reactivePick: UnwrapRef<typeof import('@vueuse/core')['reactivePick']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly refAutoReset: UnwrapRef<typeof import('@vueuse/core')['refAutoReset']>
readonly refDebounced: UnwrapRef<typeof import('@vueuse/core')['refDebounced']>
readonly refDefault: UnwrapRef<typeof import('@vueuse/core')['refDefault']>
readonly refThrottled: UnwrapRef<typeof import('@vueuse/core')['refThrottled']>
readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
readonly setGlobalOptions: UnwrapRef<typeof import('./composables/request')['setGlobalOptions']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly syncRef: UnwrapRef<typeof import('@vueuse/core')['syncRef']>
readonly syncRefs: UnwrapRef<typeof import('@vueuse/core')['syncRefs']>
readonly templateRef: UnwrapRef<typeof import('@vueuse/core')['templateRef']>
readonly throttledRef: UnwrapRef<typeof import('@vueuse/core')['throttledRef']>
readonly throttledWatch: UnwrapRef<typeof import('@vueuse/core')['throttledWatch']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toReactive: UnwrapRef<typeof import('@vueuse/core')['toReactive']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly toggleDark: UnwrapRef<typeof import('./composables/dark')['toggleDark']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']>
readonly tryOnBeforeUnmount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeUnmount']>
readonly tryOnMounted: UnwrapRef<typeof import('@vueuse/core')['tryOnMounted']>
readonly tryOnScopeDispose: UnwrapRef<typeof import('@vueuse/core')['tryOnScopeDispose']>
readonly tryOnUnmounted: UnwrapRef<typeof import('@vueuse/core')['tryOnUnmounted']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']>
readonly until: UnwrapRef<typeof import('@vueuse/core')['until']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']>
readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>
readonly useArrayFilter: UnwrapRef<typeof import('@vueuse/core')['useArrayFilter']>
readonly useArrayFind: UnwrapRef<typeof import('@vueuse/core')['useArrayFind']>
readonly useArrayFindIndex: UnwrapRef<typeof import('@vueuse/core')['useArrayFindIndex']>
readonly useArrayFindLast: UnwrapRef<typeof import('@vueuse/core')['useArrayFindLast']>
readonly useArrayIncludes: UnwrapRef<typeof import('@vueuse/core')['useArrayIncludes']>
readonly useArrayJoin: UnwrapRef<typeof import('@vueuse/core')['useArrayJoin']>
readonly useArrayMap: UnwrapRef<typeof import('@vueuse/core')['useArrayMap']>
readonly useArrayReduce: UnwrapRef<typeof import('@vueuse/core')['useArrayReduce']>
readonly useArraySome: UnwrapRef<typeof import('@vueuse/core')['useArraySome']>
readonly useArrayUnique: UnwrapRef<typeof import('@vueuse/core')['useArrayUnique']>
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']>
readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']>
readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']>
readonly useBreakpoints: UnwrapRef<typeof import('@vueuse/core')['useBreakpoints']>
readonly useBroadcastChannel: UnwrapRef<typeof import('@vueuse/core')['useBroadcastChannel']>
readonly useBrowserLocation: UnwrapRef<typeof import('@vueuse/core')['useBrowserLocation']>
readonly useCached: UnwrapRef<typeof import('@vueuse/core')['useCached']>
readonly useClipboard: UnwrapRef<typeof import('@vueuse/core')['useClipboard']>
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVar: UnwrapRef<typeof import('@vueuse/core')['useCssVar']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useCurrentElement: UnwrapRef<typeof import('@vueuse/core')['useCurrentElement']>
readonly useCycleList: UnwrapRef<typeof import('@vueuse/core')['useCycleList']>
readonly useDark: UnwrapRef<typeof import('@vueuse/core')['useDark']>
readonly useDateFormat: UnwrapRef<typeof import('@vueuse/core')['useDateFormat']>
readonly useDebounce: UnwrapRef<typeof import('@vueuse/core')['useDebounce']>
readonly useDebounceFn: UnwrapRef<typeof import('@vueuse/core')['useDebounceFn']>
readonly useDebouncedRefHistory: UnwrapRef<typeof import('@vueuse/core')['useDebouncedRefHistory']>
readonly useDeviceMotion: UnwrapRef<typeof import('@vueuse/core')['useDeviceMotion']>
readonly useDeviceOrientation: UnwrapRef<typeof import('@vueuse/core')['useDeviceOrientation']>
readonly useDevicePixelRatio: UnwrapRef<typeof import('@vueuse/core')['useDevicePixelRatio']>
readonly useDevicesList: UnwrapRef<typeof import('@vueuse/core')['useDevicesList']>
readonly useDialog: UnwrapRef<typeof import('naive-ui')['useDialog']>
readonly useDisplayMedia: UnwrapRef<typeof import('@vueuse/core')['useDisplayMedia']>
readonly useDocumentVisibility: UnwrapRef<typeof import('@vueuse/core')['useDocumentVisibility']>
readonly useDraggable: UnwrapRef<typeof import('@vueuse/core')['useDraggable']>
readonly useDropZone: UnwrapRef<typeof import('@vueuse/core')['useDropZone']>
readonly useElementBounding: UnwrapRef<typeof import('@vueuse/core')['useElementBounding']>
readonly useElementByPoint: UnwrapRef<typeof import('@vueuse/core')['useElementByPoint']>
readonly useElementHover: UnwrapRef<typeof import('@vueuse/core')['useElementHover']>
readonly useElementSize: UnwrapRef<typeof import('@vueuse/core')['useElementSize']>
readonly useElementVisibility: UnwrapRef<typeof import('@vueuse/core')['useElementVisibility']>
readonly useEventBus: UnwrapRef<typeof import('@vueuse/core')['useEventBus']>
readonly useEventListener: UnwrapRef<typeof import('@vueuse/core')['useEventListener']>
readonly useEventSource: UnwrapRef<typeof import('@vueuse/core')['useEventSource']>
readonly useEyeDropper: UnwrapRef<typeof import('@vueuse/core')['useEyeDropper']>
readonly useFavicon: UnwrapRef<typeof import('@vueuse/core')['useFavicon']>
readonly useFetch: UnwrapRef<typeof import('@vueuse/core')['useFetch']>
readonly useFileDialog: UnwrapRef<typeof import('@vueuse/core')['useFileDialog']>
readonly useFileSystemAccess: UnwrapRef<typeof import('@vueuse/core')['useFileSystemAccess']>
readonly useFocus: UnwrapRef<typeof import('@vueuse/core')['useFocus']>
readonly useFocusWithin: UnwrapRef<typeof import('@vueuse/core')['useFocusWithin']>
readonly useFps: UnwrapRef<typeof import('@vueuse/core')['useFps']>
readonly useFullscreen: UnwrapRef<typeof import('@vueuse/core')['useFullscreen']>
readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']>
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']>
readonly useHead: UnwrapRef<typeof import('@vueuse/head')['useHead']>
readonly useI18n: UnwrapRef<typeof import('vue-i18n')['useI18n']>
readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']>
readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']>
readonly useInfiniteScroll: UnwrapRef<typeof import('@vueuse/core')['useInfiniteScroll']>
readonly useIntersectionObserver: UnwrapRef<typeof import('@vueuse/core')['useIntersectionObserver']>
readonly useInterval: UnwrapRef<typeof import('@vueuse/core')['useInterval']>
readonly useIntervalFn: UnwrapRef<typeof import('@vueuse/core')['useIntervalFn']>
readonly useKeyModifier: UnwrapRef<typeof import('@vueuse/core')['useKeyModifier']>
readonly useLastChanged: UnwrapRef<typeof import('@vueuse/core')['useLastChanged']>
readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>
readonly useLoadMore: UnwrapRef<typeof import('./composables/request')['useLoadMore']>
readonly useLoadingBar: UnwrapRef<typeof import('naive-ui')['useLoadingBar']>
readonly useLocalStorage: UnwrapRef<typeof import('@vueuse/core')['useLocalStorage']>
readonly useMagicKeys: UnwrapRef<typeof import('@vueuse/core')['useMagicKeys']>
readonly useManualRefHistory: UnwrapRef<typeof import('@vueuse/core')['useManualRefHistory']>
readonly useMediaControls: UnwrapRef<typeof import('@vueuse/core')['useMediaControls']>
readonly useMediaQuery: UnwrapRef<typeof import('@vueuse/core')['useMediaQuery']>
readonly useMemoize: UnwrapRef<typeof import('@vueuse/core')['useMemoize']>
readonly useMemory: UnwrapRef<typeof import('@vueuse/core')['useMemory']>
readonly useMessage: UnwrapRef<typeof import('naive-ui')['useMessage']>
readonly useMounted: UnwrapRef<typeof import('@vueuse/core')['useMounted']>
readonly useMouse: UnwrapRef<typeof import('@vueuse/core')['useMouse']>
readonly useMouseInElement: UnwrapRef<typeof import('@vueuse/core')['useMouseInElement']>
readonly useMousePressed: UnwrapRef<typeof import('@vueuse/core')['useMousePressed']>
readonly useMutationObserver: UnwrapRef<typeof import('@vueuse/core')['useMutationObserver']>
readonly useNavigatorLanguage: UnwrapRef<typeof import('@vueuse/core')['useNavigatorLanguage']>
readonly useNetwork: UnwrapRef<typeof import('@vueuse/core')['useNetwork']>
readonly useNotification: UnwrapRef<typeof import('naive-ui')['useNotification']>
readonly useNow: UnwrapRef<typeof import('@vueuse/core')['useNow']>
readonly useObjectUrl: UnwrapRef<typeof import('@vueuse/core')['useObjectUrl']>
readonly useOffsetPagination: UnwrapRef<typeof import('@vueuse/core')['useOffsetPagination']>
readonly useOnline: UnwrapRef<typeof import('@vueuse/core')['useOnline']>
readonly usePageLeave: UnwrapRef<typeof import('@vueuse/core')['usePageLeave']>
readonly usePagination: UnwrapRef<typeof import('./composables/request')['usePagination']>
readonly useParallax: UnwrapRef<typeof import('@vueuse/core')['useParallax']>
readonly useParentElement: UnwrapRef<typeof import('@vueuse/core')['useParentElement']>
readonly usePerformanceObserver: UnwrapRef<typeof import('@vueuse/core')['usePerformanceObserver']>
readonly usePermission: UnwrapRef<typeof import('@vueuse/core')['usePermission']>
readonly usePointer: UnwrapRef<typeof import('@vueuse/core')['usePointer']>
readonly usePointerLock: UnwrapRef<typeof import('@vueuse/core')['usePointerLock']>
readonly usePointerSwipe: UnwrapRef<typeof import('@vueuse/core')['usePointerSwipe']>
readonly usePreferredColorScheme: UnwrapRef<typeof import('@vueuse/core')['usePreferredColorScheme']>
readonly usePreferredContrast: UnwrapRef<typeof import('@vueuse/core')['usePreferredContrast']>
readonly usePreferredDark: UnwrapRef<typeof import('@vueuse/core')['usePreferredDark']>
readonly usePreferredLanguages: UnwrapRef<typeof import('@vueuse/core')['usePreferredLanguages']>
readonly usePreferredReducedMotion: UnwrapRef<typeof import('@vueuse/core')['usePreferredReducedMotion']>
readonly usePrevious: UnwrapRef<typeof import('@vueuse/core')['usePrevious']>
readonly useRafFn: UnwrapRef<typeof import('@vueuse/core')['useRafFn']>
readonly useRefHistory: UnwrapRef<typeof import('@vueuse/core')['useRefHistory']>
readonly useRequest: UnwrapRef<typeof import('./composables/request')['useRequest']>
readonly useRequestProvider: UnwrapRef<typeof import('./composables/request')['useRequestProvider']>
readonly useResizeObserver: UnwrapRef<typeof import('@vueuse/core')['useResizeObserver']>
readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
readonly useScreenOrientation: UnwrapRef<typeof import('@vueuse/core')['useScreenOrientation']>
readonly useScreenSafeArea: UnwrapRef<typeof import('@vueuse/core')['useScreenSafeArea']>
readonly useScriptTag: UnwrapRef<typeof import('@vueuse/core')['useScriptTag']>
readonly useScroll: UnwrapRef<typeof import('@vueuse/core')['useScroll']>
readonly useScrollLock: UnwrapRef<typeof import('@vueuse/core')['useScrollLock']>
readonly useSeoMeta: UnwrapRef<typeof import('@vueuse/head')['useSeoMeta']>
readonly useSessionStorage: UnwrapRef<typeof import('@vueuse/core')['useSessionStorage']>
readonly useShare: UnwrapRef<typeof import('@vueuse/core')['useShare']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly useSorted: UnwrapRef<typeof import('@vueuse/core')['useSorted']>
readonly useSpeechRecognition: UnwrapRef<typeof import('@vueuse/core')['useSpeechRecognition']>
readonly useSpeechSynthesis: UnwrapRef<typeof import('@vueuse/core')['useSpeechSynthesis']>
readonly useStepper: UnwrapRef<typeof import('@vueuse/core')['useStepper']>
readonly useStorage: UnwrapRef<typeof import('@vueuse/core')['useStorage']>
readonly useStorageAsync: UnwrapRef<typeof import('@vueuse/core')['useStorageAsync']>
readonly useStyleTag: UnwrapRef<typeof import('@vueuse/core')['useStyleTag']>
readonly useSupported: UnwrapRef<typeof import('@vueuse/core')['useSupported']>
readonly useSwipe: UnwrapRef<typeof import('@vueuse/core')['useSwipe']>
readonly useTemplateRefsList: UnwrapRef<typeof import('@vueuse/core')['useTemplateRefsList']>
readonly useTextDirection: UnwrapRef<typeof import('@vueuse/core')['useTextDirection']>
readonly useTextSelection: UnwrapRef<typeof import('@vueuse/core')['useTextSelection']>
readonly useTextareaAutosize: UnwrapRef<typeof import('@vueuse/core')['useTextareaAutosize']>
readonly useThrottle: UnwrapRef<typeof import('@vueuse/core')['useThrottle']>
readonly useThrottleFn: UnwrapRef<typeof import('@vueuse/core')['useThrottleFn']>
readonly useThrottledRefHistory: UnwrapRef<typeof import('@vueuse/core')['useThrottledRefHistory']>
readonly useTimeAgo: UnwrapRef<typeof import('@vueuse/core')['useTimeAgo']>
readonly useTimeout: UnwrapRef<typeof import('@vueuse/core')['useTimeout']>
readonly useTimeoutFn: UnwrapRef<typeof import('@vueuse/core')['useTimeoutFn']>
readonly useTimeoutPoll: UnwrapRef<typeof import('@vueuse/core')['useTimeoutPoll']>
readonly useTimestamp: UnwrapRef<typeof import('@vueuse/core')['useTimestamp']>
readonly useTitle: UnwrapRef<typeof import('@vueuse/core')['useTitle']>
readonly useToNumber: UnwrapRef<typeof import('@vueuse/core')['useToNumber']>
readonly useToString: UnwrapRef<typeof import('@vueuse/core')['useToString']>
readonly useToggle: UnwrapRef<typeof import('@vueuse/core')['useToggle']>
readonly useTransition: UnwrapRef<typeof import('@vueuse/core')['useTransition']>
readonly useUrlSearchParams: UnwrapRef<typeof import('@vueuse/core')['useUrlSearchParams']>
readonly useUserMedia: UnwrapRef<typeof import('@vueuse/core')['useUserMedia']>
readonly useUserStore: UnwrapRef<typeof import('./stores/user')['useUserStore']>
readonly useVModel: UnwrapRef<typeof import('@vueuse/core')['useVModel']>
readonly useVModels: UnwrapRef<typeof import('@vueuse/core')['useVModels']>
readonly useVibrate: UnwrapRef<typeof import('@vueuse/core')['useVibrate']>
readonly useVirtualList: UnwrapRef<typeof import('@vueuse/core')['useVirtualList']>
readonly useWakeLock: UnwrapRef<typeof import('@vueuse/core')['useWakeLock']>
readonly useWebNotification: UnwrapRef<typeof import('@vueuse/core')['useWebNotification']>
readonly useWebSocket: UnwrapRef<typeof import('@vueuse/core')['useWebSocket']>
readonly useWebWorker: UnwrapRef<typeof import('@vueuse/core')['useWebWorker']>
readonly useWebWorkerFn: UnwrapRef<typeof import('@vueuse/core')['useWebWorkerFn']>
readonly useWindowFocus: UnwrapRef<typeof import('@vueuse/core')['useWindowFocus']>
readonly useWindowScroll: UnwrapRef<typeof import('@vueuse/core')['useWindowScroll']>
readonly useWindowSize: UnwrapRef<typeof import('@vueuse/core')['useWindowSize']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchArray: UnwrapRef<typeof import('@vueuse/core')['watchArray']>
readonly watchAtMost: UnwrapRef<typeof import('@vueuse/core')['watchAtMost']>
readonly watchDebounced: UnwrapRef<typeof import('@vueuse/core')['watchDebounced']>
readonly watchDeep: UnwrapRef<typeof import('@vueuse/core')['watchDeep']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchIgnorable: UnwrapRef<typeof import('@vueuse/core')['watchIgnorable']>
readonly watchImmediate: UnwrapRef<typeof import('@vueuse/core')['watchImmediate']>
readonly watchOnce: UnwrapRef<typeof import('@vueuse/core')['watchOnce']>
readonly watchPausable: UnwrapRef<typeof import('@vueuse/core')['watchPausable']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
readonly watchThrottled: UnwrapRef<typeof import('@vueuse/core')['watchThrottled']>
readonly watchTriggerable: UnwrapRef<typeof import('@vueuse/core')['watchTriggerable']>
readonly watchWithFilter: UnwrapRef<typeof import('@vueuse/core')['watchWithFilter']>
readonly whenever: UnwrapRef<typeof import('@vueuse/core')['whenever']>
}
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
readonly $$: UnwrapRef<typeof import('vue/macros')['$$']>
readonly $: UnwrapRef<typeof import('vue/macros')['$']>
readonly $computed: UnwrapRef<typeof import('vue/macros')['$computed']>
readonly $customRef: UnwrapRef<typeof import('vue/macros')['$customRef']>
readonly $ref: UnwrapRef<typeof import('vue/macros')['$ref']>
readonly $shallowRef: UnwrapRef<typeof import('vue/macros')['$shallowRef']>
readonly $toRef: UnwrapRef<typeof import('vue/macros')['$toRef']>
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']>
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly computedAsync: UnwrapRef<typeof import('@vueuse/core')['computedAsync']>
readonly computedEager: UnwrapRef<typeof import('@vueuse/core')['computedEager']>
readonly computedInject: UnwrapRef<typeof import('@vueuse/core')['computedInject']>
readonly computedWithControl: UnwrapRef<typeof import('@vueuse/core')['computedWithControl']>
readonly controlledComputed: UnwrapRef<typeof import('@vueuse/core')['controlledComputed']>
readonly controlledRef: UnwrapRef<typeof import('@vueuse/core')['controlledRef']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly createEventHook: UnwrapRef<typeof import('@vueuse/core')['createEventHook']>
readonly createGlobalState: UnwrapRef<typeof import('@vueuse/core')['createGlobalState']>
readonly createInjectionState: UnwrapRef<typeof import('@vueuse/core')['createInjectionState']>
readonly createReactiveFn: UnwrapRef<typeof import('@vueuse/core')['createReactiveFn']>
readonly createReusableTemplate: UnwrapRef<typeof import('@vueuse/core')['createReusableTemplate']>
readonly createSharedComposable: UnwrapRef<typeof import('@vueuse/core')['createSharedComposable']>
readonly createTemplatePromise: UnwrapRef<typeof import('@vueuse/core')['createTemplatePromise']>
readonly createUnrefFn: UnwrapRef<typeof import('@vueuse/core')['createUnrefFn']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly debouncedRef: UnwrapRef<typeof import('@vueuse/core')['debouncedRef']>
readonly debouncedWatch: UnwrapRef<typeof import('@vueuse/core')['debouncedWatch']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly eagerComputed: UnwrapRef<typeof import('@vueuse/core')['eagerComputed']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly envD: UnwrapRef<typeof import('./types/env.d')['default']>
readonly extendRef: UnwrapRef<typeof import('@vueuse/core')['extendRef']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isDark: UnwrapRef<typeof import('./composables/dark')['isDark']>
readonly isDefined: UnwrapRef<typeof import('@vueuse/core')['isDefined']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly makeDestructurable: UnwrapRef<typeof import('@vueuse/core')['makeDestructurable']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeRouteLeave: UnwrapRef<typeof import('vue-router')['onBeforeRouteLeave']>
readonly onBeforeRouteUpdate: UnwrapRef<typeof import('vue-router')['onBeforeRouteUpdate']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onClickOutside: UnwrapRef<typeof import('@vueuse/core')['onClickOutside']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onKeyStroke: UnwrapRef<typeof import('@vueuse/core')['onKeyStroke']>
readonly onLongPress: UnwrapRef<typeof import('@vueuse/core')['onLongPress']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onStartTyping: UnwrapRef<typeof import('@vueuse/core')['onStartTyping']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly pausableWatch: UnwrapRef<typeof import('@vueuse/core')['pausableWatch']>
readonly preferredDark: UnwrapRef<typeof import('./composables/dark')['preferredDark']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactify: UnwrapRef<typeof import('@vueuse/core')['reactify']>
readonly reactifyObject: UnwrapRef<typeof import('@vueuse/core')['reactifyObject']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly reactiveComputed: UnwrapRef<typeof import('@vueuse/core')['reactiveComputed']>
readonly reactiveOmit: UnwrapRef<typeof import('@vueuse/core')['reactiveOmit']>
readonly reactivePick: UnwrapRef<typeof import('@vueuse/core')['reactivePick']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly refAutoReset: UnwrapRef<typeof import('@vueuse/core')['refAutoReset']>
readonly refDebounced: UnwrapRef<typeof import('@vueuse/core')['refDebounced']>
readonly refDefault: UnwrapRef<typeof import('@vueuse/core')['refDefault']>
readonly refThrottled: UnwrapRef<typeof import('@vueuse/core')['refThrottled']>
readonly refWithControl: UnwrapRef<typeof import('@vueuse/core')['refWithControl']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly resolveRef: UnwrapRef<typeof import('@vueuse/core')['resolveRef']>
readonly resolveUnref: UnwrapRef<typeof import('@vueuse/core')['resolveUnref']>
readonly setGlobalOptions: UnwrapRef<typeof import('./composables/request')['setGlobalOptions']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly syncRef: UnwrapRef<typeof import('@vueuse/core')['syncRef']>
readonly syncRefs: UnwrapRef<typeof import('@vueuse/core')['syncRefs']>
readonly templateRef: UnwrapRef<typeof import('@vueuse/core')['templateRef']>
readonly throttledRef: UnwrapRef<typeof import('@vueuse/core')['throttledRef']>
readonly throttledWatch: UnwrapRef<typeof import('@vueuse/core')['throttledWatch']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toReactive: UnwrapRef<typeof import('@vueuse/core')['toReactive']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly toggleDark: UnwrapRef<typeof import('./composables/dark')['toggleDark']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly tryOnBeforeMount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeMount']>
readonly tryOnBeforeUnmount: UnwrapRef<typeof import('@vueuse/core')['tryOnBeforeUnmount']>
readonly tryOnMounted: UnwrapRef<typeof import('@vueuse/core')['tryOnMounted']>
readonly tryOnScopeDispose: UnwrapRef<typeof import('@vueuse/core')['tryOnScopeDispose']>
readonly tryOnUnmounted: UnwrapRef<typeof import('@vueuse/core')['tryOnUnmounted']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly unrefElement: UnwrapRef<typeof import('@vueuse/core')['unrefElement']>
readonly until: UnwrapRef<typeof import('@vueuse/core')['until']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']>
readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>
readonly useArrayFilter: UnwrapRef<typeof import('@vueuse/core')['useArrayFilter']>
readonly useArrayFind: UnwrapRef<typeof import('@vueuse/core')['useArrayFind']>
readonly useArrayFindIndex: UnwrapRef<typeof import('@vueuse/core')['useArrayFindIndex']>
readonly useArrayFindLast: UnwrapRef<typeof import('@vueuse/core')['useArrayFindLast']>
readonly useArrayIncludes: UnwrapRef<typeof import('@vueuse/core')['useArrayIncludes']>
readonly useArrayJoin: UnwrapRef<typeof import('@vueuse/core')['useArrayJoin']>
readonly useArrayMap: UnwrapRef<typeof import('@vueuse/core')['useArrayMap']>
readonly useArrayReduce: UnwrapRef<typeof import('@vueuse/core')['useArrayReduce']>
readonly useArraySome: UnwrapRef<typeof import('@vueuse/core')['useArraySome']>
readonly useArrayUnique: UnwrapRef<typeof import('@vueuse/core')['useArrayUnique']>
readonly useAsyncQueue: UnwrapRef<typeof import('@vueuse/core')['useAsyncQueue']>
readonly useAsyncState: UnwrapRef<typeof import('@vueuse/core')['useAsyncState']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useBase64: UnwrapRef<typeof import('@vueuse/core')['useBase64']>
readonly useBattery: UnwrapRef<typeof import('@vueuse/core')['useBattery']>
readonly useBluetooth: UnwrapRef<typeof import('@vueuse/core')['useBluetooth']>
readonly useBreakpoints: UnwrapRef<typeof import('@vueuse/core')['useBreakpoints']>
readonly useBroadcastChannel: UnwrapRef<typeof import('@vueuse/core')['useBroadcastChannel']>
readonly useBrowserLocation: UnwrapRef<typeof import('@vueuse/core')['useBrowserLocation']>
readonly useCached: UnwrapRef<typeof import('@vueuse/core')['useCached']>
readonly useClipboard: UnwrapRef<typeof import('@vueuse/core')['useClipboard']>
readonly useCloned: UnwrapRef<typeof import('@vueuse/core')['useCloned']>
readonly useColorMode: UnwrapRef<typeof import('@vueuse/core')['useColorMode']>
readonly useConfirmDialog: UnwrapRef<typeof import('@vueuse/core')['useConfirmDialog']>
readonly useCounter: UnwrapRef<typeof import('@vueuse/core')['useCounter']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVar: UnwrapRef<typeof import('@vueuse/core')['useCssVar']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useCurrentElement: UnwrapRef<typeof import('@vueuse/core')['useCurrentElement']>
readonly useCycleList: UnwrapRef<typeof import('@vueuse/core')['useCycleList']>
readonly useDark: UnwrapRef<typeof import('@vueuse/core')['useDark']>
readonly useDateFormat: UnwrapRef<typeof import('@vueuse/core')['useDateFormat']>
readonly useDebounce: UnwrapRef<typeof import('@vueuse/core')['useDebounce']>
readonly useDebounceFn: UnwrapRef<typeof import('@vueuse/core')['useDebounceFn']>
readonly useDebouncedRefHistory: UnwrapRef<typeof import('@vueuse/core')['useDebouncedRefHistory']>
readonly useDeviceMotion: UnwrapRef<typeof import('@vueuse/core')['useDeviceMotion']>
readonly useDeviceOrientation: UnwrapRef<typeof import('@vueuse/core')['useDeviceOrientation']>
readonly useDevicePixelRatio: UnwrapRef<typeof import('@vueuse/core')['useDevicePixelRatio']>
readonly useDevicesList: UnwrapRef<typeof import('@vueuse/core')['useDevicesList']>
readonly useDialog: UnwrapRef<typeof import('naive-ui')['useDialog']>
readonly useDisplayMedia: UnwrapRef<typeof import('@vueuse/core')['useDisplayMedia']>
readonly useDocumentVisibility: UnwrapRef<typeof import('@vueuse/core')['useDocumentVisibility']>
readonly useDraggable: UnwrapRef<typeof import('@vueuse/core')['useDraggable']>
readonly useDropZone: UnwrapRef<typeof import('@vueuse/core')['useDropZone']>
readonly useElementBounding: UnwrapRef<typeof import('@vueuse/core')['useElementBounding']>
readonly useElementByPoint: UnwrapRef<typeof import('@vueuse/core')['useElementByPoint']>
readonly useElementHover: UnwrapRef<typeof import('@vueuse/core')['useElementHover']>
readonly useElementSize: UnwrapRef<typeof import('@vueuse/core')['useElementSize']>
readonly useElementVisibility: UnwrapRef<typeof import('@vueuse/core')['useElementVisibility']>
readonly useEventBus: UnwrapRef<typeof import('@vueuse/core')['useEventBus']>
readonly useEventListener: UnwrapRef<typeof import('@vueuse/core')['useEventListener']>
readonly useEventSource: UnwrapRef<typeof import('@vueuse/core')['useEventSource']>
readonly useEyeDropper: UnwrapRef<typeof import('@vueuse/core')['useEyeDropper']>
readonly useFavicon: UnwrapRef<typeof import('@vueuse/core')['useFavicon']>
readonly useFetch: UnwrapRef<typeof import('@vueuse/core')['useFetch']>
readonly useFileDialog: UnwrapRef<typeof import('@vueuse/core')['useFileDialog']>
readonly useFileSystemAccess: UnwrapRef<typeof import('@vueuse/core')['useFileSystemAccess']>
readonly useFocus: UnwrapRef<typeof import('@vueuse/core')['useFocus']>
readonly useFocusWithin: UnwrapRef<typeof import('@vueuse/core')['useFocusWithin']>
readonly useFps: UnwrapRef<typeof import('@vueuse/core')['useFps']>
readonly useFullscreen: UnwrapRef<typeof import('@vueuse/core')['useFullscreen']>
readonly useGamepad: UnwrapRef<typeof import('@vueuse/core')['useGamepad']>
readonly useGeolocation: UnwrapRef<typeof import('@vueuse/core')['useGeolocation']>
readonly useHead: UnwrapRef<typeof import('@vueuse/head')['useHead']>
readonly useI18n: UnwrapRef<typeof import('vue-i18n')['useI18n']>
readonly useIdle: UnwrapRef<typeof import('@vueuse/core')['useIdle']>
readonly useImage: UnwrapRef<typeof import('@vueuse/core')['useImage']>
readonly useInfiniteScroll: UnwrapRef<typeof import('@vueuse/core')['useInfiniteScroll']>
readonly useIntersectionObserver: UnwrapRef<typeof import('@vueuse/core')['useIntersectionObserver']>
readonly useInterval: UnwrapRef<typeof import('@vueuse/core')['useInterval']>
readonly useIntervalFn: UnwrapRef<typeof import('@vueuse/core')['useIntervalFn']>
readonly useKeyModifier: UnwrapRef<typeof import('@vueuse/core')['useKeyModifier']>
readonly useLastChanged: UnwrapRef<typeof import('@vueuse/core')['useLastChanged']>
readonly useLink: UnwrapRef<typeof import('vue-router')['useLink']>
readonly useLoadMore: UnwrapRef<typeof import('./composables/request')['useLoadMore']>
readonly useLoadingBar: UnwrapRef<typeof import('naive-ui')['useLoadingBar']>
readonly useLocalStorage: UnwrapRef<typeof import('@vueuse/core')['useLocalStorage']>
readonly useMagicKeys: UnwrapRef<typeof import('@vueuse/core')['useMagicKeys']>
readonly useManualRefHistory: UnwrapRef<typeof import('@vueuse/core')['useManualRefHistory']>
readonly useMediaControls: UnwrapRef<typeof import('@vueuse/core')['useMediaControls']>
readonly useMediaQuery: UnwrapRef<typeof import('@vueuse/core')['useMediaQuery']>
readonly useMemoize: UnwrapRef<typeof import('@vueuse/core')['useMemoize']>
readonly useMemory: UnwrapRef<typeof import('@vueuse/core')['useMemory']>
readonly useMessage: UnwrapRef<typeof import('naive-ui')['useMessage']>
readonly useMounted: UnwrapRef<typeof import('@vueuse/core')['useMounted']>
readonly useMouse: UnwrapRef<typeof import('@vueuse/core')['useMouse']>
readonly useMouseInElement: UnwrapRef<typeof import('@vueuse/core')['useMouseInElement']>
readonly useMousePressed: UnwrapRef<typeof import('@vueuse/core')['useMousePressed']>
readonly useMutationObserver: UnwrapRef<typeof import('@vueuse/core')['useMutationObserver']>
readonly useNavigatorLanguage: UnwrapRef<typeof import('@vueuse/core')['useNavigatorLanguage']>
readonly useNetwork: UnwrapRef<typeof import('@vueuse/core')['useNetwork']>
readonly useNotification: UnwrapRef<typeof import('naive-ui')['useNotification']>
readonly useNow: UnwrapRef<typeof import('@vueuse/core')['useNow']>
readonly useObjectUrl: UnwrapRef<typeof import('@vueuse/core')['useObjectUrl']>
readonly useOffsetPagination: UnwrapRef<typeof import('@vueuse/core')['useOffsetPagination']>
readonly useOnline: UnwrapRef<typeof import('@vueuse/core')['useOnline']>
readonly usePageLeave: UnwrapRef<typeof import('@vueuse/core')['usePageLeave']>
readonly usePagination: UnwrapRef<typeof import('./composables/request')['usePagination']>
readonly useParallax: UnwrapRef<typeof import('@vueuse/core')['useParallax']>
readonly useParentElement: UnwrapRef<typeof import('@vueuse/core')['useParentElement']>
readonly usePerformanceObserver: UnwrapRef<typeof import('@vueuse/core')['usePerformanceObserver']>
readonly usePermission: UnwrapRef<typeof import('@vueuse/core')['usePermission']>
readonly usePointer: UnwrapRef<typeof import('@vueuse/core')['usePointer']>
readonly usePointerLock: UnwrapRef<typeof import('@vueuse/core')['usePointerLock']>
readonly usePointerSwipe: UnwrapRef<typeof import('@vueuse/core')['usePointerSwipe']>
readonly usePreferredColorScheme: UnwrapRef<typeof import('@vueuse/core')['usePreferredColorScheme']>
readonly usePreferredContrast: UnwrapRef<typeof import('@vueuse/core')['usePreferredContrast']>
readonly usePreferredDark: UnwrapRef<typeof import('@vueuse/core')['usePreferredDark']>
readonly usePreferredLanguages: UnwrapRef<typeof import('@vueuse/core')['usePreferredLanguages']>
readonly usePreferredReducedMotion: UnwrapRef<typeof import('@vueuse/core')['usePreferredReducedMotion']>
readonly usePrevious: UnwrapRef<typeof import('@vueuse/core')['usePrevious']>
readonly useRafFn: UnwrapRef<typeof import('@vueuse/core')['useRafFn']>
readonly useRefHistory: UnwrapRef<typeof import('@vueuse/core')['useRefHistory']>
readonly useRequest: UnwrapRef<typeof import('./composables/request')['useRequest']>
readonly useRequestProvider: UnwrapRef<typeof import('./composables/request')['useRequestProvider']>
readonly useResizeObserver: UnwrapRef<typeof import('@vueuse/core')['useResizeObserver']>
readonly useRoute: UnwrapRef<typeof import('vue-router')['useRoute']>
readonly useRouter: UnwrapRef<typeof import('vue-router')['useRouter']>
readonly useScreenOrientation: UnwrapRef<typeof import('@vueuse/core')['useScreenOrientation']>
readonly useScreenSafeArea: UnwrapRef<typeof import('@vueuse/core')['useScreenSafeArea']>
readonly useScriptTag: UnwrapRef<typeof import('@vueuse/core')['useScriptTag']>
readonly useScroll: UnwrapRef<typeof import('@vueuse/core')['useScroll']>
readonly useScrollLock: UnwrapRef<typeof import('@vueuse/core')['useScrollLock']>
readonly useSeoMeta: UnwrapRef<typeof import('@vueuse/head')['useSeoMeta']>
readonly useSessionStorage: UnwrapRef<typeof import('@vueuse/core')['useSessionStorage']>
readonly useShare: UnwrapRef<typeof import('@vueuse/core')['useShare']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly useSorted: UnwrapRef<typeof import('@vueuse/core')['useSorted']>
readonly useSpeechRecognition: UnwrapRef<typeof import('@vueuse/core')['useSpeechRecognition']>
readonly useSpeechSynthesis: UnwrapRef<typeof import('@vueuse/core')['useSpeechSynthesis']>
readonly useStepper: UnwrapRef<typeof import('@vueuse/core')['useStepper']>
readonly useStorage: UnwrapRef<typeof import('@vueuse/core')['useStorage']>
readonly useStorageAsync: UnwrapRef<typeof import('@vueuse/core')['useStorageAsync']>
readonly useStyleTag: UnwrapRef<typeof import('@vueuse/core')['useStyleTag']>
readonly useSupported: UnwrapRef<typeof import('@vueuse/core')['useSupported']>
readonly useSwipe: UnwrapRef<typeof import('@vueuse/core')['useSwipe']>
readonly useTemplateRefsList: UnwrapRef<typeof import('@vueuse/core')['useTemplateRefsList']>
readonly useTextDirection: UnwrapRef<typeof import('@vueuse/core')['useTextDirection']>
readonly useTextSelection: UnwrapRef<typeof import('@vueuse/core')['useTextSelection']>
readonly useTextareaAutosize: UnwrapRef<typeof import('@vueuse/core')['useTextareaAutosize']>
readonly useThrottle: UnwrapRef<typeof import('@vueuse/core')['useThrottle']>
readonly useThrottleFn: UnwrapRef<typeof import('@vueuse/core')['useThrottleFn']>
readonly useThrottledRefHistory: UnwrapRef<typeof import('@vueuse/core')['useThrottledRefHistory']>
readonly useTimeAgo: UnwrapRef<typeof import('@vueuse/core')['useTimeAgo']>
readonly useTimeout: UnwrapRef<typeof import('@vueuse/core')['useTimeout']>
readonly useTimeoutFn: UnwrapRef<typeof import('@vueuse/core')['useTimeoutFn']>
readonly useTimeoutPoll: UnwrapRef<typeof import('@vueuse/core')['useTimeoutPoll']>
readonly useTimestamp: UnwrapRef<typeof import('@vueuse/core')['useTimestamp']>
readonly useTitle: UnwrapRef<typeof import('@vueuse/core')['useTitle']>
readonly useToNumber: UnwrapRef<typeof import('@vueuse/core')['useToNumber']>
readonly useToString: UnwrapRef<typeof import('@vueuse/core')['useToString']>
readonly useToggle: UnwrapRef<typeof import('@vueuse/core')['useToggle']>
readonly useTransition: UnwrapRef<typeof import('@vueuse/core')['useTransition']>
readonly useUrlSearchParams: UnwrapRef<typeof import('@vueuse/core')['useUrlSearchParams']>
readonly useUserMedia: UnwrapRef<typeof import('@vueuse/core')['useUserMedia']>
readonly useUserStore: UnwrapRef<typeof import('./stores/user')['useUserStore']>
readonly useVModel: UnwrapRef<typeof import('@vueuse/core')['useVModel']>
readonly useVModels: UnwrapRef<typeof import('@vueuse/core')['useVModels']>
readonly useVibrate: UnwrapRef<typeof import('@vueuse/core')['useVibrate']>
readonly useVirtualList: UnwrapRef<typeof import('@vueuse/core')['useVirtualList']>
readonly useWakeLock: UnwrapRef<typeof import('@vueuse/core')['useWakeLock']>
readonly useWebNotification: UnwrapRef<typeof import('@vueuse/core')['useWebNotification']>
readonly useWebSocket: UnwrapRef<typeof import('@vueuse/core')['useWebSocket']>
readonly useWebWorker: UnwrapRef<typeof import('@vueuse/core')['useWebWorker']>
readonly useWebWorkerFn: UnwrapRef<typeof import('@vueuse/core')['useWebWorkerFn']>
readonly useWindowFocus: UnwrapRef<typeof import('@vueuse/core')['useWindowFocus']>
readonly useWindowScroll: UnwrapRef<typeof import('@vueuse/core')['useWindowScroll']>
readonly useWindowSize: UnwrapRef<typeof import('@vueuse/core')['useWindowSize']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchArray: UnwrapRef<typeof import('@vueuse/core')['watchArray']>
readonly watchAtMost: UnwrapRef<typeof import('@vueuse/core')['watchAtMost']>
readonly watchDebounced: UnwrapRef<typeof import('@vueuse/core')['watchDebounced']>
readonly watchDeep: UnwrapRef<typeof import('@vueuse/core')['watchDeep']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchIgnorable: UnwrapRef<typeof import('@vueuse/core')['watchIgnorable']>
readonly watchImmediate: UnwrapRef<typeof import('@vueuse/core')['watchImmediate']>
readonly watchOnce: UnwrapRef<typeof import('@vueuse/core')['watchOnce']>
readonly watchPausable: UnwrapRef<typeof import('@vueuse/core')['watchPausable']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
readonly watchThrottled: UnwrapRef<typeof import('@vueuse/core')['watchThrottled']>
readonly watchTriggerable: UnwrapRef<typeof import('@vueuse/core')['watchTriggerable']>
readonly watchWithFilter: UnwrapRef<typeof import('@vueuse/core')['watchWithFilter']>
readonly whenever: UnwrapRef<typeof import('@vueuse/core')['whenever']>
}
}

@ -0,0 +1,24 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDialogProvider: typeof import('naive-ui')['NDialogProvider']
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
NLayout: typeof import('naive-ui')['NLayout']
NLayoutHeader: typeof import('naive-ui')['NLayoutHeader']
NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NWatermark: typeof import('naive-ui')['NWatermark']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
}

@ -0,0 +1,9 @@
// these APIs are auto-imported from @vueuse/core
export const isDark = useDark({
selector: 'html',
attribute: 'theme-mode',
valueDark: 'dark',
valueLight: '',
})
export const toggleDark = useToggle(isDark)
export const preferredDark = usePreferredDark()

@ -0,0 +1,3 @@
import { setGlobalOptions, useLoadMore, usePagination, useRequest, useRequestProvider } from 'vue-request'
export { useLoadMore, useRequest, usePagination, setGlobalOptions, useRequestProvider }

@ -0,0 +1,18 @@
<script setup lang="ts">
const router = useRouter()
const { t } = useI18n()
</script>
<template>
<main p="x4 y10" text="center teal-700 dark:gray-200">
<div text-4xl>
<div i-carbon-warning inline-block />
</div>
<RouterView />
<div>
<button btn text-sm m="3 t8" @click="router.back()">
{{ t('button.back') }}
</button>
</div>
</main>
</template>

@ -0,0 +1,14 @@
## Layouts
Vue components in this dir are used as layouts.
By default, `default.vue` will be used unless an alternative is specified in the route meta.
With [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) and [`vite-plugin-vue-layouts`](https://github.com/JohnCampionJr/vite-plugin-vue-layouts), you can specify the layout in the page's SFCs like this:
```html
<route lang="yaml">
meta:
layout: home
</route>
```

@ -0,0 +1,11 @@
<template>
<n-layout
class="h-full"
:native-scrollbar="false"
>
<n-layout-header>
<div i="nl-logo" />
</n-layout-header>
<RouterView />
</n-layout>
</template>

@ -0,0 +1,25 @@
import { ViteSSG } from 'vite-ssg'
import { setupLayouts } from 'virtual:generated-layouts'
// import Previewer from 'virtual:vue-component-preview'
import App from './App.vue'
import type { UserModule } from './types'
import generatedRoutes from '~pages'
import '@unocss/reset/tailwind.css'
import './styles/main.css'
import 'uno.css'
const routes = setupLayouts(generatedRoutes)
// https://github.com/antfu/vite-ssg
export const createApp = ViteSSG(
App,
{ routes, base: import.meta.env.BASE_URL },
(ctx) => {
// install all modules under `modules/`
Object.values(import.meta.glob<{ install: UserModule }>('./modules/*.ts', { eager: true }))
.forEach(i => i.install?.(ctx))
// ctx.app.use(Previewer)
},
)

@ -0,0 +1,11 @@
## Modules
A custom user module system. Place a `.ts` file with the following template, it will be installed automatically.
```ts
import { type UserModule } from '~/types'
export const install: UserModule = ({ app, router, isClient }) => {
// do something
}
```

@ -0,0 +1,50 @@
import type { Locale } from 'vue-i18n'
import { createI18n } from 'vue-i18n'
import { type UserModule } from '~/types'
// Import i18n resources
// https://vitejs.dev/guide/features.html#glob-import
//
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
const i18n = createI18n({
legacy: false,
locale: '',
messages: {},
})
const localesMap = Object.fromEntries(
Object.entries(import.meta.glob('../../locales/*.yml'))
.map(([path, loadLocale]) => [path.match(/([\w-]*)\.yml$/)?.[1], loadLocale]),
) as Record<Locale, () => Promise<{ default: Record<string, string> }>>
export const availableLocales = Object.keys(localesMap)
const loadedLanguages: string[] = []
function setI18nLanguage(lang: Locale) {
i18n.global.locale.value = lang as any
if (typeof document !== 'undefined')
document.querySelector('html')?.setAttribute('lang', lang)
return lang
}
export async function loadLanguageAsync(lang: string): Promise<Locale> {
// If the same language
if (i18n.global.locale.value === lang)
return setI18nLanguage(lang)
// If the language was already loaded
if (loadedLanguages.includes(lang))
return setI18nLanguage(lang)
// If the language hasn't been loaded yet
const messages = await localesMap[lang]()
i18n.global.setLocaleMessage(lang, messages.default)
loadedLanguages.push(lang)
return setI18nLanguage(lang)
}
export const install: UserModule = ({ app }) => {
app.use(i18n)
loadLanguageAsync('en')
}

@ -0,0 +1,14 @@
import NProgress from 'nprogress'
import { type UserModule } from '~/types'
export const install: UserModule = ({ isClient, router }) => {
if (isClient) {
router.beforeEach((to, from) => {
if (to.path !== from.path)
NProgress.start()
})
router.afterEach(() => {
NProgress.done()
})
}
}

@ -0,0 +1,17 @@
import { createPinia } from 'pinia'
import { type UserModule } from '~/types'
// Setup Pinia
// https://pinia.vuejs.org/
export const install: UserModule = ({ isClient, initialState, app }) => {
const pinia = createPinia()
app.use(pinia)
// Refer to
// https://github.com/antfu/vite-ssg/blob/main/README.md#state-serialization
// for other serialization strategies.
if (isClient)
pinia.state.value = (initialState.pinia) || {}
else
initialState.pinia = pinia.state.value
}

@ -0,0 +1,14 @@
import { type UserModule } from '~/types'
// https://github.com/antfu/vite-plugin-pwa#automatic-reload-when-new-content-available
export const install: UserModule = ({ isClient, router }) => {
if (!isClient)
return
router.isReady()
.then(async () => {
const { registerSW } = await import('virtual:pwa-register')
registerSW({ immediate: true })
})
.catch(() => {})
}

@ -0,0 +1,20 @@
## File-based Routing
Routes will be auto-generated for Vue files in this dir with the same file structure.
Check out [`vite-plugin-pages`](https://github.com/hannoeru/vite-plugin-pages) for more details.
### Path Aliasing
`~/` is aliased to `./src/` folder.
For example, instead of having
```ts
import { isDark } from '../../../../composables'
```
now, you can use
```ts
import { isDark } from '~/composables'
```

@ -0,0 +1,21 @@
---
title: About
---
<div class="text-center">
<!-- You can use Vue components inside markdown -->
<div i-carbon-dicom-overlay class="text-4xl -mb-6 m-auto" />
<h3>About</h3>
</div>
[Vitesse](https://github.com/antfu/vitesse) is an opinionated [Vite](https://github.com/vitejs/vite) starter template made by [@antfu](https://github.com/antfu) for mocking apps swiftly. With **file-based routing**, **components auto importing**, **markdown support**, I18n, PWA and uses **UnoCSS** for styling and icons.
```js
// syntax highlighting example
function vitesse() {
const foo = 'bar'
console.log(foo)
}
```
Check out the [GitHub repo](https://github.com/antfu/vitesse) for more details.

@ -0,0 +1,18 @@
<script setup lang="ts">
defineOptions({
name: 'IndexPage',
})
const api = import.meta.env.VITE_API_URL
</script>
<template>
<div>
aaa {{ api }}
</div>
</template>
<route lang="yaml">
meta:
layout: default
</route>

16
src/shims.d.ts vendored

@ -0,0 +1,16 @@
declare interface Window {
// extend the window
}
// with vite-plugin-vue-markdown, markdown files can be treated as Vue components
declare module '*.md' {
import { type DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}
declare module '*.vue' {
import { type DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

@ -0,0 +1,34 @@
import { acceptHMRUpdate, defineStore } from 'pinia'
export const useUserStore = defineStore('user', () => {
/**
* Current name of the user.
*/
const savedName = ref('')
const previousNames = ref(new Set<string>())
const usedNames = computed(() => Array.from(previousNames.value))
const otherNames = computed(() => usedNames.value.filter(name => name !== savedName.value))
/**
* Changes the current name of the user and saves the one that was used
* before.
*
* @param name - new name to set
*/
function setNewName(name: string) {
if (savedName.value)
previousNames.value.add(savedName.value)
savedName.value = name
}
return {
setNewName,
otherNames,
savedName,
}
})
if (import.meta.hot)
import.meta.hot.accept(acceptHMRUpdate(useUserStore as any, import.meta.hot))

@ -0,0 +1,29 @@
@import './markdown.css';
html,
body,
#app {
height: 100%;
margin: 0;
padding: 0;
}
html.dark {
background: #121212;
color-scheme: dark;
}
#nprogress {
pointer-events: none;
}
#nprogress .bar {
background: rgb(13,148,136);
opacity: 0.75;
position: fixed;
z-index: 1031;
top: 0;
left: 0;
width: 100%;
height: 2px;
}

@ -0,0 +1,28 @@
.prose pre:not(.shiki) {
padding: 0;
}
.prose .shiki {
font-family: 'DM Mono', monospace;
font-size: 1.2em;
line-height: 1.4;
}
.prose img {
width: 100%;
}
.shiki-light {
background: #f8f8f8 !important;
}
.shiki-dark {
background: #0e0e0e !important;
}
html.dark .shiki-light {
display: none;
}
html:not(.dark) .shiki-dark {
display: none;
}

@ -0,0 +1,3 @@
import { type ViteSSGContext } from 'vite-ssg'
export type UserModule = (ctx: ViteSSGContext) => void

26
src/types/env.d.ts vendored

@ -0,0 +1,26 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
// 是否开启Mock
readonly VITE_USE_MOCK:boolean
// public path
readonly VITE_PUBLIC_PATH:string
// 全局项目标题
readonly VITE_TITLE:string
// API访问地址
readonly VITE_API_URL:string
// 上传地址
readonly VITE_UPLOAD_URL:string
// API前缀
readonly VITE_API_URL_PREFIX:string
// 项目描述
readonly VITE_DESCRIPTION:string
}
interface ImportMeta {readonly env: ImportMetaEnv}
declare module "*.vue" {
import type { DefineComponent } from "vue"
const component: DefineComponent<{}, {}, any>
export default component
}

@ -0,0 +1,12 @@
declare type Recordable<T = any> = Record<string, T>;
declare type ReadonlyRecordable<T = any> = {
readonly [key: string]: T;
};
declare type Nullable<T> = T | null;
declare type NonNullable<T> = T extends null | undefined ? never : T;
declare type Indexable<T = any> = {
[key: string]: T;
};
declare type FormType = 'create' | 'update'

@ -0,0 +1,244 @@
import type {
AxiosError,
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig,
} from 'axios'
import axios from 'axios'
import { cloneDeep } from 'lodash-es'
import qs from 'qs'
import type { CreateAxiosOptions } from './transform'
import { AxiosCanceler } from './cancel'
import { ContentTypeEnum, RequestMethodEnum } from './enum'
import { isFunction } from '~/utils/is'
export * from './transform'
/**
* @description: axios module
*/
export class VAxios {
private axiosInstance: AxiosInstance
private readonly options: CreateAxiosOptions
constructor(options: CreateAxiosOptions) {
this.options = options
this.axiosInstance = axios.create(options)
this.setupInterceptors()
}
/**
* @description: Create axios instance
*/
private createAxios(config: CreateAxiosOptions): void {
this.axiosInstance = axios.create(config)
}
private getTransform() {
const { transform } = this.options
return transform
}
getAxios(): AxiosInstance {
return this.axiosInstance
}
/**
* @description: Reconfigure axios
*/
configAxios(config: CreateAxiosOptions) {
if (!this.axiosInstance)
return
this.createAxios(config)
}
/**
* @description: Set general header
*/
setHeader(headers: any): void {
if (!this.axiosInstance)
return
Object.assign(this.axiosInstance.defaults.headers, headers)
}
/**
* @description: Interceptor configuration
*/
private setupInterceptors() {
// const transform = this.getTransform();
const {
axiosInstance,
options: { transform },
} = this
if (!transform)
return
const {
requestInterceptors,
requestInterceptorsCatch,
responseInterceptors,
responseInterceptorsCatch,
} = transform
const axiosCanceler = new AxiosCanceler()
// Request interceptor configuration processing
this.axiosInstance.interceptors.request.use((config: InternalAxiosRequestConfig) => {
// If cancel repeat request is turned on, then cancel repeat request is prohibited
const { requestOptions } = this.options
const ignoreCancelToken = requestOptions?.ignoreCancelToken ?? true
!ignoreCancelToken && axiosCanceler.addPending(config)
if (requestInterceptors && isFunction(requestInterceptors))
config = requestInterceptors(config, this.options)
return config
}, undefined)
// Request interceptor error capture
requestInterceptorsCatch
&& isFunction(requestInterceptorsCatch)
&& this.axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch)
// Response result interceptor processing
this.axiosInstance.interceptors.response.use((res: AxiosResponse<any>) => {
res && axiosCanceler.removePending(res.config)
if (responseInterceptors && isFunction(responseInterceptors))
res = responseInterceptors(res)
return res
}, undefined)
// Response result interceptor error capture
responseInterceptorsCatch
&& isFunction(responseInterceptorsCatch)
&& this.axiosInstance.interceptors.response.use(undefined, (error) => {
return responseInterceptorsCatch(axiosInstance, error)
})
}
/**
* @description: File Upload
*/
uploadFile<T = any>(config: AxiosRequestConfig, params: UploadFileParams) {
const formData = new window.FormData()
const customFilename = params.name || 'file'
if (params.filename)
formData.append(customFilename, params.file, params.filename)
else
formData.append(customFilename, params.file)
if (params.data) {
Object.keys(params.data).forEach((key) => {
const value = params.data![key]
if (Array.isArray(value)) {
value.forEach((item) => {
formData.append(`${key}[]`, item)
})
return
}
formData.append(key, params.data![key])
})
}
return this.axiosInstance.request<T>({
...config,
method: 'POST',
data: formData,
headers: {
'Content-type': ContentTypeEnum.FORM_DATA,
'ignoreCancelToken': true,
},
})
}
// support form-data
supportFormData(config: AxiosRequestConfig) {
const headers = config.headers || this.options.headers
const contentType = headers?.['Content-Type'] || headers?.['content-type']
if (
contentType !== ContentTypeEnum.FORM_URLENCODED
|| !Reflect.has(config, 'data')
|| config.method?.toUpperCase() === RequestMethodEnum.GET
)
return config
return {
...config,
data: qs.stringify(config.data, { arrayFormat: 'brackets' }),
}
}
get<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'GET' }, options)
}
post<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'POST' }, options)
}
put<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'PUT' }, options)
}
delete<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
return this.request({ ...config, method: 'DELETE' }, options)
}
request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
let conf: CreateAxiosOptions = cloneDeep(config)
// cancelToken 如果被深拷贝会导致最外层无法使用cancel方法来取消请求
if (config.cancelToken)
conf.cancelToken = config.cancelToken
const transform = this.getTransform()
const { requestOptions } = this.options
const opt: RequestOptions = Object.assign({}, requestOptions, options)
const { beforeRequestHook, requestCatchHook, transformResponseHook } = transform || {}
if (beforeRequestHook && isFunction(beforeRequestHook))
conf = beforeRequestHook(conf, opt)
conf.requestOptions = opt
conf = this.supportFormData(conf)
return new Promise((resolve, reject) => {
this.axiosInstance
.request<any, AxiosResponse<ApiResult>>(conf)
.then((res: AxiosResponse<ApiResult>) => {
if (transformResponseHook && isFunction(transformResponseHook)) {
try {
const ret = transformResponseHook(res, opt)
resolve(ret)
}
catch (err) {
reject(err || new Error('request error!'))
}
return
}
resolve(res as unknown as Promise<T>)
})
.catch((e: Error | AxiosError) => {
if (requestCatchHook && isFunction(requestCatchHook)) {
reject(requestCatchHook(e, opt))
return
}
if (axios.isAxiosError(e)) {
// rewrite error message from axios in here
}
reject(e)
})
})
}
}

@ -0,0 +1,59 @@
import type { AxiosRequestConfig } from 'axios'
// 用于存储每个请求的标识和取消函数
const pendingMap = new Map<string, AbortController>()
function getPendingUrl(config: AxiosRequestConfig): string {
return [config.method, config.url].join('&')
}
export class AxiosCanceler {
/**
*
* @param config
*/
public addPending(config: AxiosRequestConfig): void {
this.removePending(config)
const url = getPendingUrl(config)
const controller = new AbortController()
config.signal = config.signal || controller.signal
if (!pendingMap.has(url)) {
// 如果当前请求不在等待中,将其添加到等待中
pendingMap.set(url, controller)
}
}
/**
*
*/
public removeAllPending(): void {
pendingMap.forEach((abortController) => {
if (abortController)
abortController.abort()
})
this.reset()
}
/**
*
* @param config
*/
public removePending(config: AxiosRequestConfig): void {
const url = getPendingUrl(config)
if (pendingMap.has(url)) {
// 如果当前请求在等待中,取消它并将其从等待中移除
const abortController = pendingMap.get(url)
if (abortController)
abortController.abort(url)
pendingMap.delete(url)
}
}
/**
*
*/
public reset(): void {
pendingMap.clear()
}
}

@ -0,0 +1,69 @@
import { createDiscreteApi } from 'naive-ui'
const { message, dialog } = createDiscreteApi(['message', 'dialog'])
export function checkStatus(
status: number,
msg: string,
errorMessageMode: ErrorMessageMode = 'message',
): void {
let errMessage = ''
switch (status) {
case 400:
errMessage = `${msg}`
break
// 401: Not logged in
// Jump to the login page if not logged in, and carry the path of the current page
// Return to the current page after successful login. This step needs to be operated on the login page.
case 401:
// userStore.setToken(undefined)
// errMessage = msg || t('sys.api.errMsg401')
// if (stp === SessionTimeoutProcessingEnum.PAGE_COVERAGE)
// userStore.setSessionTimeout(true)
// else
// userStore.logout(true)
errMessage = `${msg}`
break
case 403:
errMessage = '用户得到授权,但是访问是被禁止的!'
break
// 404请求不存在
case 404:
errMessage = '网络请求错误,未找到该资源!'
break
case 405:
errMessage = '网络请求错误,请求方法未允许!'
break
case 408:
errMessage = '网络请求超时!'
break
case 500:
errMessage = '服务器错误,请联系管理员!'
break
case 501:
errMessage = '服务端未实现此接口,请联系管理员!'
break
case 502:
errMessage = '网络错误!'
break
case 503:
errMessage = '服务不可用,服务器暂时过载或维护!'
break
case 504:
errMessage = '网络超时!'
break
case 505:
errMessage = 'http版本不支持该请求\U+0021'
break
default:
}
if (errMessage) {
if (errorMessageMode === 'modal')
dialog.error({ title: '错误提示', content: errMessage })
else if (errorMessageMode === 'message')
message.error(errMessage)
}
}

@ -0,0 +1,32 @@
export enum ResultEnum {
SUCCESS = 200,
BadRequest = 400,
Unauthorized = 401,
Forbidden = 403,
NotFound = 404,
RequestTimeout = 408,
InternalServerError = 500,
BadGateway = 502,
}
/**
* @description: request method
*/
export enum RequestMethodEnum {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
DELETE = 'DELETE',
}
/**
* @description: contentType
*/
export enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',
// form-data qs
FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
// form-data upload
FORM_DATA = 'multipart/form-data;charset=UTF-8',
}

@ -0,0 +1,66 @@
import { isObject, isString } from '~/utils/is'
const DATE_TIME_FORMAT = 'YYYY-MM-DD HH:mm:ss'
export function joinTimestamp<T extends boolean>(
join: boolean,
restful: T,
): T extends true ? string : object
export function joinTimestamp(join: boolean, restful = false): string | object {
if (!join)
return restful ? '' : {}
const now = new Date().getTime()
if (restful)
return `?_t=${now}`
return { _t: now }
}
/**
* @description: Format request parameter time
*/
export function formatRequestDate(params: Recordable) {
if (Object.prototype.toString.call(params) !== '[object Object]')
return
for (const key in params) {
const format = params[key]?.format ?? null
if (format && typeof format === 'function')
params[key] = params[key].format(DATE_TIME_FORMAT)
if (isString(key)) {
const value = params[key]
if (value) {
try {
params[key] = isString(value) ? value.trim() : value
}
catch (error: any) {
throw new Error(error)
}
}
}
if (isObject(params[key]))
formatRequestDate(params[key])
}
}
/**
* Add the object as a parameter to the URL
* @param baseUrl url
* @param obj
* @returns {string}
* eg:
* let obj = {a: '3', b: '4'}
* setObjToUrlParams('www.baidu.com', obj)
* ==>www.baidu.com?a=3&b=4
*/
export function setObjToUrlParams(baseUrl: string, obj: any): string {
let parameters = ''
for (const key in obj)
parameters += `${key}=${encodeURIComponent(obj[key])}&`
parameters = parameters.replace(/&$/, '')
return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters
}

@ -0,0 +1,293 @@
// axios配置 可自行根据项目进行更改,只需更改该文件即可,其他文件可以不动
// The axios configuration can be changed according to the project, just change the file, other files can be left unchanged
import type {
AxiosInstance,
AxiosResponse,
} from 'axios'
import { clone } from 'lodash-es'
import axios from 'axios'
import { createDiscreteApi } from 'naive-ui'
import type { AxiosTransform, CreateAxiosOptions } from './transform'
import { VAxios } from './axios'
import { checkStatus } from './check'
import { formatRequestDate, joinTimestamp, setObjToUrlParams } from './helper'
import { ContentTypeEnum, RequestMethodEnum, ResultEnum } from './enum'
import { isEmpty, isNull, isString, isUnDef } from '~/utils/is'
import { deepMerge } from '~/utils'
const { message, dialog } = createDiscreteApi(['message', 'dialog'])
// import { getToken } from '/@/utils/auth'
// import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog'
// import { useI18n } from '/@/hooks/web/useI18n'
// import { useUserStoreWithOut } from '/@/store/modules/user'
/**
* @description: 便
*/
const transform: AxiosTransform = {
/**
* @description:
*/
transformResponseHook: (res: AxiosResponse<ApiResult>, options: RequestOptions) => {
// const { t } = useI18n()
const { isTransformResponse, isReturnNativeResponse } = options
// 是否返回原生响应头 比如:需要获取响应头时使用该属性
if (isReturnNativeResponse)
return res
// 不进行任何处理,直接返回
// 用于页面代码可能需要直接获取 codedatamsg 这些信息时开启
if (!isTransformResponse)
return res.data
// 错误的时候返回
const { data } = res
if (!data) {
// return '[HTTP] Request has no return value';
throw new Error('请求出错,请稍候重试。')
}
// 这里 coderesultmessage 为 后台统一的字段,需要在 src/types/axios.d.ts 内修改为项目自己的接口返回格式
const { code, data: result, msg } = data
// 这里逻辑可以根据项目进行修改
const hasSuccess = data && Reflect.has(data, 'code') && code === ResultEnum.SUCCESS
if (hasSuccess) {
let successMsg = msg
if (isNull(successMsg) || isUnDef(successMsg) || isEmpty(successMsg))
successMsg = '操作成功'
if (options.successMessageMode === 'modal') {
dialog.success({
title: '成功提示',
content: successMsg,
})
}
else if (options.successMessageMode === 'message') {
message.success(successMsg)
}
return result
}
let commonErrMsg = msg
if (!msg) {
switch (code) {
case ResultEnum.BadRequest:
commonErrMsg = '参数错误'
break
default:
commonErrMsg = '请求错误'
}
}
// 在此处根据自己项目的实际情况对不同的code执行不同的操作
// 如果不希望中断当前请求请return数据否则直接抛出异常即可
// let timeoutMsg = ''
// switch (code) {
// case ResultEnum.TIMEOUT:
// timeoutMsg = t('sys.api.timeoutMessage')
// const userStore = useUserStoreWithOut()
// userStore.setToken(undefined)
// userStore.logout(true)
// break
// default:
// if (message)
// timeoutMsg = message
// }
// errorMessageMode='modal'的时候会显示modal错误弹窗而不是消息提示用于一些比较重要的错误
// errorMessageMode='none' 一般是调用时明确表示不希望自动弹出错误提示
if (options.errorMessageMode === 'modal')
dialog.error({ title: '错误提示', content: commonErrMsg })
else if (options.errorMessageMode === 'message')
message.error(commonErrMsg)
// throw new Error(timeoutMsg || t('sys.api.apiRequestFailed'))
throw new Error('请求出错,请稍候重试!')
},
// 请求之前处理config
beforeRequestHook: (config, options) => {
const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options
if (joinPrefix)
config.url = `${urlPrefix}${config.url}`
if (apiUrl && isString(apiUrl))
config.url = `${apiUrl}${config.url}`
const params = config.params || {}
const data = config.data || false
formatDate && data && !isString(data) && formatRequestDate(data)
if (config.method?.toUpperCase() === RequestMethodEnum.GET) {
if (!isString(params)) {
// 给 get 请求加上时间戳参数,避免从缓存中拿数据。
config.params = Object.assign(params || {}, joinTimestamp(joinTime, false))
}
else {
// 兼容restful风格
config.url = `${config.url + params}${joinTimestamp(joinTime, true)}`
config.params = undefined
}
}
else {
if (!isString(params)) {
formatDate && formatRequestDate(params)
if (
Reflect.has(config, 'data')
&& config.data
&& (Object.keys(config.data).length > 0 || config.data instanceof FormData)
) {
config.data = data
config.params = params
}
else {
// 非GET请求如果没有提供data则将params视为data
config.data = params
config.params = undefined
}
if (joinParamsToUrl) {
config.url = setObjToUrlParams(
config.url as string,
Object.assign({}, config.params, config.data),
)
}
}
else {
// 兼容restful风格
config.url = config.url + params
config.params = undefined
}
}
return config
},
/**
* @description:
*/
requestInterceptors: (config, options) => {
// // 请求之前处理config
// const token = getToken()
// if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
// // jwt token
// (config as Recordable).headers.Authorization = options.authenticationScheme
// ? `${options.authenticationScheme} ${token}`
// : token
// }
return config
},
/**
* @description:
*/
responseInterceptors: (res: AxiosResponse<any>) => {
return res
},
/**
* @description:
*/
responseInterceptorsCatch: (axiosInstance: AxiosInstance, error: any) => {
// const { t } = useI18n()
// const errorLogStore = useErrorLogStoreWithOut()
// errorLogStore.addAjaxErrorInfo(error)
const { response, code, message, config } = error || {}
const errorMessageMode = config?.requestOptions?.errorMessageMode || 'none'
const resErrMsg: string = response?.data?.msg ?? ''
const err: string = error?.toString?.() ?? ''
let errMessage = ''
if (axios.isCancel(error))
return Promise.reject(error)
try {
if (code === 'ECONNABORTED' && message.includes('timeout'))
errMessage = '接口请求超时,请刷新页面重试!'
if (err?.includes('Network Error'))
errMessage = '网络异常,请检查您的网络连接是否正常!'
if (errMessage) {
if (errorMessageMode === 'modal') {
dialog.error({
title: '错误提示',
content: errMessage,
})
}
else if (errorMessageMode === 'message') {
message.error(errMessage)
}
return Promise.reject(error)
}
}
catch (error) {
throw new Error(error as unknown as string)
}
checkStatus(error?.response?.status, resErrMsg, errorMessageMode)
return Promise.reject(error)
},
}
function createAxios(opt?: Partial<CreateAxiosOptions>) {
return new VAxios(
// 深度合并
deepMerge(
{
// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#authentication_schemes
// authentication schemese.g: Bearer
authenticationScheme: 'Bearer',
// authenticationScheme: '',
timeout: 100 * 1000,
// 基础接口地址
// baseURL: globSetting.apiUrl,
headers: { 'Content-Type': ContentTypeEnum.JSON },
// 如果是form-data格式
// headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
// 数据处理方式
transform: clone(transform),
// 配置项,下面的选项都可以在独立的接口请求中覆盖
requestOptions: {
// 默认将prefix 添加到url
joinPrefix: true,
// 是否返回原生响应头 比如:需要获取响应头时使用该属性
isReturnNativeResponse: false,
// 需要对返回数据进行处理
isTransformResponse: true,
// post请求的时候添加参数到url
joinParamsToUrl: false,
// 格式化提交参数时间
formatDate: true,
// 消息提示类型
errorMessageMode: 'message',
// 接口地址
apiUrl: import.meta.env.VITE_API_URL,
// 接口拼接地址
urlPrefix: import.meta.env.VITE_API_URL_PREFIX,
// 是否加入时间戳
joinTime: true,
// 忽略重复请求
ignoreCancelToken: true,
// 是否携带token
withToken: true,
},
},
opt || {},
),
)
}
export const defHttp = createAxios()
// other api url
// export const otherHttp = createAxios({
// requestOptions: {
// apiUrl: 'xxx',
// urlPrefix: 'xxx',
// },
// });

@ -0,0 +1,56 @@
/**
* Data processing class, can be configured according to the project
*/
import type {
AxiosInstance,
AxiosRequestConfig,
AxiosResponse,
InternalAxiosRequestConfig,
} from 'axios'
export interface CreateAxiosOptions extends AxiosRequestConfig {
authenticationScheme?: string
transform?: AxiosTransform
requestOptions?: RequestOptions
}
export abstract class AxiosTransform {
/**
* A function that is called before a request is sent. It can modify the request configuration as needed.
*
*/
beforeRequestHook?: (config: AxiosRequestConfig, options: RequestOptions) => AxiosRequestConfig
/**
* @description:
*/
transformResponseHook?: (res: AxiosResponse<ApiResult>, options: RequestOptions) => any
/**
* @description:
*/
requestCatchHook?: (e: Error, options: RequestOptions) => Promise<any>
/**
* @description:
*/
requestInterceptors?: (
config: InternalAxiosRequestConfig,
options: CreateAxiosOptions,
) => InternalAxiosRequestConfig
/**
* @description:
*/
responseInterceptors?: (res: AxiosResponse<any>) => AxiosResponse<any>
/**
* @description:
*/
requestInterceptorsCatch?: (error: Error) => void
/**
* @description:
*/
responseInterceptorsCatch?: (axiosInstance: AxiosInstance, error: Error) => void
}

@ -0,0 +1,50 @@
declare type ErrorMessageMode = 'none' | 'modal' | 'message' | undefined;
declare type SuccessMessageMode = ErrorMessageMode;
declare interface RequestOptions {
// Splicing request parameters to url
joinParamsToUrl?: boolean;
// Format request parameter time
formatDate?: boolean;
// Whether to process the request result | 是否直接处理返回消息直接返回data
isTransformResponse?: boolean;
// Whether to return native response headers | 是否返回原生响应头
// For example: use this attribute when you need to get the response headers
isReturnNativeResponse?: boolean;
// Whether to join url
joinPrefix?: boolean;
// Interface address, use the default apiUrl if you leave it blank
apiUrl?: string;
// 请求拼接路径
urlPrefix?: string;
// Error message prompt type
errorMessageMode?: ErrorMessageMode;
// Success message prompt type
successMessageMode?: SuccessMessageMode;
// Whether to add a timestamp
joinTime?: boolean;
ignoreCancelToken?: boolean;
// Whether to send token in header
withToken?: boolean;
}
// Api返回数据结构
declare interface ApiResult<T = any> {
code: number;
type: 'success' | 'error' | 'warning';
msg: string;
data: T;
}
// multipart/form-data: upload file
declare interface UploadFileParams {
// Other parameters
data?: Recordable;
// File parameter interface field name
name?: string;
// file name
file: File | Blob;
// file name
filename?: string;
[key: string]: any;
}

@ -0,0 +1,23 @@
import { cloneDeep, isEqual, mergeWith, unionWith } from 'lodash-es'
import { isArray, isObject } from '~/utils/is'
/**
Recursively merge two objects.
@param target The target object to merge into.
@param source The source object to merge from.
@returns The merged object.
*/
export function deepMerge<T extends object | null | undefined, U extends object | null | undefined>(
target: T,
source: U,
): T & U {
return mergeWith(cloneDeep(target), source, (objValue, srcValue) => {
if (isObject(objValue) && isObject(srcValue)) {
return mergeWith(cloneDeep(objValue), srcValue, (prevValue, nextValue) => {
// 如果是数组,合并数组(去重) If it is an array, merge the array (remove duplicates)
return isArray(prevValue) ? unionWith(prevValue, nextValue, isEqual) : undefined
})
}
})
}

@ -0,0 +1,95 @@
const toString = Object.prototype.toString
export function is(val: unknown, type: string) {
return toString.call(val) === `[object ${type}]`
}
export function isDef<T = unknown>(val?: T): val is T {
return typeof val !== 'undefined'
}
export function isUnDef<T = unknown>(val?: T): val is T {
return !isDef(val)
}
export function isObject(val: any): val is Record<any, any> {
return val !== null && is(val, 'Object')
}
export function isEmpty<T = unknown>(val: T): val is T {
if (isArray(val) || isString(val))
return val.length === 0
if (val instanceof Map || val instanceof Set)
return val.size === 0
if (isObject(val))
return Object.keys(val).length === 0
return false
}
export function isDate(val: unknown): val is Date {
return is(val, 'Date')
}
export function isNull(val: unknown): val is null {
return val === null
}
export function isNullAndUnDef(val: unknown): val is null | undefined {
return isUnDef(val) && isNull(val)
}
export function isNullOrUnDef(val: unknown): val is null | undefined {
return isUnDef(val) || isNull(val)
}
export function isNumber(val: unknown): val is number {
return is(val, 'Number')
}
export function isPromise<T = any>(val: unknown): val is Promise<T> {
return is(val, 'Promise') && isObject(val) && isFunction(val.then) && isFunction(val.catch)
}
export function isString(val: unknown): val is string {
return is(val, 'String')
}
export function isFunction(val: unknown): val is Function {
return typeof val === 'function'
}
export function isBoolean(val: unknown): val is boolean {
return is(val, 'Boolean')
}
export function isRegExp(val: unknown): val is RegExp {
return is(val, 'RegExp')
}
export function isArray(val: any): val is Array<any> {
return val && Array.isArray(val)
}
export function isWindow(val: any): val is Window {
return typeof window !== 'undefined' && is(val, 'Window')
}
export function isElement(val: unknown): val is Element {
return isObject(val) && !!val.tagName
}
export function isMap(val: unknown): val is Map<any, any> {
return is(val, 'Map')
}
export const isServer = typeof window === 'undefined'
export const isClient = !isServer
export function isUrl(path: string): boolean {
const reg = /^http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- ./?%&=]*)?/
return reg.test(path)
}

@ -0,0 +1,3 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`TheCounter.vue > should render 1`] = `"<div>10 <button class=\\"inc\\"> + </button><button class=\\"dec\\"> - </button></div>"`;

@ -0,0 +1,7 @@
import { describe, expect, it } from 'vitest'
describe('tests', () => {
it('should works', () => {
expect(1 + 1).toEqual(2)
})
})

@ -0,0 +1,28 @@
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import TheCounter from '../src/components/TheCounter.vue'
describe('TheCounter.vue', () => {
it('should render', () => {
const wrapper = mount(TheCounter, { props: { initial: 10 } })
expect(wrapper.text()).toContain('10')
expect(wrapper.html()).toMatchSnapshot()
})
it('should be interactive', async () => {
const wrapper = mount(TheCounter, { props: { initial: 0 } })
expect(wrapper.text()).toContain('0')
expect(wrapper.find('.inc').exists()).toBe(true)
expect(wrapper.find('.dec').exists()).toBe(true)
await wrapper.get('.inc').trigger('click')
expect(wrapper.text()).toContain('1')
await wrapper.get('.dec').trigger('click')
expect(wrapper.text()).toContain('0')
})
})

@ -0,0 +1,47 @@
{
"compilerOptions": {
"baseUrl": ".",
"module": "ESNext",
"target": "ESNext",
"lib": ["DOM", "ESNext"],
"strict": true,
"esModuleInterop": true,
"jsx": "preserve",
"skipLibCheck": true,
"isolatedModules": true,
"moduleResolution": "node",
"resolveJsonModule": true,
"noUnusedLocals": true,
"strictNullChecks": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"types": [
"vitest",
"vite/client",
"vue/ref-macros",
"vite-plugin-pages/client",
"vite-plugin-vue-component-preview/client",
"vite-plugin-vue-layouts/client",
"vite-plugin-pwa/client",
"unplugin-vue-macros/macros-global"
],
"paths": {
"~/*": ["src/*"],
"#/*": ["src/types/*"]
}
},
"vueCompilerOptions": {
"plugins": [
"@vue-macros/volar/define-models",
"@vue-macros/volar/define-slots",
"@vue-macros/volar/short-vmodel"
]
},
"exclude": ["dist", "node_modules", "cypress"],
"include": [
"src/**/*",
"src/**/*.d.ts",
"src/types/**/*.d.ts",
"src/**/types/**/*.d.ts"
]
}

@ -0,0 +1,39 @@
import fs from 'node:fs/promises'
import {
defineConfig,
presetAttributify,
presetIcons,
presetTypography,
presetUno,
presetWebFonts,
transformerDirectives,
transformerVariantGroup,
} from 'unocss'
export default defineConfig({
shortcuts: [],
presets: [
presetUno(),
presetAttributify(),
presetIcons({
scale: 1.2,
warn: true,
collections: {
'nl-logo': () => fs.readFile('./public/favicon.svg', 'utf-8'),
},
}),
presetTypography(),
presetWebFonts({
fonts: {
sans: 'DM Sans',
serif: 'DM Serif Display',
mono: 'DM Mono',
},
}),
],
transformers: [
transformerDirectives(),
transformerVariantGroup(),
],
safelist: 'prose m-auto text-left'.split(' '),
})

@ -0,0 +1,194 @@
import path from 'node:path'
import { defineConfig } from 'vite'
import Vue from '@vitejs/plugin-vue'
import Pages from 'vite-plugin-pages'
import generateSitemap from 'vite-ssg-sitemap'
import Layouts from 'vite-plugin-vue-layouts'
import Components from 'unplugin-vue-components/vite'
import AutoImport from 'unplugin-auto-import/vite'
import Markdown from 'vite-plugin-vue-markdown'
import { VitePWA } from 'vite-plugin-pwa'
import VueI18n from '@intlify/unplugin-vue-i18n/vite'
import VueDevTools from 'vite-plugin-vue-devtools'
import LinkAttributes from 'markdown-it-link-attributes'
import Unocss from 'unocss/vite'
import Shiki from 'markdown-it-shiki'
import { transformShortVmodel } from '@vue-macros/short-vmodel'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
// @ts-expect-error failed to resolve types
import VueMacros from 'unplugin-vue-macros/vite'
import WebfontDownload from 'vite-plugin-webfont-dl'
export default defineConfig({
resolve: {
alias: {
'~/': `${path.resolve(__dirname, 'src')}/`,
'#/': `${path.resolve(__dirname, 'src/types')}/`,
},
},
plugins: [
VueMacros({
plugins: {
vue: Vue({
include: [/\.vue$/, /\.md$/],
reactivityTransform: true,
template: {
compilerOptions: {
nodeTransforms: [
transformShortVmodel({ prefix: '::' }),
],
},
},
}),
},
}),
// https://github.com/hannoeru/vite-plugin-pages
Pages({
extensions: ['vue', 'md'],
}),
// https://github.com/JohnCampionJr/vite-plugin-vue-layouts
Layouts(),
// https://github.com/antfu/unplugin-auto-import
AutoImport({
imports: [
'vue',
'vue-router',
'vue-i18n',
'vue/macros',
'@vueuse/head',
'@vueuse/core',
{
'naive-ui': [
'useDialog',
'useMessage',
'useNotification',
'useLoadingBar',
],
},
],
dts: 'src/auto-imports.d.ts',
dirs: [
'src/composables',
'src/stores',
'src/types',
],
vueTemplate: true,
resolvers: [
NaiveUiResolver(),
],
}),
// https://github.com/antfu/unplugin-vue-components
Components({
// allow auto load markdown components under `./src/components/`
extensions: ['vue', 'md'],
// allow auto import and register components used in markdown
include: [/\.vue$/, /\.vue\?vue/, /\.md$/],
dts: 'src/components.d.ts',
resolvers: [
NaiveUiResolver(),
],
}),
// https://github.com/antfu/unocss
// see uno.config.ts for config
Unocss(),
// https://github.com/antfu/vite-plugin-vue-markdown
// Don't need this? Try vitesse-lite: https://github.com/antfu/vitesse-lite
Markdown({
wrapperClasses: 'prose prose-sm m-auto text-left',
headEnabled: true,
markdownItSetup(md) {
// https://prismjs.com/
md.use(Shiki, {
theme: {
light: 'vitesse-light',
dark: 'vitesse-dark',
},
})
md.use(LinkAttributes, {
matcher: (link: string) => /^https?:\/\//.test(link),
attrs: {
target: '_blank',
rel: 'noopener',
},
})
},
}),
// https://github.com/antfu/vite-plugin-pwa
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.svg', 'safari-pinned-tab.svg'],
manifest: {
name: 'Vitesse',
short_name: 'Vitesse',
theme_color: '#ffffff',
icons: [
{
src: '/pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: '/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
}),
// https://github.com/intlify/bundle-tools/tree/main/packages/unplugin-vue-i18n
VueI18n({
runtimeOnly: true,
compositionOnly: true,
fullInstall: true,
include: [path.resolve(__dirname, 'locales/**')],
}),
// https://github.com/feat-agency/vite-plugin-webfont-dl
WebfontDownload(),
// https://github.com/webfansplz/vite-plugin-vue-devtools
VueDevTools(),
],
// https://github.com/vitest-dev/vitest
test: {
include: ['test/**/*.test.ts'],
environment: 'jsdom',
deps: {
inline: ['@vue', '@vueuse', 'vue-demi'],
},
},
// https://github.com/antfu/vite-ssg
ssgOptions: {
script: 'async',
formatting: 'minify',
crittersOptions: {
reduceInlineStyles: false,
},
onFinished() {
generateSitemap()
},
},
ssr: {
// TODO: workaround until they support native ESM
noExternal: ['workbox-window', /vue-i18n/],
},
})
Loading…
Cancel
Save