diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0552777 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +# Editor configuration, see http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.env b/.env new file mode 100644 index 0000000..01db102 --- /dev/null +++ b/.env @@ -0,0 +1,44 @@ +VITE_BASE_URL=/ + +VITE_APP_TITLE=Vue-AntD-Web + +VITE_APP_DESC=Vue-AntD-Web + +# the prefix of the icon name +VITE_ICON_PREFIX=icon + +# the prefix of the local svg icon component, must include VITE_ICON_PREFIX +# format {VITE_ICON_PREFIX}-{local icon name} +VITE_ICON_LOCAL_PREFIX=icon-local + +# auth route mode: static | dynamic +VITE_AUTH_ROUTE_MODE=dynamic + +# static auth route home +VITE_ROUTE_HOME=manage_user + +# default menu icon +VITE_MENU_ICON=mdi:menu + +# whether to enable http proxy when is dev mode +VITE_HTTP_PROXY=Y + +# vue-router mode: hash | history | memory +VITE_ROUTER_HISTORY_MODE=history + +# success code of backend service, when the code is received, the request is successful +VITE_SERVICE_SUCCESS_CODE=200 + +# logout codes of backend service, when the code is received, the user will be logged out and redirected to login page +VITE_SERVICE_LOGOUT_CODES=401 + +# modal logout codes of backend service, when the code is received, the user will be logged out by displaying a modal +VITE_SERVICE_MODAL_LOGOUT_CODES=401 + +# token expired codes of backend service, when the code is received, it will refresh the token and resend the request +VITE_SERVICE_EXPIRED_TOKEN_CODES=403 + +VITE_SERVICE_SERVER_ERROR_CODE=500 + +# when the route mode is static, the defined super role +VITE_STATIC_SUPER_ROLE=R_SUPER diff --git a/.env.prod b/.env.prod new file mode 100644 index 0000000..832d4d6 --- /dev/null +++ b/.env.prod @@ -0,0 +1,7 @@ +# backend service base url, prod environment +VITE_SERVICE_BASE_URL=https://mock.apifox.com/m1/3109515-0-default + +# other backend service base url, prod environment +VITE_OTHER_SERVICE_BASE_URL= `{ + "demo": "http://localhost:9529" +}` diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..ee2b694 --- /dev/null +++ b/.env.test @@ -0,0 +1,7 @@ +# backend service base url, test environment +VITE_SERVICE_BASE_URL=http://localhost:8080 + +# other backend service base url, test environment +VITE_OTHER_SERVICE_BASE_URL= `{ + "demo": "http://localhost:9528" +}` diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9553ccb --- /dev/null +++ b/.gitattributes @@ -0,0 +1,13 @@ +"*.vue" eol=lf +"*.js" eol=lf +"*.ts" eol=lf +"*.jsx" eol=lf +"*.tsx" eol=lf +"*.mjs" eol=lf +"*.json" eol=lf +"*.html" eol=lf +"*.css" eol=lf +"*.scss" eol=lf +"*.md" eol=lf +"*.yaml" eol=lf +"*.yml" eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..baa93f3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +!.vscode/launch.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +package-lock.json +yarn.lock + +.VSCodeCounter +**/.vitepress/cache diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..14ab03c --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +registry=https://registry.npmmirror.com/ +shamefully-hoist=true +ignore-workspace-root-check=true \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..d2f675d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,22 @@ +{ + "recommendations": [ + "afzalsayed96.icones", + "antfu.iconify", + "antfu.unocss", + "dbaeumer.vscode-eslint", + "editorconfig.editorconfig", + "esbenp.prettier-vscode", + "formulahendry.auto-close-tag", + "formulahendry.auto-complete-tag", + "formulahendry.auto-rename-tag", + "lokalise.i18n-ally", + "mhutchie.git-graph", + "mikestead.dotenv", + "naumovs.color-highlight", + "pkief.material-icon-theme", + "sdras.vue-vscode-snippets", + "vue.volar", + "whtouche.vscode-js-console-utils", + "zhuangtongfa.material-theme" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f6f291d --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Vue Debugger", + "url": "http://localhost:9527", + "webRoot": "${workspaceFolder}" + }, + { + "type": "node", + "request": "launch", + "name": "TS Debugger", + "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/tsx", + "skipFiles": ["/**", "${workspaceFolder}/node_modules/**"], + "program": "${file}" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..9344100 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,27 @@ +{ + "editor.codeActionsOnSave": { + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never" + }, + "eslint.experimental.useFlatConfig": true, + "editor.formatOnSave": false, + "eslint.validate": ["html", "css", "scss", "json", "jsonc"], + "i18n-ally.displayLanguage": "zh-cn", + "i18n-ally.enabledParsers": ["ts"], + "i18n-ally.enabledFrameworks": ["vue"], + "i18n-ally.editor.preferEditor": true, + "i18n-ally.keystyle": "nested", + "i18n-ally.localesPaths": ["src/locales/langs"], + "prettier.enable": false, + "unocss.root": ["./"], + "cSpell.words": [ + "fullscreen", + "hexcode", + "Localforage", + "nacos", + "ryadmin", + "Simplebar", + "treeselect", + "userinfo" + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7232979 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 SoybeanJS + +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. diff --git a/README.md b/README.md index ed8bd91..d298789 100644 --- a/README.md +++ b/README.md @@ -1 +1,32 @@ # Front-End at CRM + +## Wfc-Cloud-Vue-AntD-Web(SoybeanAdmin AntDesign) + +## 使用 + +**环境准备** + +确保你的环境满足以下要求: + +- **git**: 你需要git来克隆和管理项目版本。 +- **NodeJS**: >=18.12.0,推荐 18.19.0 或更高。 +- **pnpm**: >= 8.7.0,推荐 8.14.0 或更高。 + +**安装依赖** + +```bash +pnpm i +``` +> 由于本项目采用了 pnpm monorepo 的管理方式,因此请不要使用 npm 或 yarn 来安装依赖。 + +**启动项目** + +```bash +pnpm dev +``` + +**构建项目** + +```bash +pnpm build +``` \ No newline at end of file diff --git a/build/config/index.ts b/build/config/index.ts new file mode 100644 index 0000000..9bcd868 --- /dev/null +++ b/build/config/index.ts @@ -0,0 +1 @@ +export * from './proxy'; diff --git a/build/config/proxy.ts b/build/config/proxy.ts new file mode 100644 index 0000000..350dfee --- /dev/null +++ b/build/config/proxy.ts @@ -0,0 +1,36 @@ +import type { ProxyOptions } from 'vite'; +import { createServiceConfig } from '../../src/utils/service'; + +/** + * Set http proxy + * + * @param env - The current env + * @param isDev - Is development environment + */ +export function createViteProxy(env: Env.ImportMeta, isDev: boolean) { + const isEnableHttpProxy = isDev && env.VITE_HTTP_PROXY === 'Y'; + + if (!isEnableHttpProxy) return undefined; + + const { baseURL, proxyPattern, other } = createServiceConfig(env); + + const proxy: Record = createProxyItem({ baseURL, proxyPattern }); + + other.forEach(item => { + Object.assign(proxy, createProxyItem(item)); + }); + + return proxy; +} + +function createProxyItem(item: App.Service.ServiceConfigItem) { + const proxy: Record = {}; + + proxy[item.proxyPattern] = { + target: item.baseURL, + changeOrigin: true, + rewrite: path => path.replace(new RegExp(`^${item.proxyPattern}`), '') + }; + + return proxy; +} diff --git a/build/plugins/index.ts b/build/plugins/index.ts new file mode 100644 index 0000000..5f234a2 --- /dev/null +++ b/build/plugins/index.ts @@ -0,0 +1,24 @@ +import type { PluginOption } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import vueJsx from '@vitejs/plugin-vue-jsx'; +import progress from 'vite-plugin-progress'; +import { setupElegantRouter } from './router'; +import { setupUnocss } from './unocss'; +import { setupUnplugin } from './unplugin'; + +export function setupVitePlugins(viteEnv: Env.ImportMeta) { + const plugins: PluginOption = [ + vue({ + script: { + defineModel: true + } + }), + vueJsx(), + setupElegantRouter(), + setupUnocss(viteEnv), + ...setupUnplugin(viteEnv), + progress() + ]; + + return plugins; +} diff --git a/build/plugins/router.ts b/build/plugins/router.ts new file mode 100644 index 0000000..952e15d --- /dev/null +++ b/build/plugins/router.ts @@ -0,0 +1,44 @@ +import type { RouteMeta } from 'vue-router'; +import ElegantVueRouter from '@elegant-router/vue/vite'; +import type { RouteKey } from '@elegant-router/types'; + +export function setupElegantRouter() { + return ElegantVueRouter({ + layouts: { + base: 'src/layouts/base-layout/index.vue', + blank: 'src/layouts/blank-layout/index.vue' + }, + customRoutes: { + names: ['exception_403', 'exception_404', 'exception_500'] + }, + routePathTransformer(routeName, routePath) { + const key = routeName as RouteKey; + + if (key === 'login') { + const modules: UnionKey.LoginModule[] = ['pwd-login', 'code-login', 'register', 'reset-pwd', 'bind-wechat']; + + const moduleReg = modules.join('|'); + + return `/login/:module(${moduleReg})?`; + } + + return routePath; + }, + onRouteMetaGen(routeName) { + const key = routeName as RouteKey; + + const constantRoutes: RouteKey[] = ['login', '403', '404', '500']; + + const meta: Partial = { + title: key, + i18nKey: `route.${key}` as App.I18n.I18nKey + }; + + if (constantRoutes.includes(key)) { + meta.constant = true; + } + + return meta; + } + }); +} diff --git a/build/plugins/unocss.ts b/build/plugins/unocss.ts new file mode 100644 index 0000000..06b41d3 --- /dev/null +++ b/build/plugins/unocss.ts @@ -0,0 +1,32 @@ +import process from 'node:process'; +import path from 'node:path'; +import unocss from '@unocss/vite'; +import presetIcons from '@unocss/preset-icons'; +import { FileSystemIconLoader } from '@iconify/utils/lib/loader/node-loaders'; + +export function setupUnocss(viteEnv: Env.ImportMeta) { + const { VITE_ICON_PREFIX, VITE_ICON_LOCAL_PREFIX } = viteEnv; + + const localIconPath = path.join(process.cwd(), 'src/assets/svg-icon'); + + /** The name of the local icon collection */ + const collectionName = VITE_ICON_LOCAL_PREFIX.replace(`${VITE_ICON_PREFIX}-`, ''); + + return unocss({ + presets: [ + presetIcons({ + prefix: `${VITE_ICON_PREFIX}-`, + scale: 1, + extraProperties: { + display: 'inline-block' + }, + collections: { + [collectionName]: FileSystemIconLoader(localIconPath, svg => + svg.replace(/^ + svg.replace(/^ + + + + + + %VITE_APP_TITLE% + + +
+ + + diff --git a/package.json b/package.json new file mode 100644 index 0000000..2679a51 --- /dev/null +++ b/package.json @@ -0,0 +1,73 @@ +{ + "name": "vue-antd", + "type": "module", + "version": "1.0.0", + "scripts": { + "build": "vite build --mode prod", + "build:test": "vite build --mode test", + "dev": "vite --mode test", + "dev:prod": "vite --mode prod", + "gen-route": "sa gen-route", + "lint": "eslint . --fix", + "preview": "vite preview", + "typecheck": "vue-tsc --noEmit --skipLibCheck" + }, + "dependencies": { + "@better-scroll/core": "2.5.1", + "@iconify/vue": "4.1.2", + "@sa/axios": "workspace:*", + "@sa/color-palette": "workspace:*", + "@sa/fetch": "workspace:*", + "@sa/hooks": "workspace:*", + "@sa/materials": "workspace:*", + "@sa/utils": "workspace:*", + "@vueuse/core": "10.10.0", + "ant-design-vue": "4.2.2", + "clipboard": "2.0.11", + "dayjs": "1.11.11", + "echarts": "5.5.0", + "lodash-es": "4.17.21", + "nprogress": "0.2.0", + "pinia": "2.1.7", + "vue": "3.4.27", + "vue-draggable-plus": "0.5.0", + "vue-i18n": "9.13.1", + "vue-router": "4.3.2" + }, + "devDependencies": { + "@elegant-router/vue": "0.3.7", + "@iconify/json": "2.2.217", + "@sa/scripts": "workspace:*", + "@sa/uno-preset": "workspace:*", + "@soybeanjs/eslint-config": "1.3.6", + "@types/lodash-es": "4.17.12", + "@types/node": "20.14.2", + "@types/nprogress": "0.2.3", + "@unocss/eslint-config": "0.60.4", + "@unocss/preset-attributify": "^0.60.4", + "@unocss/preset-icons": "0.60.4", + "@unocss/preset-tagify": "^0.60.4", + "@unocss/preset-uno": "0.60.4", + "@unocss/transformer-directives": "0.60.4", + "@unocss/transformer-variant-group": "0.60.4", + "@unocss/vite": "0.60.4", + "@vitejs/plugin-vue": "5.0.5", + "@vitejs/plugin-vue-jsx": "4.0.0", + "eslint": "9.4.0", + "eslint-plugin-vue": "9.26.0", + "lint-staged": "15.2.5", + "sass": "1.77.4", + "simple-git-hooks": "2.11.1", + "tsx": "4.14.1", + "typescript": "5.4.5", + "unplugin-auto-import": "^0.17.6", + "unplugin-icons": "0.19.0", + "unplugin-vue-components": "0.27.0", + "vite": "5.2.13", + "vite-plugin-progress": "0.0.7", + "vite-plugin-svg-icons": "2.0.1", + "vitest": "^1.6.0", + "vue-eslint-parser": "9.4.3", + "vue-tsc": "2.0.21" + } +} diff --git a/packages/axios/package.json b/packages/axios/package.json new file mode 100644 index 0000000..d29a8db --- /dev/null +++ b/packages/axios/package.json @@ -0,0 +1,21 @@ +{ + "name": "@sa/axios", + "version": "1.0.0", + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + }, + "dependencies": { + "@sa/utils": "workspace:*", + "axios": "1.6.8", + "axios-retry": "4.1.0", + "qs": "6.12.1" + }, + "devDependencies": { + "@types/qs": "6.9.15" + } +} diff --git a/packages/axios/src/constant.ts b/packages/axios/src/constant.ts new file mode 100644 index 0000000..d6c5a33 --- /dev/null +++ b/packages/axios/src/constant.ts @@ -0,0 +1,5 @@ +/** request id key */ +export const REQUEST_ID_KEY = 'X-Request-Id'; + +/** the backend error code key */ +export const BACKEND_ERROR_CODE = 'BACKEND_ERROR'; diff --git a/packages/axios/src/index.ts b/packages/axios/src/index.ts new file mode 100644 index 0000000..64a75c3 --- /dev/null +++ b/packages/axios/src/index.ts @@ -0,0 +1,179 @@ +import axios, { AxiosError } from 'axios'; +import type { AxiosResponse, CancelTokenSource, CreateAxiosDefaults, InternalAxiosRequestConfig } from 'axios'; +import axiosRetry from 'axios-retry'; +import { nanoid } from '@sa/utils'; +import { createAxiosConfig, createDefaultOptions, createRetryOptions } from './options'; +import { BACKEND_ERROR_CODE, REQUEST_ID_KEY } from './constant'; +import type { + CustomAxiosRequestConfig, + FlatRequestInstance, + MappedType, + RequestInstance, + RequestOption, + ResponseType +} from './type'; + +function createCommonRequest( + axiosConfig?: CreateAxiosDefaults, + options?: Partial> +) { + const opts = createDefaultOptions(options); + + const axiosConf = createAxiosConfig(axiosConfig); + const instance = axios.create(axiosConf); + + const cancelTokenSourceMap = new Map(); + + // config axios retry + const retryOptions = createRetryOptions(axiosConf); + axiosRetry(instance, retryOptions); + + instance.interceptors.request.use(conf => { + const config: InternalAxiosRequestConfig = { ...conf }; + + // set request id + const requestId = nanoid(); + config.headers.set(REQUEST_ID_KEY, requestId); + + // config cancel token + const cancelTokenSource = axios.CancelToken.source(); + config.cancelToken = cancelTokenSource.token; + cancelTokenSourceMap.set(requestId, cancelTokenSource); + + // handle config by hook + const handledConfig = opts.onRequest?.(config) || config; + + return handledConfig; + }); + + instance.interceptors.response.use( + async response => { + if (opts.isBackendSuccess(response)) { + return Promise.resolve(response); + } + + const fail = await opts.onBackendFail(response, instance); + if (fail) { + return fail; + } + + const backendError = new AxiosError( + 'the backend request error', + BACKEND_ERROR_CODE, + response.config, + response.request, + response + ); + + await opts.onError(backendError); + + return Promise.reject(backendError); + }, + async (error: AxiosError) => { + await opts.onError(error); + + return Promise.reject(error); + } + ); + + function cancelRequest(requestId: string) { + const cancelTokenSource = cancelTokenSourceMap.get(requestId); + if (cancelTokenSource) { + cancelTokenSource.cancel(); + cancelTokenSourceMap.delete(requestId); + } + } + + function cancelAllRequest() { + cancelTokenSourceMap.forEach(cancelTokenSource => { + cancelTokenSource.cancel(); + }); + cancelTokenSourceMap.clear(); + } + + return { + instance, + opts, + cancelRequest, + cancelAllRequest + }; +} + +/** + * create a request instance + * + * @param axiosConfig axios config + * @param options request options + */ +export function createRequest>( + axiosConfig?: CreateAxiosDefaults, + options?: Partial> +) { + const { instance, opts, cancelRequest, cancelAllRequest } = createCommonRequest(axiosConfig, options); + + const request: RequestInstance = async function request( + config: CustomAxiosRequestConfig + ) { + const response: AxiosResponse = await instance(config); + + const responseType = response.config?.responseType || 'json'; + + if (responseType === 'json') { + return opts.transformBackendResponse(response); + } + + return response.data as MappedType; + } as RequestInstance; + + request.cancelRequest = cancelRequest; + request.cancelAllRequest = cancelAllRequest; + request.state = {} as State; + + return request; +} + +/** + * create a flat request instance + * + * The response data is a flat object: { data: any, error: AxiosError } + * + * @param axiosConfig axios config + * @param options request options + */ +export function createFlatRequest>( + axiosConfig?: CreateAxiosDefaults, + options?: Partial> +) { + const { instance, opts, cancelRequest, cancelAllRequest } = createCommonRequest(axiosConfig, options); + + const flatRequest: FlatRequestInstance = async function flatRequest< + T = any, + R extends ResponseType = 'json' + >(config: CustomAxiosRequestConfig) { + try { + const response: AxiosResponse = await instance(config); + + const responseType = response.config?.responseType || 'json'; + + if (responseType === 'json') { + const data = opts.transformBackendResponse(response); + + return { data, error: null }; + } + + return { data: response.data as MappedType, error: null }; + } catch (error) { + return { data: null, error }; + } + } as FlatRequestInstance; + + flatRequest.cancelRequest = cancelRequest; + flatRequest.cancelAllRequest = cancelAllRequest; + flatRequest.state = {} as State; + + return flatRequest; +} + +export { BACKEND_ERROR_CODE, REQUEST_ID_KEY }; +export type * from './type'; +export type { CreateAxiosDefaults, AxiosError }; diff --git a/packages/axios/src/options.ts b/packages/axios/src/options.ts new file mode 100644 index 0000000..ff59fa7 --- /dev/null +++ b/packages/axios/src/options.ts @@ -0,0 +1,48 @@ +import type { CreateAxiosDefaults } from 'axios'; +import type { IAxiosRetryConfig } from 'axios-retry'; +import { stringify } from 'qs'; +import { isHttpSuccess } from './shared'; +import type { RequestOption } from './type'; + +export function createDefaultOptions(options?: Partial>) { + const opts: RequestOption = { + onRequest: async config => config, + isBackendSuccess: _response => true, + onBackendFail: async () => {}, + transformBackendResponse: async response => response.data, + onError: async () => {} + }; + + Object.assign(opts, options); + + return opts; +} + +export function createRetryOptions(config?: Partial) { + const retryConfig: IAxiosRetryConfig = { + retries: 3 + }; + + Object.assign(retryConfig, config); + + return retryConfig; +} + +export function createAxiosConfig(config?: Partial) { + const TEN_SECONDS = 10 * 1000; + + const axiosConfig: CreateAxiosDefaults = { + timeout: TEN_SECONDS, + headers: { + 'Content-Type': 'application/json' + }, + validateStatus: isHttpSuccess, + paramsSerializer: params => { + return stringify(params); + } + }; + + Object.assign(axiosConfig, config); + + return axiosConfig; +} diff --git a/packages/axios/src/shared.ts b/packages/axios/src/shared.ts new file mode 100644 index 0000000..7afd32b --- /dev/null +++ b/packages/axios/src/shared.ts @@ -0,0 +1,28 @@ +import type { AxiosHeaderValue, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; + +export function getContentType(config: InternalAxiosRequestConfig) { + const contentType: AxiosHeaderValue = config.headers?.['Content-Type'] || 'application/json'; + + return contentType; +} + +/** + * check if http status is success + * + * @param status + */ +export function isHttpSuccess(status: number) { + const isSuccessCode = status >= 200 && status < 300; + return isSuccessCode || status === 304; +} + +/** + * is response json + * + * @param response axios response + */ +export function isResponseJson(response: AxiosResponse) { + const { responseType } = response.config; + + return responseType === 'json' || responseType === undefined; +} diff --git a/packages/axios/src/type.ts b/packages/axios/src/type.ts new file mode 100644 index 0000000..0ecbacb --- /dev/null +++ b/packages/axios/src/type.ts @@ -0,0 +1,101 @@ +import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios'; + +export type ContentType = + | 'text/html' + | 'text/plain' + | 'multipart/form-data' + | 'application/json' + | 'application/x-www-form-urlencoded' + | 'application/octet-stream'; + +export interface RequestOption { + /** + * The hook before request + * + * For example: You can add header token in this hook + * + * @param config Axios config + */ + onRequest: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise; + /** + * The hook to check backend response is success or not + * + * @param response Axios response + */ + isBackendSuccess: (response: AxiosResponse) => boolean; + /** + * The hook after backend request fail + * + * For example: You can handle the expired token in this hook + * + * @param response Axios response + * @param instance Axios instance + */ + onBackendFail: ( + response: AxiosResponse, + instance: AxiosInstance + ) => Promise | Promise; + /** + * transform backend response when the responseType is json + * + * @param response Axios response + */ + transformBackendResponse(response: AxiosResponse): any | Promise; + /** + * The hook to handle error + * + * For example: You can show error message in this hook + * + * @param error + */ + onError: (error: AxiosError) => void | Promise; +} + +interface ResponseMap { + blob: Blob; + text: string; + arrayBuffer: ArrayBuffer; + stream: ReadableStream; + document: Document; +} +export type ResponseType = keyof ResponseMap | 'json'; + +export type MappedType = R extends keyof ResponseMap + ? ResponseMap[R] + : JsonType; + +export type CustomAxiosRequestConfig = Omit & { + responseType?: R; +}; + +export interface RequestInstanceCommon { + cancelRequest: (requestId: string) => void; + cancelAllRequest: () => void; + /** you can set custom state in the request instance */ + state: T; +} + +/** The request instance */ +export interface RequestInstance> extends RequestInstanceCommon { + (config: CustomAxiosRequestConfig): Promise>; +} + +export type FlatResponseSuccessData = { + data: T; + error: null; +}; + +export type FlatResponseFailData = { + data: null; + error: AxiosError; +}; + +export type FlatResponseData = + | FlatResponseSuccessData + | FlatResponseFailData; + +export interface FlatRequestInstance, ResponseData = any> extends RequestInstanceCommon { + ( + config: CustomAxiosRequestConfig + ): Promise, ResponseData>>; +} diff --git a/packages/axios/tsconfig.json b/packages/axios/tsconfig.json new file mode 100644 index 0000000..5823ed5 --- /dev/null +++ b/packages/axios/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/color-palette/package.json b/packages/color-palette/package.json new file mode 100644 index 0000000..6515faa --- /dev/null +++ b/packages/color-palette/package.json @@ -0,0 +1,15 @@ +{ + "name": "@sa/color-palette", + "version": "1.0.0", + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + }, + "dependencies": { + "colord": "2.9.3" + } +} diff --git a/packages/color-palette/src/color.ts b/packages/color-palette/src/color.ts new file mode 100644 index 0000000..797148d --- /dev/null +++ b/packages/color-palette/src/color.ts @@ -0,0 +1,29 @@ +import { colord, extend } from 'colord'; +import type { HslColor } from 'colord'; +import labPlugin from 'colord/plugins/lab'; + +extend([labPlugin]); + +export function isValidColor(color: string) { + return colord(color).isValid(); +} + +export function getHex(color: string) { + return colord(color).toHex(); +} + +export function getRgb(color: string) { + return colord(color).toRgb(); +} + +export function getHsl(color: string) { + return colord(color).toHsl(); +} + +export function getDeltaE(color1: string, color2: string) { + return colord(color1).delta(color2); +} + +export function transformHslToHex(color: HslColor) { + return colord(color).toHex(); +} diff --git a/packages/color-palette/src/index.ts b/packages/color-palette/src/index.ts new file mode 100644 index 0000000..884a4e4 --- /dev/null +++ b/packages/color-palette/src/index.ts @@ -0,0 +1,41 @@ +import { getColorPaletteFamily } from './palette'; +import { getColorName } from './name'; +import type { ColorPalette, ColorPaletteFamily, ColorPaletteItem, ColorPaletteNumber } from './type'; +import defaultPalettes from './json/palette.json'; + +/** + * Get color palette by provided color and color name + * + * @param color The provided color + * @param colorName Color name + */ +export function getColorPalette(color: string, colorName: string) { + const colorPaletteFamily = getColorPaletteFamily(color, colorName); + + const colorMap = new Map(); + + colorPaletteFamily.palettes.forEach(palette => { + colorMap.set(palette.number, palette); + }); + + const mainColor = colorMap.get(500) as ColorPaletteItem; + const matchColor = colorPaletteFamily.palettes.find(palette => palette.hexcode === color) as ColorPaletteItem; + + const colorPalette: ColorPalette = { + ...colorPaletteFamily, + colorMap, + main: mainColor, + match: matchColor + }; + + return colorPalette; +} + +export default getColorPalette; + +/** The builtin color palettes */ +const colorPalettes = defaultPalettes as ColorPaletteFamily[]; + +export { getColorName, colorPalettes }; + +export type { ColorPalette, ColorPaletteNumber, ColorPaletteItem, ColorPaletteFamily }; diff --git a/packages/color-palette/src/json/color-name.json b/packages/color-palette/src/json/color-name.json new file mode 100644 index 0000000..82b2786 --- /dev/null +++ b/packages/color-palette/src/json/color-name.json @@ -0,0 +1,1568 @@ +[ + ["000000", "Black"], + ["000080", "Navy Blue"], + ["0000C8", "Dark Blue"], + ["0000FF", "Blue"], + ["000741", "Stratos"], + ["001B1C", "Swamp"], + ["002387", "Resolution Blue"], + ["002900", "Deep Fir"], + ["002E20", "Burnham"], + ["002FA7", "International Klein Blue"], + ["003153", "Prussian Blue"], + ["003366", "Midnight Blue"], + ["003399", "Smalt"], + ["003532", "Deep Teal"], + ["003E40", "Cyprus"], + ["004620", "Kaitoke Green"], + ["0047AB", "Cobalt"], + ["004816", "Crusoe"], + ["004950", "Sherpa Blue"], + ["0056A7", "Endeavour"], + ["00581A", "Camarone"], + ["0066CC", "Science Blue"], + ["0066FF", "Blue Ribbon"], + ["00755E", "Tropical Rain Forest"], + ["0076A3", "Allports"], + ["007BA7", "Deep Cerulean"], + ["007EC7", "Lochmara"], + ["007FFF", "Azure Radiance"], + ["008080", "Teal"], + ["0095B6", "Bondi Blue"], + ["009DC4", "Pacific Blue"], + ["00A693", "Persian Green"], + ["00A86B", "Jade"], + ["00CC99", "Caribbean Green"], + ["00CCCC", "Robin's Egg Blue"], + ["00FF00", "Green"], + ["00FF7F", "Spring Green"], + ["00FFFF", "Cyan / Aqua"], + ["010D1A", "Blue Charcoal"], + ["011635", "Midnight"], + ["011D13", "Holly"], + ["012731", "Daintree"], + ["01361C", "Cardin Green"], + ["01371A", "County Green"], + ["013E62", "Astronaut Blue"], + ["013F6A", "Regal Blue"], + ["014B43", "Aqua Deep"], + ["015E85", "Orient"], + ["016162", "Blue Stone"], + ["016D39", "Fun Green"], + ["01796F", "Pine Green"], + ["017987", "Blue Lagoon"], + ["01826B", "Deep Sea"], + ["01A368", "Green Haze"], + ["022D15", "English Holly"], + ["02402C", "Sherwood Green"], + ["02478E", "Congress Blue"], + ["024E46", "Evening Sea"], + ["026395", "Bahama Blue"], + ["02866F", "Observatory"], + ["02A4D3", "Cerulean"], + ["03163C", "Tangaroa"], + ["032B52", "Green Vogue"], + ["036A6E", "Mosque"], + ["041004", "Midnight Moss"], + ["041322", "Black Pearl"], + ["042E4C", "Blue Whale"], + ["044022", "Zuccini"], + ["044259", "Teal Blue"], + ["051040", "Deep Cove"], + ["051657", "Gulf Blue"], + ["055989", "Venice Blue"], + ["056F57", "Watercourse"], + ["062A78", "Catalina Blue"], + ["063537", "Tiber"], + ["069B81", "Gossamer"], + ["06A189", "Niagara"], + ["073A50", "Tarawera"], + ["080110", "Jaguar"], + ["081910", "Black Bean"], + ["082567", "Deep Sapphire"], + ["088370", "Elf Green"], + ["08E8DE", "Bright Turquoise"], + ["092256", "Downriver"], + ["09230F", "Palm Green"], + ["09255D", "Madison"], + ["093624", "Bottle Green"], + ["095859", "Deep Sea Green"], + ["097F4B", "Salem"], + ["0A001C", "Black Russian"], + ["0A480D", "Dark Fern"], + ["0A6906", "Japanese Laurel"], + ["0A6F75", "Atoll"], + ["0B0B0B", "Cod Gray"], + ["0B0F08", "Marshland"], + ["0B1107", "Gordons Green"], + ["0B1304", "Black Forest"], + ["0B6207", "San Felix"], + ["0BDA51", "Malachite"], + ["0C0B1D", "Ebony"], + ["0C0D0F", "Woodsmoke"], + ["0C1911", "Racing Green"], + ["0C7A79", "Surfie Green"], + ["0C8990", "Blue Chill"], + ["0D0332", "Black Rock"], + ["0D1117", "Bunker"], + ["0D1C19", "Aztec"], + ["0D2E1C", "Bush"], + ["0E0E18", "Cinder"], + ["0E2A30", "Firefly"], + ["0F2D9E", "Torea Bay"], + ["10121D", "Vulcan"], + ["101405", "Green Waterloo"], + ["105852", "Eden"], + ["110C6C", "Arapawa"], + ["120A8F", "Ultramarine"], + ["123447", "Elephant"], + ["126B40", "Jewel"], + ["130000", "Diesel"], + ["130A06", "Asphalt"], + ["13264D", "Blue Zodiac"], + ["134F19", "Parsley"], + ["140600", "Nero"], + ["1450AA", "Tory Blue"], + ["151F4C", "Bunting"], + ["1560BD", "Denim"], + ["15736B", "Genoa"], + ["161928", "Mirage"], + ["161D10", "Hunter Green"], + ["162A40", "Big Stone"], + ["163222", "Celtic"], + ["16322C", "Timber Green"], + ["163531", "Gable Green"], + ["171F04", "Pine Tree"], + ["175579", "Chathams Blue"], + ["182D09", "Deep Forest Green"], + ["18587A", "Blumine"], + ["19330E", "Palm Leaf"], + ["193751", "Nile Blue"], + ["1959A8", "Fun Blue"], + ["1A1A68", "Lucky Point"], + ["1AB385", "Mountain Meadow"], + ["1B0245", "Tolopea"], + ["1B1035", "Haiti"], + ["1B127B", "Deep Koamaru"], + ["1B1404", "Acadia"], + ["1B2F11", "Seaweed"], + ["1B3162", "Biscay"], + ["1B659D", "Matisse"], + ["1C1208", "Crowshead"], + ["1C1E13", "Rangoon Green"], + ["1C39BB", "Persian Blue"], + ["1C402E", "Everglade"], + ["1C7C7D", "Elm"], + ["1D6142", "Green Pea"], + ["1E0F04", "Creole"], + ["1E1609", "Karaka"], + ["1E1708", "El Paso"], + ["1E385B", "Cello"], + ["1E433C", "Te Papa Green"], + ["1E90FF", "Dodger Blue"], + ["1E9AB0", "Eastern Blue"], + ["1F120F", "Night Rider"], + ["1FC2C2", "Java"], + ["20208D", "Jacksons Purple"], + ["202E54", "Cloud Burst"], + ["204852", "Blue Dianne"], + ["211A0E", "Eternity"], + ["220878", "Deep Blue"], + ["228B22", "Forest Green"], + ["233418", "Mallard"], + ["240A40", "Violet"], + ["240C02", "Kilamanjaro"], + ["242A1D", "Log Cabin"], + ["242E16", "Black Olive"], + ["24500F", "Green House"], + ["251607", "Graphite"], + ["251706", "Cannon Black"], + ["251F4F", "Port Gore"], + ["25272C", "Shark"], + ["25311C", "Green Kelp"], + ["2596D1", "Curious Blue"], + ["260368", "Paua"], + ["26056A", "Paris M"], + ["261105", "Wood Bark"], + ["261414", "Gondola"], + ["262335", "Steel Gray"], + ["26283B", "Ebony Clay"], + ["273A81", "Bay of Many"], + ["27504B", "Plantation"], + ["278A5B", "Eucalyptus"], + ["281E15", "Oil"], + ["283A77", "Astronaut"], + ["286ACD", "Mariner"], + ["290C5E", "Violent Violet"], + ["292130", "Bastille"], + ["292319", "Zeus"], + ["292937", "Charade"], + ["297B9A", "Jelly Bean"], + ["29AB87", "Jungle Green"], + ["2A0359", "Cherry Pie"], + ["2A140E", "Coffee Bean"], + ["2A2630", "Baltic Sea"], + ["2A380B", "Turtle Green"], + ["2A52BE", "Cerulean Blue"], + ["2B0202", "Sepia Black"], + ["2B194F", "Valhalla"], + ["2B3228", "Heavy Metal"], + ["2C0E8C", "Blue Gem"], + ["2C1632", "Revolver"], + ["2C2133", "Bleached Cedar"], + ["2C8C84", "Lochinvar"], + ["2D2510", "Mikado"], + ["2D383A", "Outer Space"], + ["2D569B", "St Tropaz"], + ["2E0329", "Jacaranda"], + ["2E1905", "Jacko Bean"], + ["2E3222", "Rangitoto"], + ["2E3F62", "Rhino"], + ["2E8B57", "Sea Green"], + ["2EBFD4", "Scooter"], + ["2F270E", "Onion"], + ["2F3CB3", "Governor Bay"], + ["2F519E", "Sapphire"], + ["2F5A57", "Spectra"], + ["2F6168", "Casal"], + ["300529", "Melanzane"], + ["301F1E", "Cocoa Brown"], + ["302A0F", "Woodrush"], + ["304B6A", "San Juan"], + ["30D5C8", "Turquoise"], + ["311C17", "Eclipse"], + ["314459", "Pickled Bluewood"], + ["315BA1", "Azure"], + ["31728D", "Calypso"], + ["317D82", "Paradiso"], + ["32127A", "Persian Indigo"], + ["32293A", "Blackcurrant"], + ["323232", "Mine Shaft"], + ["325D52", "Stromboli"], + ["327C14", "Bilbao"], + ["327DA0", "Astral"], + ["33036B", "Christalle"], + ["33292F", "Thunder"], + ["33CC99", "Shamrock"], + ["341515", "Tamarind"], + ["350036", "Mardi Gras"], + ["350E42", "Valentino"], + ["350E57", "Jagger"], + ["353542", "Tuna"], + ["354E8C", "Chambray"], + ["363050", "Martinique"], + ["363534", "Tuatara"], + ["363C0D", "Waiouru"], + ["36747D", "Ming"], + ["368716", "La Palma"], + ["370202", "Chocolate"], + ["371D09", "Clinker"], + ["37290E", "Brown Tumbleweed"], + ["373021", "Birch"], + ["377475", "Oracle"], + ["380474", "Blue Diamond"], + ["381A51", "Grape"], + ["383533", "Dune"], + ["384555", "Oxford Blue"], + ["384910", "Clover"], + ["394851", "Limed Spruce"], + ["396413", "Dell"], + ["3A0020", "Toledo"], + ["3A2010", "Sambuca"], + ["3A2A6A", "Jacarta"], + ["3A686C", "William"], + ["3A6A47", "Killarney"], + ["3AB09E", "Keppel"], + ["3B000B", "Temptress"], + ["3B0910", "Aubergine"], + ["3B1F1F", "Jon"], + ["3B2820", "Treehouse"], + ["3B7A57", "Amazon"], + ["3B91B4", "Boston Blue"], + ["3C0878", "Windsor"], + ["3C1206", "Rebel"], + ["3C1F76", "Meteorite"], + ["3C2005", "Dark Ebony"], + ["3C3910", "Camouflage"], + ["3C4151", "Bright Gray"], + ["3C4443", "Cape Cod"], + ["3C493A", "Lunar Green"], + ["3D0C02", "Bean "], + ["3D2B1F", "Bistre"], + ["3D7D52", "Goblin"], + ["3E0480", "Kingfisher Daisy"], + ["3E1C14", "Cedar"], + ["3E2B23", "English Walnut"], + ["3E2C1C", "Black Marlin"], + ["3E3A44", "Ship Gray"], + ["3EABBF", "Pelorous"], + ["3F2109", "Bronze"], + ["3F2500", "Cola"], + ["3F3002", "Madras"], + ["3F307F", "Minsk"], + ["3F4C3A", "Cabbage Pont"], + ["3F583B", "Tom Thumb"], + ["3F5D53", "Mineral Green"], + ["3FC1AA", "Puerto Rico"], + ["3FFF00", "Harlequin"], + ["401801", "Brown Pod"], + ["40291D", "Cork"], + ["403B38", "Masala"], + ["403D19", "Thatch Green"], + ["405169", "Fiord"], + ["40826D", "Viridian"], + ["40A860", "Chateau Green"], + ["410056", "Ripe Plum"], + ["411F10", "Paco"], + ["412010", "Deep Oak"], + ["413C37", "Merlin"], + ["414257", "Gun Powder"], + ["414C7D", "East Bay"], + ["4169E1", "Royal Blue"], + ["41AA78", "Ocean Green"], + ["420303", "Burnt Maroon"], + ["423921", "Lisbon Brown"], + ["427977", "Faded Jade"], + ["431560", "Scarlet Gum"], + ["433120", "Iroko"], + ["433E37", "Armadillo"], + ["434C59", "River Bed"], + ["436A0D", "Green Leaf"], + ["44012D", "Barossa"], + ["441D00", "Morocco Brown"], + ["444954", "Mako"], + ["454936", "Kelp"], + ["456CAC", "San Marino"], + ["45B1E8", "Picton Blue"], + ["460B41", "Loulou"], + ["462425", "Crater Brown"], + ["465945", "Gray Asparagus"], + ["4682B4", "Steel Blue"], + ["480404", "Rustic Red"], + ["480607", "Bulgarian Rose"], + ["480656", "Clairvoyant"], + ["481C1C", "Cocoa Bean"], + ["483131", "Woody Brown"], + ["483C32", "Taupe"], + ["49170C", "Van Cleef"], + ["492615", "Brown Derby"], + ["49371B", "Metallic Bronze"], + ["495400", "Verdun Green"], + ["496679", "Blue Bayoux"], + ["497183", "Bismark"], + ["4A2A04", "Bracken"], + ["4A3004", "Deep Bronze"], + ["4A3C30", "Mondo"], + ["4A4244", "Tundora"], + ["4A444B", "Gravel"], + ["4A4E5A", "Trout"], + ["4B0082", "Pigment Indigo"], + ["4B5D52", "Nandor"], + ["4C3024", "Saddle"], + ["4C4F56", "Abbey"], + ["4D0135", "Blackberry"], + ["4D0A18", "Cab Sav"], + ["4D1E01", "Indian Tan"], + ["4D282D", "Cowboy"], + ["4D282E", "Livid Brown"], + ["4D3833", "Rock"], + ["4D3D14", "Punga"], + ["4D400F", "Bronzetone"], + ["4D5328", "Woodland"], + ["4E0606", "Mahogany"], + ["4E2A5A", "Bossanova"], + ["4E3B41", "Matterhorn"], + ["4E420C", "Bronze Olive"], + ["4E4562", "Mulled Wine"], + ["4E6649", "Axolotl"], + ["4E7F9E", "Wedgewood"], + ["4EABD1", "Shakespeare"], + ["4F1C70", "Honey Flower"], + ["4F2398", "Daisy Bush"], + ["4F69C6", "Indigo"], + ["4F7942", "Fern Green"], + ["4F9D5D", "Fruit Salad"], + ["4FA83D", "Apple"], + ["504351", "Mortar"], + ["507096", "Kashmir Blue"], + ["507672", "Cutty Sark"], + ["50C878", "Emerald"], + ["514649", "Emperor"], + ["516E3D", "Chalet Green"], + ["517C66", "Como"], + ["51808F", "Smalt Blue"], + ["52001F", "Castro"], + ["520C17", "Maroon Oak"], + ["523C94", "Gigas"], + ["533455", "Voodoo"], + ["534491", "Victoria"], + ["53824B", "Hippie Green"], + ["541012", "Heath"], + ["544333", "Judge Gray"], + ["54534D", "Fuscous Gray"], + ["549019", "Vida Loca"], + ["55280C", "Cioccolato"], + ["555B10", "Saratoga"], + ["556D56", "Finlandia"], + ["5590D9", "Havelock Blue"], + ["56B4BE", "Fountain Blue"], + ["578363", "Spring Leaves"], + ["583401", "Saddle Brown"], + ["585562", "Scarpa Flow"], + ["587156", "Cactus"], + ["589AAF", "Hippie Blue"], + ["591D35", "Wine Berry"], + ["592804", "Brown Bramble"], + ["593737", "Congo Brown"], + ["594433", "Millbrook"], + ["5A6E9C", "Waikawa Gray"], + ["5A87A0", "Horizon"], + ["5B3013", "Jambalaya"], + ["5C0120", "Bordeaux"], + ["5C0536", "Mulberry Wood"], + ["5C2E01", "Carnaby Tan"], + ["5C5D75", "Comet"], + ["5D1E0F", "Redwood"], + ["5D4C51", "Don Juan"], + ["5D5C58", "Chicago"], + ["5D5E37", "Verdigris"], + ["5D7747", "Dingley"], + ["5DA19F", "Breaker Bay"], + ["5E483E", "Kabul"], + ["5E5D3B", "Hemlock"], + ["5F3D26", "Irish Coffee"], + ["5F5F6E", "Mid Gray"], + ["5F6672", "Shuttle Gray"], + ["5FA777", "Aqua Forest"], + ["5FB3AC", "Tradewind"], + ["604913", "Horses Neck"], + ["605B73", "Smoky"], + ["606E68", "Corduroy"], + ["6093D1", "Danube"], + ["612718", "Espresso"], + ["614051", "Eggplant"], + ["615D30", "Costa Del Sol"], + ["61845F", "Glade Green"], + ["622F30", "Buccaneer"], + ["623F2D", "Quincy"], + ["624E9A", "Butterfly Bush"], + ["625119", "West Coast"], + ["626649", "Finch"], + ["639A8F", "Patina"], + ["63B76C", "Fern"], + ["6456B7", "Blue Violet"], + ["646077", "Dolphin"], + ["646463", "Storm Dust"], + ["646A54", "Siam"], + ["646E75", "Nevada"], + ["6495ED", "Cornflower Blue"], + ["64CCDB", "Viking"], + ["65000B", "Rosewood"], + ["651A14", "Cherrywood"], + ["652DC1", "Purple Heart"], + ["657220", "Fern Frond"], + ["65745D", "Willow Grove"], + ["65869F", "Hoki"], + ["660045", "Pompadour"], + ["660099", "Purple"], + ["66023C", "Tyrian Purple"], + ["661010", "Dark Tan"], + ["66B58F", "Silver Tree"], + ["66FF00", "Bright Green"], + ["66FF66", "Screamin Green"], + ["67032D", "Black Rose"], + ["675FA6", "Scampi"], + ["676662", "Ironside Gray"], + ["678975", "Viridian Green"], + ["67A712", "Christi"], + ["683600", "Nutmeg Wood Finish"], + ["685558", "Zambezi"], + ["685E6E", "Salt Box"], + ["692545", "Tawny Port"], + ["692D54", "Finn"], + ["695F62", "Scorpion"], + ["697E9A", "Lynch"], + ["6A442E", "Spice"], + ["6A5D1B", "Himalaya"], + ["6A6051", "Soya Bean"], + ["6B2A14", "Hairy Heath"], + ["6B3FA0", "Royal Purple"], + ["6B4E31", "Shingle Fawn"], + ["6B5755", "Dorado"], + ["6B8BA2", "Bermuda Gray"], + ["6B8E23", "Olive Drab"], + ["6C3082", "Eminence"], + ["6CDAE7", "Turquoise Blue"], + ["6D0101", "Lonestar"], + ["6D5E54", "Pine Cone"], + ["6D6C6C", "Dove Gray"], + ["6D9292", "Juniper"], + ["6D92A1", "Gothic"], + ["6E0902", "Red Oxide"], + ["6E1D14", "Moccaccino"], + ["6E4826", "Pickled Bean"], + ["6E4B26", "Dallas"], + ["6E6D57", "Kokoda"], + ["6E7783", "Pale Sky"], + ["6F440C", "Cafe Royale"], + ["6F6A61", "Flint"], + ["6F8E63", "Highland"], + ["6F9D02", "Limeade"], + ["6FD0C5", "Downy"], + ["701C1C", "Persian Plum"], + ["704214", "Sepia"], + ["704A07", "Antique Bronze"], + ["704F50", "Ferra"], + ["706555", "Coffee"], + ["708090", "Slate Gray"], + ["711A00", "Cedar Wood Finish"], + ["71291D", "Metallic Copper"], + ["714693", "Affair"], + ["714AB2", "Studio"], + ["715D47", "Tobacco Brown"], + ["716338", "Yellow Metal"], + ["716B56", "Peat"], + ["716E10", "Olivetone"], + ["717486", "Storm Gray"], + ["718080", "Sirocco"], + ["71D9E2", "Aquamarine Blue"], + ["72010F", "Venetian Red"], + ["724A2F", "Old Copper"], + ["726D4E", "Go Ben"], + ["727B89", "Raven"], + ["731E8F", "Seance"], + ["734A12", "Raw Umber"], + ["736C9F", "Kimberly"], + ["736D58", "Crocodile"], + ["737829", "Crete"], + ["738678", "Xanadu"], + ["74640D", "Spicy Mustard"], + ["747D63", "Limed Ash"], + ["747D83", "Rolling Stone"], + ["748881", "Blue Smoke"], + ["749378", "Laurel"], + ["74C365", "Mantis"], + ["755A57", "Russett"], + ["7563A8", "Deluge"], + ["76395D", "Cosmic"], + ["7666C6", "Blue Marguerite"], + ["76BD17", "Lima"], + ["76D7EA", "Sky Blue"], + ["770F05", "Dark Burgundy"], + ["771F1F", "Crown of Thorns"], + ["773F1A", "Walnut"], + ["776F61", "Pablo"], + ["778120", "Pacifika"], + ["779E86", "Oxley"], + ["77DD77", "Pastel Green"], + ["780109", "Japanese Maple"], + ["782D19", "Mocha"], + ["782F16", "Peanut"], + ["78866B", "Camouflage Green"], + ["788A25", "Wasabi"], + ["788BBA", "Ship Cove"], + ["78A39C", "Sea Nymph"], + ["795D4C", "Roman Coffee"], + ["796878", "Old Lavender"], + ["796989", "Rum"], + ["796A78", "Fedora"], + ["796D62", "Sandstone"], + ["79DEEC", "Spray"], + ["7A013A", "Siren"], + ["7A58C1", "Fuchsia Blue"], + ["7A7A7A", "Boulder"], + ["7A89B8", "Wild Blue Yonder"], + ["7AC488", "De York"], + ["7B3801", "Red Beech"], + ["7B3F00", "Cinnamon"], + ["7B6608", "Yukon Gold"], + ["7B7874", "Tapa"], + ["7B7C94", "Waterloo "], + ["7B8265", "Flax Smoke"], + ["7B9F80", "Amulet"], + ["7BA05B", "Asparagus"], + ["7C1C05", "Kenyan Copper"], + ["7C7631", "Pesto"], + ["7C778A", "Topaz"], + ["7C7B7A", "Concord"], + ["7C7B82", "Jumbo"], + ["7C881A", "Trendy Green"], + ["7CA1A6", "Gumbo"], + ["7CB0A1", "Acapulco"], + ["7CB7BB", "Neptune"], + ["7D2C14", "Pueblo"], + ["7DA98D", "Bay Leaf"], + ["7DC8F7", "Malibu"], + ["7DD8C6", "Bermuda"], + ["7E3A15", "Copper Canyon"], + ["7F1734", "Claret"], + ["7F3A02", "Peru Tan"], + ["7F626D", "Falcon"], + ["7F7589", "Mobster"], + ["7F76D3", "Moody Blue"], + ["7FFF00", "Chartreuse"], + ["7FFFD4", "Aquamarine"], + ["800000", "Maroon"], + ["800B47", "Rose Bud Cherry"], + ["801818", "Falu Red"], + ["80341F", "Red Robin"], + ["803790", "Vivid Violet"], + ["80461B", "Russet"], + ["807E79", "Friar Gray"], + ["808000", "Olive"], + ["808080", "Gray"], + ["80B3AE", "Gulf Stream"], + ["80B3C4", "Glacier"], + ["80CCEA", "Seagull"], + ["81422C", "Nutmeg"], + ["816E71", "Spicy Pink"], + ["817377", "Empress"], + ["819885", "Spanish Green"], + ["826F65", "Sand Dune"], + ["828685", "Gunsmoke"], + ["828F72", "Battleship Gray"], + ["831923", "Merlot"], + ["837050", "Shadow"], + ["83AA5D", "Chelsea Cucumber"], + ["83D0C6", "Monte Carlo"], + ["843179", "Plum"], + ["84A0A0", "Granny Smith"], + ["8581D9", "Chetwode Blue"], + ["858470", "Bandicoot"], + ["859FAF", "Bali Hai"], + ["85C4CC", "Half Baked"], + ["860111", "Red Devil"], + ["863C3C", "Lotus"], + ["86483C", "Ironstone"], + ["864D1E", "Bull Shot"], + ["86560A", "Rusty Nail"], + ["868974", "Bitter"], + ["86949F", "Regent Gray"], + ["871550", "Disco"], + ["87756E", "Americano"], + ["877C7B", "Hurricane"], + ["878D91", "Oslo Gray"], + ["87AB39", "Sushi"], + ["885342", "Spicy Mix"], + ["886221", "Kumera"], + ["888387", "Suva Gray"], + ["888D65", "Avocado"], + ["893456", "Camelot"], + ["893843", "Solid Pink"], + ["894367", "Cannon Pink"], + ["897D6D", "Makara"], + ["8A3324", "Burnt Umber"], + ["8A73D6", "True V"], + ["8A8360", "Clay Creek"], + ["8A8389", "Monsoon"], + ["8A8F8A", "Stack"], + ["8AB9F1", "Jordy Blue"], + ["8B00FF", "Electric Violet"], + ["8B0723", "Monarch"], + ["8B6B0B", "Corn Harvest"], + ["8B8470", "Olive Haze"], + ["8B847E", "Schooner"], + ["8B8680", "Natural Gray"], + ["8B9C90", "Mantle"], + ["8B9FEE", "Portage"], + ["8BA690", "Envy"], + ["8BA9A5", "Cascade"], + ["8BE6D8", "Riptide"], + ["8C055E", "Cardinal Pink"], + ["8C472F", "Mule Fawn"], + ["8C5738", "Potters Clay"], + ["8C6495", "Trendy Pink"], + ["8D0226", "Paprika"], + ["8D3D38", "Sanguine Brown"], + ["8D3F3F", "Tosca"], + ["8D7662", "Cement"], + ["8D8974", "Granite Green"], + ["8D90A1", "Manatee"], + ["8DA8CC", "Polo Blue"], + ["8E0000", "Red Berry"], + ["8E4D1E", "Rope"], + ["8E6F70", "Opium"], + ["8E775E", "Domino"], + ["8E8190", "Mamba"], + ["8EABC1", "Nepal"], + ["8F021C", "Pohutukawa"], + ["8F3E33", "El Salva"], + ["8F4B0E", "Korma"], + ["8F8176", "Squirrel"], + ["8FD6B4", "Vista Blue"], + ["900020", "Burgundy"], + ["901E1E", "Old Brick"], + ["907874", "Hemp"], + ["907B71", "Almond Frost"], + ["908D39", "Sycamore"], + ["92000A", "Sangria"], + ["924321", "Cumin"], + ["926F5B", "Beaver"], + ["928573", "Stonewall"], + ["928590", "Venus"], + ["9370DB", "Medium Purple"], + ["93CCEA", "Cornflower"], + ["93DFB8", "Algae Green"], + ["944747", "Copper Rust"], + ["948771", "Arrowtown"], + ["950015", "Scarlett"], + ["956387", "Strikemaster"], + ["959396", "Mountain Mist"], + ["960018", "Carmine"], + ["964B00", "Brown"], + ["967059", "Leather"], + ["9678B6", "Purple Mountain's Majesty"], + ["967BB6", "Lavender Purple"], + ["96A8A1", "Pewter"], + ["96BBAB", "Summer Green"], + ["97605D", "Au Chico"], + ["9771B5", "Wisteria"], + ["97CD2D", "Atlantis"], + ["983D61", "Vin Rouge"], + ["9874D3", "Lilac Bush"], + ["98777B", "Bazaar"], + ["98811B", "Hacienda"], + ["988D77", "Pale Oyster"], + ["98FF98", "Mint Green"], + ["990066", "Fresh Eggplant"], + ["991199", "Violet Eggplant"], + ["991613", "Tamarillo"], + ["991B07", "Totem Pole"], + ["996666", "Copper Rose"], + ["9966CC", "Amethyst"], + ["997A8D", "Mountbatten Pink"], + ["9999CC", "Blue Bell"], + ["9A3820", "Prairie Sand"], + ["9A6E61", "Toast"], + ["9A9577", "Gurkha"], + ["9AB973", "Olivine"], + ["9AC2B8", "Shadow Green"], + ["9B4703", "Oregon"], + ["9B9E8F", "Lemon Grass"], + ["9C3336", "Stiletto"], + ["9D5616", "Hawaiian Tan"], + ["9DACB7", "Gull Gray"], + ["9DC209", "Pistachio"], + ["9DE093", "Granny Smith Apple"], + ["9DE5FF", "Anakiwa"], + ["9E5302", "Chelsea Gem"], + ["9E5B40", "Sepia Skin"], + ["9EA587", "Sage"], + ["9EA91F", "Citron"], + ["9EB1CD", "Rock Blue"], + ["9EDEE0", "Morning Glory"], + ["9F381D", "Cognac"], + ["9F821C", "Reef Gold"], + ["9F9F9C", "Star Dust"], + ["9FA0B1", "Santas Gray"], + ["9FD7D3", "Sinbad"], + ["9FDD8C", "Feijoa"], + ["A02712", "Tabasco"], + ["A1750D", "Buttered Rum"], + ["A1ADB5", "Hit Gray"], + ["A1C50A", "Citrus"], + ["A1DAD7", "Aqua Island"], + ["A1E9DE", "Water Leaf"], + ["A2006D", "Flirt"], + ["A23B6C", "Rouge"], + ["A26645", "Cape Palliser"], + ["A2AAB3", "Gray Chateau"], + ["A2AEAB", "Edward"], + ["A3807B", "Pharlap"], + ["A397B4", "Amethyst Smoke"], + ["A3E3ED", "Blizzard Blue"], + ["A4A49D", "Delta"], + ["A4A6D3", "Wistful"], + ["A4AF6E", "Green Smoke"], + ["A50B5E", "Jazzberry Jam"], + ["A59B91", "Zorba"], + ["A5CB0C", "Bahia"], + ["A62F20", "Roof Terracotta"], + ["A65529", "Paarl"], + ["A68B5B", "Barley Corn"], + ["A69279", "Donkey Brown"], + ["A6A29A", "Dawn"], + ["A72525", "Mexican Red"], + ["A7882C", "Luxor Gold"], + ["A85307", "Rich Gold"], + ["A86515", "Reno Sand"], + ["A86B6B", "Coral Tree"], + ["A8989B", "Dusty Gray"], + ["A899E6", "Dull Lavender"], + ["A8A589", "Tallow"], + ["A8AE9C", "Bud"], + ["A8AF8E", "Locust"], + ["A8BD9F", "Norway"], + ["A8E3BD", "Chinook"], + ["A9A491", "Gray Olive"], + ["A9ACB6", "Aluminium"], + ["A9B2C3", "Cadet Blue"], + ["A9B497", "Schist"], + ["A9BDBF", "Tower Gray"], + ["A9BEF2", "Perano"], + ["A9C6C2", "Opal"], + ["AA375A", "Night Shadz"], + ["AA4203", "Fire"], + ["AA8B5B", "Muesli"], + ["AA8D6F", "Sandal"], + ["AAA5A9", "Shady Lady"], + ["AAA9CD", "Logan"], + ["AAABB7", "Spun Pearl"], + ["AAD6E6", "Regent St Blue"], + ["AAF0D1", "Magic Mint"], + ["AB0563", "Lipstick"], + ["AB3472", "Royal Heath"], + ["AB917A", "Sandrift"], + ["ABA0D9", "Cold Purple"], + ["ABA196", "Bronco"], + ["AC8A56", "Limed Oak"], + ["AC91CE", "East Side"], + ["AC9E22", "Lemon Ginger"], + ["ACA494", "Napa"], + ["ACA586", "Hillary"], + ["ACA59F", "Cloudy"], + ["ACACAC", "Silver Chalice"], + ["ACB78E", "Swamp Green"], + ["ACCBB1", "Spring Rain"], + ["ACDD4D", "Conifer"], + ["ACE1AF", "Celadon"], + ["AD781B", "Mandalay"], + ["ADBED1", "Casper"], + ["ADDFAD", "Moss Green"], + ["ADE6C4", "Padua"], + ["ADFF2F", "Green Yellow"], + ["AE4560", "Hippie Pink"], + ["AE6020", "Desert"], + ["AE809E", "Bouquet"], + ["AF4035", "Medium Carmine"], + ["AF4D43", "Apple Blossom"], + ["AF593E", "Brown Rust"], + ["AF8751", "Driftwood"], + ["AF8F2C", "Alpine"], + ["AF9F1C", "Lucky"], + ["AFA09E", "Martini"], + ["AFB1B8", "Bombay"], + ["AFBDD9", "Pigeon Post"], + ["B04C6A", "Cadillac"], + ["B05D54", "Matrix"], + ["B05E81", "Tapestry"], + ["B06608", "Mai Tai"], + ["B09A95", "Del Rio"], + ["B0E0E6", "Powder Blue"], + ["B0E313", "Inch Worm"], + ["B10000", "Bright Red"], + ["B14A0B", "Vesuvius"], + ["B1610B", "Pumpkin Skin"], + ["B16D52", "Santa Fe"], + ["B19461", "Teak"], + ["B1E2C1", "Fringy Flower"], + ["B1F4E7", "Ice Cold"], + ["B20931", "Shiraz"], + ["B2A1EA", "Biloba Flower"], + ["B32D29", "Tall Poppy"], + ["B35213", "Fiery Orange"], + ["B38007", "Hot Toddy"], + ["B3AF95", "Taupe Gray"], + ["B3C110", "La Rioja"], + ["B43332", "Well Read"], + ["B44668", "Blush"], + ["B4CFD3", "Jungle Mist"], + ["B57281", "Turkish Rose"], + ["B57EDC", "Lavender"], + ["B5A27F", "Mongoose"], + ["B5B35C", "Olive Green"], + ["B5D2CE", "Jet Stream"], + ["B5ECDF", "Cruise"], + ["B6316C", "Hibiscus"], + ["B69D98", "Thatch"], + ["B6B095", "Heathered Gray"], + ["B6BAA4", "Eagle"], + ["B6D1EA", "Spindle"], + ["B6D3BF", "Gum Leaf"], + ["B7410E", "Rust"], + ["B78E5C", "Muddy Waters"], + ["B7A214", "Sahara"], + ["B7A458", "Husk"], + ["B7B1B1", "Nobel"], + ["B7C3D0", "Heather"], + ["B7F0BE", "Madang"], + ["B81104", "Milano Red"], + ["B87333", "Copper"], + ["B8B56A", "Gimblet"], + ["B8C1B1", "Green Spring"], + ["B8C25D", "Celery"], + ["B8E0F9", "Sail"], + ["B94E48", "Chestnut"], + ["B95140", "Crail"], + ["B98D28", "Marigold"], + ["B9C46A", "Wild Willow"], + ["B9C8AC", "Rainee"], + ["BA0101", "Guardsman Red"], + ["BA450C", "Rock Spray"], + ["BA6F1E", "Bourbon"], + ["BA7F03", "Pirate Gold"], + ["BAB1A2", "Nomad"], + ["BAC7C9", "Submarine"], + ["BAEEF9", "Charlotte"], + ["BB3385", "Medium Red Violet"], + ["BB8983", "Brandy Rose"], + ["BBD009", "Rio Grande"], + ["BBD7C1", "Surf"], + ["BCC9C2", "Powder Ash"], + ["BD5E2E", "Tuscany"], + ["BD978E", "Quicksand"], + ["BDB1A8", "Silk"], + ["BDB2A1", "Malta"], + ["BDB3C7", "Chatelle"], + ["BDBBD7", "Lavender Gray"], + ["BDBDC6", "French Gray"], + ["BDC8B3", "Clay Ash"], + ["BDC9CE", "Loblolly"], + ["BDEDFD", "French Pass"], + ["BEA6C3", "London Hue"], + ["BEB5B7", "Pink Swan"], + ["BEDE0D", "Fuego"], + ["BF5500", "Rose of Sharon"], + ["BFB8B0", "Tide"], + ["BFBED8", "Blue Haze"], + ["BFC1C2", "Silver Sand"], + ["BFC921", "Key Lime Pie"], + ["BFDBE2", "Ziggurat"], + ["BFFF00", "Lime"], + ["C02B18", "Thunderbird"], + ["C04737", "Mojo"], + ["C08081", "Old Rose"], + ["C0C0C0", "Silver"], + ["C0D3B9", "Pale Leaf"], + ["C0D8B6", "Pixie Green"], + ["C1440E", "Tia Maria"], + ["C154C1", "Fuchsia Pink"], + ["C1A004", "Buddha Gold"], + ["C1B7A4", "Bison Hide"], + ["C1BAB0", "Tea"], + ["C1BECD", "Gray Suit"], + ["C1D7B0", "Sprout"], + ["C1F07C", "Sulu"], + ["C26B03", "Indochine"], + ["C2955D", "Twine"], + ["C2BDB6", "Cotton Seed"], + ["C2CAC4", "Pumice"], + ["C2E8E5", "Jagged Ice"], + ["C32148", "Maroon Flush"], + ["C3B091", "Indian Khaki"], + ["C3BFC1", "Pale Slate"], + ["C3C3BD", "Gray Nickel"], + ["C3CDE6", "Periwinkle Gray"], + ["C3D1D1", "Tiara"], + ["C3DDF9", "Tropical Blue"], + ["C41E3A", "Cardinal"], + ["C45655", "Fuzzy Wuzzy Brown"], + ["C45719", "Orange Roughy"], + ["C4C4BC", "Mist Gray"], + ["C4D0B0", "Coriander"], + ["C4F4EB", "Mint Tulip"], + ["C54B8C", "Mulberry"], + ["C59922", "Nugget"], + ["C5994B", "Tussock"], + ["C5DBCA", "Sea Mist"], + ["C5E17A", "Yellow Green"], + ["C62D42", "Brick Red"], + ["C6726B", "Contessa"], + ["C69191", "Oriental Pink"], + ["C6A84B", "Roti"], + ["C6C3B5", "Ash"], + ["C6C8BD", "Kangaroo"], + ["C6E610", "Las Palmas"], + ["C7031E", "Monza"], + ["C71585", "Red Violet"], + ["C7BCA2", "Coral Reef"], + ["C7C1FF", "Melrose"], + ["C7C4BF", "Cloud"], + ["C7C9D5", "Ghost"], + ["C7CD90", "Pine Glade"], + ["C7DDE5", "Botticelli"], + ["C88A65", "Antique Brass"], + ["C8A2C8", "Lilac"], + ["C8A528", "Hokey Pokey"], + ["C8AABF", "Lily"], + ["C8B568", "Laser"], + ["C8E3D7", "Edgewater"], + ["C96323", "Piper"], + ["C99415", "Pizza"], + ["C9A0DC", "Light Wisteria"], + ["C9B29B", "Rodeo Dust"], + ["C9B35B", "Sundance"], + ["C9B93B", "Earls Green"], + ["C9C0BB", "Silver Rust"], + ["C9D9D2", "Conch"], + ["C9FFA2", "Reef"], + ["C9FFE5", "Aero Blue"], + ["CA3435", "Flush Mahogany"], + ["CABB48", "Turmeric"], + ["CADCD4", "Paris White"], + ["CAE00D", "Bitter Lemon"], + ["CAE6DA", "Skeptic"], + ["CB8FA9", "Viola"], + ["CBCAB6", "Foggy Gray"], + ["CBD3B0", "Green Mist"], + ["CBDBD6", "Nebula"], + ["CC3333", "Persian Red"], + ["CC5500", "Burnt Orange"], + ["CC7722", "Ochre"], + ["CC8899", "Puce"], + ["CCCAA8", "Thistle Green"], + ["CCCCFF", "Periwinkle"], + ["CCFF00", "Electric Lime"], + ["CD5700", "Tenn"], + ["CD5C5C", "Chestnut Rose"], + ["CD8429", "Brandy Punch"], + ["CDF4FF", "Onahau"], + ["CEB98F", "Sorrell Brown"], + ["CEBABA", "Cold Turkey"], + ["CEC291", "Yuma"], + ["CEC7A7", "Chino"], + ["CFA39D", "Eunry"], + ["CFB53B", "Old Gold"], + ["CFDCCF", "Tasman"], + ["CFE5D2", "Surf Crest"], + ["CFF9F3", "Humming Bird"], + ["CFFAF4", "Scandal"], + ["D05F04", "Red Stage"], + ["D06DA1", "Hopbush"], + ["D07D12", "Meteor"], + ["D0BEF8", "Perfume"], + ["D0C0E5", "Prelude"], + ["D0F0C0", "Tea Green"], + ["D18F1B", "Geebung"], + ["D1BEA8", "Vanilla"], + ["D1C6B4", "Soft Amber"], + ["D1D2CA", "Celeste"], + ["D1D2DD", "Mischka"], + ["D1E231", "Pear"], + ["D2691E", "Hot Cinnamon"], + ["D27D46", "Raw Sienna"], + ["D29EAA", "Careys Pink"], + ["D2B48C", "Tan"], + ["D2DA97", "Deco"], + ["D2F6DE", "Blue Romance"], + ["D2F8B0", "Gossip"], + ["D3CBBA", "Sisal"], + ["D3CDC5", "Swirl"], + ["D47494", "Charm"], + ["D4B6AF", "Clam Shell"], + ["D4BF8D", "Straw"], + ["D4C4A8", "Akaroa"], + ["D4CD16", "Bird Flower"], + ["D4D7D9", "Iron"], + ["D4DFE2", "Geyser"], + ["D4E2FC", "Hawkes Blue"], + ["D54600", "Grenadier"], + ["D591A4", "Can Can"], + ["D59A6F", "Whiskey"], + ["D5D195", "Winter Hazel"], + ["D5F6E3", "Granny Apple"], + ["D69188", "My Pink"], + ["D6C562", "Tacha"], + ["D6CEF6", "Moon Raker"], + ["D6D6D1", "Quill Gray"], + ["D6FFDB", "Snowy Mint"], + ["D7837F", "New York Pink"], + ["D7C498", "Pavlova"], + ["D7D0FF", "Fog"], + ["D84437", "Valencia"], + ["D87C63", "Japonica"], + ["D8BFD8", "Thistle"], + ["D8C2D5", "Maverick"], + ["D8FCFA", "Foam"], + ["D94972", "Cabaret"], + ["D99376", "Burning Sand"], + ["D9B99B", "Cameo"], + ["D9D6CF", "Timberwolf"], + ["D9DCC1", "Tana"], + ["D9E4F5", "Link Water"], + ["D9F7FF", "Mabel"], + ["DA3287", "Cerise"], + ["DA5B38", "Flame Pea"], + ["DA6304", "Bamboo"], + ["DA6A41", "Red Damask"], + ["DA70D6", "Orchid"], + ["DA8A67", "Copperfield"], + ["DAA520", "Golden Grass"], + ["DAECD6", "Zanah"], + ["DAF4F0", "Iceberg"], + ["DAFAFF", "Oyster Bay"], + ["DB5079", "Cranberry"], + ["DB9690", "Petite Orchid"], + ["DB995E", "Di Serria"], + ["DBDBDB", "Alto"], + ["DBFFF8", "Frosted Mint"], + ["DC143C", "Crimson"], + ["DC4333", "Punch"], + ["DCB20C", "Galliano"], + ["DCB4BC", "Blossom"], + ["DCD747", "Wattle"], + ["DCD9D2", "Westar"], + ["DCDDCC", "Moon Mist"], + ["DCEDB4", "Caper"], + ["DCF0EA", "Swans Down"], + ["DDD6D5", "Swiss Coffee"], + ["DDF9F1", "White Ice"], + ["DE3163", "Cerise Red"], + ["DE6360", "Roman"], + ["DEA681", "Tumbleweed"], + ["DEBA13", "Gold Tips"], + ["DEC196", "Brandy"], + ["DECBC6", "Wafer"], + ["DED4A4", "Sapling"], + ["DED717", "Barberry"], + ["DEE5C0", "Beryl Green"], + ["DEF5FF", "Pattens Blue"], + ["DF73FF", "Heliotrope"], + ["DFBE6F", "Apache"], + ["DFCD6F", "Chenin"], + ["DFCFDB", "Lola"], + ["DFECDA", "Willow Brook"], + ["DFFF00", "Chartreuse Yellow"], + ["E0B0FF", "Mauve"], + ["E0B646", "Anzac"], + ["E0B974", "Harvest Gold"], + ["E0C095", "Calico"], + ["E0FFFF", "Baby Blue"], + ["E16865", "Sunglo"], + ["E1BC64", "Equator"], + ["E1C0C8", "Pink Flare"], + ["E1E6D6", "Periglacial Blue"], + ["E1EAD4", "Kidnapper"], + ["E1F6E8", "Tara"], + ["E25465", "Mandy"], + ["E2725B", "Terracotta"], + ["E28913", "Golden Bell"], + ["E292C0", "Shocking"], + ["E29418", "Dixie"], + ["E29CD2", "Light Orchid"], + ["E2D8ED", "Snuff"], + ["E2EBED", "Mystic"], + ["E2F3EC", "Apple Green"], + ["E30B5C", "Razzmatazz"], + ["E32636", "Alizarin Crimson"], + ["E34234", "Cinnabar"], + ["E3BEBE", "Cavern Pink"], + ["E3F5E1", "Peppermint"], + ["E3F988", "Mindaro"], + ["E47698", "Deep Blush"], + ["E49B0F", "Gamboge"], + ["E4C2D5", "Melanie"], + ["E4CFDE", "Twilight"], + ["E4D1C0", "Bone"], + ["E4D422", "Sunflower"], + ["E4D5B7", "Grain Brown"], + ["E4D69B", "Zombie"], + ["E4F6E7", "Frostee"], + ["E4FFD1", "Snow Flurry"], + ["E52B50", "Amaranth"], + ["E5841B", "Zest"], + ["E5CCC9", "Dust Storm"], + ["E5D7BD", "Stark White"], + ["E5D8AF", "Hampton"], + ["E5E0E1", "Bon Jour"], + ["E5E5E5", "Mercury"], + ["E5F9F6", "Polar"], + ["E64E03", "Trinidad"], + ["E6BE8A", "Gold Sand"], + ["E6BEA5", "Cashmere"], + ["E6D7B9", "Double Spanish White"], + ["E6E4D4", "Satin Linen"], + ["E6F2EA", "Harp"], + ["E6F8F3", "Off Green"], + ["E6FFE9", "Hint of Green"], + ["E6FFFF", "Tranquil"], + ["E77200", "Mango Tango"], + ["E7730A", "Christine"], + ["E79F8C", "Tonys Pink"], + ["E79FC4", "Kobi"], + ["E7BCB4", "Rose Fog"], + ["E7BF05", "Corn"], + ["E7CD8C", "Putty"], + ["E7ECE6", "Gray Nurse"], + ["E7F8FF", "Lily White"], + ["E7FEFF", "Bubbles"], + ["E89928", "Fire Bush"], + ["E8B9B3", "Shilo"], + ["E8E0D5", "Pearl Bush"], + ["E8EBE0", "Green White"], + ["E8F1D4", "Chrome White"], + ["E8F2EB", "Gin"], + ["E8F5F2", "Aqua Squeeze"], + ["E96E00", "Clementine"], + ["E97451", "Burnt Sienna"], + ["E97C07", "Tahiti Gold"], + ["E9CECD", "Oyster Pink"], + ["E9D75A", "Confetti"], + ["E9E3E3", "Ebb"], + ["E9F8ED", "Ottoman"], + ["E9FFFD", "Clear Day"], + ["EA88A8", "Carissma"], + ["EAAE69", "Porsche"], + ["EAB33B", "Tulip Tree"], + ["EAC674", "Rob Roy"], + ["EADAB8", "Raffia"], + ["EAE8D4", "White Rock"], + ["EAF6EE", "Panache"], + ["EAF6FF", "Solitude"], + ["EAF9F5", "Aqua Spring"], + ["EAFFFE", "Dew"], + ["EB9373", "Apricot"], + ["EBC2AF", "Zinnwaldite"], + ["ECA927", "Fuel Yellow"], + ["ECC54E", "Ronchi"], + ["ECC7EE", "French Lilac"], + ["ECCDB9", "Just Right"], + ["ECE090", "Wild Rice"], + ["ECEBBD", "Fall Green"], + ["ECEBCE", "Aths Special"], + ["ECF245", "Starship"], + ["ED0A3F", "Red Ribbon"], + ["ED7A1C", "Tango"], + ["ED9121", "Carrot Orange"], + ["ED989E", "Sea Pink"], + ["EDB381", "Tacao"], + ["EDC9AF", "Desert Sand"], + ["EDCDAB", "Pancho"], + ["EDDCB1", "Chamois"], + ["EDEA99", "Primrose"], + ["EDF5DD", "Frost"], + ["EDF5F5", "Aqua Haze"], + ["EDF6FF", "Zumthor"], + ["EDF9F1", "Narvik"], + ["EDFC84", "Honeysuckle"], + ["EE82EE", "Lavender Magenta"], + ["EEC1BE", "Beauty Bush"], + ["EED794", "Chalky"], + ["EED9C4", "Almond"], + ["EEDC82", "Flax"], + ["EEDEDA", "Bizarre"], + ["EEE3AD", "Double Colonial White"], + ["EEEEE8", "Cararra"], + ["EEEF78", "Manz"], + ["EEF0C8", "Tahuna Sands"], + ["EEF0F3", "Athens Gray"], + ["EEF3C3", "Tusk"], + ["EEF4DE", "Loafer"], + ["EEF6F7", "Catskill White"], + ["EEFDFF", "Twilight Blue"], + ["EEFF9A", "Jonquil"], + ["EEFFE2", "Rice Flower"], + ["EF863F", "Jaffa"], + ["EFEFEF", "Gallery"], + ["EFF2F3", "Porcelain"], + ["F091A9", "Mauvelous"], + ["F0D52D", "Golden Dream"], + ["F0DB7D", "Golden Sand"], + ["F0DC82", "Buff"], + ["F0E2EC", "Prim"], + ["F0E68C", "Khaki"], + ["F0EEFD", "Selago"], + ["F0EEFF", "Titan White"], + ["F0F8FF", "Alice Blue"], + ["F0FCEA", "Feta"], + ["F18200", "Gold Drop"], + ["F19BAB", "Wewak"], + ["F1E788", "Sahara Sand"], + ["F1E9D2", "Parchment"], + ["F1E9FF", "Blue Chalk"], + ["F1EEC1", "Mint Julep"], + ["F1F1F1", "Seashell"], + ["F1F7F2", "Saltpan"], + ["F1FFAD", "Tidal"], + ["F1FFC8", "Chiffon"], + ["F2552A", "Flamingo"], + ["F28500", "Tangerine"], + ["F2C3B2", "Mandys Pink"], + ["F2F2F2", "Concrete"], + ["F2FAFA", "Black Squeeze"], + ["F34723", "Pomegranate"], + ["F3AD16", "Buttercup"], + ["F3D69D", "New Orleans"], + ["F3D9DF", "Vanilla Ice"], + ["F3E7BB", "Sidecar"], + ["F3E9E5", "Dawn Pink"], + ["F3EDCF", "Wheatfield"], + ["F3FB62", "Canary"], + ["F3FBD4", "Orinoco"], + ["F3FFD8", "Carla"], + ["F400A1", "Hollywood Cerise"], + ["F4A460", "Sandy brown"], + ["F4C430", "Saffron"], + ["F4D81C", "Ripe Lemon"], + ["F4EBD3", "Janna"], + ["F4F2EE", "Pampas"], + ["F4F4F4", "Wild Sand"], + ["F4F8FF", "Zircon"], + ["F57584", "Froly"], + ["F5C85C", "Cream Can"], + ["F5C999", "Manhattan"], + ["F5D5A0", "Maize"], + ["F5DEB3", "Wheat"], + ["F5E7A2", "Sandwisp"], + ["F5E7E2", "Pot Pourri"], + ["F5E9D3", "Albescent White"], + ["F5EDEF", "Soft Peach"], + ["F5F3E5", "Ecru White"], + ["F5F5DC", "Beige"], + ["F5FB3D", "Golden Fizz"], + ["F5FFBE", "Australian Mint"], + ["F64A8A", "French Rose"], + ["F653A6", "Brilliant Rose"], + ["F6A4C9", "Illusion"], + ["F6F0E6", "Merino"], + ["F6F7F7", "Black Haze"], + ["F6FFDC", "Spring Sun"], + ["F7468A", "Violet Red"], + ["F77703", "Chilean Fire"], + ["F77FBE", "Persian Pink"], + ["F7B668", "Rajah"], + ["F7C8DA", "Azalea"], + ["F7DBE6", "We Peep"], + ["F7F2E1", "Quarter Spanish White"], + ["F7F5FA", "Whisper"], + ["F7FAF7", "Snow Drift"], + ["F8B853", "Casablanca"], + ["F8C3DF", "Chantilly"], + ["F8D9E9", "Cherub"], + ["F8DB9D", "Marzipan"], + ["F8DD5C", "Energy Yellow"], + ["F8E4BF", "Givry"], + ["F8F0E8", "White Linen"], + ["F8F4FF", "Magnolia"], + ["F8F6F1", "Spring Wood"], + ["F8F7DC", "Coconut Cream"], + ["F8F7FC", "White Lilac"], + ["F8F8F7", "Desert Storm"], + ["F8F99C", "Texas"], + ["F8FACD", "Corn Field"], + ["F8FDD3", "Mimosa"], + ["F95A61", "Carnation"], + ["F9BF58", "Saffron Mango"], + ["F9E0ED", "Carousel Pink"], + ["F9E4BC", "Dairy Cream"], + ["F9E663", "Portica"], + ["F9EAF3", "Amour"], + ["F9F8E4", "Rum Swizzle"], + ["F9FF8B", "Dolly"], + ["F9FFF6", "Sugar Cane"], + ["FA7814", "Ecstasy"], + ["FA9D5A", "Tan Hide"], + ["FAD3A2", "Corvette"], + ["FADFAD", "Peach Yellow"], + ["FAE600", "Turbo"], + ["FAEAB9", "Astra"], + ["FAECCC", "Champagne"], + ["FAF0E6", "Linen"], + ["FAF3F0", "Fantasy"], + ["FAF7D6", "Citrine White"], + ["FAFAFA", "Alabaster"], + ["FAFDE4", "Hint of Yellow"], + ["FAFFA4", "Milan"], + ["FB607F", "Brink Pink"], + ["FB8989", "Geraldine"], + ["FBA0E3", "Lavender Rose"], + ["FBA129", "Sea Buckthorn"], + ["FBAC13", "Sun"], + ["FBAED2", "Lavender Pink"], + ["FBB2A3", "Rose Bud"], + ["FBBEDA", "Cupid"], + ["FBCCE7", "Classic Rose"], + ["FBCEB1", "Apricot Peach"], + ["FBE7B2", "Banana Mania"], + ["FBE870", "Marigold Yellow"], + ["FBE96C", "Festival"], + ["FBEA8C", "Sweet Corn"], + ["FBEC5D", "Candy Corn"], + ["FBF9F9", "Hint of Red"], + ["FBFFBA", "Shalimar"], + ["FC0FC0", "Shocking Pink"], + ["FC80A5", "Tickle Me Pink"], + ["FC9C1D", "Tree Poppy"], + ["FCC01E", "Lightning Yellow"], + ["FCD667", "Goldenrod"], + ["FCD917", "Candlelight"], + ["FCDA98", "Cherokee"], + ["FCF4D0", "Double Pearl Lusta"], + ["FCF4DC", "Pearl Lusta"], + ["FCF8F7", "Vista White"], + ["FCFBF3", "Bianca"], + ["FCFEDA", "Moon Glow"], + ["FCFFE7", "China Ivory"], + ["FCFFF9", "Ceramic"], + ["FD0E35", "Torch Red"], + ["FD5B78", "Wild Watermelon"], + ["FD7B33", "Crusta"], + ["FD7C07", "Sorbus"], + ["FD9FA2", "Sweet Pink"], + ["FDD5B1", "Light Apricot"], + ["FDD7E4", "Pig Pink"], + ["FDE1DC", "Cinderella"], + ["FDE295", "Golden Glow"], + ["FDE910", "Lemon"], + ["FDF5E6", "Old Lace"], + ["FDF6D3", "Half Colonial White"], + ["FDF7AD", "Drover"], + ["FDFEB8", "Pale Prim"], + ["FDFFD5", "Cumulus"], + ["FE28A2", "Persian Rose"], + ["FE4C40", "Sunset Orange"], + ["FE6F5E", "Bittersweet"], + ["FE9D04", "California"], + ["FEA904", "Yellow Sea"], + ["FEBAAD", "Melon"], + ["FED33C", "Bright Sun"], + ["FED85D", "Dandelion"], + ["FEDB8D", "Salomie"], + ["FEE5AC", "Cape Honey"], + ["FEEBF3", "Remy"], + ["FEEFCE", "Oasis"], + ["FEF0EC", "Bridesmaid"], + ["FEF2C7", "Beeswax"], + ["FEF3D8", "Bleach White"], + ["FEF4CC", "Pipi"], + ["FEF4DB", "Half Spanish White"], + ["FEF4F8", "Wisp Pink"], + ["FEF5F1", "Provincial Pink"], + ["FEF7DE", "Half Dutch White"], + ["FEF8E2", "Solitaire"], + ["FEF8FF", "White Pointer"], + ["FEF9E3", "Off Yellow"], + ["FEFCED", "Orange White"], + ["FF0000", "Red"], + ["FF007F", "Rose"], + ["FF00CC", "Purple Pizzazz"], + ["FF00FF", "Magenta / Fuchsia"], + ["FF2400", "Scarlet"], + ["FF3399", "Wild Strawberry"], + ["FF33CC", "Razzle Dazzle Rose"], + ["FF355E", "Radical Red"], + ["FF3F34", "Red Orange"], + ["FF4040", "Coral Red"], + ["FF4D00", "Vermilion"], + ["FF4F00", "International Orange"], + ["FF6037", "Outrageous Orange"], + ["FF6600", "Blaze Orange"], + ["FF66FF", "Pink Flamingo"], + ["FF681F", "Orange"], + ["FF69B4", "Hot Pink"], + ["FF6B53", "Persimmon"], + ["FF6FFF", "Blush Pink"], + ["FF7034", "Burning Orange"], + ["FF7518", "Pumpkin"], + ["FF7D07", "Flamenco"], + ["FF7F00", "Flush Orange"], + ["FF7F50", "Coral"], + ["FF8C69", "Salmon"], + ["FF9000", "Pizazz"], + ["FF910F", "West Side"], + ["FF91A4", "Pink Salmon"], + ["FF9933", "Neon Carrot"], + ["FF9966", "Atomic Tangerine"], + ["FF9980", "Vivid Tangerine"], + ["FF9E2C", "Sunshade"], + ["FFA000", "Orange Peel"], + ["FFA194", "Mona Lisa"], + ["FFA500", "Web Orange"], + ["FFA6C9", "Carnation Pink"], + ["FFAB81", "Hit Pink"], + ["FFAE42", "Yellow Orange"], + ["FFB0AC", "Cornflower Lilac"], + ["FFB1B3", "Sundown"], + ["FFB31F", "My Sin"], + ["FFB555", "Texas Rose"], + ["FFB7D5", "Cotton Candy"], + ["FFB97B", "Macaroni and Cheese"], + ["FFBA00", "Selective Yellow"], + ["FFBD5F", "Koromiko"], + ["FFBF00", "Amber"], + ["FFC0A8", "Wax Flower"], + ["FFC0CB", "Pink"], + ["FFC3C0", "Your Pink"], + ["FFC901", "Supernova"], + ["FFCBA4", "Flesh"], + ["FFCC33", "Sunglow"], + ["FFCC5C", "Golden Tainoi"], + ["FFCC99", "Peach Orange"], + ["FFCD8C", "Chardonnay"], + ["FFD1DC", "Pastel Pink"], + ["FFD2B7", "Romantic"], + ["FFD38C", "Grandis"], + ["FFD700", "Gold"], + ["FFD800", "School bus Yellow"], + ["FFD8D9", "Cosmos"], + ["FFDB58", "Mustard"], + ["FFDCD6", "Peach Schnapps"], + ["FFDDAF", "Caramel"], + ["FFDDCD", "Tuft Bush"], + ["FFDDCF", "Watusi"], + ["FFDDF4", "Pink Lace"], + ["FFDEAD", "Navajo White"], + ["FFDEB3", "Frangipani"], + ["FFE1DF", "Pippin"], + ["FFE1F2", "Pale Rose"], + ["FFE2C5", "Negroni"], + ["FFE5A0", "Cream Brulee"], + ["FFE5B4", "Peach"], + ["FFE6C7", "Tequila"], + ["FFE772", "Kournikova"], + ["FFEAC8", "Sandy Beach"], + ["FFEAD4", "Karry"], + ["FFEC13", "Broom"], + ["FFEDBC", "Colonial White"], + ["FFEED8", "Derby"], + ["FFEFA1", "Vis Vis"], + ["FFEFC1", "Egg White"], + ["FFEFD5", "Papaya Whip"], + ["FFEFEC", "Fair Pink"], + ["FFF0DB", "Peach Cream"], + ["FFF0F5", "Lavender blush"], + ["FFF14F", "Gorse"], + ["FFF1B5", "Buttermilk"], + ["FFF1D8", "Pink Lady"], + ["FFF1EE", "Forget Me Not"], + ["FFF1F9", "Tutu"], + ["FFF39D", "Picasso"], + ["FFF3F1", "Chardon"], + ["FFF46E", "Paris Daisy"], + ["FFF4CE", "Barley White"], + ["FFF4DD", "Egg Sour"], + ["FFF4E0", "Sazerac"], + ["FFF4E8", "Serenade"], + ["FFF4F3", "Chablis"], + ["FFF5EE", "Seashell Peach"], + ["FFF5F3", "Sauvignon"], + ["FFF6D4", "Milk Punch"], + ["FFF6DF", "Varden"], + ["FFF6F5", "Rose White"], + ["FFF8D1", "Baja White"], + ["FFF9E2", "Gin Fizz"], + ["FFF9E6", "Early Dawn"], + ["FFFACD", "Lemon Chiffon"], + ["FFFAF4", "Bridal Heath"], + ["FFFBDC", "Scotch Mist"], + ["FFFBF9", "Soapstone"], + ["FFFC99", "Witch Haze"], + ["FFFCEA", "Buttery White"], + ["FFFCEE", "Island Spice"], + ["FFFDD0", "Cream"], + ["FFFDE6", "Chilean Heath"], + ["FFFDE8", "Travertine"], + ["FFFDF3", "Orchid White"], + ["FFFDF4", "Quarter Pearl Lusta"], + ["FFFEE1", "Half and Half"], + ["FFFEEC", "Apricot White"], + ["FFFEF0", "Rice Cake"], + ["FFFEF6", "Black White"], + ["FFFEFD", "Romance"], + ["FFFF00", "Yellow"], + ["FFFF66", "Laser Lemon"], + ["FFFF99", "Pale Canary"], + ["FFFFB4", "Portafino"], + ["FFFFF0", "Ivory"], + ["FFFFFF", "White"] +] diff --git a/packages/color-palette/src/json/palette.json b/packages/color-palette/src/json/palette.json new file mode 100644 index 0000000..440a04b --- /dev/null +++ b/packages/color-palette/src/json/palette.json @@ -0,0 +1,274 @@ +[ + { + "key": "red", + "palettes": [ + { "hexcode": "#fef2f2", "number": 50, "name": "Bridesmaid" }, + { "hexcode": "#fee2e2", "number": 100, "name": "Pippin" }, + { "hexcode": "#fecaca", "number": 200, "name": "Your Pink" }, + { "hexcode": "#fca5a5", "number": 300, "name": "Cornflower Lilac" }, + { "hexcode": "#f87171", "number": 400, "name": "Bittersweet" }, + { "hexcode": "#ef4444", "number": 500, "name": "Cinnabar" }, + { "hexcode": "#dc2626", "number": 600, "name": "Persian Red" }, + { "hexcode": "#b91c1c", "number": 700, "name": "Thunderbird" }, + { "hexcode": "#991b1b", "number": 800, "name": "Old Brick" }, + { "hexcode": "#7f1d1d", "number": 900, "name": "Falu Red" }, + { "hexcode": "#450a0a", "number": 950, "name": "Mahogany" } + ] + }, + { + "key": "orange", + "palettes": [ + { "hexcode": "#fff7ed", "number": 50, "name": "Serenade" }, + { "hexcode": "#ffedd5", "number": 100, "name": "Derby" }, + { "hexcode": "#fed7aa", "number": 200, "name": "Caramel" }, + { "hexcode": "#fdba74", "number": 300, "name": "Macaroni and Cheese" }, + { "hexcode": "#fb923c", "number": 400, "name": "Neon Carrot" }, + { "hexcode": "#f97316", "number": 500, "name": "Ecstasy" }, + { "hexcode": "#ea580c", "number": 600, "name": "Trinidad" }, + { "hexcode": "#c2410c", "number": 700, "name": "Tia Maria" }, + { "hexcode": "#9a3412", "number": 800, "name": "Tabasco" }, + { "hexcode": "#7c2d12", "number": 900, "name": "Pueblo" }, + { "hexcode": "#431407", "number": 950, "name": "Rebel" } + ] + }, + { + "key": "amber", + "palettes": [ + { "hexcode": "#fffbeb", "number": 50, "name": "Island Spice" }, + { "hexcode": "#fef3c7", "number": 100, "name": "Beeswax" }, + { "hexcode": "#fde68a", "number": 200, "name": "Sweet Corn" }, + { "hexcode": "#fcd34d", "number": 300, "name": "Mustard" }, + { "hexcode": "#fbbf24", "number": 400, "name": "Lightning Yellow" }, + { "hexcode": "#f59e0b", "number": 500, "name": "California" }, + { "hexcode": "#d97706", "number": 600, "name": "Christine" }, + { "hexcode": "#b45309", "number": 700, "name": "Vesuvius" }, + { "hexcode": "#92400e", "number": 800, "name": "Korma" }, + { "hexcode": "#78350f", "number": 900, "name": "Copper Canyon" }, + { "hexcode": "#451a03", "number": 950, "name": "Brown Pod" } + ] + }, + { + "key": "yellow", + "palettes": [ + { "hexcode": "#fefce8", "number": 50, "name": "Orange White" }, + { "hexcode": "#fef9c3", "number": 100, "name": "Lemon Chiffon" }, + { "hexcode": "#fef08a", "number": 200, "name": "Sweet Corn" }, + { "hexcode": "#fde047", "number": 300, "name": "Bright Sun" }, + { "hexcode": "#facc15", "number": 400, "name": "Candlelight" }, + { "hexcode": "#eab308", "number": 500, "name": "Corn" }, + { "hexcode": "#ca8a04", "number": 600, "name": "Pirate Gold" }, + { "hexcode": "#a16207", "number": 700, "name": "Mai Tai" }, + { "hexcode": "#854d0e", "number": 800, "name": "Korma" }, + { "hexcode": "#713f12", "number": 900, "name": "Sepia" }, + { "hexcode": "#422006", "number": 950, "name": "Dark Ebony" } + ] + }, + { + "key": "lime", + "palettes": [ + { "hexcode": "#f7fee7", "number": 50, "name": "Spring Sun" }, + { "hexcode": "#ecfccb", "number": 100, "name": "Chiffon" }, + { "hexcode": "#d9f99d", "number": 200, "name": "Gossip" }, + { "hexcode": "#bef264", "number": 300, "name": "Sulu" }, + { "hexcode": "#a3e635", "number": 400, "name": "Conifer" }, + { "hexcode": "#84cc16", "number": 500, "name": "Lima" }, + { "hexcode": "#65a30d", "number": 600, "name": "Christi" }, + { "hexcode": "#4d7c0f", "number": 700, "name": "Green Leaf" }, + { "hexcode": "#3f6212", "number": 800, "name": "Dell" }, + { "hexcode": "#365314", "number": 900, "name": "Clover" }, + { "hexcode": "#1a2e05", "number": 950, "name": "Deep Forest Green" } + ] + }, + { + "key": "green", + "palettes": [ + { "hexcode": "#f0fdf4", "number": 50, "name": "Ottoman" }, + { "hexcode": "#dcfce7", "number": 100, "name": "Blue Romance" }, + { "hexcode": "#bbf7d0", "number": 200, "name": "Magic Mint" }, + { "hexcode": "#86efac", "number": 300, "name": "Algae Green" }, + { "hexcode": "#4ade80", "number": 400, "name": "Emerald" }, + { "hexcode": "#22c55e", "number": 500, "name": "Malachite" }, + { "hexcode": "#16a34a", "number": 600, "name": "Salem" }, + { "hexcode": "#15803d", "number": 700, "name": "Jewel" }, + { "hexcode": "#166534", "number": 800, "name": "Jewel" }, + { "hexcode": "#14532d", "number": 900, "name": "Green Pea" }, + { "hexcode": "#052e16", "number": 950, "name": "English Holly" } + ] + }, + { + "key": "emerald", + "palettes": [ + { "hexcode": "#ecfdf5", "number": 50, "name": "White Ice" }, + { "hexcode": "#d1fae5", "number": 100, "name": "Granny Apple" }, + { "hexcode": "#a7f3d0", "number": 200, "name": "Magic Mint" }, + { "hexcode": "#6ee7b7", "number": 300, "name": "Bermuda" }, + { "hexcode": "#34d399", "number": 400, "name": "Shamrock" }, + { "hexcode": "#10b981", "number": 500, "name": "Mountain Meadow" }, + { "hexcode": "#059669", "number": 600, "name": "Green Haze" }, + { "hexcode": "#047857", "number": 700, "name": "Watercourse" }, + { "hexcode": "#065f46", "number": 800, "name": "Watercourse" }, + { "hexcode": "#064e3b", "number": 900, "name": "Evening Sea" }, + { "hexcode": "#022c22", "number": 950, "name": "Burnham" } + ] + }, + { + "key": "teal", + "palettes": [ + { "hexcode": "#f0fdfa", "number": 50, "name": "White Ice" }, + { "hexcode": "#ccfbf1", "number": 100, "name": "Scandal" }, + { "hexcode": "#99f6e4", "number": 200, "name": "Ice Cold" }, + { "hexcode": "#5eead4", "number": 300, "name": "Turquoise Blue" }, + { "hexcode": "#2dd4bf", "number": 400, "name": "Turquoise" }, + { "hexcode": "#14b8a6", "number": 500, "name": "Java" }, + { "hexcode": "#0d9488", "number": 600, "name": "Blue Chill" }, + { "hexcode": "#0f766e", "number": 700, "name": "Genoa" }, + { "hexcode": "#115e59", "number": 800, "name": "Eden" }, + { "hexcode": "#134e4a", "number": 900, "name": "Eden" }, + { "hexcode": "#042f2e", "number": 950, "name": "Tiber" } + ] + }, + { + "key": "cyan", + "palettes": [ + { "hexcode": "#ecfeff", "number": 50, "name": "Bubbles" }, + { "hexcode": "#cffafe", "number": 100, "name": "Oyster Bay" }, + { "hexcode": "#a5f3fc", "number": 200, "name": "Anakiwa" }, + { "hexcode": "#67e8f9", "number": 300, "name": "Spray" }, + { "hexcode": "#22d3ee", "number": 400, "name": "Bright Turquoise" }, + { "hexcode": "#06b6d4", "number": 500, "name": "Cerulean" }, + { "hexcode": "#0891b2", "number": 600, "name": "Bondi Blue" }, + { "hexcode": "#0e7490", "number": 700, "name": "Blue Chill" }, + { "hexcode": "#155e75", "number": 800, "name": "Blumine" }, + { "hexcode": "#164e63", "number": 900, "name": "Chathams Blue" }, + { "hexcode": "#083344", "number": 950, "name": "Tarawera" } + ] + }, + { + "key": "sky", + "palettes": [ + { "hexcode": "#f0f9ff", "number": 50, "name": "Alice Blue" }, + { "hexcode": "#e0f2fe", "number": 100, "name": "Pattens Blue" }, + { "hexcode": "#bae6fd", "number": 200, "name": "French Pass" }, + { "hexcode": "#7dd3fc", "number": 300, "name": "Malibu" }, + { "hexcode": "#38bdf8", "number": 400, "name": "Picton Blue" }, + { "hexcode": "#0ea5e9", "number": 500, "name": "Cerulean" }, + { "hexcode": "#0284c7", "number": 600, "name": "Lochmara" }, + { "hexcode": "#0369a1", "number": 700, "name": "Bahama Blue" }, + { "hexcode": "#075985", "number": 800, "name": "Venice Blue" }, + { "hexcode": "#0c4a6e", "number": 900, "name": "Chathams Blue" }, + { "hexcode": "#082f49", "number": 950, "name": "Blue Whale" } + ] + }, + { + "key": "blue", + "palettes": [ + { "hexcode": "#eff6ff", "number": 50, "name": "Zumthor" }, + { "hexcode": "#dbeafe", "number": 100, "name": "Hawkes Blue" }, + { "hexcode": "#bfdbfe", "number": 200, "name": "Tropical Blue" }, + { "hexcode": "#93c5fd", "number": 300, "name": "Malibu" }, + { "hexcode": "#60a5fa", "number": 400, "name": "Cornflower Blue" }, + { "hexcode": "#3b82f6", "number": 500, "name": "Dodger Blue" }, + { "hexcode": "#2563eb", "number": 600, "name": "Royal Blue" }, + { "hexcode": "#1d4ed8", "number": 700, "name": "Cerulean Blue" }, + { "hexcode": "#1e40af", "number": 800, "name": "Persian Blue" }, + { "hexcode": "#1e3a8a", "number": 900, "name": "Bay of Many" }, + { "hexcode": "#172554", "number": 950, "name": "Bunting" } + ] + }, + { + "key": "indigo", + "palettes": [ + { "hexcode": "#eef2ff", "number": 50, "name": "Zircon" }, + { "hexcode": "#e0e7ff", "number": 100, "name": "Hawkes Blue" }, + { "hexcode": "#c7d2fe", "number": 200, "name": "Periwinkle" }, + { "hexcode": "#a5b4fc", "number": 300, "name": "Perano" }, + { "hexcode": "#818cf8", "number": 400, "name": "Portage" }, + { "hexcode": "#6366f1", "number": 500, "name": "Royal Blue" }, + { "hexcode": "#4f46e5", "number": 600, "name": "Royal Blue" }, + { "hexcode": "#4338ca", "number": 700, "name": "Governor Bay" }, + { "hexcode": "#3730a3", "number": 800, "name": "Governor Bay" }, + { "hexcode": "#312e81", "number": 900, "name": "Minsk" }, + { "hexcode": "#1e1b4b", "number": 950, "name": "Port Gore" } + ] + }, + { + "key": "violet", + "palettes": [ + { "hexcode": "#f5f3ff", "number": 50, "name": "Titan White" }, + { "hexcode": "#ede9fe", "number": 100, "name": "Titan White" }, + { "hexcode": "#ddd6fe", "number": 200, "name": "Fog" }, + { "hexcode": "#c4b5fd", "number": 300, "name": "Melrose" }, + { "hexcode": "#a78bfa", "number": 400, "name": "Dull Lavender" }, + { "hexcode": "#8b5cf6", "number": 500, "name": "Medium Purple" }, + { "hexcode": "#7c3aed", "number": 600, "name": "Purple Heart" }, + { "hexcode": "#6d28d9", "number": 700, "name": "Purple Heart" }, + { "hexcode": "#5b21b6", "number": 800, "name": "Purple Heart" }, + { "hexcode": "#4c1d95", "number": 900, "name": "Daisy Bush" }, + { "hexcode": "#2e1065", "number": 950, "name": "Violent Violet" } + ] + }, + { + "key": "purple", + "palettes": [ + { "hexcode": "#faf5ff", "number": 50, "name": "Magnolia" }, + { "hexcode": "#f3e8ff", "number": 100, "name": "Blue Chalk" }, + { "hexcode": "#e9d5ff", "number": 200, "name": "Blue Chalk" }, + { "hexcode": "#d8b4fe", "number": 300, "name": "Mauve" }, + { "hexcode": "#c084fc", "number": 400, "name": "Heliotrope" }, + { "hexcode": "#a855f7", "number": 500, "name": "Medium Purple" }, + { "hexcode": "#9333ea", "number": 600, "name": "Electric Violet" }, + { "hexcode": "#7e22ce", "number": 700, "name": "Purple Heart" }, + { "hexcode": "#6b21a8", "number": 800, "name": "Seance" }, + { "hexcode": "#581c87", "number": 900, "name": "Daisy Bush" }, + { "hexcode": "#3b0764", "number": 950, "name": "Christalle" } + ] + }, + { + "key": "fuchsia", + "palettes": [ + { "hexcode": "#fdf4ff", "number": 50, "name": "White Pointer" }, + { "hexcode": "#fae8ff", "number": 100, "name": "White Pointer" }, + { "hexcode": "#f5d0fe", "number": 200, "name": "Mauve" }, + { "hexcode": "#f0abfc", "number": 300, "name": "Mauve" }, + { "hexcode": "#e879f9", "number": 400, "name": "Heliotrope" }, + { "hexcode": "#d946ef", "number": 500, "name": "Heliotrope" }, + { "hexcode": "#c026d3", "number": 600, "name": "Fuchsia Pink" }, + { "hexcode": "#a21caf", "number": 700, "name": "Violet Eggplant" }, + { "hexcode": "#86198f", "number": 800, "name": "Seance" }, + { "hexcode": "#701a75", "number": 900, "name": "Seance" }, + { "hexcode": "#4a044e", "number": 950, "name": "Clairvoyant" } + ] + }, + { + "key": "pink", + "palettes": [ + { "hexcode": "#fdf2f8", "number": 50, "name": "Wisp Pink" }, + { "hexcode": "#fce7f3", "number": 100, "name": "Carousel Pink" }, + { "hexcode": "#fbcfe8", "number": 200, "name": "Classic Rose" }, + { "hexcode": "#f9a8d4", "number": 300, "name": "Lavender Pink" }, + { "hexcode": "#f472b6", "number": 400, "name": "Persian Pink" }, + { "hexcode": "#ec4899", "number": 500, "name": "Brilliant Rose" }, + { "hexcode": "#db2777", "number": 600, "name": "Cerise" }, + { "hexcode": "#be185d", "number": 700, "name": "Maroon Flush" }, + { "hexcode": "#9d174d", "number": 800, "name": "Disco" }, + { "hexcode": "#831843", "number": 900, "name": "Disco" }, + { "hexcode": "#500724", "number": 950, "name": "Cab Sav" } + ] + }, + { + "key": "rose", + "palettes": [ + { "hexcode": "#fff1f2", "number": 50, "name": "Lavender blush" }, + { "hexcode": "#ffe4e6", "number": 100, "name": "Cosmos" }, + { "hexcode": "#fecdd3", "number": 200, "name": "Pastel Pink" }, + { "hexcode": "#fda4af", "number": 300, "name": "Sweet Pink" }, + { "hexcode": "#fb7185", "number": 400, "name": "Froly" }, + { "hexcode": "#f43f5e", "number": 500, "name": "Radical Red" }, + { "hexcode": "#e11d48", "number": 600, "name": "Amaranth" }, + { "hexcode": "#be123c", "number": 700, "name": "Cardinal" }, + { "hexcode": "#9f1239", "number": 800, "name": "Shiraz" }, + { "hexcode": "#881337", "number": 900, "name": "Claret" }, + { "hexcode": "#4c0519", "number": 950, "name": "Cab Sav" } + ] + } +] diff --git a/packages/color-palette/src/name.ts b/packages/color-palette/src/name.ts new file mode 100644 index 0000000..2cd5a44 --- /dev/null +++ b/packages/color-palette/src/name.ts @@ -0,0 +1,46 @@ +import { getHex, getHsl, getRgb } from './color'; +import colorNames from './json/color-name.json'; + +export function getColorName(color: string) { + const hex = getHex(color); + const rgb = getRgb(color); + const hsl = getHsl(color); + + let ndf = 0; + let ndf1 = 0; + let ndf2 = 0; + let cl = -1; + let df = -1; + + let name = ''; + + colorNames.some((item, index) => { + const [hexValue, colorName] = item; + + const hexcode = `#${hexValue}`; + + const match = hex === hexcode; + + if (match) { + name = colorName; + } else { + const { r, g, b } = getRgb(hexcode); + const { h, s, l } = getHsl(hexcode); + + ndf1 = (rgb.r - r) ** 2 + (rgb.g - g) ** 2 + (rgb.b - b) ** 2; + ndf2 = (hsl.h - h) ** 2 + (hsl.s - s) ** 2 + (hsl.l - l) ** 2; + + ndf = ndf1 + ndf2 * 2; + if (df < 0 || df > ndf) { + df = ndf; + cl = index; + } + } + + return match; + }); + + name = cl < 0 ? 'Invalid Color' : colorNames[cl][1]; + + return name; +} diff --git a/packages/color-palette/src/palette.ts b/packages/color-palette/src/palette.ts new file mode 100644 index 0000000..c920023 --- /dev/null +++ b/packages/color-palette/src/palette.ts @@ -0,0 +1,95 @@ +import { getDeltaE, getHsl, isValidColor, transformHslToHex } from './color'; +import { getColorName } from './name'; +import type { ColorPaletteFamily, ColorPaletteFamilyWithNearestPalette } from './type'; +import defaultPalettes from './json/palette.json'; + +export function getNearestColorPaletteFamily(color: string, families: ColorPaletteFamily[]) { + const familyWithConfig = families.map(family => { + const palettes = family.palettes.map(palette => { + return { + ...palette, + delta: getDeltaE(color, palette.hexcode) + }; + }); + + const nearestPalette = palettes.reduce((prev, curr) => (prev.delta < curr.delta ? prev : curr)); + + return { + ...family, + palettes, + nearestPalette + }; + }); + + const nearestPaletteFamily = familyWithConfig.reduce((prev, curr) => + prev.nearestPalette.delta < curr.nearestPalette.delta ? prev : curr + ); + + const { l } = getHsl(color); + + const paletteFamily: ColorPaletteFamilyWithNearestPalette = { + ...nearestPaletteFamily, + nearestLightnessPalette: nearestPaletteFamily.palettes.reduce((prev, curr) => { + const { l: prevLightness } = getHsl(prev.hexcode); + const { l: currLightness } = getHsl(curr.hexcode); + + const deltaPrev = Math.abs(prevLightness - l); + const deltaCurr = Math.abs(currLightness - l); + + return deltaPrev < deltaCurr ? prev : curr; + }) + }; + + return paletteFamily; +} + +export function getColorPaletteFamily(color: string, colorName: string) { + if (!isValidColor(color)) { + throw new Error('Invalid color, please check color value!'); + } + + const { h: h1, s: s1 } = getHsl(color); + + const { nearestLightnessPalette, palettes } = getNearestColorPaletteFamily( + color, + defaultPalettes as ColorPaletteFamily[] + ); + + const { number, hexcode } = nearestLightnessPalette; + + const { h: h2, s: s2 } = getHsl(hexcode); + + const deltaH = h1 - h2 || h2; + + const sRatio = s1 / s2; + + const colorPaletteFamily: ColorPaletteFamily = { + key: colorName, + palettes: palettes.map(palette => { + let hexValue = color; + + const isSame = number === palette.number; + + if (!isSame) { + const { h: h3, s: s3, l } = getHsl(palette.hexcode); + + const newH = deltaH < 0 ? h3 + deltaH : deltaH; + const newS = s3 * sRatio; + + hexValue = transformHslToHex({ + h: newH, + s: newS, + l + }); + } + + return { + hexcode: hexValue, + number: palette.number, + name: getColorName(hexValue) + }; + }) + }; + + return colorPaletteFamily; +} diff --git a/packages/color-palette/src/type.ts b/packages/color-palette/src/type.ts new file mode 100644 index 0000000..505d38a --- /dev/null +++ b/packages/color-palette/src/type.ts @@ -0,0 +1,49 @@ +/** The color palette number */ +export type ColorPaletteNumber = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950; + +/** The color palette item */ +export type ColorPaletteItem = { + /** The color hexcode */ + hexcode: string; + /** + * The color number + * + * @link {@link ColorPaletteNumber} + */ + number: ColorPaletteNumber; + /** The color name */ + name: string; +}; + +export type ColorPaletteFamily = { + /** The color palette family key */ + key: string; + /** The color palette family's palettes */ + palettes: ColorPaletteItem[]; +}; + +export type ColorPaletteWithDelta = ColorPaletteItem & { + delta: number; +}; + +export type ColorPaletteItemWithName = ColorPaletteItem & { + name: string; +}; + +export type ColorPaletteFamilyWithNearestPalette = ColorPaletteFamily & { + nearestPalette: ColorPaletteWithDelta; + nearestLightnessPalette: ColorPaletteWithDelta; +}; + +export type ColorPalette = ColorPaletteFamily & { + /** The color map of the palette */ + colorMap: Map; + /** + * The main color of the palette + * + * Which number is 500 + */ + main: ColorPaletteItemWithName; + /** The match color of the palette */ + match: ColorPaletteItemWithName; +}; diff --git a/packages/docs/.vitepress/config.ts b/packages/docs/.vitepress/config.ts new file mode 100644 index 0000000..96c835e --- /dev/null +++ b/packages/docs/.vitepress/config.ts @@ -0,0 +1,39 @@ +import process from 'node:process'; +import path from 'node:path'; +import { defineConfig } from 'vitepress'; + +export default defineConfig({ + title: 'Soybean Admin', + description: '一个优雅、清新、漂亮的中后台模版', + head: [ + ['meta', { name: 'author', content: 'Soybean' }], + [ + 'meta', + { + name: 'keywords', + content: 'soybean, soybean-admin, vite, vue, vue3, soybean-admin docs' + } + ], + ['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }], + [ + 'meta', + { + name: 'viewport', + content: 'width=device-width,initial-scale=1,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no' + } + ], + ['link', { rel: 'icon', href: '/favicon.ico' }] + ], + srcDir: path.join(process.cwd(), 'packages/docs/src'), + themeConfig: { + logo: '/logo.svg', + socialLinks: [{ icon: 'github', link: 'https://github.com/honghuangdc/soybean-admin' }], + algolia: { + appId: '98WN1RY04S', + apiKey: '13e9f5767b774422a5880723d9c23265', + indexName: 'soybean' + }, + nav: [], + sidebar: {} + } +}); diff --git a/packages/docs/.vitepress/icon.ts b/packages/docs/.vitepress/icon.ts new file mode 100644 index 0000000..28717de --- /dev/null +++ b/packages/docs/.vitepress/icon.ts @@ -0,0 +1,32 @@ +export const qqSvg = ` + + + + + + + + + + + + +`; diff --git a/packages/docs/.vitepress/theme/index.ts b/packages/docs/.vitepress/theme/index.ts new file mode 100644 index 0000000..7850521 --- /dev/null +++ b/packages/docs/.vitepress/theme/index.ts @@ -0,0 +1,4 @@ +import Theme from 'vitepress/theme'; +import './style.css'; + +export default Theme; diff --git a/packages/docs/.vitepress/theme/style.css b/packages/docs/.vitepress/theme/style.css new file mode 100644 index 0000000..b9d3c28 --- /dev/null +++ b/packages/docs/.vitepress/theme/style.css @@ -0,0 +1,86 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * -------------------------------------------------------------------------- */ + +:root { + --vp-c-brand: #646cff; + --vp-c-brand-light: #747bff; + --vp-c-brand-lighter: #9499ff; + --vp-c-brand-lightest: #bcc0ff; + --vp-c-brand-dark: #535bf2; + --vp-c-brand-darker: #454ce1; + --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: var(--vp-c-brand-light); + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand); + --vp-button-brand-hover-border: var(--vp-c-brand-light); + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-light); + --vp-button-brand-active-border: var(--vp-c-brand-light); + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-button-brand-bg); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + var(--vp-c-brand-lightest) 30%, + var(--vp-c-brand-darker) + ); + + --vp-home-hero-image-background-image: linear-gradient(-45deg, var(--vp-c-brand-lightest) 30%, var(--vp-c-brand) 50%); + --vp-home-hero-image-filter: blur(40px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(72px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-darker); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +.dark { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand) !important; +} diff --git a/packages/docs/package.json b/packages/docs/package.json new file mode 100644 index 0000000..d038045 --- /dev/null +++ b/packages/docs/package.json @@ -0,0 +1,12 @@ +{ + "name": "@sa/docs", + "version": "1.0.0", + "scripts": { + "build": "vitepress build", + "dev": "vitepress dev", + "serve": "vitepress serve" + }, + "devDependencies": { + "vitepress": "1.0.0-rc.36" + } +} diff --git a/packages/docs/src/index.md b/packages/docs/src/index.md new file mode 100644 index 0000000..af7f532 --- /dev/null +++ b/packages/docs/src/index.md @@ -0,0 +1,44 @@ +--- +layout: home + +title: Soybean Admin +titleTemplate: 一个清新优雅的中后台模版 + +hero: + name: Soybean Admin + text: 清新优雅的中后台模版 + tagline: 基于 Vue3 + Vite3 + TS + NaiveUI + UnoCSS + image: + src: /logo.svg + alt: Soybean Admin + actions: + - theme: brand + text: 开始 + link: /guide/ + - theme: alt + text: 介绍 + link: /guide/introduction + - theme: alt + text: 在 GitHub 上查看 + link: https://github.com/honghuangdc/soybean-admin + +features: + - icon: 🆕 + title: 最新流行技术栈 + details: 基于Vue3、Vite3、TS、NaiveUI和UnoCSS等最新技术栈开发 + - icon: 🦋 + title: 极高水准的代码规范 + details: 代码规范完善,代码结构清晰 + - icon: 🛠️ + title: 丰富的插件 + details: 常见的Web端插件示例实现 + - icon: 🔩 + title: 主题配置 + details: 丰富的主题配置及暗黑主题适配 + - icon: 🔗 + title: 基于文件的路由系统 + details: 自动生成路由声明、路由导入和路由模块 + - icon: 🔑 + title: 权限管理 + details: 完善的前后端权限管理方案 +--- diff --git a/packages/eslint-config/configs/base.js b/packages/eslint-config/configs/base.js new file mode 100644 index 0000000..60dca27 --- /dev/null +++ b/packages/eslint-config/configs/base.js @@ -0,0 +1,4 @@ +/** @type {import('eslint').ESLint.ConfigData} */ +module.exports = { + extends: [require.resolve('./ts.js'), require.resolve('./prettier.js')] +}; diff --git a/packages/eslint-config/configs/js.js b/packages/eslint-config/configs/js.js new file mode 100644 index 0000000..c10730f --- /dev/null +++ b/packages/eslint-config/configs/js.js @@ -0,0 +1,42 @@ +/** @type {import('eslint').ESLint.ConfigData} */ +module.exports = { + root: true, + env: { + browser: true, + node: true, + commonjs: true, + es2024: true + }, + parserOptions: { + ecmaVersion: 2024, + ecmaFeatures: { + jsx: true + }, + sourceType: 'module' + }, + ignorePatterns: [ + 'node_modules', + '*.min.*', + 'CHANGELOG.md', + 'dist', + 'LICENSE*', + 'output', + 'coverage', + 'public', + 'temp', + 'package-lock.json', + 'pnpm-lock.yaml', + 'yarn.lock', + '__snapshots__', + '!.github', + '!.vitepress', + '!.vscode' + ], + plugins: ['n', 'promise'], + extends: [require.resolve('../rules/all.js'), 'plugin:import/recommended'], + rules: { + // import + 'import/no-mutable-exports': 'error', + 'import/no-named-as-default': 'off' + } +}; diff --git a/packages/eslint-config/configs/prettier.js b/packages/eslint-config/configs/prettier.js new file mode 100644 index 0000000..2e168c5 --- /dev/null +++ b/packages/eslint-config/configs/prettier.js @@ -0,0 +1,9 @@ +const prettierRules = require('../rules/prettier'); + +/** @type {import('eslint').ESLint.ConfigData} */ +module.exports = { + extends: ['plugin:prettier/recommended'], + rules: { + 'prettier/prettier': ['error', prettierRules] + } +}; diff --git a/packages/eslint-config/configs/ts.js b/packages/eslint-config/configs/ts.js new file mode 100644 index 0000000..36d10b1 --- /dev/null +++ b/packages/eslint-config/configs/ts.js @@ -0,0 +1,59 @@ +/** @type {import('eslint').ESLint.ConfigData} */ +module.exports = { + plugins: ['@typescript-eslint'], + extends: [require.resolve('./js.js'), 'plugin:import/typescript', 'plugin:@typescript-eslint/recommended'], + settings: { + 'import/resolver': { + typescript: { + project: ['tsconfig.json', 'packages/*/tsconfig.json', 'examples/*/tsconfig.json', 'docs/*/tsconfig.json'] + } + } + }, + overrides: [ + { + files: ['*.ts', '*.tsx', '*.mts', '*.cts'], + parser: '@typescript-eslint/parser' + }, + { + files: ['*.js', '*.mjs', '*.cjs', '*.cts'], + rules: { + '@typescript-eslint/no-var-requires': 'off' + } + } + ], + rules: { + // TS + '@typescript-eslint/consistent-type-imports': ['error', { prefer: 'type-imports', disallowTypeAnnotations: false }], + '@typescript-eslint/no-empty-interface': [ + 'error', + { + allowSingleExtends: true + } + ], + + // Override JS + 'no-redeclare': 'off', + '@typescript-eslint/no-redeclare': 'error', + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + vars: 'all', + args: 'all', + ignoreRestSiblings: false, + varsIgnorePattern: '^_', + argsIgnorePattern: '^_' + } + ], + 'no-use-before-define': 'off', + '@typescript-eslint/no-use-before-define': ['error', { functions: false, classes: false, variables: true }], + 'no-shadow': 'off', + '@typescript-eslint/no-shadow': 'error', + + // off + '@typescript-eslint/consistent-type-definitions': 'off', + '@typescript-eslint/no-empty-function': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off' + } +}; diff --git a/packages/eslint-config/configs/vue.js b/packages/eslint-config/configs/vue.js new file mode 100644 index 0000000..dcaa4cc --- /dev/null +++ b/packages/eslint-config/configs/vue.js @@ -0,0 +1,28 @@ +/** @type {import('eslint').ESLint.ConfigData} */ +module.exports = { + extends: ['plugin:vue/vue3-recommended', require.resolve('./base.js')], + overrides: [ + { + files: ['*.vue'], + parser: 'vue-eslint-parser', + parserOptions: { + parser: { + js: 'espree', + jsx: 'espree', + ts: '@typescript-eslint/parser', + tsx: '@typescript-eslint/parser' + }, + extraFileExtensions: ['.vue'], + ecmaFeatures: { + jsx: true + } + }, + rules: { + 'no-undef': 'off' // TS will check un declared variables, if the script code is is in a .vue file, this rule should not disabled + } + } + ], + rules: { + 'vue/multi-word-component-names': 'off' + } +}; diff --git a/packages/eslint-config/index.js b/packages/eslint-config/index.js new file mode 100644 index 0000000..bb95170 --- /dev/null +++ b/packages/eslint-config/index.js @@ -0,0 +1,4 @@ +const baseConfig = require('./configs/base'); + +/** @type {import('eslint').ESLint.ConfigData} */ +module.exports = baseConfig; diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json new file mode 100644 index 0000000..ab85051 --- /dev/null +++ b/packages/eslint-config/package.json @@ -0,0 +1,23 @@ +{ + "name": "eslint-config-sa", + "version": "1.0.0", + "description": "SoybeanAdmin's eslint config resets", + "exports": { + ".": "./index.js", + "./vue": "./configs/vue.js" + }, + "devDependencies": { + "@types/eslint": "8.56.1", + "@typescript-eslint/eslint-plugin": "6.18.0", + "@typescript-eslint/parser": "6.18.0", + "eslint": "8.56.0", + "eslint-config-prettier": "9.1.0", + "eslint-import-resolver-typescript": "3.6.1", + "eslint-plugin-import": "2.29.1", + "eslint-plugin-n": "16.6.1", + "eslint-plugin-prettier": "5.1.2", + "eslint-plugin-promise": "6.1.1", + "eslint-plugin-vue": "9.19.2", + "prettier": "3.1.1" + } +} diff --git a/packages/eslint-config/rules/all.js b/packages/eslint-config/rules/all.js new file mode 100644 index 0000000..43d4cfd --- /dev/null +++ b/packages/eslint-config/rules/all.js @@ -0,0 +1,1944 @@ +/** @type {import('eslint').Linter.RulesRecord} */ +module.exports = { + rules: { + /* + * Possible Problems + * These rules relate to possible logic errors in code + */ + + /** + * Enforce return statements in callbacks of array methods + * + * @link https://eslint.org/docs/latest/rules/array-callback-return + */ + 'array-callback-return': 'error', + + /** + * Require `super()` calls in constructors + * + * @link https://eslint.org/docs/latest/rules/constructor-super + */ + 'constructor-super': 'error', + + /** + * Enforce "for" loop update clause moving the counter in the right direction. + * + * @link https://eslint.org/docs/latest/rules/for-direction + */ + 'for-direction': 'error', + + /** + * Enforce `return` statements in getters + * + * @link https://eslint.org/docs/latest/rules/getter-return + */ + 'getter-return': 'error', + + /** + * Disallow using an async function as a Promise executor + * + * @link https://eslint.org/docs/latest/rules/no-async-promise-executor + */ + 'no-async-promise-executor': 'error', + + /** + * Disallow `await` inside of loops + * + * @link https://eslint.org/docs/latest/rules/no-await-in-loop + */ + 'no-await-in-loop': 'error', + + /** + * Disallow reassigning class members + * + * @link https://eslint.org/docs/latest/rules/no-class-assign + */ + 'no-class-assign': 'error', + + /** + * Disallow comparing against -0 + * + * @link https://eslint.org/docs/latest/rules/no-compare-neg-zero + */ + 'no-compare-neg-zero': 'error', + + /** + * Disallow assignment operators in conditional expressions + * + * @link https://eslint.org/docs/latest/rules/no-cond-assign + */ + 'no-cond-assign': 'error', + + /** + * Disallow reassigning `const` variables + * + * @link https://eslint.org/docs/latest/rules/no-const-assign + */ + 'no-const-assign': 'error', + + /** + * Disallow expressions where the operation doesn't affect the value + * + * @link https://eslint.org/docs/latest/rules/no-constant-binary-expression + */ + 'no-constant-binary-expression': 'error', + + /** + * Disallow constant expressions in conditions + * + * @link https://eslint.org/docs/latest/rules/no-constant-condition + */ + 'no-constant-condition': 'error', + + /** + * Disallow returning value from constructor + * + * @link https://eslint.org/docs/latest/rules/no-constructor-return + */ + 'no-constructor-return': 'error', + + /** + * Disallow control characters in regular expressions + * + * @link https://eslint.org/docs/latest/rules/no-control-regex + */ + 'no-control-regex': 'error', + + /** + * Disallow the use of `debugger` + * + * @link https://eslint.org/docs/latest/rules/no-debugger + */ + 'no-debugger': 'error', + + /** + * Disallow duplicate arguments in `function` definitions + * + * @link https://eslint.org/docs/latest/rules/no-dupe-args + */ + 'no-dupe-args': 'error', + + /** + * Disallow duplicate class members + * + * @link https://eslint.org/docs/latest/rules/no-dupe-class-members + */ + 'no-dupe-class-members': 'error', + + /** + * Disallow duplicate conditions in if-else-if chains + * + * @link https://eslint.org/docs/latest/rules/no-dupe-else-if + */ + 'no-dupe-else-if': 'error', + + /** + * Disallow duplicate keys in object literals + * + * @link https://eslint.org/docs/latest/rules/no-dupe-keys + */ + 'no-dupe-keys': 'error', + + /** + * Disallow duplicate case labels + * + * @link https://eslint.org/docs/latest/rules/no-duplicate-case + */ + 'no-duplicate-case': 'error', + + /** + * Disallow duplicate module imports + * + * @link https://eslint.org/docs/latest/rules/no-duplicate-imports + */ + 'no-duplicate-imports': 'off', + + /** + * Disallow empty character classes in regular expressions + * + * @link https://eslint.org/docs/latest/rules/no-empty-character-class + */ + 'no-empty-character-class': 'error', + + /** + * Disallow empty destructuring patterns + * + * @link https://eslint.org/docs/latest/rules/no-empty-pattern + */ + 'no-empty-pattern': 'error', + + /** + * Disallow reassigning exceptions in `catch` clauses + * + * @link https://eslint.org/docs/latest/rules/no-ex-assign + */ + 'no-ex-assign': 'error', + + /** + * Disallow fallthrough of `case` statements + * + * @link https://eslint.org/docs/latest/rules/no-fallthrough + */ + 'no-fallthrough': 'error', + + /** + * Disallow reassigning `function` declarations + * + * @link https://eslint.org/docs/latest/rules/no-func-assign + */ + 'no-func-assign': 'error', + + /** + * Disallow assigning to imported bindings + * + * @link https://eslint.org/docs/latest/rules/no-import-assign + */ + 'no-import-assign': 'error', + + /** + * Disallow variable or `function` declarations in nested blocks + * + * @link https://eslint.org/docs/latest/rules/no-inner-declarations + */ + 'no-inner-declarations': 'error', + + /** + * Disallow invalid regular expression strings in `RegExp` constructors + * + * @link https://eslint.org/docs/latest/rules/no-invalid-regexp + */ + 'no-invalid-regexp': 'error', + + /** + * Disallow irregular whitespace + * + * @link https://eslint.org/docs/latest/rules/no-irregular-whitespace + */ + 'no-irregular-whitespace': 'error', + + /** + * Disallow literal numbers that lose precision + * + * @link https://eslint.org/docs/latest/rules/no-loss-of-precision + */ + 'no-loss-of-precision': 'error', + + /** + * Disallow characters which are made with multiple code points in character class syntax + * + * @link https://eslint.org/docs/latest/rules/no-misleading-character-class + */ + 'no-misleading-character-class': 'error', + + /** + * Disallow `new` operators with the `Symbol` object + * + * @link https://eslint.org/docs/latest/rules/no-new-symbol + */ + 'no-new-symbol': 'error', + + /** + * Disallow calling global object properties as functions + * + * @link https://eslint.org/docs/latest/rules/no-obj-calls + */ + 'no-obj-calls': 'error', + + /** + * Disallow returning values from Promise executor functions + * + * @link https://eslint.org/docs/latest/rules/no-promise-executor-return + */ + 'no-promise-executor-return': 'error', + + /** + * Disallow calling some `Object.prototype` methods directly on objects + * + * @link https://eslint.org/docs/latest/rules/no-prototype-builtins + */ + 'no-prototype-builtins': 'error', + + /** + * Disallow assignments where both sides are exactly the same + * + * @link https://eslint.org/docs/latest/rules/no-self-assign + */ + 'no-self-assign': 'error', + + /** + * Disallow comparisons where both sides are exactly the same + * + * @link https://eslint.org/docs/latest/rules/no-self-compare + */ + 'no-self-compare': 'error', + + /** + * Disallow returning values from setters + * + * @link https://eslint.org/docs/latest/rules/no-setter-return + */ + 'no-setter-return': 'error', + + /** + * Disallow sparse arrays + * + * @link https://eslint.org/docs/latest/rules/no-sparse-arrays + */ + 'no-sparse-arrays': 'error', + + /** + * Disallow template literal placeholder syntax in regular strings + * + * @link https://eslint.org/docs/latest/rules/no-template-curly-in-string + */ + 'no-template-curly-in-string': 'error', + + /** + * Disallow `this`/`super` before calling `super()` in constructors + * + * @link https://eslint.org/docs/latest/rules/no-this-before-super + */ + 'no-this-before-super': 'error', + + /** + * Disallow the use of undeclared variables unless mentioned in _global_ comments + * + * @link https://eslint.org/docs/latest/rules/no-undef + */ + 'no-undef': 'error', + + /** + * Disallow confusing multiline expressions + * + * @link https://eslint.org/docs/latest/rules/no-unexpected-multiline + */ + 'no-unexpected-multiline': 'error', + + /** + * Disallow unmodified loop conditions + * + * @link https://eslint.org/docs/latest/rules/no-unmodified-loop-condition + */ + 'no-unmodified-loop-condition': 'error', + + /** + * Disallow unreachable code after `return`, `throw`, `continue`, and `break` statements + * + * @link https://eslint.org/docs/latest/rules/no-unreachable + */ + 'no-unreachable': 'error', + + /** + * Disallow loops with a body that allows only one iteration + * + * @link https://eslint.org/docs/latest/rules/no-unreachable-loop + */ + 'no-unreachable-loop': 'error', + + /** + * Disallow control flow statements in `finally` blocks + * + * @link https://eslint.org/docs/latest/rules/no-unsafe-finally + */ + 'no-unsafe-finally': 'error', + + /** + * Disallow negating the left operand of relational operators + * + * @link https://eslint.org/docs/latest/rules/no-unsafe-negation + */ + 'no-unsafe-negation': 'error', + + /** + * Disallow use of optional chaining in contexts where the `undefined` value is not allowed + * + * @link https://eslint.org/docs/latest/rules/no-unsafe-optional-chaining + */ + 'no-unsafe-optional-chaining': 'error', + + /** + * Disallow unused private class members + * + * @link https://eslint.org/docs/latest/rules/no-unused-private-class-members + */ + 'no-unused-private-class-members': 'error', + + /** + * Disallow unused variables + * + * @link https://eslint.org/docs/latest/rules/no-unused-vars + */ + 'no-unused-vars': 'error', + + /** + * Disallow the use of variables before they are defined + * + * @link https://eslint.org/docs/latest/rules/no-use-before-define + */ + 'no-use-before-define': ['error', { functions: false, classes: false, variables: true }], + + /** + * Disallow useless backreferences in regular expressions + * + * @link https://eslint.org/docs/latest/rules/no-useless-backreference + */ + 'no-useless-backreference': 'error', + + /** + * Disallow assignments that can lead to race conditions due to usage of `await` or `yield` + * + * @link https://eslint.org/docs/latest/rules/require-atomic-updates + */ + 'require-atomic-updates': 'error', + + /** + * Require calls to `isNaN()` when checking for `NaN` + * + * @link https://eslint.org/docs/latest/rules/use-isnan + */ + 'use-isnan': 'error', + + /** + * Enforce comparing `typeof` expressions against valid strings + * + * @link https://eslint.org/docs/latest/rules/valid-typeof + */ + 'valid-typeof': 'error', + + // End + + /* + * Suggestions + * These rules suggest alternate ways of doing things: + */ + + /** + * Enforce getter and setter pairs in objects and classes + * + * @link https://eslint.org/docs/latest/rules/accessor-pairs + */ + 'accessor-pairs': ['error', { setWithoutGet: true, enforceForClassMembers: true }], + + /** + * Require braces around arrow function bodies + * + * @link https://eslint.org/docs/latest/rules/arrow-body-style + */ + 'arrow-body-style': 'error', + + /** + * Enforce the use of variables within the scope they are defined + * + * @link https://eslint.org/docs/latest/rules/block-scoped-var + */ + 'block-scoped-var': 'error', + + /** + * Enforce camelcase naming convention + * + * @link https://eslint.org/docs/latest/rules/camelcase + */ + camelcase: 'off', + + /** + * Enforce or disallow capitalization of the first letter of a comment + * + * @link https://eslint.org/docs/latest/rules/capitalized-comments + */ + 'capitalized-comments': 'off', + + /** + * Enforce that class methods utilize `this` + * + * @link https://eslint.org/docs/latest/rules/class-methods-use-this + */ + 'class-methods-use-this': 'error', + + /** + * Enforce a maximum cyclomatic complexity allowed in a program + * + * @link https://eslint.org/docs/latest/rules/complexity + */ + complexity: 'error', + + /** + * Require `return` statements to either always or never specify values + * + * @link https://eslint.org/docs/latest/rules/consistent-return + */ + 'consistent-return': 'error', + + /** + * Enforce consistent naming when capturing the current execution context + * + * @link https://eslint.org/docs/latest/rules/consistent-this + */ + 'consistent-this': 'error', + + /** + * Enforce consistent brace style for all control statements + * + * @link https://eslint.org/docs/latest/rules/curly + */ + curly: 'error', + + /** + * Require `default` cases in `switch` statements + * + * @link https://eslint.org/docs/latest/rules/default-case + */ + 'default-case': 'error', + + /** + * Enforce default clauses in switch statements to be last + * + * @link https://eslint.org/docs/latest/rules/default-case-last + */ + 'default-case-last': 'error', + + /** + * Enforce default parameters to be last + * + * @link https://eslint.org/docs/latest/rules/default-param-last + */ + 'default-param-last': 'error', + + /** + * Enforce dot notation whenever possible + * + * @link https://eslint.org/docs/latest/rules/dot-notation + */ + 'dot-notation': 'error', + + /** + * Require the use of `===` and `!==` + * + * @link https://eslint.org/docs/latest/rules/eqeqeq + */ + eqeqeq: 'error', + + /** + * Require function names to match the name of the variable or property to which they are assigned + * + * @link https://eslint.org/docs/latest/rules/func-name-matching + */ + 'func-name-matching': 'error', + + /** + * Require or disallow named `function` expressions + * + * @link https://eslint.org/docs/latest/rules/func-names + */ + 'func-names': 'error', + + /** + * Enforce the consistent use of either `function` declarations or expressions + * + * @link https://eslint.org/docs/latest/rules/func-style + */ + 'func-style': 'off', + + /** + * Require grouped accessor pairs in object literals and classes + * + * @link https://eslint.org/docs/latest/rules/grouped-accessor-pairs + */ + 'grouped-accessor-pairs': 'error', + + /** + * Require `for-in` loops to include an `if` statement + * + * @link https://eslint.org/docs/latest/rules/guard-for-in + */ + 'guard-for-in': 'error', + + /** + * Disallow specified identifiers + * + * @link https://eslint.org/docs/latest/rules/id-denylist + */ + 'id-denylist': 'error', + + /** + * Enforce minimum and maximum identifier lengths + * + * @link https://eslint.org/docs/latest/rules/id-length + */ + 'id-length': 'off', + + /** + * Require identifiers to match a specified regular expression + * + * @link https://eslint.org/docs/latest/rules/id-match + */ + 'id-match': 'error', + + /** + * Require or disallow initialization in variable declarations + * + * @link https://eslint.org/docs/latest/rules/init-declarations + */ + 'init-declarations': 'off', + + /** + * Enforce a maximum number of classes per file + * + * @link https://eslint.org/docs/latest/rules/max-classes-per-file + */ + 'max-classes-per-file': 'off', + + /** + * Enforce a maximum depth that blocks can be nested + * + * @link https://eslint.org/docs/latest/rules/max-depth + */ + 'max-depth': 'error', + + /** + * Enforce a maximum number of lines per file + * + * @link https://eslint.org/docs/latest/rules/max-lines + */ + 'max-lines': 'off', + + /** + * Enforce a maximum number of lines of code in a function + * + * @link https://eslint.org/docs/latest/rules/max-lines-per-function + */ + 'max-lines-per-function': 'off', + + /** + * Enforce a maximum depth that callbacks can be nested + * + * @link https://eslint.org/docs/latest/rules/max-nested-callbacks + */ + 'max-nested-callbacks': 'error', + + /** + * Enforce a maximum number of parameters in function definitions + * + * @link https://eslint.org/docs/latest/rules/max-params + */ + 'max-params': 'error', + + /** + * Enforce a maximum number of statements allowed in function blocks + * + * @link https://eslint.org/docs/latest/rules/max-statements + */ + 'max-statements': 'off', + + /** + * Enforce a particular style for multiline comments + * + * @link https://eslint.org/docs/latest/rules/multiline-comment-style + */ + 'multiline-comment-style': 'off', + + /** + * Require constructor names to begin with a capital letter + * + * @link https://eslint.org/docs/latest/rules/new-cap + */ + 'new-cap': ['error', { newIsCap: true, capIsNew: false, properties: true }], + + /** + * Disallow the use of `alert`, `confirm`, and `prompt` + * + * @link https://eslint.org/docs/latest/rules/no-alert + */ + 'no-alert': 'error', + + /** + * Disallow `Array` constructors + * + * @link https://eslint.org/docs/latest/rules/no-array-constructor + */ + 'no-array-constructor': 'error', + + /** + * Disallow bitwise operators + * + * @link https://eslint.org/docs/latest/rules/no-bitwise + */ + 'no-bitwise': 'error', + + /** + * Disallow the use of `arguments.caller` or `arguments.callee` + * + * @link https://eslint.org/docs/latest/rules/no-caller + */ + 'no-caller': 'error', + + /** + * Disallow lexical declarations in case clauses + * + * @link https://eslint.org/docs/latest/rules/no-case-declarations + */ + 'no-case-declarations': 'error', + + /** + * Disallow arrow functions where they could be confused with comparisons + * + * @link https://eslint.org/docs/latest/rules/no-confusing-arrow + */ + 'no-confusing-arrow': 'error', + + /** + * Disallow the use of `console` + * + * @link https://eslint.org/docs/latest/rules/no-console + */ + 'no-console': 'warn', + + /** + * Disallow `continue` statements + * + * @link https://eslint.org/docs/latest/rules/no-continue + */ + 'no-continue': 'error', + + /** + * Disallow deleting variables + * + * @link https://eslint.org/docs/latest/rules/no-delete-var + */ + 'no-delete-var': 'error', + + /** + * Disallow division operators explicitly at the beginning of regular expressions + * + * @link https://eslint.org/docs/latest/rules/no-div-regex + */ + 'no-div-regex': 'error', + + /** + * Disallow `else` blocks after `return` statements in `if` statements + * + * @link https://eslint.org/docs/latest/rules/no-else-return + */ + 'no-else-return': 'error', + + /** + * Disallow empty block statements + * + * @link https://eslint.org/docs/latest/rules/no-empty + */ + 'no-empty': [ + 'error', + { + allowEmptyCatch: true + } + ], + + /** + * Disallow empty functions + * + * @link https://eslint.org/docs/latest/rules/no-empty-function + */ + 'no-empty-function': 'error', + + /** + * Disallow `null` comparisons without type-checking operators + * + * @link https://eslint.org/docs/latest/rules/no-eq-null + */ + 'no-eq-null': 'error', + + /** + * Disallow the use of `eval()` + * + * @link https://eslint.org/docs/latest/rules/no-eval + */ + 'no-eval': 'error', + + /** + * Disallow extending native types + * + * @link https://eslint.org/docs/latest/rules/no-extend-native + */ + 'no-extend-native': 'error', + + /** + * Disallow unnecessary calls to `.bind()` + * + * @link https://eslint.org/docs/latest/rules/no-extra-bind + */ + 'no-extra-bind': 'error', + + /** + * Disallow unnecessary boolean casts + * + * @link https://eslint.org/docs/latest/rules/no-extra-boolean-cast + */ + 'no-extra-boolean-cast': 'error', + + /** + * Disallow unnecessary labels + * + * @link https://eslint.org/docs/latest/rules/no-extra-label + */ + 'no-extra-label': 'error', + + /** + * Disallow unnecessary semicolons + * + * @link https://eslint.org/docs/latest/rules/no-extra-semi + */ + 'no-extra-semi': 'error', + + /** + * Disallow leading or trailing decimal points in numeric literals + * + * @link https://eslint.org/docs/latest/rules/no-floating-decimal + */ + 'no-floating-decimal': 'error', + + /** + * Disallow assignments to native objects or read-only global variables + * + * @link https://eslint.org/docs/latest/rules/no-global-assign + */ + 'no-global-assign': 'error', + + /** + * Disallow shorthand type conversions + * + * @link https://eslint.org/docs/latest/rules/no-implicit-coercion + */ + 'no-implicit-coercion': 'error', + + /** + * Disallow declarations in the global scope + * + * @link https://eslint.org/docs/latest/rules/no-implicit-globals + */ + 'no-implicit-globals': 'error', + + /** + * Disallow the use of `eval()`-like methods + * + * @link https://eslint.org/docs/latest/rules/no-implied-eval + */ + 'no-implied-eval': 'error', + + /** + * Disallow inline comments after code + * + * @link https://eslint.org/docs/latest/rules/no-inline-comments + */ + 'no-inline-comments': 'off', + + /** + * Disallow use of `this` in contexts where the value of `this` is `undefined` + * + * @link https://eslint.org/docs/latest/rules/no-invalid-this + */ + 'no-invalid-this': 'error', + + /** + * Disallow the use of the `__iterator__` property + * + * @link https://eslint.org/docs/latest/rules/no-iterator + */ + 'no-iterator': 'error', + + /** + * Disallow labels that share a name with a variable + * + * @link https://eslint.org/docs/latest/rules/no-label-var + */ + 'no-label-var': 'error', + + /** + * Disallow labeled statements + * + * @link https://eslint.org/docs/latest/rules/no-labels + */ + 'no-labels': 'error', + + /** + * Disallow unnecessary nested blocks + * + * @link https://eslint.org/docs/latest/rules/no-lone-blocks + */ + 'no-lone-blocks': 'error', + + /** + * Disallow `if` statements as the only statement in `else` blocks + * + * @link https://eslint.org/docs/latest/rules/no-lonely-if + */ + 'no-lonely-if': 'error', + + /** + * Disallow function declarations that contain unsafe references inside loop statements + * + * @link https://eslint.org/docs/latest/rules/no-loop-func + */ + 'no-loop-func': 'error', + + /** + * Disallow magic numbers + * + * @link https://eslint.org/docs/latest/rules/no-magic-numbers + */ + 'no-magic-numbers': 'off', + + /** + * Disallow mixed binary operators + * + * @link https://eslint.org/docs/latest/rules/no-mixed-operators + */ + 'no-mixed-operators': [ + 'error', + { + groups: [ + ['+', '-', '*', '/', '%', '**'], + ['&', '|', '^', '~', '<<', '>>', '>>>'], + ['==', '!=', '===', '!==', '>', '>=', '<', '<='], + ['&&', '||'], + ['in', 'instanceof'] + ], + allowSamePrecedence: true + } + ], + + /** + * Disallow use of chained assignment expressions + * + * @link https://eslint.org/docs/latest/rules/no-multi-assign + */ + 'no-multi-assign': 'error', + + /** + * Disallow multiline strings + * + * @link https://eslint.org/docs/latest/rules/no-multi-str + */ + 'no-multi-str': 'error', + + /** + * Disallow negated conditions + * + * @link https://eslint.org/docs/latest/rules/no-negated-condition + */ + 'no-negated-condition': 'off', + + /** + * Disallow nested ternary expressions + * + * @link https://eslint.org/docs/latest/rules/no-nested-ternary + */ + 'no-nested-ternary': 'error', + + /** + * Disallow `new` operators outside of assignments or comparisons + * + * @link https://eslint.org/docs/latest/rules/no-new + */ + 'no-new': 'error', + + /** + * Disallow `new` operators with the `Function` object + * + * @link https://eslint.org/docs/latest/rules/no-new-func + */ + 'no-new-func': 'error', + + /** + * Disallow `Object` constructors + * + * @link https://eslint.org/docs/latest/rules/no-new-object + */ + 'no-new-object': 'error', + + /** + * Disallow `new` operators with the `String`, `Number`, and `Boolean` objects + * + * @link https://eslint.org/docs/latest/rules/no-new-wrappers + */ + 'no-new-wrappers': 'error', + + /** + * Disallow `\\8` and `\\9` escape sequences in string literals + * + * @link https://eslint.org/docs/latest/rules/no-nonoctal-decimal-escape + */ + 'no-nonoctal-decimal-escape': 'error', + + /** + * Disallow octal literals + * + * @link https://eslint.org/docs/latest/rules/no-octal + */ + 'no-octal': 'error', + + /** + * Disallow octal escape sequences in string literals + * + * @link https://eslint.org/docs/latest/rules/no-octal-escape + */ + 'no-octal-escape': 'error', + + /** + * Disallow reassigning `function` parameters + * + * @link https://eslint.org/docs/latest/rules/no-param-reassign + */ + 'no-param-reassign': 'error', + + /** + * Disallow the unary operators `++` and `--` + * + * @link https://eslint.org/docs/latest/rules/no-plusplus + */ + 'no-plusplus': 'error', + + /** + * Disallow the use of the `__proto__` property + * + * @link https://eslint.org/docs/latest/rules/no-proto + */ + 'no-proto': 'error', + + /** + * Disallow variable redeclaration + * + * @link https://eslint.org/docs/latest/rules/no-redeclare + */ + 'no-redeclare': 'error', + + /** + * Disallow multiple spaces in regular expressions + * + * @link https://eslint.org/docs/latest/rules/no-regex-spaces + */ + 'no-regex-spaces': 'error', + + /** + * Disallow specified names in exports + * + * @link https://eslint.org/docs/latest/rules/no-restricted-exports + */ + 'no-restricted-exports': 'error', + + /** + * Disallow specified global variables + * + * @link https://eslint.org/docs/latest/rules/no-restricted-globals + */ + 'no-restricted-globals': 'error', + + /** + * Disallow specified modules when loaded by `import` + * + * @link https://eslint.org/docs/latest/rules/no-restricted-imports + */ + 'no-restricted-imports': 'error', + + /** + * Disallow certain properties on certain objects + * + * @link https://eslint.org/docs/latest/rules/no-restricted-properties + */ + 'no-restricted-properties': 'error', + + /** + * Disallow specified syntax + * + * @link https://eslint.org/docs/latest/rules/no-restricted-syntax + */ + 'no-restricted-syntax': ['error', 'DebuggerStatement', 'LabeledStatement', 'WithStatement'], + + /** + * Disallow assignment operators in `return` statements + * + * @link https://eslint.org/docs/latest/rules/no-return-assign + */ + 'no-return-assign': 'error', + + /** + * Disallow unnecessary `return await` + * + * @link https://eslint.org/docs/latest/rules/no-return-await + */ + 'no-return-await': 'error', + + /** + * Disallow `javascript:` urls + * + * @link https://eslint.org/docs/latest/rules/no-script-url + */ + 'no-script-url': 'error', + + /** + * Disallow comma operators + * + * @link https://eslint.org/docs/latest/rules/no-sequences + */ + 'no-sequences': 'error', + + /** + * Disallow variable declarations from shadowing variables declared in the outer scope + * + * @link https://eslint.org/docs/latest/rules/no-shadow + */ + 'no-shadow': 'error', + + /** + * Disallow identifiers from shadowing restricted names + * + * @link https://eslint.org/docs/latest/rules/no-shadow-restricted-names + */ + 'no-shadow-restricted-names': 'error', + + /** + * Disallow ternary operators + * + * @link https://eslint.org/docs/latest/rules/no-ternary + */ + 'no-ternary': 'off', + + /** + * Disallow throwing literals as exceptions + * + * @link https://eslint.org/docs/latest/rules/no-throw-literal + */ + 'no-throw-literal': 'error', + + /** + * Disallow initializing variables to `undefined` + * + * @link https://eslint.org/docs/latest/rules/no-undef-init + */ + 'no-undef-init': 'error', + + /** + * Disallow the use of `undefined` as an identifier + * + * @link https://eslint.org/docs/latest/rules/no-undefined + */ + 'no-undefined': 'off', + + /** + * Disallow dangling underscores in identifiers + * + * @link https://eslint.org/docs/latest/rules/no-underscore-dangle + */ + 'no-underscore-dangle': 'error', + + /** + * Disallow ternary operators when simpler alternatives exist + * + * @link https://eslint.org/docs/latest/rules/no-unneeded-ternary + */ + 'no-unneeded-ternary': 'error', + + /** + * Disallow unused expressions + * + * @link https://eslint.org/docs/latest/rules/no-unused-expressions + */ + 'no-unused-expressions': 'error', + + /** + * Disallow unused labels + * + * @link https://eslint.org/docs/latest/rules/no-unused-labels + */ + 'no-unused-labels': 'error', + + /** + * Disallow unnecessary calls to `.call()` and `.apply()` + * + * @link https://eslint.org/docs/latest/rules/no-useless-call + */ + 'no-useless-call': 'error', + + /** + * Disallow unnecessary `catch` clauses + * + * @link https://eslint.org/docs/latest/rules/no-useless-catch + */ + 'no-useless-catch': 'error', + + /** + * Disallow unnecessary computed property keys in objects and classes + * + * @link https://eslint.org/docs/latest/rules/no-useless-computed-key + */ + 'no-useless-computed-key': 'error', + + /** + * Disallow unnecessary concatenation of literals or template literals + * + * @link https://eslint.org/docs/latest/rules/no-useless-concat + */ + 'no-useless-concat': 'error', + + /** + * Disallow unnecessary constructors + * + * @link https://eslint.org/docs/latest/rules/no-useless-constructor + */ + 'no-useless-constructor': 'error', + + /** + * Disallow unnecessary escape characters + * + * @link https://eslint.org/docs/latest/rules/no-useless-escape + */ + 'no-useless-escape': 'error', + + /** + * Disallow renaming import, export, and destructured assignments to the same name + * + * @link https://eslint.org/docs/latest/rules/no-useless-rename + */ + 'no-useless-rename': 'error', + + /** + * Disallow redundant return statements + * + * @link https://eslint.org/docs/latest/rules/no-useless-return + */ + 'no-useless-return': 'error', + + /** + * Require `let` or `const` instead of `var` + * + * @link https://eslint.org/docs/latest/rules/no-var + */ + 'no-var': 'error', + + /** + * Disallow `void` operators + * + * @link https://eslint.org/docs/latest/rules/no-void + */ + 'no-void': 'error', + + /** + * Disallow specified warning terms in comments + * + * @link https://eslint.org/docs/latest/rules/no-warning-comments + */ + 'no-warning-comments': 'error', + + /** + * Disallow `with` statements + * + * @link https://eslint.org/docs/latest/rules/no-with + */ + 'no-with': 'error', + + /** + * Require or disallow method and property shorthand syntax for object literals + * + * @link https://eslint.org/docs/latest/rules/object-shorthand + */ + 'object-shorthand': [ + 'error', + 'always', + { + ignoreConstructors: false, + avoidQuotes: true + } + ], + + /** + * Enforce variables to be declared either together or separately in functions + * + * @link https://eslint.org/docs/latest/rules/one-var + */ + 'one-var': ['error', 'never'], + + /** + * Require or disallow newlines around variable declarations + * + * @link https://eslint.org/docs/latest/rules/one-var-declaration-per-line + */ + 'one-var-declaration-per-line': 'error', + + /** + * Require or disallow assignment operator shorthand where possible + * + * @link https://eslint.org/docs/latest/rules/operator-assignment + */ + 'operator-assignment': 'error', + + /** + * Require using arrow functions for callbacks + * + * @link https://eslint.org/docs/latest/rules/prefer-arrow-callback + */ + 'prefer-arrow-callback': 'error', + + /** + * Require `const` declarations for variables that are never reassigned after declared + * + * @link https://eslint.org/docs/latest/rules/prefer-const + */ + 'prefer-const': 'error', + + /** + * Require destructuring from arrays and/or objects + * + * @link https://eslint.org/docs/latest/rules/prefer-destructuring + */ + 'prefer-destructuring': 'off', + + /** + * Disallow the use of `Math.pow` in favor of the `**` operator + * + * @link https://eslint.org/docs/latest/rules/prefer-exponentiation-operator + */ + 'prefer-exponentiation-operator': 'error', + + /** + * Enforce using named capture group in regular expression + * + * @link https://eslint.org/docs/latest/rules/prefer-named-capture-group + */ + 'prefer-named-capture-group': 'off', + + /** + * Disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals + * + * @link https://eslint.org/docs/latest/rules/prefer-numeric-literals + */ + 'prefer-numeric-literals': 'error', + + /** + * Disallow use of `Object.prototype.hasOwnProperty.call()` and prefer use of `Object.hasOwn()` + * + * @link https://eslint.org/docs/latest/rules/prefer-object-has-own + */ + 'prefer-object-has-own': 'error', + + /** + * Disallow using Object.assign with an object literal as the first argument and prefer the use of object spread + * instead. + * + * @link https://eslint.org/docs/latest/rules/prefer-object-spread + */ + 'prefer-object-spread': 'error', + + /** + * Require using Error objects as Promise rejection reasons + * + * @link https://eslint.org/docs/latest/rules/prefer-promise-reject-errors + */ + 'prefer-promise-reject-errors': 'error', + + /** + * Disallow use of the `RegExp` constructor in favor of regular expression literals + * + * @link https://eslint.org/docs/latest/rules/prefer-regex-literals + */ + 'prefer-regex-literals': 'error', + + /** + * Require rest parameters instead of `arguments` + * + * @link https://eslint.org/docs/latest/rules/prefer-rest-params + */ + 'prefer-rest-params': 'error', + + /** + * Require spread operators instead of `.apply()` + * + * @link https://eslint.org/docs/latest/rules/prefer-spread + */ + 'prefer-spread': 'error', + + /** + * Require template literals instead of string concatenation + * + * @link https://eslint.org/docs/latest/rules/prefer-template + */ + 'prefer-template': 'error', + + /** + * Require quotes around object literal property names + * + * @link https://eslint.org/docs/latest/rules/quote-props + */ + 'quote-props': 'error', + + /** + * Enforce the consistent use of the radix argument when using `parseInt()` + * + * @link https://eslint.org/docs/latest/rules/radix + */ + radix: 'error', + + /** + * Disallow async functions which have no `await` expression + * + * @link https://eslint.org/docs/latest/rules/require-await + */ + 'require-await': 'off', + + /** + * Enforce the use of `u` flag on RegExp + * + * @link https://eslint.org/docs/latest/rules/require-unicode-regexp + */ + 'require-unicode-regexp': 'off', + + /** + * Require generator functions to contain `yield` + * + * @link https://eslint.org/docs/latest/rules/require-yield + */ + 'require-yield': 'error', + + /** + * Enforce sorted import declarations within modules + * + * @link https://eslint.org/docs/latest/rules/sort-imports + */ + 'sort-imports': 'off', + + /** + * Require object keys to be sorted + * + * @link https://eslint.org/docs/latest/rules/sort-keys + */ + 'sort-keys': 'off', + + /** + * Require variables within the same declaration block to be sorted + * + * @link https://eslint.org/docs/latest/rules/sort-vars + */ + 'sort-vars': 'error', + + /** + * Enforce consistent spacing after the `//` or `/*` in a comment + * + * @link https://eslint.org/docs/latest/rules/spaced-comment + */ + 'spaced-comment': [ + 'error', + 'always', + { + line: { markers: ['*package', '!', '/', ',', '='] }, + block: { + balanced: true, + markers: ['*package', '!', ',', ':', '::', 'flow-include'], + exceptions: ['*'] + } + } + ], + + /** + * Require or disallow strict mode directives + * + * @link https://eslint.org/docs/latest/rules/strict + */ + strict: 'error', + + /** + * Require symbol descriptions + * + * @link https://eslint.org/docs/latest/rules/symbol-description + */ + 'symbol-description': 'error', + + /** + * Require `var` declarations be placed at the top of their containing scope + * + * @link https://eslint.org/docs/latest/rules/vars-on-top + */ + 'vars-on-top': 'error', + + /** + * Require or disallow "Yoda" conditions + * + * @link https://eslint.org/docs/latest/rules/yoda + */ + yoda: 'error', + + // End + + /* + * Layout & Formatting + * These rules care about how the code looks rather than how it executes: + */ + + /** + * Enforce linebreaks after opening and before closing array brackets + * + * @link https://eslint.org/docs/latest/rules/array-bracket-newline + */ + 'array-bracket-newline': 'error', + + /** + * Enforce consistent spacing inside array brackets + * + * @link https://eslint.org/docs/latest/rules/array-bracket-spacing + */ + 'array-bracket-spacing': 'error', + + /** + * Enforce line breaks after each array element + * + * @link https://eslint.org/docs/latest/rules/array-element-newline + */ + 'array-element-newline': 'error', + + /** + * Require parentheses around arrow function arguments + * + * @link https://eslint.org/docs/latest/rules/arrow-parens + */ + 'arrow-parens': ['error', 'as-needed'], + + /** + * Enforce consistent spacing before and after the arrow in arrow functions + * + * @link https://eslint.org/docs/latest/rules/arrow-spacing + */ + 'arrow-spacing': 'error', + + /** + * Disallow or enforce spaces inside of blocks after opening block and before closing block + * + * @link https://eslint.org/docs/latest/rules/block-spacing + */ + 'block-spacing': 'error', + + /** + * Enforce consistent brace style for blocks + * + * @link https://eslint.org/docs/latest/rules/brace-style + */ + 'brace-style': 'error', + + /** + * Require or disallow trailing commas + * + * @link https://eslint.org/docs/latest/rules/comma-dangle + */ + 'comma-dangle': 'error', + + /** + * Enforce consistent spacing before and after commas + * + * @link https://eslint.org/docs/latest/rules/comma-spacing + */ + 'comma-spacing': 'error', + + /** + * Enforce consistent comma style + * + * @link https://eslint.org/docs/latest/rules/comma-style + */ + 'comma-style': 'error', + + /** + * Enforce consistent spacing inside computed property brackets + * + * @link https://eslint.org/docs/latest/rules/computed-property-spacing + */ + 'computed-property-spacing': 'error', + + /** + * Enforce consistent newlines before and after dots + * + * @link https://eslint.org/docs/latest/rules/dot-location + */ + 'dot-location': ['error', 'property'], + + /** + * Require or disallow newline at the end of files + * + * @link https://eslint.org/docs/latest/rules/eol-last + */ + 'eol-last': 'error', + + /** + * Require or disallow spacing between function identifiers and their invocations + * + * @link https://eslint.org/docs/latest/rules/func-call-spacing + */ + 'func-call-spacing': 'error', + + /** + * Enforce line breaks between arguments of a function call + * + * @link https://eslint.org/docs/latest/rules/function-call-argument-newline + */ + 'function-call-argument-newline': 'error', + + /** + * Enforce consistent line breaks inside function parentheses + * + * @link https://eslint.org/docs/latest/rules/function-paren-newline + */ + 'function-paren-newline': 'error', + + /** + * Enforce consistent spacing around `*` operators in generator functions + * + * @link https://eslint.org/docs/latest/rules/generator-star-spacing + */ + 'generator-star-spacing': 'error', + + /** + * Enforce the location of arrow function bodies + * + * @link https://eslint.org/docs/latest/rules/implicit-arrow-linebreak + */ + 'implicit-arrow-linebreak': 'error', + + /** + * Enforce consistent indentation + * + * @link https://eslint.org/docs/latest/rules/indent + */ + indent: [ + 'error', + 2, + { + SwitchCase: 1, + VariableDeclarator: 1, + outerIIFEBody: 1, + MemberExpression: 1, + FunctionDeclaration: { parameters: 1, body: 1 }, + FunctionExpression: { parameters: 1, body: 1 }, + CallExpression: { arguments: 1 }, + ArrayExpression: 1, + ObjectExpression: 1, + ImportDeclaration: 1, + flatTernaryExpressions: false, + ignoreComments: false, + ignoredNodes: [ + 'TemplateLiteral *', + 'JSXElement', + 'JSXElement > *', + 'JSXAttribute', + 'JSXIdentifier', + 'JSXNamespacedName', + 'JSXMemberExpression', + 'JSXSpreadAttribute', + 'JSXExpressionContainer', + 'JSXOpeningElement', + 'JSXClosingElement', + 'JSXFragment', + 'JSXOpeningFragment', + 'JSXClosingFragment', + 'JSXText', + 'JSXEmptyExpression', + 'JSXSpreadChild' + ], + offsetTernaryExpressions: true + } + ], + + /** + * Enforce the consistent use of either double or single quotes in JSX attributes + * + * @link https://eslint.org/docs/latest/rules/jsx-quotes + */ + 'jsx-quotes': 'error', + + /** + * Enforce consistent spacing between keys and values in object literal properties + * + * @link https://eslint.org/docs/latest/rules/key-spacing + */ + 'key-spacing': 'error', + + /** + * Enforce consistent spacing before and after keywords + * + * @link https://eslint.org/docs/latest/rules/keyword-spacing + */ + 'keyword-spacing': 'error', + + /** + * Enforce position of line comments + * + * @link https://eslint.org/docs/latest/rules/line-comment-position + */ + 'line-comment-position': 'off', + + /** + * Enforce consistent linebreak style + * + * @link https://eslint.org/docs/latest/rules/linebreak-style + */ + 'linebreak-style': 'error', + + /** + * Require empty lines around comments + * + * @link https://eslint.org/docs/latest/rules/lines-around-comment + */ + 'lines-around-comment': 'error', + + /** + * Require or disallow an empty line between class members + * + * @link https://eslint.org/docs/latest/rules/lines-between-class-members + */ + 'lines-between-class-members': 'error', + + /** + * Enforce a maximum line length + * + * @link https://eslint.org/docs/latest/rules/max-len + */ + 'max-len': 'error', + + /** + * Enforce a maximum number of statements allowed per line + * + * @link https://eslint.org/docs/latest/rules/max-statements-per-line + */ + 'max-statements-per-line': 'off', + + /** + * Enforce newlines between operands of ternary expressions + * + * @link https://eslint.org/docs/latest/rules/multiline-ternary + */ + 'multiline-ternary': ['error', 'always-multiline'], + + /** + * Enforce or disallow parentheses when invoking a constructor with no arguments + * + * @link https://eslint.org/docs/latest/rules/new-parens + */ + 'new-parens': 'error', + + /** + * Require a newline after each call in a method chain + * + * @link https://eslint.org/docs/latest/rules/newline-per-chained-call + */ + 'newline-per-chained-call': 'error', + + /** + * Disallow unnecessary parentheses + * + * @link https://eslint.org/docs/latest/rules/no-extra-parens + */ + 'no-extra-parens': 'error', + + /** + * Disallow mixed spaces and tabs for indentation + * + * @link https://eslint.org/docs/latest/rules/no-mixed-spaces-and-tabs + */ + 'no-mixed-spaces-and-tabs': 'error', + + /** + * Disallow multiple spaces + * + * @link https://eslint.org/docs/latest/rules/no-multi-spaces + */ + 'no-multi-spaces': 'error', + + /** + * Disallow multiple empty lines + * + * @link https://eslint.org/docs/latest/rules/no-multiple-empty-lines + */ + 'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 0 }], + + /** + * Disallow all tabs + * + * @link https://eslint.org/docs/latest/rules/no-tabs + */ + 'no-tabs': 'error', + + /** + * Disallow trailing whitespace at the end of lines + * + * @link https://eslint.org/docs/latest/rules/no-trailing-spaces + */ + 'no-trailing-spaces': 'error', + + /** + * Disallow whitespace before properties + * + * @link https://eslint.org/docs/latest/rules/no-whitespace-before-property + */ + 'no-whitespace-before-property': 'error', + + /** + * Enforce the location of single-line statements + * + * @link https://eslint.org/docs/latest/rules/nonblock-statement-body-position + */ + 'nonblock-statement-body-position': 'error', + + /** + * Enforce consistent line breaks after opening and before closing braces + * + * @link https://eslint.org/docs/latest/rules/object-curly-newline + */ + 'object-curly-newline': 'error', + + /** + * Enforce consistent spacing inside braces + * + * @link https://eslint.org/docs/latest/rules/object-curly-spacing + */ + 'object-curly-spacing': 'error', + + /** + * Enforce placing object properties on separate lines + * + * @link https://eslint.org/docs/latest/rules/object-property-newline + */ + 'object-property-newline': 'error', + + /** + * Enforce consistent linebreak style for operators + * + * @link https://eslint.org/docs/latest/rules/operator-linebreak + */ + 'operator-linebreak': 'error', + + /** + * Require or disallow padding within blocks + * + * @link https://eslint.org/docs/latest/rules/padded-blocks + */ + 'padded-blocks': 'error', + + /** + * Require or disallow padding lines between statements + * + * @link https://eslint.org/docs/latest/rules/padding-line-between-statements + */ + 'padding-line-between-statements': 'error', + + /** + * Enforce the consistent use of either backticks, double, or single quotes + * + * @link https://eslint.org/docs/latest/rules/quotes + */ + quotes: 'error', + + /** + * Enforce spacing between rest and spread operators and their expressions + * + * @link https://eslint.org/docs/latest/rules/rest-spread-spacing + */ + 'rest-spread-spacing': 'error', + + /** + * Require or disallow semicolons instead of ASI + * + * @link https://eslint.org/docs/latest/rules/semi + */ + semi: 'error', + + /** + * Enforce consistent spacing before and after semicolons + * + * @link https://eslint.org/docs/latest/rules/semi-spacing + */ + 'semi-spacing': 'error', + + /** + * Enforce location of semicolons + * + * @link https://eslint.org/docs/latest/rules/semi-style + */ + 'semi-style': 'error', + + /** + * Enforce consistent spacing before blocks + * + * @link https://eslint.org/docs/latest/rules/space-before-blocks + */ + 'space-before-blocks': 'error', + + /** + * Enforce consistent spacing before `function` definition opening parenthesis + * + * @link https://eslint.org/docs/latest/rules/space-before-function-paren + */ + 'space-before-function-paren': 'error', + + /** + * Enforce consistent spacing inside parentheses + * + * @link https://eslint.org/docs/latest/rules/space-in-parens + */ + 'space-in-parens': 'error', + + /** + * Require spacing around infix operators + * + * @link https://eslint.org/docs/latest/rules/space-infix-ops + */ + 'space-infix-ops': 'error', + + /** + * Enforce consistent spacing before or after unary operators + * + * @link https://eslint.org/docs/latest/rules/space-unary-ops + */ + 'space-unary-ops': 'error', + + /** + * Enforce spacing around colons of switch statements + * + * @link https://eslint.org/docs/latest/rules/switch-colon-spacing + */ + 'switch-colon-spacing': 'error', + + /** + * Require or disallow spacing around embedded expressions of template strings + * + * @link https://eslint.org/docs/latest/rules/template-curly-spacing + */ + 'template-curly-spacing': 'error', + + /** + * Require or disallow spacing between template tags and their literals + * + * @link https://eslint.org/docs/latest/rules/template-tag-spacing + */ + 'template-tag-spacing': 'error', + + /** + * Require or disallow Unicode byte order mark (BOM) + * + * @link https://eslint.org/docs/latest/rules/unicode-bom + */ + 'unicode-bom': 'error', + + /** + * Require parentheses around immediate `function` invocations + * + * @link https://eslint.org/docs/latest/rules/wrap-iife + */ + 'wrap-iife': 'error', + + /** + * Require parenthesis around regex literals + * + * @link https://eslint.org/docs/latest/rules/wrap-regex + */ + 'wrap-regex': 'error', + + /** + * Require or disallow spacing around the `*` in `yield*` expressions + * + * @link https://eslint.org/docs/latest/rules/yield-star-spacing + */ + 'yield-star-spacing': 'error' + } +}; diff --git a/packages/eslint-config/rules/prettier.js b/packages/eslint-config/rules/prettier.js new file mode 100644 index 0000000..469cc1b --- /dev/null +++ b/packages/eslint-config/rules/prettier.js @@ -0,0 +1,24 @@ +/** @type {import('prettier').Options} */ +module.exports = { + printWidth: 120, + tabWidth: 2, + useTabs: false, + semi: true, + singleQuote: true, + quoteProps: 'as-needed', + jsxSingleQuote: false, + trailingComma: 'none', + bracketSpacing: true, + bracketSameLine: false, + arrowParens: 'avoid', + rangeStart: 0, + rangeEnd: Number.POSITIVE_INFINITY, + requirePragma: false, + insertPragma: false, + proseWrap: 'preserve', + htmlWhitespaceSensitivity: 'ignore', + vueIndentScriptAndStyle: false, + endOfLine: 'lf', + embeddedLanguageFormatting: 'auto', + singleAttributePerLine: false +}; diff --git a/packages/hooks/package.json b/packages/hooks/package.json new file mode 100644 index 0000000..8329fd6 --- /dev/null +++ b/packages/hooks/package.json @@ -0,0 +1,15 @@ +{ + "name": "@sa/hooks", + "version": "1.0.0", + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + }, + "dependencies": { + "@sa/axios": "workspace:*" + } +} diff --git a/packages/hooks/src/index.ts b/packages/hooks/src/index.ts new file mode 100644 index 0000000..a36c843 --- /dev/null +++ b/packages/hooks/src/index.ts @@ -0,0 +1,10 @@ +import useBoolean from './use-boolean'; +import useLoading from './use-loading'; +import useCountDown from './use-count-down'; +import useContext from './use-context'; +import useSvgIconRender from './use-svg-icon-render'; +import useHookTable from './use-table'; + +export { useBoolean, useLoading, useCountDown, useContext, useSvgIconRender, useHookTable }; + +export * from './use-table'; diff --git a/packages/hooks/src/use-boolean.ts b/packages/hooks/src/use-boolean.ts new file mode 100644 index 0000000..a60d45a --- /dev/null +++ b/packages/hooks/src/use-boolean.ts @@ -0,0 +1,31 @@ +import { ref } from 'vue'; + +/** + * Boolean + * + * @param initValue Init value + */ +export default function useBoolean(initValue = false) { + const bool = ref(initValue); + + function setBool(value: boolean) { + bool.value = value; + } + function setTrue() { + setBool(true); + } + function setFalse() { + setBool(false); + } + function toggle() { + setBool(!bool.value); + } + + return { + bool, + setBool, + setTrue, + setFalse, + toggle + }; +} diff --git a/packages/hooks/src/use-context.ts b/packages/hooks/src/use-context.ts new file mode 100644 index 0000000..001d8aa --- /dev/null +++ b/packages/hooks/src/use-context.ts @@ -0,0 +1,96 @@ +import { inject, provide } from 'vue'; +import type { InjectionKey } from 'vue'; + +/** + * Use context + * + * @example + * ```ts + * // there are three vue files: A.vue, B.vue, C.vue, and A.vue is the parent component of B.vue and C.vue + * + * // context.ts + * import { ref } from 'vue'; + * import { useContext } from '@sa/hooks'; + * + * export const { setupStore, useStore } = useContext('demo', () => { + * const count = ref(0); + * + * function increment() { + * count.value++; + * } + * + * function decrement() { + * count.value--; + * } + * + * return { + * count, + * increment, + * decrement + * }; + * }) + * ``` // A.vue + * ```vue + * + * + * ``` // B.vue + * ```vue + * + * + * ```; + * + * // C.vue is same as B.vue + * + * @param contextName Context name + * @param fn Context function + */ +export default function useContext any>(contextName: string, fn: T) { + type Context = ReturnType; + + const { useProvide, useInject: useStore } = createContext(contextName); + + function setupStore(...args: Parameters) { + const context: Context = fn(...args); + return useProvide(context); + } + + return { + /** Setup store in the parent component */ + setupStore, + /** Use store in the child component */ + useStore + }; +} + +/** Create context */ +function createContext(contextName: string) { + const injectKey: InjectionKey = Symbol(contextName); + + function useProvide(context: T) { + provide(injectKey, context); + + return context; + } + + function useInject() { + return inject(injectKey) as T; + } + + return { + useProvide, + useInject + }; +} diff --git a/packages/hooks/src/use-count-down.ts b/packages/hooks/src/use-count-down.ts new file mode 100644 index 0000000..bfad064 --- /dev/null +++ b/packages/hooks/src/use-count-down.ts @@ -0,0 +1,49 @@ +import { computed, onScopeDispose, ref } from 'vue'; +import { useRafFn } from '@vueuse/core'; + +/** + * count down + * + * @param seconds - count down seconds + */ +export default function useCountDown(seconds: number) { + const FPS_PER_SECOND = 60; + + const fps = ref(0); + + const count = computed(() => Math.ceil(fps.value / FPS_PER_SECOND)); + + const isCounting = computed(() => fps.value > 0); + + const { pause, resume } = useRafFn( + () => { + if (fps.value > 0) { + fps.value -= 1; + } else { + pause(); + } + }, + { immediate: false } + ); + + function start(updateSeconds: number = seconds) { + fps.value = FPS_PER_SECOND * updateSeconds; + resume(); + } + + function stop() { + fps.value = 0; + pause(); + } + + onScopeDispose(() => { + pause(); + }); + + return { + count, + isCounting, + start, + stop + }; +} diff --git a/packages/hooks/src/use-loading.ts b/packages/hooks/src/use-loading.ts new file mode 100644 index 0000000..b8f89ad --- /dev/null +++ b/packages/hooks/src/use-loading.ts @@ -0,0 +1,16 @@ +import useBoolean from './use-boolean'; + +/** + * Loading + * + * @param initValue Init value + */ +export default function useLoading(initValue = false) { + const { bool: loading, setTrue: startLoading, setFalse: endLoading } = useBoolean(initValue); + + return { + loading, + startLoading, + endLoading + }; +} diff --git a/packages/hooks/src/use-request.ts b/packages/hooks/src/use-request.ts new file mode 100644 index 0000000..a0a40e6 --- /dev/null +++ b/packages/hooks/src/use-request.ts @@ -0,0 +1,79 @@ +import { ref } from 'vue'; +import type { Ref } from 'vue'; +import { createFlatRequest } from '@sa/axios'; +import type { + AxiosError, + CreateAxiosDefaults, + CustomAxiosRequestConfig, + MappedType, + RequestOption, + ResponseType +} from '@sa/axios'; +import useLoading from './use-loading'; + +export type HookRequestInstanceResponseSuccessData = { + data: Ref; + error: Ref; +}; + +export type HookRequestInstanceResponseFailData = { + data: Ref; + error: Ref>; +}; + +export type HookRequestInstanceResponseData = { + loading: Ref; +} & (HookRequestInstanceResponseSuccessData | HookRequestInstanceResponseFailData); + +export interface HookRequestInstance { + ( + config: CustomAxiosRequestConfig + ): HookRequestInstanceResponseData, ResponseData>; + cancelRequest: (requestId: string) => void; + cancelAllRequest: () => void; +} + +/** + * create a hook request instance + * + * @param axiosConfig + * @param options + */ +export default function createHookRequest( + axiosConfig?: CreateAxiosDefaults, + options?: Partial> +) { + const request = createFlatRequest(axiosConfig, options); + + const hookRequest: HookRequestInstance = function hookRequest( + config: CustomAxiosRequestConfig + ) { + const { loading, startLoading, endLoading } = useLoading(); + + const data = ref | null>(null) as Ref>; + const error = ref | null>(null) as Ref | null>; + + startLoading(); + + request(config).then(res => { + if (res.data) { + data.value = res.data; + } else { + error.value = res.error; + } + + endLoading(); + }); + + return { + loading, + data, + error + }; + } as HookRequestInstance; + + hookRequest.cancelRequest = request.cancelRequest; + hookRequest.cancelAllRequest = request.cancelAllRequest; + + return hookRequest; +} diff --git a/packages/hooks/src/use-svg-icon-render.ts b/packages/hooks/src/use-svg-icon-render.ts new file mode 100644 index 0000000..62c2206 --- /dev/null +++ b/packages/hooks/src/use-svg-icon-render.ts @@ -0,0 +1,50 @@ +import { h } from 'vue'; +import type { Component } from 'vue'; + +/** + * Svg icon render hook + * + * @param SvgIcon Svg icon component + */ +export default function useSvgIconRender(SvgIcon: Component) { + interface IconConfig { + /** Iconify icon name */ + icon?: string; + /** Local icon name */ + localIcon?: string; + /** Icon color */ + color?: string; + /** Icon size */ + fontSize?: number; + } + + type IconStyle = Partial>; + + /** + * Svg icon VNode + * + * @param config + */ + const SvgIconVNode = (config: IconConfig) => { + const { color, fontSize, icon, localIcon } = config; + + const style: IconStyle = {}; + + if (color) { + style.color = color; + } + if (fontSize) { + style.fontSize = `${fontSize}px`; + } + + if (!icon && !localIcon) { + return undefined; + } + + return () => h(SvgIcon, { icon, localIcon, style }); + }; + + return { + SvgIconVNode + }; +} diff --git a/packages/hooks/src/use-table.ts b/packages/hooks/src/use-table.ts new file mode 100644 index 0000000..ee78498 --- /dev/null +++ b/packages/hooks/src/use-table.ts @@ -0,0 +1,152 @@ +import { computed, reactive, ref } from 'vue'; +import type { Ref } from 'vue'; +import useBoolean from './use-boolean'; +import useLoading from './use-loading'; + +export type MaybePromise = T | Promise; + +export type ApiFn = (args: any) => Promise; + +export type TableColumnCheck = { + key: string; + title: string; + checked: boolean; +}; + +export type TableDataWithIndex = T & { index: number }; + +export type TransformedData = { + rows: TableDataWithIndex[]; + total: number; +}; + +export type Transformer = (response: Response) => TransformedData; + +export type TableConfig = { + /** api function to get table data */ + apiFn: A; + /** row key */ + rowKey?: string; + /** api params */ + apiParams?: Parameters[0]; + /** transform api response to table data */ + transformer: Transformer>>; + /** columns factory */ + columns: () => C[]; + /** + * get column checks + * + * @param columns + */ + getColumnChecks: (columns: C[]) => TableColumnCheck[]; + /** + * get columns + * + * @param columns + */ + getColumns: (columns: C[], checks: TableColumnCheck[]) => C[]; + /** + * callback when response fetched + * + * @param transformed transformed data + */ + onFetched?: (transformed: TransformedData) => MaybePromise; + /** + * whether to get data immediately + * + * @default true + */ + immediate?: boolean; +}; + +export default function useHookTable(config: TableConfig) { + const { loading, startLoading, endLoading } = useLoading(); + const { bool: empty, setBool: setEmpty } = useBoolean(); + + const { apiFn, apiParams, transformer, immediate = true, getColumnChecks, getColumns } = config; + + const searchParams: NonNullable[0]> = reactive({ ...apiParams }); + + const allColumns = ref(config.columns()) as Ref; + + const data: Ref = ref([]); + + const columnChecks: Ref = ref(getColumnChecks(config.columns())); + + const columns = computed(() => getColumns(allColumns.value, columnChecks.value)); + + function reloadColumns() { + allColumns.value = config.columns(); + + const checkMap = new Map(columnChecks.value.map(col => [col.key, col.checked])); + + const defaultChecks = getColumnChecks(allColumns.value); + + columnChecks.value = defaultChecks.map(col => ({ + ...col, + checked: checkMap.get(col.key) ?? col.checked + })); + } + + async function getData() { + startLoading(); + + const formattedParams = formatSearchParams(searchParams); + + const response = await apiFn(formattedParams); + + const transformed = transformer(response as Awaited>); + + data.value = transformed.rows; + + setEmpty(transformed.rows.length === 0); + + await config.onFetched?.(transformed); + + endLoading(); + } + + function formatSearchParams(params: Record) { + const formattedParams: Record = {}; + + Object.entries(params).forEach(([key, value]) => { + if (value !== null && value !== undefined) { + formattedParams[key] = value; + } + }); + + return formattedParams; + } + + /** + * update search params + * + * @param params + */ + function updateSearchParams(params: Partial[0]>) { + Object.assign(searchParams, params); + } + + /** reset search params */ + function resetSearchParams() { + Object.assign(searchParams, apiParams); + getData(); + } + + if (immediate) { + getData(); + } + + return { + loading, + empty, + data, + columns, + columnChecks, + reloadColumns, + getData, + searchParams, + updateSearchParams, + resetSearchParams + }; +} diff --git a/packages/hooks/tsconfig.json b/packages/hooks/tsconfig.json new file mode 100644 index 0000000..5823ed5 --- /dev/null +++ b/packages/hooks/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/materials/.eslintrc b/packages/materials/.eslintrc new file mode 100644 index 0000000..38de2a0 --- /dev/null +++ b/packages/materials/.eslintrc @@ -0,0 +1,6 @@ +{ + "extends": "sa/vue", + "rules": { + "vue/multi-word-component-names": "off" + } +} diff --git a/packages/materials/package.json b/packages/materials/package.json new file mode 100644 index 0000000..2d437d6 --- /dev/null +++ b/packages/materials/package.json @@ -0,0 +1,20 @@ +{ + "name": "@sa/materials", + "version": "1.0.0", + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + }, + "dependencies": { + "@sa/utils": "workspace:*", + "@simonwep/pickr": "1.9.0", + "simplebar-vue": "2.3.3" + }, + "devDependencies": { + "typed-css-modules": "0.9.1" + } +} diff --git a/packages/materials/src/index.ts b/packages/materials/src/index.ts new file mode 100644 index 0000000..99694d1 --- /dev/null +++ b/packages/materials/src/index.ts @@ -0,0 +1,7 @@ +import AdminLayout, { LAYOUT_MAX_Z_INDEX, LAYOUT_SCROLL_EL_ID } from './libs/admin-layout'; +import PageTab from './libs/page-tab'; +import SimpleScrollbar from './libs/simple-scrollbar'; +import ColorPicker from './libs/color-picker'; + +export { AdminLayout, LAYOUT_SCROLL_EL_ID, LAYOUT_MAX_Z_INDEX, PageTab, SimpleScrollbar, ColorPicker }; +export * from './types'; diff --git a/packages/materials/src/libs/admin-layout/index.module.css b/packages/materials/src/libs/admin-layout/index.module.css new file mode 100644 index 0000000..e5c8ac8 --- /dev/null +++ b/packages/materials/src/libs/admin-layout/index.module.css @@ -0,0 +1,63 @@ +/* @type */ + +.layout-header, +.layout-header-placement { + height: var(--soy-header-height); +} + +.layout-header { + z-index: var(--soy-header-z-index); +} + +.layout-tab { + top: var(--soy-header-height); + height: var(--soy-tab-height); + z-index: var(--soy-tab-z-index); +} + +.layout-tab-placement { + height: var(--soy-tab-height); +} + +.layout-sider { + width: var(--soy-sider-width); + z-index: var(--soy-sider-z-index); +} + +.layout-mobile-sider { + z-index: var(--soy-sider-z-index); +} + +.layout-mobile-sider-mask { + z-index: var(--soy-mobile-sider-z-index); +} + +.layout-sider_collapsed { + width: var(--soy-sider-collapsed-width); + z-index: var(--soy-sider-z-index); +} + +.layout-footer, +.layout-footer-placement { + height: var(--soy-footer-height); +} + +.layout-footer { + z-index: var(--soy-footer-z-index); +} + +.left-gap { + padding-left: var(--soy-sider-width); +} + +.left-gap_collapsed { + padding-left: var(--soy-sider-collapsed-width); +} + +.sider-padding-top { + padding-top: var(--soy-header-height); +} + +.sider-padding-bottom { + padding-bottom: var(--soy-footer-height); +} diff --git a/packages/materials/src/libs/admin-layout/index.module.css.d.ts b/packages/materials/src/libs/admin-layout/index.module.css.d.ts new file mode 100644 index 0000000..e6d10d1 --- /dev/null +++ b/packages/materials/src/libs/admin-layout/index.module.css.d.ts @@ -0,0 +1,17 @@ +declare const styles: { + readonly 'layout-header': string; + readonly 'layout-header-placement': string; + readonly 'layout-tab': string; + readonly 'layout-tab-placement': string; + readonly 'layout-sider': string; + readonly 'layout-mobile-sider': string; + readonly 'layout-mobile-sider-mask': string; + readonly 'layout-sider_collapsed': string; + readonly 'layout-footer': string; + readonly 'layout-footer-placement': string; + readonly 'left-gap': string; + readonly 'left-gap_collapsed': string; + readonly 'sider-padding-top': string; + readonly 'sider-padding-bottom': string; +}; +export default styles; diff --git a/packages/materials/src/libs/admin-layout/index.ts b/packages/materials/src/libs/admin-layout/index.ts new file mode 100644 index 0000000..0687362 --- /dev/null +++ b/packages/materials/src/libs/admin-layout/index.ts @@ -0,0 +1,5 @@ +import AdminLayout from './index.vue'; +import { LAYOUT_MAX_Z_INDEX, LAYOUT_SCROLL_EL_ID } from './shared'; + +export default AdminLayout; +export { LAYOUT_SCROLL_EL_ID, LAYOUT_MAX_Z_INDEX }; diff --git a/packages/materials/src/libs/admin-layout/index.vue b/packages/materials/src/libs/admin-layout/index.vue new file mode 100644 index 0000000..543f7dc --- /dev/null +++ b/packages/materials/src/libs/admin-layout/index.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/packages/materials/src/libs/admin-layout/shared.ts b/packages/materials/src/libs/admin-layout/shared.ts new file mode 100644 index 0000000..940451e --- /dev/null +++ b/packages/materials/src/libs/admin-layout/shared.ts @@ -0,0 +1,68 @@ +import type { AdminLayoutProps, LayoutCssVars, LayoutCssVarsProps } from '../../types'; + +/** The id of the scroll element of the layout */ +export const LAYOUT_SCROLL_EL_ID = '__SCROLL_EL_ID__'; + +/** The max z-index of the layout */ +export const LAYOUT_MAX_Z_INDEX = 100; + +/** + * Create layout css vars by css vars props + * + * @param props Css vars props + */ +function createLayoutCssVarsByCssVarsProps(props: LayoutCssVarsProps) { + const cssVars: LayoutCssVars = { + '--soy-header-height': `${props.headerHeight}px`, + '--soy-header-z-index': props.headerZIndex, + '--soy-tab-height': `${props.tabHeight}px`, + '--soy-tab-z-index': props.tabZIndex, + '--soy-sider-width': `${props.siderWidth}px`, + '--soy-sider-collapsed-width': `${props.siderCollapsedWidth}px`, + '--soy-sider-z-index': props.siderZIndex, + '--soy-mobile-sider-z-index': props.mobileSiderZIndex, + '--soy-footer-height': `${props.footerHeight}px`, + '--soy-footer-z-index': props.footerZIndex + }; + + return cssVars; +} + +/** + * Create layout css vars + * + * @param props + */ +export function createLayoutCssVars(props: AdminLayoutProps) { + const { + mode, + isMobile, + maxZIndex = LAYOUT_MAX_Z_INDEX, + headerHeight, + tabHeight, + siderWidth, + siderCollapsedWidth, + footerHeight + } = props; + + const headerZIndex = maxZIndex - 3; + const tabZIndex = maxZIndex - 5; + const siderZIndex = mode === 'vertical' || isMobile ? maxZIndex - 1 : maxZIndex - 4; + const mobileSiderZIndex = isMobile ? maxZIndex - 2 : 0; + const footerZIndex = maxZIndex - 5; + + const cssProps: LayoutCssVarsProps = { + headerHeight, + headerZIndex, + tabHeight, + tabZIndex, + siderWidth, + siderZIndex, + mobileSiderZIndex, + siderCollapsedWidth, + footerHeight, + footerZIndex + }; + + return createLayoutCssVarsByCssVarsProps(cssProps); +} diff --git a/packages/materials/src/libs/color-picker/index.ts b/packages/materials/src/libs/color-picker/index.ts new file mode 100644 index 0000000..131b1d1 --- /dev/null +++ b/packages/materials/src/libs/color-picker/index.ts @@ -0,0 +1,3 @@ +import ColorPicker from './index.vue'; + +export default ColorPicker; diff --git a/packages/materials/src/libs/color-picker/index.vue b/packages/materials/src/libs/color-picker/index.vue new file mode 100644 index 0000000..1267886 --- /dev/null +++ b/packages/materials/src/libs/color-picker/index.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/packages/materials/src/libs/page-tab/button-tab.vue b/packages/materials/src/libs/page-tab/button-tab.vue new file mode 100644 index 0000000..bce4db5 --- /dev/null +++ b/packages/materials/src/libs/page-tab/button-tab.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/packages/materials/src/libs/page-tab/chrome-tab-bg.vue b/packages/materials/src/libs/page-tab/chrome-tab-bg.vue new file mode 100644 index 0000000..151e03a --- /dev/null +++ b/packages/materials/src/libs/page-tab/chrome-tab-bg.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/packages/materials/src/libs/page-tab/chrome-tab.vue b/packages/materials/src/libs/page-tab/chrome-tab.vue new file mode 100644 index 0000000..e4509b0 --- /dev/null +++ b/packages/materials/src/libs/page-tab/chrome-tab.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/packages/materials/src/libs/page-tab/icon-close.vue b/packages/materials/src/libs/page-tab/icon-close.vue new file mode 100644 index 0000000..86026d7 --- /dev/null +++ b/packages/materials/src/libs/page-tab/icon-close.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/packages/materials/src/libs/page-tab/index.module.css b/packages/materials/src/libs/page-tab/index.module.css new file mode 100644 index 0000000..abf56a5 --- /dev/null +++ b/packages/materials/src/libs/page-tab/index.module.css @@ -0,0 +1,97 @@ +/* @type */ + +.button-tab { + border-color: #e5e7eb; +} + +.button-tab_dark { + border-color: #ffffff3d; +} + +.button-tab:hover { + color: var(--soy-primary-color); + border-color: var(--soy-primary-color-opacity3); +} + +.button-tab_active { + color: var(--soy-primary-color); + border-color: var(--soy-primary-color-opacity3); + background-color: var(--soy-primary-color-opacity1); +} + +.button-tab_active_dark { + background-color: var(--soy-primary-color-opacity2); +} + +.button-tab .svg-close:hover { + font-size: 12px; + color: #ffffff; + background-color: var(--soy-primary-color); +} + +.button-tab_dark .svg-close:hover { + color: #000000; +} + +.chrome-tab:hover { + z-index: 9; +} + +.chrome-tab_active { + z-index: 10; + color: var(--soy-primary-color); +} + +.chrome-tab__bg { + color: transparent; +} + +.chrome-tab_active .chrome-tab__bg { + color: var(--soy-primary-color1); +} + +.chrome-tab_active_dark .chrome-tab__bg { + color: var(--soy-primary-color2); +} + +.chrome-tab:hover .chrome-tab__bg { + color: #dee1e6; +} + +.chrome-tab_active:hover .chrome-tab__bg { + color: var(--soy-primary-color1); +} + +.chrome-tab_dark:hover .chrome-tab__bg { + color: #333333; +} + +.chrome-tab_active_dark:hover .chrome-tab__bg { + color: var(--soy-primary-color2); +} + +.chrome-tab .svg-close:hover { + font-size: 12px; + color: #ffffff; + background-color: #9ca3af; +} + +.chrome-tab_active .svg-close:hover { + background-color: var(--soy-primary-color); +} + +.chrome-tab_dark .svg-close:hover { + color: #000000; +} + +.chrome-tab_active .chrome-tab-divider { + opacity: 0; +} + +.chrome-tab:hover .chrome-tab-divider { + opacity: 0; +} + +.chrome-tab_dark .chrome-tab-divider { + background-color: rgba(255, 255, 255, 0.9); +} diff --git a/packages/materials/src/libs/page-tab/index.module.css.d.ts b/packages/materials/src/libs/page-tab/index.module.css.d.ts new file mode 100644 index 0000000..f04f933 --- /dev/null +++ b/packages/materials/src/libs/page-tab/index.module.css.d.ts @@ -0,0 +1,14 @@ +declare const styles: { + readonly 'button-tab': string; + readonly 'button-tab_dark': string; + readonly 'button-tab_active': string; + readonly 'button-tab_active_dark': string; + readonly 'chrome-tab': string; + readonly 'chrome-tab_active': string; + readonly 'chrome-tab__bg': string; + readonly 'chrome-tab_active_dark': string; + readonly 'chrome-tab_dark': string; + readonly 'chrome-tab-divider': string; + readonly 'svg-close': string; +}; +export default styles; diff --git a/packages/materials/src/libs/page-tab/index.ts b/packages/materials/src/libs/page-tab/index.ts new file mode 100644 index 0000000..b402adf --- /dev/null +++ b/packages/materials/src/libs/page-tab/index.ts @@ -0,0 +1,3 @@ +import PageTab from './index.vue'; + +export default PageTab; diff --git a/packages/materials/src/libs/page-tab/index.vue b/packages/materials/src/libs/page-tab/index.vue new file mode 100644 index 0000000..6f93115 --- /dev/null +++ b/packages/materials/src/libs/page-tab/index.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/packages/materials/src/libs/page-tab/shared.ts b/packages/materials/src/libs/page-tab/shared.ts new file mode 100644 index 0000000..c6ff0c3 --- /dev/null +++ b/packages/materials/src/libs/page-tab/shared.ts @@ -0,0 +1,31 @@ +import { addColorAlpha, transformColorWithOpacity } from '@sa/utils'; +import type { PageTabCssVars, PageTabCssVarsProps } from '../../types'; + +/** The active color of the tab */ +export const ACTIVE_COLOR = '#1890ff'; + +function createCssVars(props: PageTabCssVarsProps) { + const cssVars: PageTabCssVars = { + '--soy-primary-color': props.primaryColor, + '--soy-primary-color1': props.primaryColor1, + '--soy-primary-color2': props.primaryColor2, + '--soy-primary-color-opacity1': props.primaryColorOpacity1, + '--soy-primary-color-opacity2': props.primaryColorOpacity2, + '--soy-primary-color-opacity3': props.primaryColorOpacity3 + }; + + return cssVars; +} + +export function createTabCssVars(primaryColor: string) { + const cssProps: PageTabCssVarsProps = { + primaryColor, + primaryColor1: transformColorWithOpacity(primaryColor, 0.1, '#ffffff'), + primaryColor2: transformColorWithOpacity(primaryColor, 0.3, '#000000'), + primaryColorOpacity1: addColorAlpha(primaryColor, 0.1), + primaryColorOpacity2: addColorAlpha(primaryColor, 0.15), + primaryColorOpacity3: addColorAlpha(primaryColor, 0.3) + }; + + return createCssVars(cssProps); +} diff --git a/packages/materials/src/libs/page-tab/svg-close.vue b/packages/materials/src/libs/page-tab/svg-close.vue new file mode 100644 index 0000000..1e51fcd --- /dev/null +++ b/packages/materials/src/libs/page-tab/svg-close.vue @@ -0,0 +1,31 @@ + + + + + diff --git a/packages/materials/src/libs/simple-scrollbar/index.ts b/packages/materials/src/libs/simple-scrollbar/index.ts new file mode 100644 index 0000000..1453a06 --- /dev/null +++ b/packages/materials/src/libs/simple-scrollbar/index.ts @@ -0,0 +1,3 @@ +import SimpleScrollbar from './index.vue'; + +export default SimpleScrollbar; diff --git a/packages/materials/src/libs/simple-scrollbar/index.vue b/packages/materials/src/libs/simple-scrollbar/index.vue new file mode 100644 index 0000000..ac59d60 --- /dev/null +++ b/packages/materials/src/libs/simple-scrollbar/index.vue @@ -0,0 +1,18 @@ + + + + + diff --git a/packages/materials/src/types/index.ts b/packages/materials/src/types/index.ts new file mode 100644 index 0000000..bbcfb9d --- /dev/null +++ b/packages/materials/src/types/index.ts @@ -0,0 +1,294 @@ +/** Header config */ +interface AdminLayoutHeaderConfig { + /** + * Whether header is visible + * + * @default true + */ + headerVisible?: boolean; + /** + * Header class + * + * @default '' + */ + headerClass?: string; + /** + * Header height + * + * @default 56px + */ + headerHeight?: number; +} + +/** Tab config */ +interface AdminLayoutTabConfig { + /** + * Whether tab is visible + * + * @default true + */ + tabVisible?: boolean; + /** + * Tab class + * + * @default '' + */ + tabClass?: string; + /** + * Tab height + * + * @default 48px + */ + tabHeight?: number; +} + +/** Sider config */ +interface AdminLayoutSiderConfig { + /** + * Whether sider is visible + * + * @default true + */ + siderVisible?: boolean; + /** + * Sider class + * + * @default '' + */ + siderClass?: string; + /** + * Mobile sider class + * + * @default '' + */ + mobileSiderClass?: string; + /** + * Sider collapse status + * + * @default false + */ + siderCollapse?: boolean; + /** + * Sider width when collapse is false + * + * @default '220px' + */ + siderWidth?: number; + /** + * Sider width when collapse is true + * + * @default '64px' + */ + siderCollapsedWidth?: number; +} + +/** Content config */ +export interface AdminLayoutContentConfig { + /** + * Content class + * + * @default '' + */ + contentClass?: string; + /** + * Whether content is full the page + * + * If true, other elements will be hidden by `display: none` + */ + fullContent?: boolean; +} + +/** Footer config */ +export interface AdminLayoutFooterConfig { + /** + * Whether footer is visible + * + * @default true + */ + footerVisible?: boolean; + /** + * Whether footer is fixed + * + * @default true + */ + fixedFooter?: boolean; + /** + * Footer class + * + * @default '' + */ + footerClass?: string; + /** + * Footer height + * + * @default 48px + */ + footerHeight?: number; + /** + * Whether footer is on the right side + * + * When the layout is vertical, the footer is on the right side + */ + rightFooter?: boolean; +} + +/** + * Layout mode + * + * - Horizontal + * - Vertical + */ +export type LayoutMode = 'horizontal' | 'vertical'; + +/** + * The scroll mode when content overflow + * + * - Wrapper: the layout component's wrapper element has a scrollbar + * - Content: the layout component's content element has a scrollbar + * + * @default 'wrapper' + */ +export type LayoutScrollMode = 'wrapper' | 'content'; + +/** Admin layout props */ +export interface AdminLayoutProps + extends AdminLayoutHeaderConfig, + AdminLayoutTabConfig, + AdminLayoutSiderConfig, + AdminLayoutContentConfig, + AdminLayoutFooterConfig { + /** + * Layout mode + * + * - {@link LayoutMode} + */ + mode?: LayoutMode; + /** Is mobile layout */ + isMobile?: boolean; + /** + * Scroll mode + * + * - {@link ScrollMode} + */ + scrollMode?: LayoutScrollMode; + /** + * The id of the scroll element of the layout + * + * It can be used to get the corresponding Dom and scroll it + * + * @example + * use the default id by import + * ```ts + * import { adminLayoutScrollElId } from '@sa/vue-materials'; + * ``` + * + * @default + * ```ts + * const adminLayoutScrollElId = '__ADMIN_LAYOUT_SCROLL_EL_ID__' + * ``` + */ + scrollElId?: string; + /** The class of the scroll element */ + scrollElClass?: string; + /** The class of the scroll wrapper element */ + scrollWrapperClass?: string; + /** + * The common class of the layout + * + * Is can be used to configure the transition animation + * + * @default 'transition-all-300' + */ + commonClass?: string; + /** + * Whether fix the header and tab + * + * @default true + */ + fixedTop?: boolean; + /** + * The max z-index of the layout + * + * The z-index of Header,Tab,Sider and Footer will not exceed this value + */ + maxZIndex?: number; +} + +type Kebab = S extends Uncapitalize ? S : `-${Uncapitalize}`; + +type KebabCase = S extends `${infer Start}${infer End}` + ? `${Uncapitalize}${KebabCase>}` + : S; + +type Prefix = '--soy-'; + +export type LayoutCssVarsProps = Pick< + AdminLayoutProps, + 'headerHeight' | 'tabHeight' | 'siderWidth' | 'siderCollapsedWidth' | 'footerHeight' +> & { + headerZIndex?: number; + tabZIndex?: number; + siderZIndex?: number; + mobileSiderZIndex?: number; + footerZIndex?: number; +}; + +export type LayoutCssVars = { + [K in keyof LayoutCssVarsProps as `${Prefix}${KebabCase}`]: string | number; +}; + +/** + * The mode of the tab + * + * - Button: button style + * - Chrome: chrome style + * + * @default chrome + */ +export type PageTabMode = 'button' | 'chrome'; + +export interface PageTabProps { + /** Whether is dark mode */ + darkMode?: boolean; + /** + * The mode of the tab + * + * - {@link TabMode} + */ + mode?: PageTabMode; + /** + * The common class of the layout + * + * Is can be used to configure the transition animation + * + * @default 'transition-all-300' + */ + commonClass?: string; + /** The class of the button tab */ + buttonClass?: string; + /** The class of the chrome tab */ + chromeClass?: string; + /** Whether the tab is active */ + active?: boolean; + /** The color of the active tab */ + activeColor?: string; + /** + * Whether the tab is closable + * + * Show the close icon when true + */ + closable?: boolean; +} + +export type PageTabCssVarsProps = { + primaryColor: string; + primaryColor1: string; + primaryColor2: string; + primaryColorOpacity1: string; + primaryColorOpacity2: string; + primaryColorOpacity3: string; +}; + +export type PageTabCssVars = { + [K in keyof PageTabCssVarsProps as `${Prefix}${KebabCase}`]: string | number; +}; diff --git a/packages/materials/tsconfig.json b/packages/materials/tsconfig.json new file mode 100644 index 0000000..5823ed5 --- /dev/null +++ b/packages/materials/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/ofetch/package.json b/packages/ofetch/package.json new file mode 100644 index 0000000..905ff27 --- /dev/null +++ b/packages/ofetch/package.json @@ -0,0 +1,15 @@ +{ + "name": "@sa/fetch", + "version": "1.0.0", + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + }, + "dependencies": { + "ofetch": "1.3.4" + } +} diff --git a/packages/ofetch/src/index.ts b/packages/ofetch/src/index.ts new file mode 100644 index 0000000..dce1ed4 --- /dev/null +++ b/packages/ofetch/src/index.ts @@ -0,0 +1,10 @@ +import { ofetch } from 'ofetch'; +import type { FetchOptions } from 'ofetch'; + +export function createRequest(options: FetchOptions) { + const request = ofetch.create(options); + + return request; +} + +export default createRequest; diff --git a/packages/ofetch/tsconfig.json b/packages/ofetch/tsconfig.json new file mode 100644 index 0000000..5823ed5 --- /dev/null +++ b/packages/ofetch/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/scripts/bin.ts b/packages/scripts/bin.ts new file mode 100644 index 0000000..1a1817b --- /dev/null +++ b/packages/scripts/bin.ts @@ -0,0 +1,3 @@ +#!/usr/bin/env tsx + +import './src/index.ts'; diff --git a/packages/scripts/package.json b/packages/scripts/package.json new file mode 100644 index 0000000..59b315c --- /dev/null +++ b/packages/scripts/package.json @@ -0,0 +1,27 @@ +{ + "name": "@sa/scripts", + "version": "1.0.0", + "bin": { + "sa": "./bin.ts" + }, + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + }, + "devDependencies": { + "@soybeanjs/changelog": "0.3.22", + "bumpp": "9.4.0", + "c12": "1.10.0", + "cac": "6.7.14", + "consola": "3.2.3", + "enquirer": "^2.4.1", + "execa": "8.0.1", + "kolorist": "1.8.0", + "npm-check-updates": "16.14.18", + "rimraf": "5.0.5" + } +} diff --git a/packages/scripts/src/commands/changelog.ts b/packages/scripts/src/commands/changelog.ts new file mode 100644 index 0000000..e01ce40 --- /dev/null +++ b/packages/scripts/src/commands/changelog.ts @@ -0,0 +1,10 @@ +import { generateChangelog, generateTotalChangelog } from '@soybeanjs/changelog'; +import type { ChangelogOption } from '@soybeanjs/changelog'; + +export async function genChangelog(options?: Partial, total = false) { + if (total) { + await generateTotalChangelog(options); + } else { + await generateChangelog(options); + } +} diff --git a/packages/scripts/src/commands/cleanup.ts b/packages/scripts/src/commands/cleanup.ts new file mode 100644 index 0000000..a9d3990 --- /dev/null +++ b/packages/scripts/src/commands/cleanup.ts @@ -0,0 +1,5 @@ +import { rimraf } from 'rimraf'; + +export async function cleanup(paths: string[]) { + await rimraf(paths, { glob: true }); +} diff --git a/packages/scripts/src/commands/git-commit.ts b/packages/scripts/src/commands/git-commit.ts new file mode 100644 index 0000000..875ea96 --- /dev/null +++ b/packages/scripts/src/commands/git-commit.ts @@ -0,0 +1,86 @@ +import path from 'node:path'; +import { readFileSync } from 'node:fs'; +import { prompt } from 'enquirer'; +import { bgRed, green, red, yellow } from 'kolorist'; +import { execCommand } from '../shared'; +import type { CliOption } from '../types'; + +interface PromptObject { + types: string; + scopes: string; + description: string; +} + +/** + * Git commit with Conventional Commits standard + * + * @param gitCommitTypes + * @param gitCommitScopes + */ +export async function gitCommit( + gitCommitTypes: CliOption['gitCommitTypes'], + gitCommitScopes: CliOption['gitCommitScopes'] +) { + const typesChoices = gitCommitTypes.map(([value, msg]) => { + const nameWithSuffix = `${value}:`; + + const message = `${nameWithSuffix.padEnd(12)}${msg}`; + + return { + name: value, + message + }; + }); + + const scopesChoices = gitCommitScopes.map(([value, msg]) => ({ + name: value, + message: `${value.padEnd(30)} (${msg})` + })); + + const result = await prompt([ + { + name: 'types', + type: 'select', + message: 'Please select a type', + choices: typesChoices + }, + { + name: 'scopes', + type: 'select', + message: 'Please select a scope', + choices: scopesChoices + }, + { + name: 'description', + type: 'text', + message: `Please enter a description (add prefix ${yellow('!')} to indicate breaking change)` + } + ]); + + const breaking = result.description.startsWith('!') ? '!' : ''; + + const description = result.description.replace(/^!/, '').trim(); + + const commitMsg = `${result.types}(${result.scopes})${breaking}: ${description}`; + + await execCommand('git', ['commit', '-m', commitMsg], { stdio: 'inherit' }); +} + +/** Git commit message verify */ +export async function gitCommitVerify() { + const gitPath = await execCommand('git', ['rev-parse', '--show-toplevel']); + + const gitMsgPath = path.join(gitPath, '.git', 'COMMIT_EDITMSG'); + + const commitMsg = readFileSync(gitMsgPath, 'utf8').trim(); + + const REG_EXP = /(?[a-z]+)(?:\((?.+)\))?(?!)?: (?.+)/i; + + if (!REG_EXP.test(commitMsg)) { + throw new Error( + `${bgRed(' ERROR ')} ${red('git commit message must match the Conventional Commits standard!')}\n\n${green( + 'Recommended to use the command `pnpm commit` to generate Conventional Commits compliant commit information.\nGet more info about Conventional Commits, follow this link: https://conventionalcommits.org' + )}` + ); + } +} diff --git a/packages/scripts/src/commands/index.ts b/packages/scripts/src/commands/index.ts new file mode 100644 index 0000000..db4fc15 --- /dev/null +++ b/packages/scripts/src/commands/index.ts @@ -0,0 +1,6 @@ +export * from './git-commit'; +export * from './cleanup'; +export * from './update-pkg'; +export * from './changelog'; +export * from './release'; +export * from './router'; diff --git a/packages/scripts/src/commands/release.ts b/packages/scripts/src/commands/release.ts new file mode 100644 index 0000000..1cf3bc3 --- /dev/null +++ b/packages/scripts/src/commands/release.ts @@ -0,0 +1,12 @@ +import { versionBump } from 'bumpp'; + +export async function release(execute = 'pnpm sa changelog', push = true) { + await versionBump({ + files: ['**/package.json', '!**/node_modules'], + execute, + all: true, + tag: true, + commit: 'chore(projects): release v%s', + push + }); +} diff --git a/packages/scripts/src/commands/router.ts b/packages/scripts/src/commands/router.ts new file mode 100644 index 0000000..f407589 --- /dev/null +++ b/packages/scripts/src/commands/router.ts @@ -0,0 +1,90 @@ +import process from 'node:process'; +import path from 'node:path'; +import { writeFile } from 'node:fs/promises'; +import { existsSync, mkdirSync } from 'node:fs'; +import { prompt } from 'enquirer'; +import { green, red } from 'kolorist'; + +interface PromptObject { + routeName: string; + addRouteParams: boolean; + routeParams: string; +} + +/** generate route */ +export async function generateRoute() { + const result = await prompt([ + { + name: 'routeName', + type: 'text', + message: 'please enter route name', + initial: 'demo-route_child' + }, + { + name: 'addRouteParams', + type: 'confirm', + message: 'add route params?', + initial: false + } + ]); + + if (result.addRouteParams) { + const answers = await prompt({ + name: 'routeParams', + type: 'text', + message: 'please enter route params', + initial: 'id' + }); + + Object.assign(result, answers); + } + + const PAGE_DIR_NAME_PATTERN = /^[\w-]+[0-9a-zA-Z]+$/; + + if (!PAGE_DIR_NAME_PATTERN.test(result.routeName)) { + throw new Error(`${red('route name is invalid, it only allow letters, numbers, "-" or "_"')}. +For example: +(1) one level route: ${green('demo-route')} +(2) two level route: ${green('demo-route_child')} +(3) multi level route: ${green('demo-route_child_child')} +(4) group route: ${green('_ignore_demo-route')}' +`); + } + + const PARAM_REG = /^\w+$/g; + + if (result.routeParams && !PARAM_REG.test(result.routeParams)) { + throw new Error(red('route params is invalid, it only allow letters, numbers or "_".')); + } + + const cwd = process.cwd(); + + const [dir, ...rest] = result.routeName.split('_') as string[]; + + let routeDir = path.join(cwd, 'src', 'views', dir); + + if (rest.length) { + routeDir = path.join(routeDir, rest.join('_')); + } + + if (!existsSync(routeDir)) { + mkdirSync(routeDir, { recursive: true }); + } else { + throw new Error(red('route already exists')); + } + + const fileName = result.routeParams ? `[${result.routeParams}].vue` : 'index.vue'; + + const vueTemplate = ` + + + + +`; + + const filePath = path.join(routeDir, fileName); + + await writeFile(filePath, vueTemplate); +} diff --git a/packages/scripts/src/commands/update-pkg.ts b/packages/scripts/src/commands/update-pkg.ts new file mode 100644 index 0000000..54d1132 --- /dev/null +++ b/packages/scripts/src/commands/update-pkg.ts @@ -0,0 +1,5 @@ +import { execCommand } from '../shared'; + +export async function updatePkg(args: string[] = ['--deep', '-u']) { + execCommand('npx', ['ncu', ...args], { stdio: 'inherit' }); +} diff --git a/packages/scripts/src/config/index.ts b/packages/scripts/src/config/index.ts new file mode 100644 index 0000000..e5978d1 --- /dev/null +++ b/packages/scripts/src/config/index.ts @@ -0,0 +1,53 @@ +import process from 'node:process'; +import { loadConfig } from 'c12'; +import type { CliOption } from '../types'; + +const defaultOptions: CliOption = { + cwd: process.cwd(), + cleanupDirs: [ + '**/dist', + '**/package-lock.json', + '**/yarn.lock', + '**/pnpm-lock.yaml', + '**/node_modules', + '!node_modules/**' + ], + gitCommitTypes: [ + ['feat', 'A new feature'], + ['fix', 'A bug fix'], + ['docs', 'Documentation only changes'], + ['style', 'Changes that do not affect the meaning of the code'], + ['refactor', 'A code change that neither fixes a bug nor adds a feature'], + ['perf', 'A code change that improves performance'], + ['test', 'Adding missing tests or correcting existing tests'], + ['build', 'Changes that affect the build system or external dependencies'], + ['ci', 'Changes to our CI configuration files and scripts'], + ['chore', "Other changes that don't modify src or test files"], + ['revert', 'Reverts a previous commit'] + ], + gitCommitScopes: [ + ['projects', 'project'], + ['components', 'components'], + ['hooks', 'hook functions'], + ['utils', 'utils functions'], + ['types', 'TS declaration'], + ['styles', 'style'], + ['deps', 'project dependencies'], + ['release', 'release project'], + ['other', 'other changes'] + ], + ncuCommandArgs: ['--deep', '-u'], + changelogOptions: {} +}; + +export async function loadCliOptions(overrides?: Partial, cwd = process.cwd()) { + const { config } = await loadConfig>({ + name: 'soybean', + defaults: defaultOptions, + overrides, + cwd, + packageJson: true + }); + + return config as CliOption; +} diff --git a/packages/scripts/src/index.ts b/packages/scripts/src/index.ts new file mode 100644 index 0000000..909dda3 --- /dev/null +++ b/packages/scripts/src/index.ts @@ -0,0 +1,101 @@ +import cac from 'cac'; +import { blue, lightGreen } from 'kolorist'; +import { version } from '../package.json'; +import { cleanup, genChangelog, generateRoute, gitCommit, gitCommitVerify, release, updatePkg } from './commands'; +import { loadCliOptions } from './config'; + +type Command = 'cleanup' | 'update-pkg' | 'git-commit' | 'git-commit-verify' | 'changelog' | 'release' | 'gen-route'; + +type CommandAction = (args?: A) => Promise | void; + +type CommandWithAction = Record }>; + +interface CommandArg { + /** Execute additional command after bumping and before git commit. Defaults to 'pnpm sa changelog' */ + execute?: string; + /** Indicates whether to push the git commit and tag. Defaults to true */ + push?: boolean; + /** Generate changelog by total tags */ + total?: boolean; + /** + * The glob pattern of dirs to cleanup + * + * If not set, it will use the default value + * + * Multiple values use "," to separate them + */ + cleanupDir?: string; +} + +export async function setupCli() { + const cliOptions = await loadCliOptions(); + + const cli = cac(blue('soybean-admin')); + + cli + .version(lightGreen(version)) + .option( + '-e, --execute [command]', + "Execute additional command after bumping and before git commit. Defaults to 'npx soy changelog'" + ) + .option('-p, --push', 'Indicates whether to push the git commit and tag') + .option('-t, --total', 'Generate changelog by total tags') + .option( + '-c, --cleanupDir ', + 'The glob pattern of dirs to cleanup, If not set, it will use the default value, Multiple values use "," to separate them' + ) + .help(); + + const commands: CommandWithAction = { + cleanup: { + desc: 'delete dirs: node_modules, dist, etc.', + action: async () => { + await cleanup(cliOptions.cleanupDirs); + } + }, + 'update-pkg': { + desc: 'update package.json dependencies versions', + action: async () => { + await updatePkg(cliOptions.ncuCommandArgs); + } + }, + 'git-commit': { + desc: 'git commit, generate commit message which match Conventional Commits standard', + action: async () => { + await gitCommit(cliOptions.gitCommitTypes, cliOptions.gitCommitScopes); + } + }, + 'git-commit-verify': { + desc: 'verify git commit message, make sure it match Conventional Commits standard', + action: async () => { + await gitCommitVerify(); + } + }, + changelog: { + desc: 'generate changelog', + action: async args => { + await genChangelog(cliOptions.changelogOptions, args?.total); + } + }, + release: { + desc: 'release: update version, generate changelog, commit code', + action: async args => { + await release(args?.execute, args?.push); + } + }, + 'gen-route': { + desc: 'generate route', + action: async () => { + await generateRoute(); + } + } + }; + + for (const [command, { desc, action }] of Object.entries(commands)) { + cli.command(command, lightGreen(desc)).action(action); + } + + cli.parse(); +} + +setupCli(); diff --git a/packages/scripts/src/shared/index.ts b/packages/scripts/src/shared/index.ts new file mode 100644 index 0000000..80d933c --- /dev/null +++ b/packages/scripts/src/shared/index.ts @@ -0,0 +1,7 @@ +import type { Options } from 'execa'; + +export async function execCommand(cmd: string, args: string[], options?: Options) { + const { execa } = await import('execa'); + const res = await execa(cmd, args, options); + return res?.stdout?.trim() || ''; +} diff --git a/packages/scripts/src/types/index.ts b/packages/scripts/src/types/index.ts new file mode 100644 index 0000000..598760e --- /dev/null +++ b/packages/scripts/src/types/index.ts @@ -0,0 +1,33 @@ +import type { ChangelogOption } from '@soybeanjs/changelog'; + +export interface CliOption { + /** The project root directory */ + cwd: string; + /** + * Cleanup dirs + * + * Glob pattern syntax {@link https://github.com/isaacs/minimatch} + * + * @default + * ```json + * ["** /dist", "** /pnpm-lock.yaml", "** /node_modules", "!node_modules/**"] + * ``` + */ + cleanupDirs: string[]; + /** Git commit types */ + gitCommitTypes: [string, string][]; + /** Git commit scopes */ + gitCommitScopes: [string, string][]; + /** + * Npm-check-updates command args + * + * @default ['--deep', '-u'] + */ + ncuCommandArgs: string[]; + /** + * Options of generate changelog + * + * @link https://github.com/soybeanjs/changelog + */ + changelogOptions: Partial; +} diff --git a/packages/scripts/tsconfig.json b/packages/scripts/tsconfig.json new file mode 100644 index 0000000..67ab8a4 --- /dev/null +++ b/packages/scripts/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*", "typings/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/uno-preset/package.json b/packages/uno-preset/package.json new file mode 100644 index 0000000..c1aefed --- /dev/null +++ b/packages/uno-preset/package.json @@ -0,0 +1,12 @@ +{ + "name": "@sa/uno-preset", + "version": "1.0.0", + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + } +} diff --git a/packages/uno-preset/src/index.ts b/packages/uno-preset/src/index.ts new file mode 100644 index 0000000..f0b13e1 --- /dev/null +++ b/packages/uno-preset/src/index.ts @@ -0,0 +1,54 @@ +// @unocss-include + +import type { Preset } from '@unocss/core'; +import type { Theme } from '@unocss/preset-uno'; + +export function presetSoybeanAdmin(): Preset { + const preset: Preset = { + name: 'preset-soybean-admin', + shortcuts: [ + { + 'flex-center': 'flex justify-center items-center', + 'flex-x-center': 'flex justify-center', + 'flex-y-center': 'flex items-center', + 'flex-col': 'flex flex-col', + 'flex-col-center': 'flex-center flex-col', + 'flex-col-stretch': 'flex-col items-stretch', + 'i-flex-center': 'inline-flex justify-center items-center', + 'i-flex-x-center': 'inline-flex justify-center', + 'i-flex-y-center': 'inline-flex items-center', + 'i-flex-col': 'flex-col inline-flex', + 'i-flex-col-stretch': 'i-flex-col items-stretch', + 'flex-1-hidden': 'flex-1 overflow-hidden' + }, + { + 'absolute-lt': 'absolute left-0 top-0', + 'absolute-lb': 'absolute left-0 bottom-0', + 'absolute-rt': 'absolute right-0 top-0', + 'absolute-rb': 'absolute right-0 bottom-0', + 'absolute-tl': 'absolute-lt', + 'absolute-tr': 'absolute-rt', + 'absolute-bl': 'absolute-lb', + 'absolute-br': 'absolute-rb', + 'absolute-center': 'absolute-lt flex-center size-full', + 'fixed-lt': 'fixed left-0 top-0', + 'fixed-lb': 'fixed left-0 bottom-0', + 'fixed-rt': 'fixed right-0 top-0', + 'fixed-rb': 'fixed right-0 bottom-0', + 'fixed-tl': 'fixed-lt', + 'fixed-tr': 'fixed-rt', + 'fixed-bl': 'fixed-lb', + 'fixed-br': 'fixed-rb', + 'fixed-center': 'fixed-lt flex-center size-full' + }, + { + 'nowrap-hidden': 'overflow-hidden whitespace-nowrap', + 'ellipsis-text': 'nowrap-hidden text-ellipsis' + } + ] + }; + + return preset; +} + +export default presetSoybeanAdmin; diff --git a/packages/uno-preset/tsconfig.json b/packages/uno-preset/tsconfig.json new file mode 100644 index 0000000..5823ed5 --- /dev/null +++ b/packages/uno-preset/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "ESNext", + "jsx": "preserve", + "lib": ["DOM", "ESNext"], + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node"], + "strict": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/utils/package.json b/packages/utils/package.json new file mode 100644 index 0000000..e29b5de --- /dev/null +++ b/packages/utils/package.json @@ -0,0 +1,21 @@ +{ + "name": "@sa/utils", + "version": "1.0.0", + "exports": { + ".": "./src/index.ts" + }, + "typesVersions": { + "*": { + "*": ["./src/*"] + } + }, + "dependencies": { + "colord": "2.9.3", + "crypto-js": "4.2.0", + "localforage": "1.10.0", + "nanoid": "5.0.7" + }, + "devDependencies": { + "@types/crypto-js": "4.2.2" + } +} diff --git a/packages/utils/src/color.ts b/packages/utils/src/color.ts new file mode 100644 index 0000000..88c3595 --- /dev/null +++ b/packages/utils/src/color.ts @@ -0,0 +1,252 @@ +import { colord, extend } from 'colord'; +import namesPlugin from 'colord/plugins/names'; +import mixPlugin from 'colord/plugins/mix'; +import type { AnyColor, HsvColor, RgbColor } from 'colord'; + +extend([namesPlugin, mixPlugin]); + +/** + * Add color alpha + * + * @param color - Color + * @param alpha - Alpha (0 - 1) + */ +export function addColorAlpha(color: string, alpha: number) { + return colord(color).alpha(alpha).toHex(); +} + +/** + * Mix color + * + * @param firstColor - First color + * @param secondColor - Second color + * @param ratio - The ratio of the second color (0 - 1) + */ +export function mixColor(firstColor: string, secondColor: string, ratio: number) { + return colord(firstColor).mix(secondColor, ratio).toHex(); +} + +/** + * Transform color with opacity to similar color without opacity + * + * @param color - Color + * @param alpha - Alpha (0 - 1) + * @param bgColor Background color (usually white or black) + */ +export function transformColorWithOpacity(color: string, alpha: number, bgColor = '#ffffff') { + const originColor = addColorAlpha(color, alpha); + const { r: oR, g: oG, b: oB } = colord(originColor).toRgb(); + + const { r: bgR, g: bgG, b: bgB } = colord(bgColor).toRgb(); + + function calRgb(or: number, bg: number, al: number) { + return bg + (or - bg) * al; + } + + const resultRgb: RgbColor = { + r: calRgb(oR, bgR, alpha), + g: calRgb(oG, bgG, alpha), + b: calRgb(oB, bgB, alpha) + }; + + return colord(resultRgb).toHex(); +} + +/** + * Is white color + * + * @param color - Color + */ +export function isWhiteColor(color: string) { + return colord(color).isEqual('#ffffff'); +} + +/** + * Get rgb of color + * + * @param color Color + */ +export function getRgbOfColor(color: string) { + return colord(color).toRgb(); +} + +/** Hue step */ +const hueStep = 2; +/** Saturation step, light color part */ +const saturationStep = 16; +/** Saturation step, dark color part */ +const saturationStep2 = 5; +/** Brightness step, light color part */ +const brightnessStep1 = 5; +/** Brightness step, dark color part */ +const brightnessStep2 = 15; +/** Light color count, main color up */ +const lightColorCount = 5; +/** Dark color count, main color down */ +const darkColorCount = 4; + +/** + * The color index of color palette + * + * From left to right, the color is from light to dark, 6 is main color + */ +type ColorIndex = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10; + +/** + * Get color palette (from left to right, the color is from light to dark, 6 is main color) + * + * @param color - Color + * @param index - The color index of color palette (the main color index is 6) + * @returns Hex color + */ +export function getColorPalette(color: AnyColor, index: ColorIndex): string { + const transformColor = colord(color); + + if (!transformColor.isValid()) { + throw new Error('invalid input color value'); + } + + if (index === 6) { + return colord(transformColor).toHex(); + } + + const isLight = index < 6; + const hsv = transformColor.toHsv(); + const i = isLight ? lightColorCount + 1 - index : index - lightColorCount - 1; + + const newHsv: HsvColor = { + h: getHue(hsv, i, isLight), + s: getSaturation(hsv, i, isLight), + v: getValue(hsv, i, isLight) + }; + + return colord(newHsv).toHex(); +} + +/** Map of dark color index and opacity */ +const darkColorMap = [ + { index: 7, opacity: 0.15 }, + { index: 6, opacity: 0.25 }, + { index: 5, opacity: 0.3 }, + { index: 5, opacity: 0.45 }, + { index: 5, opacity: 0.65 }, + { index: 5, opacity: 0.85 }, + { index: 4, opacity: 0.9 }, + { index: 3, opacity: 0.95 }, + { index: 2, opacity: 0.97 }, + { index: 1, opacity: 0.98 } +]; + +/** + * Get color palettes + * + * @param color - Color + * @param darkTheme - Dark theme + * @param darkThemeMixColor - Dark theme mix color (default: #141414) + */ +export function getColorPalettes(color: AnyColor, darkTheme = false, darkThemeMixColor = '#141414'): string[] { + const indexes: ColorIndex[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + + const patterns = indexes.map(index => getColorPalette(color, index)); + + if (darkTheme) { + const darkPatterns = darkColorMap.map(({ index, opacity }) => { + const darkColor = colord(darkThemeMixColor).mix(patterns[index], opacity); + + return darkColor; + }); + + return darkPatterns.map(item => colord(item).toHex()); + } + + return patterns; +} + +/** + * Get hue + * + * @param hsv - Hsv format color + * @param i - The relative distance from 6 + * @param isLight - Is light color + */ +function getHue(hsv: HsvColor, i: number, isLight: boolean) { + let hue: number; + + const hsvH = Math.round(hsv.h); + + if (hsvH >= 60 && hsvH <= 240) { + hue = isLight ? hsvH - hueStep * i : hsvH + hueStep * i; + } else { + hue = isLight ? hsvH + hueStep * i : hsvH - hueStep * i; + } + + if (hue < 0) { + hue += 360; + } + + if (hue >= 360) { + hue -= 360; + } + + return hue; +} + +/** + * Get saturation + * + * @param hsv - Hsv format color + * @param i - The relative distance from 6 + * @param isLight - Is light color + */ +function getSaturation(hsv: HsvColor, i: number, isLight: boolean) { + if (hsv.h === 0 && hsv.s === 0) { + return hsv.s; + } + + let saturation: number; + + if (isLight) { + saturation = hsv.s - saturationStep * i; + } else if (i === darkColorCount) { + saturation = hsv.s + saturationStep; + } else { + saturation = hsv.s + saturationStep2 * i; + } + + if (saturation > 100) { + saturation = 100; + } + + if (isLight && i === lightColorCount && saturation > 10) { + saturation = 10; + } + + if (saturation < 6) { + saturation = 6; + } + + return saturation; +} + +/** + * Get value of hsv + * + * @param hsv - Hsv format color + * @param i - The relative distance from 6 + * @param isLight - Is light color + */ +function getValue(hsv: HsvColor, i: number, isLight: boolean) { + let value: number; + + if (isLight) { + value = hsv.v + brightnessStep1 * i; + } else { + value = hsv.v - brightnessStep2 * i; + } + + if (value > 100) { + value = 100; + } + + return value; +} diff --git a/packages/utils/src/crypto.ts b/packages/utils/src/crypto.ts new file mode 100644 index 0000000..dc173c8 --- /dev/null +++ b/packages/utils/src/crypto.ts @@ -0,0 +1,27 @@ +import CryptoJS from 'crypto-js'; + +export class Crypto { + /** Secret */ + secret: string; + + constructor(secret: string) { + this.secret = secret; + } + + encrypt(data: T): string { + const dataString = JSON.stringify(data); + const encrypted = CryptoJS.AES.encrypt(dataString, this.secret); + return encrypted.toString(); + } + + decrypt(encrypted: string) { + const decrypted = CryptoJS.AES.decrypt(encrypted, this.secret); + const dataString = decrypted.toString(CryptoJS.enc.Utf8); + try { + return JSON.parse(dataString) as T; + } catch { + // avoid parse error + return null; + } + } +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts new file mode 100644 index 0000000..a12ed34 --- /dev/null +++ b/packages/utils/src/index.ts @@ -0,0 +1,4 @@ +export * from './color'; +export * from './crypto'; +export * from './storage'; +export * from './nanoid'; diff --git a/packages/utils/src/nanoid.ts b/packages/utils/src/nanoid.ts new file mode 100644 index 0000000..5cc1d2e --- /dev/null +++ b/packages/utils/src/nanoid.ts @@ -0,0 +1,3 @@ +import { nanoid } from 'nanoid'; + +export { nanoid }; diff --git a/packages/utils/src/storage.ts b/packages/utils/src/storage.ts new file mode 100644 index 0000000..5dd8cdc --- /dev/null +++ b/packages/utils/src/storage.ts @@ -0,0 +1,76 @@ +import localforage from 'localforage'; + +/** The storage type */ +export type StorageType = 'local' | 'session'; + +export function createStorage(type: StorageType) { + const stg = type === 'session' ? window.sessionStorage : window.localStorage; + + const storage = { + /** + * Set session + * + * @param key Session key + * @param value Session value + */ + set(key: K, value: T[K]) { + const json = JSON.stringify(value); + + stg.setItem(key as string, json); + }, + /** + * Get session + * + * @param key Session key + */ + get(key: K): T[K] | null { + const json = stg.getItem(key as string); + if (json) { + let storageData: T[K] | null = null; + + try { + storageData = JSON.parse(json); + } catch {} + + if (storageData) { + return storageData as T[K]; + } + } + + stg.removeItem(key as string); + + return null; + }, + remove(key: keyof T) { + stg.removeItem(key as string); + }, + clear() { + stg.clear(); + } + }; + return storage; +} + +type LocalForage = Omit & { + getItem(key: K, callback?: (err: any, value: T[K] | null) => void): Promise; + + setItem(key: K, value: T[K], callback?: (err: any, value: T[K]) => void): Promise; + + removeItem(key: keyof T, callback?: (err: any) => void): Promise; +}; + +type LocalforageDriver = 'local' | 'indexedDB' | 'webSQL'; + +export function createLocalforage(driver: LocalforageDriver) { + const driverMap: Record = { + local: localforage.LOCALSTORAGE, + indexedDB: localforage.INDEXEDDB, + webSQL: localforage.WEBSQL + }; + + localforage.config({ + driver: driverMap[driver] + }); + + return localforage as LocalForage; +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..eb65d44 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,10574 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@better-scroll/core': + specifier: 2.5.1 + version: 2.5.1 + '@iconify/vue': + specifier: 4.1.2 + version: 4.1.2(vue@3.4.27(typescript@5.4.5)) + '@sa/axios': + specifier: workspace:* + version: link:packages/axios + '@sa/color-palette': + specifier: workspace:* + version: link:packages/color-palette + '@sa/fetch': + specifier: workspace:* + version: link:packages/ofetch + '@sa/hooks': + specifier: workspace:* + version: link:packages/hooks + '@sa/materials': + specifier: workspace:* + version: link:packages/materials + '@sa/utils': + specifier: workspace:* + version: link:packages/utils + '@vueuse/core': + specifier: 10.10.0 + version: 10.10.0(vue@3.4.27(typescript@5.4.5)) + ant-design-vue: + specifier: 4.2.2 + version: 4.2.2(vue@3.4.27(typescript@5.4.5)) + clipboard: + specifier: 2.0.11 + version: 2.0.11 + dayjs: + specifier: 1.11.11 + version: 1.11.11 + echarts: + specifier: 5.5.0 + version: 5.5.0 + lodash-es: + specifier: 4.17.21 + version: 4.17.21 + nprogress: + specifier: 0.2.0 + version: 0.2.0 + pinia: + specifier: 2.1.7 + version: 2.1.7(typescript@5.4.5)(vue@3.4.27(typescript@5.4.5)) + vue: + specifier: 3.4.27 + version: 3.4.27(typescript@5.4.5) + vue-draggable-plus: + specifier: 0.5.0 + version: 0.5.0(@types/sortablejs@1.15.8) + vue-i18n: + specifier: 9.13.1 + version: 9.13.1(vue@3.4.27(typescript@5.4.5)) + vue-router: + specifier: 4.3.2 + version: 4.3.2(vue@3.4.27(typescript@5.4.5)) + devDependencies: + '@elegant-router/vue': + specifier: 0.3.7 + version: 0.3.7 + '@iconify/json': + specifier: 2.2.217 + version: 2.2.217 + '@sa/scripts': + specifier: workspace:* + version: link:packages/scripts + '@sa/uno-preset': + specifier: workspace:* + version: link:packages/uno-preset + '@soybeanjs/eslint-config': + specifier: 1.3.6 + version: 1.3.6(@types/eslint@8.56.10)(@unocss/eslint-config@0.60.4(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-vue@9.26.0(eslint@9.4.0))(eslint@9.4.0)(typescript@5.4.5)(vue-eslint-parser@9.4.3(eslint@9.4.0)) + '@types/lodash-es': + specifier: 4.17.12 + version: 4.17.12 + '@types/node': + specifier: 20.14.2 + version: 20.14.2 + '@types/nprogress': + specifier: 0.2.3 + version: 0.2.3 + '@unocss/eslint-config': + specifier: 0.60.4 + version: 0.60.4(eslint@9.4.0)(typescript@5.4.5) + '@unocss/preset-attributify': + specifier: ^0.60.4 + version: 0.60.4 + '@unocss/preset-icons': + specifier: 0.60.4 + version: 0.60.4 + '@unocss/preset-tagify': + specifier: ^0.60.4 + version: 0.60.4 + '@unocss/preset-uno': + specifier: 0.60.4 + version: 0.60.4 + '@unocss/transformer-directives': + specifier: 0.60.4 + version: 0.60.4 + '@unocss/transformer-variant-group': + specifier: 0.60.4 + version: 0.60.4 + '@unocss/vite': + specifier: 0.60.4 + version: 0.60.4(rollup@4.18.0)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)) + '@vitejs/plugin-vue': + specifier: 5.0.5 + version: 5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4))(vue@3.4.27(typescript@5.4.5)) + '@vitejs/plugin-vue-jsx': + specifier: 4.0.0 + version: 4.0.0(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4))(vue@3.4.27(typescript@5.4.5)) + eslint: + specifier: 9.4.0 + version: 9.4.0 + eslint-plugin-vue: + specifier: 9.26.0 + version: 9.26.0(eslint@9.4.0) + lint-staged: + specifier: 15.2.5 + version: 15.2.5 + sass: + specifier: 1.77.4 + version: 1.77.4 + simple-git-hooks: + specifier: 2.11.1 + version: 2.11.1 + tsx: + specifier: 4.14.1 + version: 4.14.1 + typescript: + specifier: 5.4.5 + version: 5.4.5 + unplugin-auto-import: + specifier: ^0.17.6 + version: 0.17.6(@vueuse/core@10.10.0(vue@3.4.27(typescript@5.4.5)))(rollup@4.18.0) + unplugin-icons: + specifier: 0.19.0 + version: 0.19.0(@vue/compiler-sfc@3.4.27)(vue-template-compiler@2.7.16) + unplugin-vue-components: + specifier: 0.27.0 + version: 0.27.0(@babel/parser@7.24.7)(rollup@4.18.0)(vue@3.4.27(typescript@5.4.5)) + vite: + specifier: 5.2.13 + version: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + vite-plugin-progress: + specifier: 0.0.7 + version: 0.0.7(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)) + vite-plugin-svg-icons: + specifier: 2.0.1 + version: 2.0.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)) + vitest: + specifier: ^1.6.0 + version: 1.6.0(@types/node@20.14.2)(sass@1.77.4) + vue-eslint-parser: + specifier: 9.4.3 + version: 9.4.3(eslint@9.4.0) + vue-tsc: + specifier: 2.0.21 + version: 2.0.21(typescript@5.4.5) + + packages/axios: + dependencies: + '@sa/utils': + specifier: workspace:* + version: link:../utils + axios: + specifier: 1.6.8 + version: 1.7.2 + axios-retry: + specifier: 4.1.0 + version: 4.4.0(axios@1.7.2) + qs: + specifier: 6.12.1 + version: 6.12.1 + devDependencies: + '@types/qs': + specifier: 6.9.15 + version: 6.9.15 + + packages/color-palette: + dependencies: + colord: + specifier: 2.9.3 + version: 2.9.3 + + packages/docs: + devDependencies: + vitepress: + specifier: 1.0.0-rc.36 + version: 1.2.3(@algolia/client-search@4.23.3)(@types/node@20.14.2)(async-validator@4.2.5)(axios@1.7.2)(nprogress@0.2.0)(postcss@8.4.38)(sass@1.77.4)(search-insights@2.14.0)(typescript@5.4.5) + + packages/eslint-config: + devDependencies: + '@types/eslint': + specifier: 8.56.1 + version: 8.56.10 + '@typescript-eslint/eslint-plugin': + specifier: 6.18.0 + version: 7.12.0(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint@9.4.0)(typescript@5.4.5) + '@typescript-eslint/parser': + specifier: 6.18.0 + version: 7.12.0(eslint@9.4.0)(typescript@5.4.5) + eslint: + specifier: 8.56.0 + version: 9.4.0 + eslint-config-prettier: + specifier: 9.1.0 + version: 9.1.0(eslint@9.4.0) + eslint-import-resolver-typescript: + specifier: 3.6.1 + version: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@9.4.0) + eslint-plugin-import: + specifier: 2.29.1 + version: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@9.4.0) + eslint-plugin-n: + specifier: 16.6.1 + version: 17.8.1(eslint@9.4.0) + eslint-plugin-prettier: + specifier: 5.1.2 + version: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.1) + eslint-plugin-promise: + specifier: 6.1.1 + version: 6.2.0(eslint@9.4.0) + eslint-plugin-vue: + specifier: 9.19.2 + version: 9.26.0(eslint@9.4.0) + prettier: + specifier: 3.1.1 + version: 3.3.1 + + packages/hooks: + dependencies: + '@sa/axios': + specifier: workspace:* + version: link:../axios + + packages/materials: + dependencies: + '@sa/utils': + specifier: workspace:* + version: link:../utils + '@simonwep/pickr': + specifier: 1.9.0 + version: 1.9.1 + simplebar-vue: + specifier: 2.3.3 + version: 2.3.4(vue@3.4.27(typescript@5.4.5)) + devDependencies: + typed-css-modules: + specifier: 0.9.1 + version: 0.9.1 + + packages/ofetch: + dependencies: + ofetch: + specifier: 1.3.4 + version: 1.3.4 + + packages/scripts: + devDependencies: + '@soybeanjs/changelog': + specifier: 0.3.22 + version: 0.3.24(@types/eslint@8.56.10)(@unocss/eslint-config@0.60.4(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-vue@9.26.0(eslint@9.4.0))(eslint@9.4.0)(typescript@5.4.5)(vue-eslint-parser@9.4.3(eslint@9.4.0)) + bumpp: + specifier: 9.4.0 + version: 9.4.1 + c12: + specifier: 1.10.0 + version: 1.10.0 + cac: + specifier: 6.7.14 + version: 6.7.14 + consola: + specifier: 3.2.3 + version: 3.2.3 + enquirer: + specifier: ^2.4.1 + version: 2.4.1 + execa: + specifier: 8.0.1 + version: 9.2.0 + kolorist: + specifier: 1.8.0 + version: 1.8.0 + npm-check-updates: + specifier: 16.14.18 + version: 16.14.20 + rimraf: + specifier: 5.0.5 + version: 5.0.7 + + packages/uno-preset: {} + + packages/utils: + dependencies: + colord: + specifier: 2.9.3 + version: 2.9.3 + crypto-js: + specifier: 4.2.0 + version: 4.2.0 + localforage: + specifier: 1.10.0 + version: 1.10.0 + nanoid: + specifier: 5.0.7 + version: 5.0.7 + devDependencies: + '@types/crypto-js': + specifier: 4.2.2 + version: 4.2.2 + +packages: + + '@algolia/autocomplete-core@1.9.3': + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3': + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + + '@algolia/autocomplete-preset-algolia@1.9.3': + resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/autocomplete-shared@1.9.3': + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + + '@algolia/cache-browser-local-storage@4.23.3': + resolution: {integrity: sha512-vRHXYCpPlTDE7i6UOy2xE03zHF2C8MEFjPN2v7fRbqVpcOvAUQK81x3Kc21xyb5aSIpYCjWCZbYZuz8Glyzyyg==} + + '@algolia/cache-common@4.23.3': + resolution: {integrity: sha512-h9XcNI6lxYStaw32pHpB1TMm0RuxphF+Ik4o7tcQiodEdpKK+wKufY6QXtba7t3k8eseirEMVB83uFFF3Nu54A==} + + '@algolia/cache-in-memory@4.23.3': + resolution: {integrity: sha512-yvpbuUXg/+0rbcagxNT7un0eo3czx2Uf0y4eiR4z4SD7SiptwYTpbuS0IHxcLHG3lq22ukx1T6Kjtk/rT+mqNg==} + + '@algolia/client-account@4.23.3': + resolution: {integrity: sha512-hpa6S5d7iQmretHHF40QGq6hz0anWEHGlULcTIT9tbUssWUriN9AUXIFQ8Ei4w9azD0hc1rUok9/DeQQobhQMA==} + + '@algolia/client-analytics@4.23.3': + resolution: {integrity: sha512-LBsEARGS9cj8VkTAVEZphjxTjMVCci+zIIiRhpFun9jGDUlS1XmhCW7CTrnaWeIuCQS/2iPyRqSy1nXPjcBLRA==} + + '@algolia/client-common@4.23.3': + resolution: {integrity: sha512-l6EiPxdAlg8CYhroqS5ybfIczsGUIAC47slLPOMDeKSVXYG1n0qGiz4RjAHLw2aD0xzh2EXZ7aRguPfz7UKDKw==} + + '@algolia/client-personalization@4.23.3': + resolution: {integrity: sha512-3E3yF3Ocr1tB/xOZiuC3doHQBQ2zu2MPTYZ0d4lpfWads2WTKG7ZzmGnsHmm63RflvDeLK/UVx7j2b3QuwKQ2g==} + + '@algolia/client-search@4.23.3': + resolution: {integrity: sha512-P4VAKFHqU0wx9O+q29Q8YVuaowaZ5EM77rxfmGnkHUJggh28useXQdopokgwMeYw2XUht49WX5RcTQ40rZIabw==} + + '@algolia/logger-common@4.23.3': + resolution: {integrity: sha512-y9kBtmJwiZ9ZZ+1Ek66P0M68mHQzKRxkW5kAAXYN/rdzgDN0d2COsViEFufxJ0pb45K4FRcfC7+33YB4BLrZ+g==} + + '@algolia/logger-console@4.23.3': + resolution: {integrity: sha512-8xoiseoWDKuCVnWP8jHthgaeobDLolh00KJAdMe9XPrWPuf1by732jSpgy2BlsLTaT9m32pHI8CRfrOqQzHv3A==} + + '@algolia/recommend@4.23.3': + resolution: {integrity: sha512-9fK4nXZF0bFkdcLBRDexsnGzVmu4TSYZqxdpgBW2tEyfuSSY54D4qSRkLmNkrrz4YFvdh2GM1gA8vSsnZPR73w==} + + '@algolia/requester-browser-xhr@4.23.3': + resolution: {integrity: sha512-jDWGIQ96BhXbmONAQsasIpTYWslyjkiGu0Quydjlowe+ciqySpiDUrJHERIRfELE5+wFc7hc1Q5hqjGoV7yghw==} + + '@algolia/requester-common@4.23.3': + resolution: {integrity: sha512-xloIdr/bedtYEGcXCiF2muajyvRhwop4cMZo+K2qzNht0CMzlRkm8YsDdj5IaBhshqfgmBb3rTg4sL4/PpvLYw==} + + '@algolia/requester-node-http@4.23.3': + resolution: {integrity: sha512-zgu++8Uj03IWDEJM3fuNl34s746JnZOWn1Uz5taV1dFyJhVM/kTNw9Ik7YJWiUNHJQXcaD8IXD1eCb0nq/aByA==} + + '@algolia/transporter@4.23.3': + resolution: {integrity: sha512-Wjl5gttqnf/gQKJA+dafnD0Y6Yw97yvfY8R9h0dQltX1GXTgNs1zWgvtWW0tHl1EgMdhAyw189uWiZMnL3QebQ==} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@ant-design/colors@6.0.0': + resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==} + + '@ant-design/icons-svg@4.4.2': + resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} + + '@ant-design/icons-vue@7.0.1': + resolution: {integrity: sha512-eCqY2unfZK6Fe02AwFlDHLfoyEFreP6rBwAZMIJ1LugmfMiVgwWDYlp1YsRugaPtICYOabV1iWxXdP12u9U43Q==} + peerDependencies: + vue: '>=3.0.3' + + '@antfu/eslint-define-config@1.23.0-2': + resolution: {integrity: sha512-LvxY21+ZhpuBf/aHeBUtGQhSEfad4PkNKXKvDOSvukaM3XVTfBhwmHX2EKwAsdq5DlfjbT3qqYyMiueBIO5iDQ==} + engines: {node: '>=18.0.0', npm: '>=9.0.0', pnpm: '>= 8.6.0'} + + '@antfu/install-pkg@0.1.1': + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + + '@antfu/install-pkg@0.3.3': + resolution: {integrity: sha512-nHHsk3NXQ6xkCfiRRC8Nfrg8pU5kkr3P3Y9s9dKqiuRmBD0Yap7fymNDjGFKeWhZQHqqbCS5CfeMy9wtExM24w==} + + '@antfu/utils@0.7.8': + resolution: {integrity: sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==} + + '@babel/code-frame@7.24.7': + resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.24.7': + resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.24.7': + resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.24.7': + resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.24.7': + resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.24.7': + resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.24.7': + resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.24.7': + resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.22.15': + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.24.7': + resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.24.7': + resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.24.7': + resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.24.7': + resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.24.7': + resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.24.7': + resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.24.7': + resolution: {integrity: sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.24.7': + resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.24.7': + resolution: {integrity: sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.24.7': + resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.24.7': + resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.24.7': + resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.24.7': + resolution: {integrity: sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.24.7': + resolution: {integrity: sha512-iLD3UNkgx2n/HrjBesVbYX6j0yqn/sJktvbtKKgcaLIQ4bTTQ8obAypc1VpyHPD2y4Phh9zHOaAt8e/L14wCpw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.24.7': + resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.24.7': + resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.24.7': + resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.7': + resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} + engines: {node: '>=6.9.0'} + + '@better-scroll/core@2.5.1': + resolution: {integrity: sha512-koKOuYA55dQ04FJRIVUpMGDr1hbCfWmfX0MGp1hKagkQSWSRpwblqACiwtggVauoj9aaJRJZ9hDsTM4weaavlg==} + + '@better-scroll/shared-utils@2.5.1': + resolution: {integrity: sha512-AplkfSjXVYP9LZiD6JsKgmgQJ/mG4uuLmBuwLz8W5OsYc7AYTfN8kw6GqZ5OwCGoXkVhBGyd8NeC4xwYItp0aw==} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@ctrl/tinycolor@3.6.1': + resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} + engines: {node: '>=10'} + + '@docsearch/css@3.6.0': + resolution: {integrity: sha512-+sbxb71sWre+PwDK7X2T8+bhS6clcVMLwBPznX45Qu6opJcgRjAp7gYSDzVFp187J+feSj5dNBN1mJoi6ckkUQ==} + + '@docsearch/js@3.6.0': + resolution: {integrity: sha512-QujhqINEElrkIfKwyyyTfbsfMAYCkylInLYMRqHy7PHc8xTBQCow73tlo/Kc7oIwBrCLf0P3YhjlOeV4v8hevQ==} + + '@docsearch/react@3.6.0': + resolution: {integrity: sha512-HUFut4ztcVNmqy9gp/wxNbC7pTOHhgVVkHVGCACTuLhUKUhKAF9KYHJtMiLUJxEqiFLQiuri1fWF8zqwM/cu1w==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + search-insights: '>= 1 < 3' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + search-insights: + optional: true + + '@elegant-router/core@0.3.7': + resolution: {integrity: sha512-iNj+ZGage9w6vnZyAvZzrRX+yQX7Tr02PJZjwX92ShdEEDnDkM71UnUOv94X6z6T1y4QQo+v1/z6MNP0fJl5mw==} + + '@elegant-router/vue@0.3.7': + resolution: {integrity: sha512-nw1M62SIlvyVE+BsHoOVntJzib2Ch1uz1U8QLJygNMuKfltb9VmWhZzEpKr8ZSIWLQt3ibK6wsla2T4h67mxGQ==} + + '@emotion/hash@0.9.1': + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + + '@emotion/unitless@0.8.1': + resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} + + '@esbuild/aix-ppc64@0.20.2': + resolution: {integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.20.2': + resolution: {integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.20.2': + resolution: {integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.20.2': + resolution: {integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.20.2': + resolution: {integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.20.2': + resolution: {integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.20.2': + resolution: {integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.20.2': + resolution: {integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.20.2': + resolution: {integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.20.2': + resolution: {integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.20.2': + resolution: {integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.20.2': + resolution: {integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.20.2': + resolution: {integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.20.2': + resolution: {integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.20.2': + resolution: {integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.20.2': + resolution: {integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.20.2': + resolution: {integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.20.2': + resolution: {integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.20.2': + resolution: {integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.20.2': + resolution: {integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.20.2': + resolution: {integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.20.2': + resolution: {integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.20.2': + resolution: {integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.10.1': + resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.15.1': + resolution: {integrity: sha512-K4gzNq+yymn/EVsXYmf+SBcBro8MTf+aXJZUphM96CdzUEr+ClGDvAbpmaEK+cGVigVXIgs9gNmvHAlrzzY5JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.4.0': + resolution: {integrity: sha512-fdI7VJjP3Rvc70lC4xkFXHB0fiPeojiL1PxVG6t1ZvXQrarj893PweuBTujxDUFk0Fxj4R7PIIAZ/aiiyZPZcg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.3': + resolution: {integrity: sha512-HAbhAYKfsAC2EkTqve00ibWIZlaU74Z1EHwAjYr4PXF0YU2VEA1zSIKSSpKszRLRWwHzzRZXvK632u+uXzvsvw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@gar/promisify@1.1.3': + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.0': + resolution: {integrity: sha512-d2CGZR2o7fS6sWB7DG/3a95bGKQyHMACZ5aW8qGkkqQpUoZV6C0X7Pc7l4ZNMZkfNBf4VWNe9E1jRsf0G146Ew==} + engines: {node: '>=18.18'} + + '@iconify/json@2.2.217': + resolution: {integrity: sha512-+sSR9iKsoThUmgG4wA9xdtyazROIqMOo5h5otOXYRyOQjMNJCpJltq5hEhHInC5aG/DUQmXDiN/YsCoJdCYUbQ==} + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.1.24': + resolution: {integrity: sha512-H8r2KpL5uKyrkb3z9/3HD/22JcxqW3BJyjEWZhX2T7DehnYVZthEap1cNsEl/UtCDC3TlpNmwiPX8wg3y8E4dg==} + + '@iconify/vue@4.1.2': + resolution: {integrity: sha512-CQnYqLiQD5LOAaXhBrmj1mdL2/NCJvwcC4jtW2Z8ukhThiFkLDkutarTOV2trfc9EXqUqRs0KqXOL9pZ/IyysA==} + peerDependencies: + vue: '>=3' + + '@intlify/core-base@9.13.1': + resolution: {integrity: sha512-+bcQRkJO9pcX8d0gel9ZNfrzU22sZFSA0WVhfXrf5jdJOS24a+Bp8pozuS9sBI9Hk/tGz83pgKfmqcn/Ci7/8w==} + engines: {node: '>= 16'} + + '@intlify/message-compiler@9.13.1': + resolution: {integrity: sha512-SKsVa4ajYGBVm7sHMXd5qX70O2XXjm55zdZB3VeMFCvQyvLew/dLvq3MqnaIsTMF1VkkOb9Ttr6tHcMlyPDL9w==} + engines: {node: '>= 16'} + + '@intlify/shared@9.13.1': + resolution: {integrity: sha512-u3b6BKGhE6j/JeRU6C/RL2FgyJfy6LakbtfeVF8fJXURpZZTzfh3e05J0bu0XPw447Q6/WUp3C4ajv4TMS4YsQ==} + engines: {node: '>= 16'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.4.15': + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jsdevtools/ez-spawn@3.0.4': + resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==} + engines: {node: '>=10'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@npmcli/fs@2.1.2': + resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/git@4.1.0': + resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/installed-package-contents@2.1.0': + resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + '@npmcli/move-file@2.0.1': + resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This functionality has been moved to @npmcli/fs + + '@npmcli/node-gyp@3.0.0': + resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/promise-spawn@6.0.2': + resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/run-script@6.0.2': + resolution: {integrity: sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@2.2.2': + resolution: {integrity: sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==} + engines: {node: '>=12'} + + '@polka/url@1.0.0-next.25': + resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==} + + '@rollup/pluginutils@5.1.0': + resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.18.0': + resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.18.0': + resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.18.0': + resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.18.0': + resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.18.0': + resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.18.0': + resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.18.0': + resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.18.0': + resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} + cpu: [x64] + os: [win32] + + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + + '@shikijs/core@1.6.3': + resolution: {integrity: sha512-QnJKHFUW95GnlJLJGP6QLx4M69HM0KlXk+R2Y8lr/x4nAx1Yb/lsuxq4XwybuUjTxbJk+BT0g/kvn0bcsjGGHg==} + + '@shikijs/transformers@1.6.3': + resolution: {integrity: sha512-ptBuP/IIeqCzK3zZO/knFICZWs58uZWzbv7ND+bKOewe5NcCjZfSiMyzFwOyl23ewPJ1APjRBwLi6Asrodmmxw==} + + '@sigstore/bundle@1.1.0': + resolution: {integrity: sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/protobuf-specs@0.2.1': + resolution: {integrity: sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/sign@1.0.0': + resolution: {integrity: sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/tuf@1.0.3': + resolution: {integrity: sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@simonwep/pickr@1.8.2': + resolution: {integrity: sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==} + + '@simonwep/pickr@1.9.1': + resolution: {integrity: sha512-fR3qmfAcPf/HSFS7GEnTmZLM3+xERv1+jyMBbzT63ilRRM8veYjI7ELvkHHKk0/du3lHp7uh/FqatjM3646X1g==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@soybeanjs/changelog@0.3.24': + resolution: {integrity: sha512-QQVDFOsAdrYkyE5eEXuwtEi3poIOptkZhA0NxV2dfZoU3ChfFo0pkkuDplgpXaZvx09Omu2i04fdNKxFftAC3w==} + engines: {node: '>=16', pnpm: '>=9'} + + '@soybeanjs/eslint-config@1.3.6': + resolution: {integrity: sha512-ZSTCGxbNe6ext+WPnjzE5lYveYYnu32n8GDkcvc8OWC27PHiYd1DnpQtWwAdXIRxdbVBw+QH3+phD/9TLUkqwA==} + peerDependencies: + '@toml-tools/parser': '*' + '@unocss/eslint-config': '>=0.58.0' + eslint: '>=8.40.0' + eslint-plugin-astro: '>=0.30.0' + eslint-plugin-react: '>=7.0.0' + eslint-plugin-react-hooks: '>=4.0.0' + eslint-plugin-react-native: '>=4.0.0' + eslint-plugin-react-refresh: '>=0.4.0' + eslint-plugin-solid: '>=0.10.0' + eslint-plugin-svelte: '>=2.0.0' + eslint-plugin-vue: '>=9.19.0' + prettier-plugin-astro: '>=0.12.0' + prettier-plugin-svelte: '>=3.0.0' + prettier-plugin-toml: '>=2.0.0' + typescript: '>=5.0.0' + vue-eslint-parser: '>=9.3.2' + peerDependenciesMeta: + '@toml-tools/parser': + optional: true + '@unocss/eslint-config': + optional: true + eslint-plugin-astro: + optional: true + eslint-plugin-react: + optional: true + eslint-plugin-react-hooks: + optional: true + eslint-plugin-react-native: + optional: true + eslint-plugin-react-refresh: + optional: true + eslint-plugin-solid: + optional: true + eslint-plugin-svelte: + optional: true + eslint-plugin-vue: + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-svelte: + optional: true + prettier-plugin-toml: + optional: true + vue-eslint-parser: + optional: true + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + '@trysound/sax@0.2.0': + resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} + engines: {node: '>=10.13.0'} + + '@tufjs/canonical-json@1.0.0': + resolution: {integrity: sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@tufjs/models@1.0.4': + resolution: {integrity: sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@types/crypto-js@4.2.2': + resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/eslint@8.56.10': + resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.5': + resolution: {integrity: sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==} + + '@types/markdown-it@14.1.1': + resolution: {integrity: sha512-4NpsnpYl2Gt1ljyBGrKMxFYAYvpqbnnkgP/i/g+NLpjEUa3obn1XJCur9YbEXKDAkaXqsR1LbDnGEJ0MmKFxfg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + + '@types/node@20.14.2': + resolution: {integrity: sha512-xyu6WAMVwv6AKFLB+e/7ySZVr/0zLCzOa7rSpq6jNwpqOrUbcACDWC+53d4n2QHOnDou0fbIsg8wZu/sxrnI4Q==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/nprogress@0.2.3': + resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} + + '@types/qs@6.9.15': + resolution: {integrity: sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==} + + '@types/semver-utils@1.1.3': + resolution: {integrity: sha512-T+YwkslhsM+CeuhYUxyAjWm7mJ5am/K10UX40RuA6k6Lc7eGtq8iY2xOzy7Vq0GOqhl/xZl5l2FwURZMTPTUww==} + + '@types/sortablejs@1.15.8': + resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==} + + '@types/svgo@2.6.4': + resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==} + + '@types/unist@3.0.2': + resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@typescript-eslint/eslint-plugin@7.12.0': + resolution: {integrity: sha512-7F91fcbuDf/d3S8o21+r3ZncGIke/+eWk0EpO21LXhDfLahriZF9CGj4fbAetEjlaBdjdSm9a6VeXbpbT6Z40Q==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + '@typescript-eslint/parser': ^7.0.0 + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@7.12.0': + resolution: {integrity: sha512-dm/J2UDY3oV3TKius2OUZIFHsomQmpHtsV0FTh1WO8EKgHLQ1QCADUqscPgTpU+ih1e21FQSRjXckHn3txn6kQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.12.0': + resolution: {integrity: sha512-itF1pTnN6F3unPak+kutH9raIkL3lhH1YRPGgt7QQOh43DQKVJXmWkpb+vpc/TiDHs6RSd9CTbDsc/Y+Ygq7kg==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.12.0': + resolution: {integrity: sha512-lib96tyRtMhLxwauDWUp/uW3FMhLA6D0rJ8T7HmH7x23Gk1Gwwu8UZ94NMXBvOELn6flSPiBrCKlehkiXyaqwA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.12.0': + resolution: {integrity: sha512-o+0Te6eWp2ppKY3mLCU+YA9pVJxhUJE15FV7kxuD9jgwIAa+w/ycGJBMrYDTpVGUM/tgpa9SeMOugSabWFq7bg==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.12.0': + resolution: {integrity: sha512-5bwqLsWBULv1h6pn7cMW5dXX/Y2amRqLaKqsASVwbBHMZSnHqE/HN4vT4fE0aFsiwxYvr98kqOWh1a8ZKXalCQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.12.0': + resolution: {integrity: sha512-Y6hhwxwDx41HNpjuYswYp6gDbkiZ8Hin9Bf5aJQn1bpTs3afYY4GX+MPYxma8jtoIV2GRwTM/UJm/2uGCVv+DQ==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.12.0': + resolution: {integrity: sha512-uZk7DevrQLL3vSnfFl5bj4sL75qC9D6EdjemIdbtkuUmIheWpuiiylSY01JxJE7+zGrOWDZrp1WxOuDntvKrHQ==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@unocss/config@0.60.4': + resolution: {integrity: sha512-ri9P2+YztD5JdPYSLiNjcLf6NgoBbwJDVutP/tQnfYYrE72DQ+j+4vepyxEBa1YaH/X4qsmLJCj+2tI/ufIiog==} + engines: {node: '>=14'} + + '@unocss/core@0.60.4': + resolution: {integrity: sha512-6tz8KTzC30oB0YikwRQoIpJ6Y6Dg+ZiK3NfCIsH+UX11bh2J2M53as2EL/5VQCqtiUn3YP0ZEzR2d1AWX78RCA==} + + '@unocss/eslint-config@0.60.4': + resolution: {integrity: sha512-V39NnGDfjaQ+KsfSCQ21BZkQdCb17GHkyEk/LxaaH33+hEEbrXw4ggQp7S/g/gmTDhiwfcCFvURGd51L+Qn9nA==} + engines: {node: '>=14'} + + '@unocss/eslint-plugin@0.60.4': + resolution: {integrity: sha512-+ZWlc5TrzVjnvK3fKJqaTH7phSrYAKcbXC0aTTfM1PeTg8ya6tW4sqUmESRkbn9M5AYxhDADqFdqenQN0qlXqQ==} + engines: {node: '>=14'} + + '@unocss/extractor-arbitrary-variants@0.60.4': + resolution: {integrity: sha512-USuFGs5CLft9q7IGNdAEp1oliuUns+W7OO0Tx5qtx/oBh6pU/L93lcNNsuuGNrMU8BCmF3atx1/PEmGymgJ7VA==} + + '@unocss/inspector@0.60.4': + resolution: {integrity: sha512-PcnrEQ2H7osZho4Nh0+84O4IXzlkF7pvTUe/7FTJYF1HQGWHB/PfOSoyKn7/sF5sED8hMK9RlSJ9YGUH9ioY+g==} + + '@unocss/preset-attributify@0.60.4': + resolution: {integrity: sha512-J2GWUC0bcmZSXlBGLYUXwWQos/dNzKbq2CKweWVBAmAH9XyfM0mA5CTNBRv05PN1g6C/0z5st7ntUjV6KHJuTg==} + + '@unocss/preset-icons@0.60.4': + resolution: {integrity: sha512-UN/dj+nhI3+S06YxCZQPLw3GZy780iaE71dysyhDMdh+Qq2KFVs3d94mr1427fjz/3Y8ZyXkgqyhCFr7UT0bMQ==} + + '@unocss/preset-mini@0.60.4': + resolution: {integrity: sha512-ZiHbP69vkyz0xmhqzC4B4PegwV+LPlZOBT7cRhsh0P8oPOQKYOyDRy4rAl+sJBJeIrggn1r1LgN+Z0Xvd8Ytcw==} + + '@unocss/preset-tagify@0.60.4': + resolution: {integrity: sha512-GxL/W3qkdWWDqXi43qyLbp/BpEj7gMw99KqkO7bmbVi3BVlFggreTFwmQu89pB6iatxGjxnAsc+TsQZqxKftZA==} + + '@unocss/preset-uno@0.60.4': + resolution: {integrity: sha512-AN8ZTtiKSaZNGKZZIqt/JAhMzSY2hHLwhGEOFDrXgjWFr85UlwZzODMDoT58PrU04VlbhN8+0N4lHfLmZCKpiQ==} + + '@unocss/preset-wind@0.60.4': + resolution: {integrity: sha512-dT/U+RkbL21lDTOP7/mlFZxlBbUAefUzQZINC0BX7vTKvO57G4HxRq62u9xvMGFv38lQ+qXXzKhABVsEPDNpUA==} + + '@unocss/rule-utils@0.60.4': + resolution: {integrity: sha512-7qUN33NM4T/IwWavm9VIOCZ2+4hLBc0YUGxcMNTDZSFQRQLkWe3N5dOlgwKXtMyMKatZfbIRUKVDUgvEefoCTA==} + engines: {node: '>=14'} + + '@unocss/scope@0.60.4': + resolution: {integrity: sha512-AOu/qvi4agy0XfGF3QEBbuxVHkVZHpmU0NMBYuxa0B869YZENT87sTM6DVwtvr75CZvACWxv/hcL3lR68uKBjw==} + + '@unocss/transformer-directives@0.60.4': + resolution: {integrity: sha512-u3fQI8RszMhUevhJICtQ/bNpAfbh8MEXQf7YNnzUvLvbXGkkoieyU5mj0ray6fbToqxfxVceQtXYcFYIuf4aNg==} + + '@unocss/transformer-variant-group@0.60.4': + resolution: {integrity: sha512-R4d16G7s3fDXj9prUNFnJi8cZvH8/XZsqiKDzCBjXNKrbf9zp7YnWD2VaMFjUISgW5kSQjQNSWK84soVNWq3UQ==} + + '@unocss/vite@0.60.4': + resolution: {integrity: sha512-af9hhtW11geF56cotKUE16Fr+FirTdV/Al/usjKJ6P5hnCEQnqSHXQDFXL5Y6vXwcvLDmOhHYNrVR8duKgC8Mw==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + + '@vitejs/plugin-vue-jsx@4.0.0': + resolution: {integrity: sha512-A+6wL2AdQhDsLsDnY+2v4rRDI1HLJGIMc97a8FURO9tqKsH5QvjWrzsa5DH3NlZsM742W2wODl2fF+bfcTWtXw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@5.0.5': + resolution: {integrity: sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@vitest/expect@1.6.0': + resolution: {integrity: sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==} + + '@vitest/runner@1.6.0': + resolution: {integrity: sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==} + + '@vitest/snapshot@1.6.0': + resolution: {integrity: sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==} + + '@vitest/spy@1.6.0': + resolution: {integrity: sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==} + + '@vitest/utils@1.6.0': + resolution: {integrity: sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==} + + '@volar/language-core@2.3.0': + resolution: {integrity: sha512-pvhL24WUh3VDnv7Yw5N1sjhPtdx7q9g+Wl3tggmnkMcyK8GcCNElF2zHiKznryn0DiUGk+eez/p2qQhz+puuHw==} + + '@volar/source-map@2.3.0': + resolution: {integrity: sha512-G/228aZjAOGhDjhlyZ++nDbKrS9uk+5DMaEstjvzglaAw7nqtDyhnQAsYzUg6BMP9BtwZ59RIw5HGePrutn00Q==} + + '@volar/typescript@2.3.0': + resolution: {integrity: sha512-PtUwMM87WsKVeLJN33GSTUjBexlKfKgouWlOUIv7pjrOnTwhXHZNSmpc312xgXdTjQPpToK6KXSIcKu9sBQ5LQ==} + + '@vue/babel-helper-vue-transform-on@1.2.2': + resolution: {integrity: sha512-nOttamHUR3YzdEqdM/XXDyCSdxMA9VizUKoroLX6yTyRtggzQMHXcmwh8a7ZErcJttIBIc9s68a1B8GZ+Dmvsw==} + + '@vue/babel-plugin-jsx@1.2.2': + resolution: {integrity: sha512-nYTkZUVTu4nhP199UoORePsql0l+wj7v/oyQjtThUVhJl1U+6qHuoVhIvR3bf7eVKjbCK+Cs2AWd7mi9Mpz9rA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.2.2': + resolution: {integrity: sha512-EntyroPwNg5IPVdUJupqs0CFzuf6lUrVvCspmv2J1FITLeGnUCuoGNNk78dgCusxEiYj6RMkTJflGSxk5aIC4A==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.4.27': + resolution: {integrity: sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==} + + '@vue/compiler-dom@3.4.27': + resolution: {integrity: sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==} + + '@vue/compiler-sfc@3.4.27': + resolution: {integrity: sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==} + + '@vue/compiler-ssr@3.4.27': + resolution: {integrity: sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==} + + '@vue/devtools-api@6.6.3': + resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==} + + '@vue/devtools-api@7.2.1': + resolution: {integrity: sha512-6oNCtyFOrNdqm6GUkFujsCgFlpbsHLnZqq7edeM/+cxAbMyCWvsaCsIMUaz7AiluKLccCGEM8fhOsjaKgBvb7g==} + + '@vue/devtools-kit@7.2.1': + resolution: {integrity: sha512-Wak/fin1X0Q8LLIfCAHBrdaaB+R6IdpSXsDByPHbQ3BmkCP0/cIo/oEGp9i0U2+gEqD4L3V9RDjNf1S34DTzQQ==} + peerDependencies: + vue: ^3.0.0 + + '@vue/devtools-shared@7.2.1': + resolution: {integrity: sha512-PCJF4UknJmOal68+X9XHyVeQ+idv0LFujkTOIW30+GaMJqwFVN9LkQKX4gLqn61KkGMdJTzQ1bt7EJag3TI6AA==} + + '@vue/language-core@2.0.21': + resolution: {integrity: sha512-vjs6KwnCK++kIXT+eI63BGpJHfHNVJcUCr3RnvJsccT3vbJnZV5IhHR2puEkoOkIbDdp0Gqi1wEnv3hEd3WsxQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.4.27': + resolution: {integrity: sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==} + + '@vue/runtime-core@3.4.27': + resolution: {integrity: sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==} + + '@vue/runtime-dom@3.4.27': + resolution: {integrity: sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==} + + '@vue/server-renderer@3.4.27': + resolution: {integrity: sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==} + peerDependencies: + vue: 3.4.27 + + '@vue/shared@3.4.27': + resolution: {integrity: sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==} + + '@vueuse/core@10.10.0': + resolution: {integrity: sha512-vexJ/YXYs2S42B783rI95lMt3GzEwkxzC8Hb0Ndpd8rD+p+Lk/Za4bd797Ym7yq4jXqdSyj3JLChunF/vyYjUw==} + + '@vueuse/integrations@10.10.0': + resolution: {integrity: sha512-vHGeK7X6mkdkpcm1eE9t3Cpm21pNVfZRwrjwwbrEs9XftnSgszF4831G2rei8Dt9cIYJIfFV+iyx/29muimJPQ==} + peerDependencies: + async-validator: '*' + axios: '*' + change-case: '*' + drauu: '*' + focus-trap: '*' + fuse.js: '*' + idb-keyval: '*' + jwt-decode: '*' + nprogress: '*' + qrcode: '*' + sortablejs: '*' + universal-cookie: '*' + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + + '@vueuse/metadata@10.10.0': + resolution: {integrity: sha512-UNAo2sTCAW5ge6OErPEHb5z7NEAg3XcO9Cj7OK45aZXfLLH1QkexDcZD77HBi5zvEiLOm1An+p/4b5K3Worpug==} + + '@vueuse/shared@10.10.0': + resolution: {integrity: sha512-2aW33Ac0Uk0U+9yo3Ypg9s5KcR42cuehRWl7vnUHadQyFvCktseyxxEPBi1Eiq4D2yBGACOnqLZpx1eMc7g5Og==} + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} + engines: {node: '>=0.4.0'} + + acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + algoliasearch@4.23.3: + resolution: {integrity: sha512-Le/3YgNvjW9zxIQMRhUHuhiUjAlKY/zsdZpfq4dlLqg6mEm0nL6yk+7f2hDOtLpxsgE4jSzDmvHL7nXdBp5feg==} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + ant-design-vue@4.2.2: + resolution: {integrity: sha512-6Mg63//f8+5rE/yZEv7lfzGn8IXr0lPyhNNLAxJ/7Mc4lq1SiDJcHxR2gGEaNZxFzz/gHoryqBVhUxkMX7EOhA==} + engines: {node: '>=12.22.0'} + peerDependencies: + vue: '>=3.2.0' + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + + are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-tree-filter@2.1.0: + resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios-retry@4.4.0: + resolution: {integrity: sha512-yewTKjzl6jSgc+2M7FCJ3LxRGgL1iiXHcj+E6h6xie6H1mTHr7yqaUroWIvVXG1UKSPwGDXxV05YxtGvrD6Paw==} + peerDependencies: + axios: 0.x || 1.x + + axios@1.7.2: + resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + binary-searching@2.0.5: + resolution: {integrity: sha512-v4N2l3RxL+m4zDxyxz3Ne2aTmiPn8ZUpKFpdPtO+ItW1NcTCXA7JeHG5GMBSvoKSkQZ9ycS+EouDVxYB9ufKWA==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boxen@7.1.1: + resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==} + engines: {node: '>=14.16'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.23.1: + resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + bumpp@9.4.1: + resolution: {integrity: sha512-kzhp/LpNX0HkUpEyLd7sU2LTN/mbAVgcxJ1Zi2cAJTE/tul6rypSKGpH8UywDpzKWItL8LVdKsIFnwmylw0+7g==} + engines: {node: '>=10'} + hasBin: true + + c12@1.10.0: + resolution: {integrity: sha512-0SsG7UDhoRWcuSvKWHaXmu5uNjDCDN3nkQLRL4Q42IlFy+ze58FcCoI3uPwINXinkz7ZinbhEgyzYFw9u9ZV8g==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cacache@16.1.3: + resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + cacache@17.1.4: + resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + + can-use-dom@0.1.0: + resolution: {integrity: sha512-ceOhN1DL7Y4O6M0j9ICgmTYziV89WMd96SvSl0REd8PMgrY0B/WBOPoed5S1KUmJqXgUXh8gzSe6E3ae27upsQ==} + + caniuse-lite@1.0.30001629: + resolution: {integrity: sha512-c3dl911slnQhmxUIT4HhYzT7wnBK/XYpGnYLOj4nJBaRiw52Ibe7YxlDaAeRECvA786zCuExhxIUJ2K7nHMrBw==} + + chai@4.4.1: + resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} + engines: {node: '>=4'} + + chalk@1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + + citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + + clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@3.0.0: + resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==} + engines: {node: '>=10'} + + cli-cursor@4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + cli-progress@3.12.0: + resolution: {integrity: sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==} + engines: {node: '>=4'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + + clipboard@2.0.11: + resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + comment-parser@1.4.1: + resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} + engines: {node: '>= 12.0.0'} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + compute-scroll-into-view@1.0.20: + resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==} + + computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + configstore@6.0.0: + resolution: {integrity: sha512-cD31W1v3GqUlQvbBCGcXmd2Nj9SvLDOP1oQ0YFuLETufzSPaKp11rYBsSOm7rCsW3OnIRAFM3OxRhceaXNYHkA==} + engines: {node: '>=12'} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + convert-gitmoji@0.1.5: + resolution: {integrity: sha512-4wqOafJdk2tqZC++cjcbGcaJ13BZ3kwldf06PTiAQRAB76Z1KJwZNL1SaRZMi2w1FM9RYTgZ6QErS8NUl/GBmQ==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + + core-js-compat@3.37.1: + resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} + + core-js@3.37.0: + resolution: {integrity: sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==} + + core-js@3.37.1: + resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + crypto-random-string@4.0.0: + resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} + engines: {node: '>=12'} + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + dayjs@1.11.11: + resolution: {integrity: sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.5: + resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegate@3.2.0: + resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-align@1.12.4: + resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==} + + dom-scroll-into-view@2.0.1: + resolution: {integrity: sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==} + + dom-serializer@0.2.2: + resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + domelementtype@1.3.1: + resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@2.4.2: + resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domutils@1.7.0: + resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + + dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} + engines: {node: '>=12'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + echarts@5.5.0: + resolution: {integrity: sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==} + + electron-to-chromium@1.4.796: + resolution: {integrity: sha512-NglN/xprcM+SHD2XCli4oC6bWe6kHoytcyLKCWXmRL854F0qhPhaYgUswUsglnPxYaNQIg2uMY4BvaomIf3kLA==} + + emoji-regex@10.3.0: + resolution: {integrity: sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + enhanced-resolve@5.17.0: + resolution: {integrity: sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==} + engines: {node: '>=10.13.0'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@1.1.2: + resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild@0.20.2: + resolution: {integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} + engines: {node: '>=6'} + + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.6.1: + resolution: {integrity: sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + + eslint-module-utils@2.8.1: + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-parser-plain@0.1.0: + resolution: {integrity: sha512-oOeA6FWU0UJT/Rxc3XF5Cq0nbIZbylm7j8+plqq0CZoE6m4u32OXJrR+9iy4srGMmF6v6pmgvP1zPxSRIGh3sg==} + + eslint-plugin-es-x@7.7.0: + resolution: {integrity: sha512-aP3qj8BwiEDPttxQkZdI221DLKq9sI/qHolE2YSQL1/9+xk7dTV+tB1Fz8/IaCA+lnLA1bDEnvaS2LKs0k2Uig==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-import-x@0.5.1: + resolution: {integrity: sha512-2JK8bbFOLes+gG6tgdnM8safCxMAj4u2wjX8X1BRFPfnY7Ct2hFYESoIcVwABX/DDcdpQFLGtKmzbNEWJZD9iQ==} + engines: {node: '>=16'} + peerDependencies: + eslint: ^8.56.0 || ^9.0.0-0 + + eslint-plugin-import@2.29.1: + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-n@17.7.0: + resolution: {integrity: sha512-4Jg4ZKVE4VjHig2caBqPHYNW5na84RVufUuipFLJbgM/G57O6FdpUKJbHakCDJb/yjQuyqVzYWRtU3HNYaZUwg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.23.0' + + eslint-plugin-n@17.8.1: + resolution: {integrity: sha512-KdG0h0voZms8UhndNu8DeWx1eM4sY+A4iXtsNo6kOfJLYHNeTGPacGalJ9GcvrbmOL3r/7QOMwVZDSw+1SqsrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: '>=8.23.0' + + eslint-plugin-prettier@5.1.3: + resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-promise@6.2.0: + resolution: {integrity: sha512-QmAqwizauvnKOlifxyDj2ObfULpHQawlg/zQdgEixur9vl0CvZGv/LCJV2rtj3210QCoeGBzVMfMXqGAOr/4fA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-plugin-unicorn@53.0.0: + resolution: {integrity: sha512-kuTcNo9IwwUCfyHGwQFOK/HjJAYzbODHN3wP0PgqbW+jbXqpNWxNVpVhj2tO9SixBwuAdmal8rVcWKBxwFnGuw==} + engines: {node: '>=18.18'} + peerDependencies: + eslint: '>=8.56.0' + + eslint-plugin-vue@9.26.0: + resolution: {integrity: sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-scope@8.0.1: + resolution: {integrity: sha512-pL8XjgP4ZOmmwfFE8mEhSxA7ZY4C+LWyqjQ3o4yWkkmD0qcMT9kkW3zWHOczhWcjTSgqycYAgwSlXvZltv65og==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.0.0: + resolution: {integrity: sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.4.0: + resolution: {integrity: sha512-sjc7Y8cUD1IlwYcTS9qPSvGjAC8Ne9LctpxKKu3x/1IC9bnOg98Zy6GxEJUfr1NojMgVPlyANXYns8oE2c1TAA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + + espree@10.0.1: + resolution: {integrity: sha512-MWkrWZbJsL2UwnjxTX3gG8FneachS/Mwg7tdGXce011sJd5b0JG54vat5KHnfSBODZ3Wvzd2WnjxyzsRoVv+ww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + execa@9.1.0: + resolution: {integrity: sha512-lSgHc4Elo2m6bUDhc3Hl/VxvUDJdQWI40RZ4KMY9bKRc+hgMOT7II/JjbNDhI8VnMtrCb7U/fhpJIkLORZozWw==} + engines: {node: '>=18'} + + execa@9.2.0: + resolution: {integrity: sha512-vpOyYg7UAVKLAWWtRS2gAdgkT7oJbCn0me3gmUmxZih4kd3MF/oo8kNTBTIbkO3yuuF5uB4ZCZfn8BOolITYhg==} + engines: {node: ^18.19.0 || >=20.5.0} + + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + + exponential-backoff@3.1.1: + resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-memoize@2.5.2: + resolution: {integrity: sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + focus-trap@7.5.4: + resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==} + + follow-redirects@1.15.6: + resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + + foreground-child@3.1.1: + resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} + engines: {node: '>=14'} + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + fp-and-or@0.1.4: + resolution: {integrity: sha512-+yRYRhpnFPWXSly/6V4Lw9IfOV26uu30kynGJ03PW+MnjOEQe45RZ141QcS0aJehYBYA50GfCDnsRbFJdhssRw==} + engines: {node: '>=10'} + + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + giget@1.2.3: + resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} + hasBin: true + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.1: + resolution: {integrity: sha512-2jelhlq3E4ho74ZyVLN03oKdAZVUa6UDZzFLVH1H7dnoax+y9qyaq8zBkfDIggjniU19z0wU18y16jMB2eyVIw==} + engines: {node: '>=16 || 14 >=14.18'} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.3.0: + resolution: {integrity: sha512-cCdyVjIUVTtX8ZsPkq1oCsOsLmGIswqnjZYMJJTGaNApj1yHtLSymKhwH51ttirREn75z3p4k051clwg7rvNKA==} + engines: {node: '>=18'} + + globals@15.4.0: + resolution: {integrity: sha512-unnwvMZpv0eDUyjNyh9DH/yxUaRYrEjW/qK4QcdrHg3oO11igUQrCSgODHEqxlKg8v2CD2Sd7UkqqEBoz5U7TQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + good-listener@1.2.2: + resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + + has-yarn@3.0.0: + resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + hookable@5.5.3: + resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@5.2.1: + resolution: {integrity: sha512-xIcQYMnhcx2Nr4JTjsFmwwnr9vldugPy9uVm0o87bjqqWMv9GaqsTeT+i99wTl0mk1uLxJtHxLb8kymqTENQsw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + hosted-git-info@6.1.1: + resolution: {integrity: sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + htmlparser2@3.10.1: + resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + human-signals@7.0.0: + resolution: {integrity: sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==} + engines: {node: '>=18.18.0'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + icss-replace-symbols@1.1.0: + resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + ignore-walk@6.0.5: + resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} + engines: {node: '>= 4'} + + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immutable@4.3.6: + resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + ini@4.1.3: + resolution: {integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + is-accessor-descriptor@1.0.1: + resolution: {integrity: sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==} + engines: {node: '>= 0.10'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + + is-data-descriptor@1.0.1: + resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-descriptor@0.1.7: + resolution: {integrity: sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==} + engines: {node: '>= 0.4'} + + is-descriptor@1.0.3: + resolution: {integrity: sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==} + engines: {node: '>= 0.4'} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-npm@6.0.0: + resolution: {integrity: sha512-JEjxbSmtPSt1c8XTkVrlujcXdKV1/tvuQ7GwKcAlyiVLeYFQ2VHat8xfrDJsIkhCdF/tZ7CiIR3sy141c6+gPQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-plain-object@3.0.1: + resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} + engines: {node: '>=0.10.0'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-retry-allowed@2.2.0: + resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} + engines: {node: '>=10'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-there@4.5.1: + resolution: {integrity: sha512-vIZ7HTXAoRoIwYSsTnxb0sg9L6rth+JOulNcavsbskQkCIWoSM2cjFOWZs4wGziGZER+Xgs/HXiCQZgiL8ppxQ==} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@2.0.0: + resolution: {integrity: sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==} + engines: {node: '>=18'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-yarn-global@0.4.1: + resolution: {integrity: sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==} + engines: {node: '>=12'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + jackspeak@3.4.0: + resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} + engines: {node: '>=14'} + + jiti@1.21.3: + resolution: {integrity: sha512-uy2bNX5zQ+tESe+TiC7ilGRz8AtRGmnJH55NC5S0nSUjvvvM2hJHmefHErugGXN4pNv4Qx7vLsnNw9qJ9mtIsw==} + hasBin: true + + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + + js-base64@2.6.4: + resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-tokens@9.0.0: + resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + + jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + json-parse-helpfulerror@1.0.3: + resolution: {integrity: sha512-XgP0FGR77+QhUxjXkwOMkC94k3WtqEBfcnjWqhRd82qTat4SWKRE+9kUnynz/shm3I4ea2+qISvTIeGTNU7kJg==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonlines@0.1.1: + resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + + kind-of@5.1.0: + resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lie@3.1.1: + resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + + lilconfig@3.1.1: + resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lint-staged@15.2.5: + resolution: {integrity: sha512-j+DfX7W9YUvdzEZl3Rk47FhDF6xwDBV5wwsCPw6BwWZVPYJemusQmvb9bRsW23Sqsaa+vRloAWogbK4BUuU2zA==} + engines: {node: '>=18.12.0'} + hasBin: true + + listr2@8.2.1: + resolution: {integrity: sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==} + engines: {node: '>=18.0.0'} + + loader-utils@1.4.2: + resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} + engines: {node: '>=4.0.0'} + + local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + + localforage@1.10.0: + resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-update@6.0.0: + resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} + engines: {node: '>=18'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@10.2.2: + resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} + engines: {node: 14 || >=16.14} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + magic-string@0.30.10: + resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} + + magicast@0.3.4: + resolution: {integrity: sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==} + + make-fetch-happen@10.2.1: + resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + make-fetch-happen@11.1.1: + resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + + mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + + mdast-util-from-markdown@2.0.1: + resolution: {integrity: sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + merge-options@1.0.1: + resolution: {integrity: sha512-iuPV41VWKWBIOpBsjoxjDZw8/GbSfZ2mk7N1453bwMrfzdrIk7EzBd+8UVR6rkw67th7xnk9Dytl3J+lHPdxvg==} + engines: {node: '>=4'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.1: + resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} + + micromark-factory-destination@2.0.0: + resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==} + + micromark-factory-label@2.0.0: + resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==} + + micromark-factory-space@2.0.0: + resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==} + + micromark-factory-title@2.0.0: + resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==} + + micromark-factory-whitespace@2.0.0: + resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==} + + micromark-util-character@2.1.0: + resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==} + + micromark-util-chunked@2.0.0: + resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==} + + micromark-util-classify-character@2.0.0: + resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==} + + micromark-util-combine-extensions@2.0.0: + resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==} + + micromark-util-decode-numeric-character-reference@2.0.1: + resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==} + + micromark-util-decode-string@2.0.0: + resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==} + + micromark-util-encode@2.0.0: + resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==} + + micromark-util-html-tag-name@2.0.0: + resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==} + + micromark-util-normalize-identifier@2.0.0: + resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==} + + micromark-util-resolve-all@2.0.0: + resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==} + + micromark-util-sanitize-uri@2.0.0: + resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==} + + micromark-util-subtokenize@2.0.1: + resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==} + + micromark-util-symbol@2.0.0: + resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==} + + micromark-util-types@2.0.0: + resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==} + + micromark@4.0.0: + resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==} + + micromatch@3.1.0: + resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==} + engines: {node: '>=0.10.0'} + + micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + + micromatch@4.0.7: + resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.4: + resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-fetch@2.1.2: + resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + + minipass-json-stream@1.0.1: + resolution: {integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minisearch@6.3.0: + resolution: {integrity: sha512-ihFnidEeU8iXzcVHy74dhkxh/dn8Dc08ERl0xwoMMGqp4+LvRSCgicb+zGqWthVokQKvCSxITlh3P08OzdTYCQ==} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + engines: {node: ^18 || >=20} + hasBin: true + + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + + nanopop@2.4.2: + resolution: {integrity: sha512-NzOgmMQ+elxxHeIha+OG/Pv3Oc3p4RU2aBhwWwAqDpXrdTbtRylbRLQztLy8dMMwfl6pclznBdfUhccEn9ZIzw==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-gyp@9.4.1: + resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==} + engines: {node: ^12.13 || ^14.13 || >=16} + hasBin: true + + node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + + nopt@6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@5.0.0: + resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + engines: {node: '>=14.16'} + + npm-bundled@3.0.1: + resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-check-updates@16.14.20: + resolution: {integrity: sha512-sYbIhun4DrjO7NFOTdvs11nCar0etEhZTsEjL47eM0TuiGMhmYughRCxG2SpGRmGAQ7AkwN7bw2lWzoE7q6yOQ==} + engines: {node: '>=14.14'} + hasBin: true + + npm-install-checks@6.3.0: + resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-normalize-package-bin@3.0.1: + resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@10.1.0: + resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-packlist@7.0.4: + resolution: {integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-pick-manifest@8.0.2: + resolution: {integrity: sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-registry-fetch@14.0.5: + resolution: {integrity: sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + nypm@0.3.8: + resolution: {integrity: sha512-IGWlC6So2xv6V4cIDmoV0SwwWx7zLG086gyqkyumteH2fIgCAM4nDVFB2iDRszDvmdSVW9xb1N+2KjQ6C7d4og==} + engines: {node: ^14.16.0 || >=16.10.0} + hasBin: true + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + ofetch@1.3.4: + resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + + ohash@1.1.3: + resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + pacote@15.2.0: + resolution: {integrity: sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-github-url@1.0.2: + resolution: {integrity: sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==} + engines: {node: '>=0.10.0'} + hasBin: true + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@0.2.0: + resolution: {integrity: sha512-sTitTPYnn23esFR3RlqYBWn4c45WGeLcsKzQiUpXJAyfcWkolvlYpV8FLo7JishK946oQwMFUCHXQ9AjGPKExw==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.0.1: + resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pinia@2.1.7: + resolution: {integrity: sha512-+C2AHFtcFqjPih0zpYuvof37SFxMQ7OEG2zV9jRI12i9BOy3YQVAHwdKtyyc8pDcDyIc33WCIsZaCFWU7WWxGQ==} + peerDependencies: + '@vue/composition-api': ^1.4.0 + typescript: '>=4.4.4' + vue: ^2.6.14 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + typescript: + optional: true + + pkg-types@1.1.1: + resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.0.5: + resolution: {integrity: sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.0: + resolution: {integrity: sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-prefix-selector@1.16.1: + resolution: {integrity: sha512-Umxu+FvKMwlY6TyDzGFoSUnzW+NOfMBLyC1tAkIjgX+Z/qGspJeRjVC903D7mx7TuBpJlwti2ibXtWuA7fKMeQ==} + peerDependencies: + postcss: '>4 <9' + + postcss-selector-parser@6.1.0: + resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==} + engines: {node: '>=4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@5.2.18: + resolution: {integrity: sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==} + engines: {node: '>=0.12'} + + postcss@8.4.38: + resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} + engines: {node: ^10 || ^12 || >=14} + + posthtml-parser@0.2.1: + resolution: {integrity: sha512-nPC53YMqJnc/+1x4fRYFfm81KV2V+G9NZY+hTohpYg64Ay7NemWWcV4UWuy/SgMupqQ3kJ88M/iRfZmSnxT+pw==} + + posthtml-rename-id@1.0.12: + resolution: {integrity: sha512-UKXf9OF/no8WZo9edRzvuMenb6AD5hDLzIepJW+a4oJT+T/Lx7vfMYWT4aWlGNQh0WMhnUx1ipN9OkZ9q+ddEw==} + + posthtml-render@1.4.0: + resolution: {integrity: sha512-W1779iVHGfq0Fvh2PROhCe2QhB8mEErgqzo1wpIt36tCgChafP+hbXIhLDOM8ePJrZcFs0vkNEtdibEWVqChqw==} + engines: {node: '>=10'} + + posthtml-svg-mode@1.0.3: + resolution: {integrity: sha512-hEqw9NHZ9YgJ2/0G7CECOeuLQKZi8HjWLkBaSVtOWjygQ9ZD8P7tqeowYs7WrFdKsWEKG7o+IlsPY8jrr0CJpQ==} + + posthtml@0.9.2: + resolution: {integrity: sha512-spBB5sgC4cv2YcW03f/IAUN1pgDJWNWD8FzkyY4mArLUMJW+KlQhlmUdKAHQuPfb00Jl5xIfImeOsf6YL8QK7Q==} + engines: {node: '>=0.10.0'} + + preact@10.22.0: + resolution: {integrity: sha512-RRurnSjJPj4rp5K6XoP45Ui33ncb7e4H7WiOHVpjbkvqvA3U+N8Z6Qbo0AE6leGYBV66n8EhEaFixvIu3SkxFw==} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier-plugin-jsdoc@1.3.0: + resolution: {integrity: sha512-cQm8xIa0fN9ieJFMXACQd6JPycl+8ouOijAqUqu44EF/s4fXL3Wi9sKXuEaodsEWgCN42Xby/bNhqgM1iWx4uw==} + engines: {node: '>=14.13.1 || >=16.0.0'} + peerDependencies: + prettier: ^3.0.0 + + prettier-plugin-json-sort@0.0.2: + resolution: {integrity: sha512-xd5VVfneeUBdWhTm5uh0rAto3qnkkosbte6poO5WVTZEAiQdndMQMRPv1SROXx968zfyAlS+Z+C6rkr4jbVOgg==} + peerDependencies: + prettier: '>=2.0.0' + + prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} + engines: {node: '>=14'} + hasBin: true + + prettier@3.3.0: + resolution: {integrity: sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==} + engines: {node: '>=14'} + hasBin: true + + prettier@3.3.1: + resolution: {integrity: sha512-7CAwy5dRsxs8PHXT3twixW9/OEll8MLE0VRPCJyl7CkS6VHGPSlsVaWTiASPTyGyYRyApxlaWTzwUxVNrhcwDg==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-ms@9.0.0: + resolution: {integrity: sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==} + engines: {node: '>=18'} + + proc-log@3.0.0: + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + prompts-ncu@3.0.0: + resolution: {integrity: sha512-qyz9UxZ5MlPKWVhWrCmSZ1ahm2GVYdjLb8og2sg0IPth1KRuhcggHGuijz0e41dkx35p1t1q3GRISGH7QGALFA==} + engines: {node: '>= 14'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pupa@3.1.0: + resolution: {integrity: sha512-FLpr4flz5xZTSJxSeaheeMKN/EDzMdK7b8PTOC6a5PYFKTucWbdqjgqaEyH0shFiSJrVB1+Qqi4Tk19ccU6Aug==} + engines: {node: '>=12.20'} + + qs@6.12.1: + resolution: {integrity: sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==} + engines: {node: '>=0.6'} + + query-string@4.3.4: + resolution: {integrity: sha512-O2XLNDBIg1DnTOa+2XrIwSiXEV8h2KImXUnjhhn2+UsvZ+Es2uyd5CCRTNQlDGbzUQOW3aYCBx9rVA6dzsiY7Q==} + engines: {node: '>=0.10.0'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + rc-config-loader@4.1.3: + resolution: {integrity: sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==} + + rc9@2.1.2: + resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + rd@2.0.1: + resolution: {integrity: sha512-/XdKU4UazUZTXFmI0dpABt8jSXPWcEyaGdk340KdHnsEOdkTctlX23aAK7ChQDn39YGNlAJr1M5uvaKt4QnpNw==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + read-package-json-fast@3.0.2: + resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-package-json@6.0.4: + resolution: {integrity: sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + deprecated: This package is no longer supported. Please use @npmcli/package-json instead. + + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + recast@0.23.7: + resolution: {integrity: sha512-MpQlLZVpqbbxYcqEjwpRWo88sGvjOYoXptySz710RuddNMHx+wPkoNX6YyLZJlXAh5VZr1qmPrTwcTuFMh0Lag==} + engines: {node: '>= 4'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + + regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + + regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} + engines: {node: '>= 0.4'} + + registry-auth-token@5.0.2: + resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + regjsparser@0.10.0: + resolution: {integrity: sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==} + hasBin: true + + remote-git-tags@3.0.0: + resolution: {integrity: sha512-C9hAO4eoEsX+OXA4rla66pXZQ+TLQ8T9dttgQj18yuKlPMTVkIkdYXvlMC55IuUsIkV6DpmQYi10JKFLaU+l7w==} + engines: {node: '>=8'} + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + restore-cursor@4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.7: + resolution: {integrity: sha512-nV6YcJo5wbLW77m+8KjH8aB/7/rxQy9SZ0HY5shnwULfS+9nmTtVXAJET5NdZmCzA4fPI/Hm1wo/Po/4mopOdg==} + engines: {node: '>=14.18'} + hasBin: true + + rollup@4.18.0: + resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass@1.77.4: + resolution: {integrity: sha512-vcF3Ckow6g939GMA4PeU7b2K/9FALXk2KF9J87txdHzXbUF9XRQRwSxcAs/fGaTnJeBFd7UoV22j3lzMLdM0Pw==} + engines: {node: '>=14.0.0'} + hasBin: true + + scroll-into-view-if-needed@2.2.31: + resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + search-insights@2.14.0: + resolution: {integrity: sha512-OLN6MsPMCghDOqlCtsIsYgtsC0pnwVTyT9Mu6A3ewOj1DxvzZF6COrn2g86E/c05xbktB0XN04m/t1Z+n+fTGw==} + + select@1.1.2: + resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==} + + semver-diff@4.0.0: + resolution: {integrity: sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==} + engines: {node: '>=12'} + + semver-utils@1.1.4: + resolution: {integrity: sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} + engines: {node: '>=10'} + hasBin: true + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + + shallow-equal@1.2.1: + resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shiki@1.6.3: + resolution: {integrity: sha512-lE1/YGlzFY0hQSyEfsZj18xGrTWxyhFQkaiILALqTBZPbJeYFWpbUhlmTGPOupYB/qC+H6sV4UznJzcEh3WMHQ==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sigstore@1.9.0: + resolution: {integrity: sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + simple-git-hooks@2.11.1: + resolution: {integrity: sha512-tgqwPUMDcNDhuf1Xf6KTUsyeqGdgKMhzaH4PAZZuzguOgTl5uuyeYe/8mWgAr6IBxB5V06uqEf6Dy37gIWDtDg==} + hasBin: true + + simplebar-core@1.2.5: + resolution: {integrity: sha512-33AVCYXS8yavWId0GbE4TG1cYELsYybpCKWHJYuWEY/j6nccgz6zQdJ7nCqOpIGo7HgPPbkSSSIlJhi43fHP6A==} + + simplebar-vue@2.3.4: + resolution: {integrity: sha512-ur00AfvISccO7w9HxhIrnU7hqOUoebzQ5LBla3rrgu89O0C5QhXI08KqlS4E1msfdC+vqn+VfPQ0RJotqh42Mw==} + peerDependencies: + vue: '>=2.5.17' + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + + socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + + socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spawn-please@2.0.2: + resolution: {integrity: sha512-KM8coezO6ISQ89c1BzyWNtcn2V2kAVtwIXd3cN/V5a0xPYc1F/vydrRc01wsKFEQ/p+V1a4sw4z2yMITIXrgGw==} + engines: {node: '>=14'} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.18: + resolution: {integrity: sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==} + + speakingurl@14.0.1: + resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} + engines: {node: '>=0.10.0'} + + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ssri@9.0.1: + resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + + strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string-width@7.1.0: + resolution: {integrity: sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==} + engines: {node: '>=18'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-json-comments@5.0.1: + resolution: {integrity: sha512-0fk9zBqO67Nq5M/m45qHCJxylV/DhBlIOVExqgOMiCCrzrhU6tCibRXNqE3jwJLftzE9SNuZtYbpzcO+i9FiKw==} + engines: {node: '>=14.16'} + + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + + stylis@4.3.2: + resolution: {integrity: sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==} + + supports-color@2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + + supports-color@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-baker@1.7.0: + resolution: {integrity: sha512-nibslMbkXOIkqKVrfcncwha45f97fGuAOn1G99YwnwTj8kF9YiM6XexPcUso97NxOm6GsP0SIvYVIosBis1xLg==} + + svg-tags@1.0.0: + resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} + + svgo@2.8.0: + resolution: {integrity: sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==} + engines: {node: '>=10.13.0'} + hasBin: true + + synckit@0.8.8: + resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} + engines: {node: ^14.18.0 || >=16.0.0} + + synckit@0.9.0: + resolution: {integrity: sha512-7RnqIMq572L8PeEzKeBINYEJDDxpcH8JEgLwUqBd3TkofhFRbkq4QLR0u+36avGAhCRbk2nnmjcW9SE531hPDg==} + engines: {node: ^14.18.0 || >=16.0.0} + + tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + throttle-debounce@5.0.0: + resolution: {integrity: sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==} + engines: {node: '>=12.22'} + + tiny-emitter@2.1.0: + resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tinybench@2.8.0: + resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} + + tinypool@0.8.4: + resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} + engines: {node: '>=14.0.0'} + + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + traverse@0.6.9: + resolution: {integrity: sha512-7bBrcF+/LQzSgFmT0X5YclVqQxtv7TDJ1f8Wj7ibBu/U6BMLeOpUxuZjV7rMc44UtKxlnMFigdhFAIszSX1DMg==} + engines: {node: '>= 0.4'} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + + tsx@4.14.1: + resolution: {integrity: sha512-GU8pPJq8DdxcJDSK6Bc64c2jW8zBK2hb0jzwHZDfjapbwu6AqvFnAElnzZ17Xb9TH5a/j6/sicTCVYF+eO/cmA==} + engines: {node: '>=18.0.0'} + hasBin: true + + tuf-js@1.1.7: + resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@1.4.0: + resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typed-css-modules@0.9.1: + resolution: {integrity: sha512-W2HWKncdKd+bLWsnuWB2EyuQBzZ7KJ9Byr/67KLiiyGegcN52rOveun9JR8yAvuL5IXunRMxt0eORMtAUj5bmA==} + engines: {node: '>=18.0.0'} + hasBin: true + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typedarray.prototype.slice@1.0.3: + resolution: {integrity: sha512-8WbVAQAUlENo1q3c3zZYuy5k9VzBQvp8AX9WOtbvyWlLM1v5JaSRmjubLjzHF4JFtptjH/5c/i95yaElvcjC0A==} + engines: {node: '>= 0.4'} + + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + unconfig@0.3.13: + resolution: {integrity: sha512-N9Ph5NC4+sqtcOjPfHrRcHekBCadCXWTBzp2VYYbySOHW0PfD9XLCeXshTXjkPYwLrBr9AtSeU0CZmkYECJhng==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unimport@3.7.2: + resolution: {integrity: sha512-91mxcZTadgXyj3lFWmrGT8GyoRHWuE5fqPOjg5RVtF6vj+OfM5G6WCzXjuYtSgELE5ggB34RY4oiCSEP8I3AHw==} + + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + + unique-filename@2.0.1: + resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@3.0.0: + resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-string@3.0.0: + resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} + engines: {node: '>=12'} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unplugin-auto-import@0.17.6: + resolution: {integrity: sha512-dmX0Pex5DzMzVuALkexboOZvh51fL/BD6aoPO7qHoTYGlQp0GRKsREv2KMF1lzYI9SXKQiRxAjwzbQnrFFNydQ==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': ^3.2.2 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-icons@0.19.0: + resolution: {integrity: sha512-u5g/gIZPZEj1wUGEQxe9nzftOSqmblhusc+sL3cawIRoIt/xWpE6XYcPOfAeFTYNjSbRrX/3QiX89PFiazgU1w==} + peerDependencies: + '@svgr/core': '>=7.0.0' + '@svgx/core': ^1.0.1 + '@vue/compiler-sfc': ^3.0.2 || ^2.7.0 + vue-template-compiler: ^2.6.12 + vue-template-es2015-compiler: ^1.9.0 + peerDependenciesMeta: + '@svgr/core': + optional: true + '@svgx/core': + optional: true + '@vue/compiler-sfc': + optional: true + vue-template-compiler: + optional: true + vue-template-es2015-compiler: + optional: true + + unplugin-vue-components@0.27.0: + resolution: {integrity: sha512-77eTEy23sQ0UpzGWnZ9I2mY3cnmXwklz4ITcn3JfxjCoX643ghImkiZ4nFm58sxbdVcc4Fo/o4LIoFnlqEqsSg==} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + + unplugin@1.10.1: + resolution: {integrity: sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==} + engines: {node: '>=14.0.0'} + + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + update-browserslist-db@1.0.16: + resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@6.0.2: + resolution: {integrity: sha512-EDxhTEVPZZRLWYcJ4ZXjGFN0oP7qYvbXWzEgRm/Yql4dHX5wDbvh89YHP6PK1lzZJYrMtXUuZZz8XGK+U6U1og==} + engines: {node: '>=14.16'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vite-node@1.6.0: + resolution: {integrity: sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite-plugin-progress@0.0.7: + resolution: {integrity: sha512-zyvKdcc/X+6hnw3J1HVV1TKrlFKC4Rh8GnDnWG/2qhRXjqytTcM++xZ+SAPnoDsSyWl8O93ymK0wZRgHAoglEQ==} + engines: {node: '>=14', pnpm: '>=7.0.0'} + peerDependencies: + vite: '>2.0.0-0' + + vite-plugin-svg-icons@2.0.1: + resolution: {integrity: sha512-6ktD+DhV6Rz3VtedYvBKKVA2eXF+sAQVaKkKLDSqGUfnhqXl3bj5PPkVTl3VexfTuZy66PmINi8Q6eFnVfRUmA==} + peerDependencies: + vite: '>=2.0.0' + + vite@5.2.13: + resolution: {integrity: sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitepress@1.2.3: + resolution: {integrity: sha512-GvEsrEeNLiDE1+fuwDAYJCYLNZDAna+EtnXlPajhv/MYeTjbNK6Bvyg6NoTdO1sbwuQJ0vuJR99bOlH53bo6lg==} + hasBin: true + peerDependencies: + markdown-it-mathjax3: ^4 + postcss: ^8 + peerDependenciesMeta: + markdown-it-mathjax3: + optional: true + postcss: + optional: true + + vitest@1.6.0: + resolution: {integrity: sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 1.6.0 + '@vitest/ui': 1.6.0 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + vue-demi@0.13.11: + resolution: {integrity: sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-demi@0.14.8: + resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-draggable-plus@0.5.0: + resolution: {integrity: sha512-A5TT5+M5JceROSjPO9aDZTsrSN1TetEs419czPlboomarSiGIBIxTp2WD7XH53EHMrbO7Qo+leRiHWV/rMlyjA==} + peerDependencies: + '@types/sortablejs': ^1.15.0 + '@vue/composition-api': '*' + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + vue-i18n@9.13.1: + resolution: {integrity: sha512-mh0GIxx0wPtPlcB1q4k277y0iKgo25xmDPWioVVYanjPufDBpvu5ySTjP5wOrSvlYQ2m1xI+CFhGdauv/61uQg==} + engines: {node: '>= 16'} + peerDependencies: + vue: ^3.0.0 + + vue-router@4.3.2: + resolution: {integrity: sha512-hKQJ1vDAZ5LVkKEnHhmm1f9pMiWIBNGF5AwU67PdH7TyXCj/a4hTccuUuYCAMgJK6rO/NVYtQIEN3yL8CECa7Q==} + peerDependencies: + vue: ^3.2.0 + + vue-template-compiler@2.7.16: + resolution: {integrity: sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==} + + vue-tsc@2.0.21: + resolution: {integrity: sha512-E6x1p1HaHES6Doy8pqtm7kQern79zRtIewkf9fiv7Y43Zo4AFDS5hKi+iHi2RwEhqRmuiwliB1LCEFEGwvxQnw==} + hasBin: true + peerDependencies: + typescript: '*' + + vue-types@3.0.2: + resolution: {integrity: sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==} + engines: {node: '>=10.15.0'} + peerDependencies: + vue: ^3.0.0 + + vue@3.4.27: + resolution: {integrity: sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + warning@4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.6.2: + resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@3.0.1: + resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + widest-line@4.0.1: + resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==} + engines: {node: '>=12'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + xdg-basedir@5.1.0: + resolution: {integrity: sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==} + engines: {node: '>=12'} + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@2.4.5: + resolution: {integrity: sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + + yoctocolors@2.0.2: + resolution: {integrity: sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==} + engines: {node: '>=18'} + + zrender@5.5.0: + resolution: {integrity: sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==} + +snapshots: + + '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.14.0)': + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.14.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + + '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.14.0)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + search-insights: 2.14.0 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + + '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + '@algolia/client-search': 4.23.3 + algoliasearch: 4.23.3 + + '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)': + dependencies: + '@algolia/client-search': 4.23.3 + algoliasearch: 4.23.3 + + '@algolia/cache-browser-local-storage@4.23.3': + dependencies: + '@algolia/cache-common': 4.23.3 + + '@algolia/cache-common@4.23.3': {} + + '@algolia/cache-in-memory@4.23.3': + dependencies: + '@algolia/cache-common': 4.23.3 + + '@algolia/client-account@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-analytics@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-common@4.23.3': + dependencies: + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-personalization@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/client-search@4.23.3': + dependencies: + '@algolia/client-common': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/logger-common@4.23.3': {} + + '@algolia/logger-console@4.23.3': + dependencies: + '@algolia/logger-common': 4.23.3 + + '@algolia/recommend@4.23.3': + dependencies: + '@algolia/cache-browser-local-storage': 4.23.3 + '@algolia/cache-common': 4.23.3 + '@algolia/cache-in-memory': 4.23.3 + '@algolia/client-common': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/logger-console': 4.23.3 + '@algolia/requester-browser-xhr': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/requester-node-http': 4.23.3 + '@algolia/transporter': 4.23.3 + + '@algolia/requester-browser-xhr@4.23.3': + dependencies: + '@algolia/requester-common': 4.23.3 + + '@algolia/requester-common@4.23.3': {} + + '@algolia/requester-node-http@4.23.3': + dependencies: + '@algolia/requester-common': 4.23.3 + + '@algolia/transporter@4.23.3': + dependencies: + '@algolia/cache-common': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/requester-common': 4.23.3 + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@ant-design/colors@6.0.0': + dependencies: + '@ctrl/tinycolor': 3.6.1 + + '@ant-design/icons-svg@4.4.2': {} + + '@ant-design/icons-vue@7.0.1(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@ant-design/colors': 6.0.0 + '@ant-design/icons-svg': 4.4.2 + vue: 3.4.27(typescript@5.4.5) + + '@antfu/eslint-define-config@1.23.0-2': {} + + '@antfu/install-pkg@0.1.1': + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + + '@antfu/install-pkg@0.3.3': + dependencies: + '@jsdevtools/ez-spawn': 3.0.4 + + '@antfu/utils@0.7.8': {} + + '@babel/code-frame@7.24.7': + dependencies: + '@babel/highlight': 7.24.7 + picocolors: 1.0.1 + + '@babel/compat-data@7.24.7': {} + + '@babel/core@7.24.7': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-compilation-targets': 7.24.7 + '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) + '@babel/helpers': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + convert-source-map: 2.0.0 + debug: 4.3.5 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.24.7': + dependencies: + '@babel/types': 7.24.7 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/helper-annotate-as-pure@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-compilation-targets@7.24.7': + dependencies: + '@babel/compat-data': 7.24.7 + '@babel/helper-validator-option': 7.24.7 + browserslist: 4.23.1 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) + '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-function-name@7.24.7': + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/helper-hoist-variables@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-member-expression-to-functions@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.22.15': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-module-imports@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-module-imports': 7.24.7 + '@babel/helper-simple-access': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-plugin-utils@7.24.7': {} + + '@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-member-expression-to-functions': 7.24.7 + '@babel/helper-optimise-call-expression': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.24.7': + dependencies: + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/helper-string-parser@7.24.7': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/helper-validator-option@7.24.7': {} + + '@babel/helpers@7.24.7': + dependencies: + '@babel/template': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/highlight@7.24.7': + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.1 + + '@babel/parser@7.24.7': + dependencies: + '@babel/types': 7.24.7 + + '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-plugin-utils': 7.24.7 + + '@babel/plugin-transform-typescript@7.24.7(@babel/core@7.24.7)': + dependencies: + '@babel/core': 7.24.7 + '@babel/helper-annotate-as-pure': 7.24.7 + '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.24.7) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.24.7': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + + '@babel/traverse@7.24.7': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/generator': 7.24.7 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + debug: 4.3.5 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.24.7': + dependencies: + '@babel/helper-string-parser': 7.24.7 + '@babel/helper-validator-identifier': 7.24.7 + to-fast-properties: 2.0.0 + + '@better-scroll/core@2.5.1': + dependencies: + '@better-scroll/shared-utils': 2.5.1 + + '@better-scroll/shared-utils@2.5.1': {} + + '@colors/colors@1.5.0': + optional: true + + '@ctrl/tinycolor@3.6.1': {} + + '@docsearch/css@3.6.0': {} + + '@docsearch/js@3.6.0(@algolia/client-search@4.23.3)(search-insights@2.14.0)': + dependencies: + '@docsearch/react': 3.6.0(@algolia/client-search@4.23.3)(search-insights@2.14.0) + preact: 10.22.0 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + + '@docsearch/react@3.6.0(@algolia/client-search@4.23.3)(search-insights@2.14.0)': + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3)(search-insights@2.14.0) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.23.3)(algoliasearch@4.23.3) + '@docsearch/css': 3.6.0 + algoliasearch: 4.23.3 + optionalDependencies: + search-insights: 2.14.0 + transitivePeerDependencies: + - '@algolia/client-search' + + '@elegant-router/core@0.3.7': + dependencies: + chokidar: 3.6.0 + consola: 3.2.3 + fast-glob: 3.3.2 + kolorist: 1.8.0 + micromatch: 4.0.5 + + '@elegant-router/vue@0.3.7': + dependencies: + '@elegant-router/core': 0.3.7 + consola: 3.2.3 + kolorist: 1.8.0 + magic-string: 0.30.10 + magicast: 0.3.4 + prettier: 3.2.5 + recast: 0.23.7 + unplugin: 1.10.1 + + '@emotion/hash@0.9.1': {} + + '@emotion/unitless@0.8.1': {} + + '@esbuild/aix-ppc64@0.20.2': + optional: true + + '@esbuild/android-arm64@0.20.2': + optional: true + + '@esbuild/android-arm@0.20.2': + optional: true + + '@esbuild/android-x64@0.20.2': + optional: true + + '@esbuild/darwin-arm64@0.20.2': + optional: true + + '@esbuild/darwin-x64@0.20.2': + optional: true + + '@esbuild/freebsd-arm64@0.20.2': + optional: true + + '@esbuild/freebsd-x64@0.20.2': + optional: true + + '@esbuild/linux-arm64@0.20.2': + optional: true + + '@esbuild/linux-arm@0.20.2': + optional: true + + '@esbuild/linux-ia32@0.20.2': + optional: true + + '@esbuild/linux-loong64@0.20.2': + optional: true + + '@esbuild/linux-mips64el@0.20.2': + optional: true + + '@esbuild/linux-ppc64@0.20.2': + optional: true + + '@esbuild/linux-riscv64@0.20.2': + optional: true + + '@esbuild/linux-s390x@0.20.2': + optional: true + + '@esbuild/linux-x64@0.20.2': + optional: true + + '@esbuild/netbsd-x64@0.20.2': + optional: true + + '@esbuild/openbsd-x64@0.20.2': + optional: true + + '@esbuild/sunos-x64@0.20.2': + optional: true + + '@esbuild/win32-arm64@0.20.2': + optional: true + + '@esbuild/win32-ia32@0.20.2': + optional: true + + '@esbuild/win32-x64@0.20.2': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@9.4.0)': + dependencies: + eslint: 9.4.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.10.1': {} + + '@eslint/config-array@0.15.1': + dependencies: + '@eslint/object-schema': 2.1.3 + debug: 4.3.5 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.5 + espree: 10.0.1 + globals: 14.0.0 + ignore: 5.3.1 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.4.0': {} + + '@eslint/object-schema@2.1.3': {} + + '@gar/promisify@1.1.3': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.0': {} + + '@iconify/json@2.2.217': + dependencies: + '@iconify/types': 2.0.0 + pathe: 1.1.2 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.1.24': + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.8 + '@iconify/types': 2.0.0 + debug: 4.3.5 + kolorist: 1.8.0 + local-pkg: 0.5.0 + mlly: 1.7.1 + transitivePeerDependencies: + - supports-color + + '@iconify/vue@4.1.2(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@iconify/types': 2.0.0 + vue: 3.4.27(typescript@5.4.5) + + '@intlify/core-base@9.13.1': + dependencies: + '@intlify/message-compiler': 9.13.1 + '@intlify/shared': 9.13.1 + + '@intlify/message-compiler@9.13.1': + dependencies: + '@intlify/shared': 9.13.1 + source-map-js: 1.2.0 + + '@intlify/shared@9.13.1': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.4.15': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + + '@jsdevtools/ez-spawn@3.0.4': + dependencies: + call-me-maybe: 1.0.2 + cross-spawn: 7.0.3 + string-argv: 0.3.2 + type-detect: 4.0.8 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@npmcli/fs@2.1.2': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.6.2 + + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.6.2 + + '@npmcli/git@4.1.0': + dependencies: + '@npmcli/promise-spawn': 6.0.2 + lru-cache: 7.18.3 + npm-pick-manifest: 8.0.2 + proc-log: 3.0.0 + promise-inflight: 1.0.1 + promise-retry: 2.0.1 + semver: 7.6.2 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + + '@npmcli/installed-package-contents@2.1.0': + dependencies: + npm-bundled: 3.0.1 + npm-normalize-package-bin: 3.0.1 + + '@npmcli/move-file@2.0.1': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@npmcli/node-gyp@3.0.0': {} + + '@npmcli/promise-spawn@6.0.2': + dependencies: + which: 3.0.1 + + '@npmcli/run-script@6.0.2': + dependencies: + '@npmcli/node-gyp': 3.0.0 + '@npmcli/promise-spawn': 6.0.2 + node-gyp: 9.4.1 + read-package-json-fast: 3.0.2 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@2.2.2': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@polka/url@1.0.0-next.25': {} + + '@rollup/pluginutils@5.1.0(rollup@4.18.0)': + dependencies: + '@types/estree': 1.0.5 + estree-walker: 2.0.2 + picomatch: 2.3.1 + optionalDependencies: + rollup: 4.18.0 + + '@rollup/rollup-android-arm-eabi@4.18.0': + optional: true + + '@rollup/rollup-android-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.18.0': + optional: true + + '@rollup/rollup-darwin-x64@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.18.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.18.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.18.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.18.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.18.0': + optional: true + + '@sec-ant/readable-stream@0.4.1': {} + + '@shikijs/core@1.6.3': {} + + '@shikijs/transformers@1.6.3': + dependencies: + shiki: 1.6.3 + + '@sigstore/bundle@1.1.0': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + + '@sigstore/protobuf-specs@0.2.1': {} + + '@sigstore/sign@1.0.0': + dependencies: + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@1.0.3': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + tuf-js: 1.1.7 + transitivePeerDependencies: + - supports-color + + '@simonwep/pickr@1.8.2': + dependencies: + core-js: 3.37.1 + nanopop: 2.4.2 + + '@simonwep/pickr@1.9.1': + dependencies: + core-js: 3.37.0 + nanopop: 2.4.2 + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@5.6.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@soybeanjs/changelog@0.3.24(@types/eslint@8.56.10)(@unocss/eslint-config@0.60.4(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-vue@9.26.0(eslint@9.4.0))(eslint@9.4.0)(typescript@5.4.5)(vue-eslint-parser@9.4.3(eslint@9.4.0))': + dependencies: + '@soybeanjs/eslint-config': 1.3.6(@types/eslint@8.56.10)(@unocss/eslint-config@0.60.4(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-vue@9.26.0(eslint@9.4.0))(eslint@9.4.0)(typescript@5.4.5)(vue-eslint-parser@9.4.3(eslint@9.4.0)) + cli-progress: 3.12.0 + convert-gitmoji: 0.1.5 + dayjs: 1.11.11 + execa: 9.1.0 + ofetch: 1.3.4 + semver: 7.6.2 + transitivePeerDependencies: + - '@toml-tools/parser' + - '@types/eslint' + - '@unocss/eslint-config' + - eslint + - eslint-plugin-astro + - eslint-plugin-react + - eslint-plugin-react-hooks + - eslint-plugin-react-native + - eslint-plugin-react-refresh + - eslint-plugin-solid + - eslint-plugin-svelte + - eslint-plugin-vue + - prettier-plugin-astro + - prettier-plugin-svelte + - prettier-plugin-toml + - supports-color + - typescript + - vue-eslint-parser + + '@soybeanjs/eslint-config@1.3.6(@types/eslint@8.56.10)(@unocss/eslint-config@0.60.4(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-vue@9.26.0(eslint@9.4.0))(eslint@9.4.0)(typescript@5.4.5)(vue-eslint-parser@9.4.3(eslint@9.4.0))': + dependencies: + '@antfu/eslint-define-config': 1.23.0-2 + '@antfu/install-pkg': 0.3.3 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.4.0 + '@typescript-eslint/eslint-plugin': 7.12.0(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint@9.4.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + eslint: 9.4.0 + eslint-config-prettier: 9.1.0(eslint@9.4.0) + eslint-parser-plain: 0.1.0 + eslint-plugin-import-x: 0.5.1(eslint@9.4.0)(typescript@5.4.5) + eslint-plugin-n: 17.7.0(eslint@9.4.0) + eslint-plugin-prettier: 5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.0) + eslint-plugin-unicorn: 53.0.0(eslint@9.4.0) + globals: 15.3.0 + local-pkg: 0.5.0 + prettier: 3.3.0 + prettier-plugin-jsdoc: 1.3.0(prettier@3.3.0) + prettier-plugin-json-sort: 0.0.2(prettier@3.3.0) + prompts: 2.4.2 + typescript: 5.4.5 + optionalDependencies: + '@unocss/eslint-config': 0.60.4(eslint@9.4.0)(typescript@5.4.5) + eslint-plugin-vue: 9.26.0(eslint@9.4.0) + vue-eslint-parser: 9.4.3(eslint@9.4.0) + transitivePeerDependencies: + - '@types/eslint' + - supports-color + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@tootallnate/once@2.0.0': {} + + '@trysound/sax@0.2.0': {} + + '@tufjs/canonical-json@1.0.0': {} + + '@tufjs/models@1.0.4': + dependencies: + '@tufjs/canonical-json': 1.0.0 + minimatch: 9.0.4 + + '@types/crypto-js@4.2.2': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.34 + + '@types/eslint@8.56.10': + dependencies: + '@types/estree': 1.0.5 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.5': {} + + '@types/http-cache-semantics@4.0.4': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/linkify-it@5.0.0': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.5 + + '@types/lodash@4.17.5': {} + + '@types/markdown-it@14.1.1': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.2 + + '@types/mdurl@2.0.0': {} + + '@types/ms@0.7.34': {} + + '@types/node@10.17.60': {} + + '@types/node@20.14.2': + dependencies: + undici-types: 5.26.5 + + '@types/normalize-package-data@2.4.4': {} + + '@types/nprogress@0.2.3': {} + + '@types/qs@6.9.15': {} + + '@types/semver-utils@1.1.3': {} + + '@types/sortablejs@1.15.8': {} + + '@types/svgo@2.6.4': + dependencies: + '@types/node': 20.14.2 + + '@types/unist@3.0.2': {} + + '@types/web-bluetooth@0.0.20': {} + + '@typescript-eslint/eslint-plugin@7.12.0(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint@9.4.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/regexpp': 4.10.1 + '@typescript-eslint/parser': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.12.0 + '@typescript-eslint/type-utils': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.12.0 + eslint: 9.4.0 + graphemer: 1.4.0 + ignore: 5.3.1 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/scope-manager': 7.12.0 + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.12.0 + debug: 4.3.5 + eslint: 9.4.0 + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.12.0': + dependencies: + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/visitor-keys': 7.12.0 + + '@typescript-eslint/type-utils@7.12.0(eslint@9.4.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + debug: 4.3.5 + eslint: 9.4.0 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.12.0': {} + + '@typescript-eslint/typescript-estree@7.12.0(typescript@5.4.5)': + dependencies: + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/visitor-keys': 7.12.0 + debug: 4.3.5 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.12.0(eslint@9.4.0)(typescript@5.4.5)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.4.0) + '@typescript-eslint/scope-manager': 7.12.0 + '@typescript-eslint/types': 7.12.0 + '@typescript-eslint/typescript-estree': 7.12.0(typescript@5.4.5) + eslint: 9.4.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.12.0': + dependencies: + '@typescript-eslint/types': 7.12.0 + eslint-visitor-keys: 3.4.3 + + '@unocss/config@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + unconfig: 0.3.13 + + '@unocss/core@0.60.4': {} + + '@unocss/eslint-config@0.60.4(eslint@9.4.0)(typescript@5.4.5)': + dependencies: + '@unocss/eslint-plugin': 0.60.4(eslint@9.4.0)(typescript@5.4.5) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@unocss/eslint-plugin@0.60.4(eslint@9.4.0)(typescript@5.4.5)': + dependencies: + '@typescript-eslint/utils': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + '@unocss/config': 0.60.4 + '@unocss/core': 0.60.4 + magic-string: 0.30.10 + synckit: 0.9.0 + transitivePeerDependencies: + - eslint + - supports-color + - typescript + + '@unocss/extractor-arbitrary-variants@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + + '@unocss/inspector@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + '@unocss/rule-utils': 0.60.4 + gzip-size: 6.0.0 + sirv: 2.0.4 + + '@unocss/preset-attributify@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + + '@unocss/preset-icons@0.60.4': + dependencies: + '@iconify/utils': 2.1.24 + '@unocss/core': 0.60.4 + ofetch: 1.3.4 + transitivePeerDependencies: + - supports-color + + '@unocss/preset-mini@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + '@unocss/extractor-arbitrary-variants': 0.60.4 + '@unocss/rule-utils': 0.60.4 + + '@unocss/preset-tagify@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + + '@unocss/preset-uno@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + '@unocss/preset-mini': 0.60.4 + '@unocss/preset-wind': 0.60.4 + '@unocss/rule-utils': 0.60.4 + + '@unocss/preset-wind@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + '@unocss/preset-mini': 0.60.4 + '@unocss/rule-utils': 0.60.4 + + '@unocss/rule-utils@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + magic-string: 0.30.10 + + '@unocss/scope@0.60.4': {} + + '@unocss/transformer-directives@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + '@unocss/rule-utils': 0.60.4 + css-tree: 2.3.1 + + '@unocss/transformer-variant-group@0.60.4': + dependencies: + '@unocss/core': 0.60.4 + + '@unocss/vite@0.60.4(rollup@4.18.0)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + '@unocss/config': 0.60.4 + '@unocss/core': 0.60.4 + '@unocss/inspector': 0.60.4 + '@unocss/scope': 0.60.4 + '@unocss/transformer-directives': 0.60.4 + chokidar: 3.6.0 + fast-glob: 3.3.2 + magic-string: 0.30.10 + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + transitivePeerDependencies: + - rollup + + '@vitejs/plugin-vue-jsx@4.0.0(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4))(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@babel/core': 7.24.7 + '@babel/plugin-transform-typescript': 7.24.7(@babel/core@7.24.7) + '@vue/babel-plugin-jsx': 1.2.2(@babel/core@7.24.7) + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + vue: 3.4.27(typescript@5.4.5) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4))(vue@3.4.27(typescript@5.4.5))': + dependencies: + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + vue: 3.4.27(typescript@5.4.5) + + '@vitest/expect@1.6.0': + dependencies: + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + chai: 4.4.1 + + '@vitest/runner@1.6.0': + dependencies: + '@vitest/utils': 1.6.0 + p-limit: 5.0.0 + pathe: 1.1.2 + + '@vitest/snapshot@1.6.0': + dependencies: + magic-string: 0.30.10 + pathe: 1.1.2 + pretty-format: 29.7.0 + + '@vitest/spy@1.6.0': + dependencies: + tinyspy: 2.2.1 + + '@vitest/utils@1.6.0': + dependencies: + diff-sequences: 29.6.3 + estree-walker: 3.0.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + '@volar/language-core@2.3.0': + dependencies: + '@volar/source-map': 2.3.0 + + '@volar/source-map@2.3.0': + dependencies: + muggle-string: 0.4.1 + + '@volar/typescript@2.3.0': + dependencies: + '@volar/language-core': 2.3.0 + path-browserify: 1.0.1 + vscode-uri: 3.0.8 + + '@vue/babel-helper-vue-transform-on@1.2.2': {} + + '@vue/babel-plugin-jsx@1.2.2(@babel/core@7.24.7)': + dependencies: + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.24.7) + '@babel/template': 7.24.7 + '@babel/traverse': 7.24.7 + '@babel/types': 7.24.7 + '@vue/babel-helper-vue-transform-on': 1.2.2 + '@vue/babel-plugin-resolve-type': 1.2.2(@babel/core@7.24.7) + camelcase: 6.3.0 + html-tags: 3.3.1 + svg-tags: 1.0.0 + optionalDependencies: + '@babel/core': 7.24.7 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.2.2(@babel/core@7.24.7)': + dependencies: + '@babel/code-frame': 7.24.7 + '@babel/core': 7.24.7 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.24.7 + '@babel/parser': 7.24.7 + '@vue/compiler-sfc': 3.4.27 + + '@vue/compiler-core@3.4.27': + dependencies: + '@babel/parser': 7.24.7 + '@vue/shared': 3.4.27 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.0 + + '@vue/compiler-dom@3.4.27': + dependencies: + '@vue/compiler-core': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/compiler-sfc@3.4.27': + dependencies: + '@babel/parser': 7.24.7 + '@vue/compiler-core': 3.4.27 + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + estree-walker: 2.0.2 + magic-string: 0.30.10 + postcss: 8.4.38 + source-map-js: 1.2.0 + + '@vue/compiler-ssr@3.4.27': + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/devtools-api@6.6.3': {} + + '@vue/devtools-api@7.2.1(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@vue/devtools-kit': 7.2.1(vue@3.4.27(typescript@5.4.5)) + transitivePeerDependencies: + - vue + + '@vue/devtools-kit@7.2.1(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@vue/devtools-shared': 7.2.1 + hookable: 5.5.3 + mitt: 3.0.1 + perfect-debounce: 1.0.0 + speakingurl: 14.0.1 + vue: 3.4.27(typescript@5.4.5) + + '@vue/devtools-shared@7.2.1': + dependencies: + rfdc: 1.3.1 + + '@vue/language-core@2.0.21(typescript@5.4.5)': + dependencies: + '@volar/language-core': 2.3.0 + '@vue/compiler-dom': 3.4.27 + '@vue/shared': 3.4.27 + computeds: 0.0.1 + minimatch: 9.0.4 + path-browserify: 1.0.1 + vue-template-compiler: 2.7.16 + optionalDependencies: + typescript: 5.4.5 + + '@vue/reactivity@3.4.27': + dependencies: + '@vue/shared': 3.4.27 + + '@vue/runtime-core@3.4.27': + dependencies: + '@vue/reactivity': 3.4.27 + '@vue/shared': 3.4.27 + + '@vue/runtime-dom@3.4.27': + dependencies: + '@vue/runtime-core': 3.4.27 + '@vue/shared': 3.4.27 + csstype: 3.1.3 + + '@vue/server-renderer@3.4.27(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@vue/compiler-ssr': 3.4.27 + '@vue/shared': 3.4.27 + vue: 3.4.27(typescript@5.4.5) + + '@vue/shared@3.4.27': {} + + '@vueuse/core@10.10.0(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.10.0 + '@vueuse/shared': 10.10.0(vue@3.4.27(typescript@5.4.5)) + vue-demi: 0.14.8(vue@3.4.27(typescript@5.4.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/integrations@10.10.0(async-validator@4.2.5)(axios@1.7.2)(focus-trap@7.5.4)(nprogress@0.2.0)(vue@3.4.27(typescript@5.4.5))': + dependencies: + '@vueuse/core': 10.10.0(vue@3.4.27(typescript@5.4.5)) + '@vueuse/shared': 10.10.0(vue@3.4.27(typescript@5.4.5)) + vue-demi: 0.14.8(vue@3.4.27(typescript@5.4.5)) + optionalDependencies: + async-validator: 4.2.5 + axios: 1.7.2 + focus-trap: 7.5.4 + nprogress: 0.2.0 + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@10.10.0': {} + + '@vueuse/shared@10.10.0(vue@3.4.27(typescript@5.4.5))': + dependencies: + vue-demi: 0.14.8(vue@3.4.27(typescript@5.4.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + abbrev@1.1.1: {} + + acorn-jsx@5.3.2(acorn@8.11.3): + dependencies: + acorn: 8.11.3 + + acorn-walk@8.3.2: {} + + acorn@8.11.3: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + agentkeepalive@4.5.0: + dependencies: + humanize-ms: 1.2.1 + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + algoliasearch@4.23.3: + dependencies: + '@algolia/cache-browser-local-storage': 4.23.3 + '@algolia/cache-common': 4.23.3 + '@algolia/cache-in-memory': 4.23.3 + '@algolia/client-account': 4.23.3 + '@algolia/client-analytics': 4.23.3 + '@algolia/client-common': 4.23.3 + '@algolia/client-personalization': 4.23.3 + '@algolia/client-search': 4.23.3 + '@algolia/logger-common': 4.23.3 + '@algolia/logger-console': 4.23.3 + '@algolia/recommend': 4.23.3 + '@algolia/requester-browser-xhr': 4.23.3 + '@algolia/requester-common': 4.23.3 + '@algolia/requester-node-http': 4.23.3 + '@algolia/transporter': 4.23.3 + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@4.1.3: {} + + ansi-escapes@6.2.1: {} + + ansi-regex@2.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.0.1: {} + + ansi-styles@2.2.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + ant-design-vue@4.2.2(vue@3.4.27(typescript@5.4.5)): + dependencies: + '@ant-design/colors': 6.0.0 + '@ant-design/icons-vue': 7.0.1(vue@3.4.27(typescript@5.4.5)) + '@babel/runtime': 7.24.7 + '@ctrl/tinycolor': 3.6.1 + '@emotion/hash': 0.9.1 + '@emotion/unitless': 0.8.1 + '@simonwep/pickr': 1.8.2 + array-tree-filter: 2.1.0 + async-validator: 4.2.5 + csstype: 3.1.3 + dayjs: 1.11.11 + dom-align: 1.12.4 + dom-scroll-into-view: 2.0.1 + lodash: 4.17.21 + lodash-es: 4.17.21 + resize-observer-polyfill: 1.5.1 + scroll-into-view-if-needed: 2.2.31 + shallow-equal: 1.2.1 + stylis: 4.3.2 + throttle-debounce: 5.0.0 + vue: 3.4.27(typescript@5.4.5) + vue-types: 3.0.2(vue@3.4.27(typescript@5.4.5)) + warning: 4.0.3 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + aproba@2.0.0: {} + + are-we-there-yet@3.0.1: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + argparse@2.0.1: {} + + arr-diff@4.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-tree-filter@2.1.0: {} + + array-union@2.1.0: {} + + array-unique@0.3.2: {} + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + assertion-error@1.1.0: {} + + assign-symbols@1.0.0: {} + + ast-types@0.16.1: + dependencies: + tslib: 2.6.3 + + async-validator@4.2.5: {} + + asynckit@0.4.0: {} + + atob@2.1.2: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axios-retry@4.4.0(axios@1.7.2): + dependencies: + axios: 1.7.2 + is-retry-allowed: 2.2.0 + + axios@1.7.2: + dependencies: + follow-redirects: 1.15.6 + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.1 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + + big.js@5.2.2: {} + + binary-extensions@2.3.0: {} + + binary-searching@2.0.5: {} + + bluebird@3.7.2: {} + + boolbase@1.0.0: {} + + boxen@7.1.1: + dependencies: + ansi-align: 3.0.1 + camelcase: 7.0.1 + chalk: 5.3.0 + cli-boxes: 3.0.0 + string-width: 5.1.2 + type-fest: 2.19.0 + widest-line: 4.0.1 + wrap-ansi: 8.1.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@2.3.2: + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.23.1: + dependencies: + caniuse-lite: 1.0.30001629 + electron-to-chromium: 1.4.796 + node-releases: 2.0.14 + update-browserslist-db: 1.0.16(browserslist@4.23.1) + + buffer-from@1.1.2: {} + + builtin-modules@3.3.0: {} + + bumpp@9.4.1: + dependencies: + '@jsdevtools/ez-spawn': 3.0.4 + c12: 1.10.0 + cac: 6.7.14 + escalade: 3.1.2 + fast-glob: 3.3.2 + js-yaml: 4.1.0 + prompts: 2.4.2 + semver: 7.6.2 + + c12@1.10.0: + dependencies: + chokidar: 3.6.0 + confbox: 0.1.7 + defu: 6.1.4 + dotenv: 16.4.5 + giget: 1.2.3 + jiti: 1.21.3 + mlly: 1.7.1 + ohash: 1.1.3 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + pkg-types: 1.1.1 + rc9: 2.1.2 + + cac@6.7.14: {} + + cacache@16.1.3: + dependencies: + '@npmcli/fs': 2.1.2 + '@npmcli/move-file': 2.0.1 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 8.1.0 + infer-owner: 1.0.4 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 9.0.1 + tar: 6.2.1 + unique-filename: 2.0.1 + transitivePeerDependencies: + - bluebird + + cacache@17.1.4: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.4.1 + lru-cache: 7.18.3 + minipass: 7.1.2 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.2.1 + unique-filename: 3.0.0 + + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.1 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.0.1 + responselike: 3.0.0 + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + call-me-maybe@1.0.2: {} + + callsites@3.1.0: {} + + camelcase@6.3.0: {} + + camelcase@7.0.1: {} + + can-use-dom@0.1.0: {} + + caniuse-lite@1.0.30001629: {} + + chai@4.4.1: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.0.8 + + chalk@1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + character-entities@2.0.2: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@2.0.0: {} + + ci-info@3.9.0: {} + + ci-info@4.0.0: {} + + citty@0.1.6: + dependencies: + consola: 3.2.3 + + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + + clean-regexp@1.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + clean-stack@2.2.0: {} + + cli-boxes@3.0.0: {} + + cli-cursor@4.0.0: + dependencies: + restore-cursor: 4.0.0 + + cli-progress@3.12.0: + dependencies: + string-width: 4.2.3 + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.1.0 + + clipboard@2.0.11: + dependencies: + good-listener: 1.2.2 + select: 1.1.2 + tiny-emitter: 2.1.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone@2.1.2: {} + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-support@1.1.3: {} + + colord@2.9.3: {} + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@10.0.1: {} + + commander@12.1.0: {} + + commander@7.2.0: {} + + comment-parser@1.4.1: {} + + component-emitter@1.3.1: {} + + compute-scroll-into-view@1.0.20: {} + + computeds@0.0.1: {} + + concat-map@0.0.1: {} + + confbox@0.1.7: {} + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + configstore@6.0.0: + dependencies: + dot-prop: 6.0.1 + graceful-fs: 4.2.11 + unique-string: 3.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 5.1.0 + + consola@3.2.3: {} + + console-control-strings@1.1.0: {} + + convert-gitmoji@0.1.5: {} + + convert-source-map@2.0.0: {} + + copy-descriptor@0.1.1: {} + + core-js-compat@3.37.1: + dependencies: + browserslist: 4.23.1 + + core-js@3.37.0: {} + + core-js@3.37.1: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-js@4.2.0: {} + + crypto-random-string@4.0.0: + dependencies: + type-fest: 1.4.0 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.0 + + css-what@6.1.0: {} + + cssesc@3.0.0: {} + + csso@4.2.0: + dependencies: + css-tree: 1.1.3 + + csstype@3.1.3: {} + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + dayjs@1.11.11: {} + + de-indent@1.0.2: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.5: + dependencies: + ms: 2.1.2 + + decode-named-character-reference@1.0.2: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-eql@4.1.4: + dependencies: + type-detect: 4.0.8 + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.7 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.3 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.3 + isobject: 3.0.1 + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + delegate@3.2.0: {} + + delegates@1.0.0: {} + + dequal@2.0.3: {} + + destr@2.0.3: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff-sequences@29.6.3: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-align@1.12.4: {} + + dom-scroll-into-view@2.0.1: {} + + dom-serializer@0.2.2: + dependencies: + domelementtype: 2.3.0 + entities: 2.2.0 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + domelementtype@1.3.1: {} + + domelementtype@2.3.0: {} + + domhandler@2.4.2: + dependencies: + domelementtype: 1.3.1 + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domutils@1.7.0: + dependencies: + dom-serializer: 0.2.2 + domelementtype: 1.3.1 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + dot-prop@6.0.1: + dependencies: + is-obj: 2.0.0 + + dotenv@16.4.5: {} + + duplexer@0.1.2: {} + + eastasianwidth@0.2.0: {} + + echarts@5.5.0: + dependencies: + tslib: 2.3.0 + zrender: 5.5.0 + + electron-to-chromium@1.4.796: {} + + emoji-regex@10.3.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojis-list@3.0.0: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + enhanced-resolve@5.17.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@1.1.2: {} + + entities@2.2.0: {} + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + err-code@2.0.3: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + esbuild@0.20.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.20.2 + '@esbuild/android-arm': 0.20.2 + '@esbuild/android-arm64': 0.20.2 + '@esbuild/android-x64': 0.20.2 + '@esbuild/darwin-arm64': 0.20.2 + '@esbuild/darwin-x64': 0.20.2 + '@esbuild/freebsd-arm64': 0.20.2 + '@esbuild/freebsd-x64': 0.20.2 + '@esbuild/linux-arm': 0.20.2 + '@esbuild/linux-arm64': 0.20.2 + '@esbuild/linux-ia32': 0.20.2 + '@esbuild/linux-loong64': 0.20.2 + '@esbuild/linux-mips64el': 0.20.2 + '@esbuild/linux-ppc64': 0.20.2 + '@esbuild/linux-riscv64': 0.20.2 + '@esbuild/linux-s390x': 0.20.2 + '@esbuild/linux-x64': 0.20.2 + '@esbuild/netbsd-x64': 0.20.2 + '@esbuild/openbsd-x64': 0.20.2 + '@esbuild/sunos-x64': 0.20.2 + '@esbuild/win32-arm64': 0.20.2 + '@esbuild/win32-ia32': 0.20.2 + '@esbuild/win32-x64': 0.20.2 + + escalade@3.1.2: {} + + escape-goat@4.0.0: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escape-string-regexp@5.0.0: {} + + eslint-compat-utils@0.5.1(eslint@9.4.0): + dependencies: + eslint: 9.4.0 + semver: 7.6.2 + + eslint-config-prettier@9.1.0(eslint@9.4.0): + dependencies: + eslint: 9.4.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.13.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@9.4.0): + dependencies: + debug: 4.3.5 + enhanced-resolve: 5.17.0 + eslint: 9.4.0 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@9.4.0))(eslint@9.4.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@9.4.0) + fast-glob: 3.3.2 + get-tsconfig: 4.7.5 + is-core-module: 2.13.1 + is-glob: 4.0.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-module-utils@2.8.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@9.4.0))(eslint@9.4.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + eslint: 9.4.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@9.4.0) + transitivePeerDependencies: + - supports-color + + eslint-parser-plain@0.1.0: {} + + eslint-plugin-es-x@7.7.0(eslint@9.4.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.4.0) + '@eslint-community/regexpp': 4.10.1 + eslint: 9.4.0 + eslint-compat-utils: 0.5.1(eslint@9.4.0) + + eslint-plugin-import-x@0.5.1(eslint@9.4.0)(typescript@5.4.5): + dependencies: + '@typescript-eslint/utils': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + debug: 4.3.5 + doctrine: 3.0.0 + eslint: 9.4.0 + eslint-import-resolver-node: 0.3.9 + get-tsconfig: 4.7.5 + is-glob: 4.0.3 + minimatch: 9.0.4 + semver: 7.6.2 + tslib: 2.6.3 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-import-resolver-typescript@3.6.1)(eslint@9.4.0): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.4.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@7.12.0(eslint@9.4.0)(typescript@5.4.5))(eslint-plugin-import@2.29.1)(eslint@9.4.0))(eslint@9.4.0) + hasown: 2.0.2 + is-core-module: 2.13.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 7.12.0(eslint@9.4.0)(typescript@5.4.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-n@17.7.0(eslint@9.4.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.4.0) + enhanced-resolve: 5.17.0 + eslint: 9.4.0 + eslint-plugin-es-x: 7.7.0(eslint@9.4.0) + get-tsconfig: 4.7.5 + globals: 15.3.0 + ignore: 5.3.1 + minimatch: 9.0.4 + semver: 7.6.2 + + eslint-plugin-n@17.8.1(eslint@9.4.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.4.0) + enhanced-resolve: 5.17.0 + eslint: 9.4.0 + eslint-plugin-es-x: 7.7.0(eslint@9.4.0) + get-tsconfig: 4.7.5 + globals: 15.4.0 + ignore: 5.3.1 + minimatch: 9.0.4 + semver: 7.6.2 + + eslint-plugin-prettier@5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.0): + dependencies: + eslint: 9.4.0 + prettier: 3.3.0 + prettier-linter-helpers: 1.0.0 + synckit: 0.8.8 + optionalDependencies: + '@types/eslint': 8.56.10 + eslint-config-prettier: 9.1.0(eslint@9.4.0) + + eslint-plugin-prettier@5.1.3(@types/eslint@8.56.10)(eslint-config-prettier@9.1.0(eslint@9.4.0))(eslint@9.4.0)(prettier@3.3.1): + dependencies: + eslint: 9.4.0 + prettier: 3.3.1 + prettier-linter-helpers: 1.0.0 + synckit: 0.8.8 + optionalDependencies: + '@types/eslint': 8.56.10 + eslint-config-prettier: 9.1.0(eslint@9.4.0) + + eslint-plugin-promise@6.2.0(eslint@9.4.0): + dependencies: + eslint: 9.4.0 + + eslint-plugin-unicorn@53.0.0(eslint@9.4.0): + dependencies: + '@babel/helper-validator-identifier': 7.24.7 + '@eslint-community/eslint-utils': 4.4.0(eslint@9.4.0) + '@eslint/eslintrc': 3.1.0 + ci-info: 4.0.0 + clean-regexp: 1.0.0 + core-js-compat: 3.37.1 + eslint: 9.4.0 + esquery: 1.5.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.10.0 + semver: 7.6.2 + strip-indent: 3.0.0 + transitivePeerDependencies: + - supports-color + + eslint-plugin-vue@9.26.0(eslint@9.4.0): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.4.0) + eslint: 9.4.0 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.0 + semver: 7.6.2 + vue-eslint-parser: 9.4.3(eslint@9.4.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-scope@8.0.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.0.0: {} + + eslint@9.4.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.4.0) + '@eslint-community/regexpp': 4.10.1 + '@eslint/config-array': 0.15.1 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.4.0 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.0 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.5 + escape-string-regexp: 4.0.0 + eslint-scope: 8.0.1 + eslint-visitor-keys: 4.0.0 + espree: 10.0.1 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + espree@10.0.1: + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 4.0.0 + + espree@9.6.1: + dependencies: + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.5.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.5 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eventemitter3@5.0.1: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + execa@9.1.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.3 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 7.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 5.3.0 + pretty-ms: 9.0.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.0.2 + + execa@9.2.0: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.3 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 7.0.0 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 5.3.0 + pretty-ms: 9.0.0 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.0.2 + + expand-brackets@2.1.4: + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + exponential-backoff@3.1.1: {} + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + + extglob@2.0.4: + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.7 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-memoize@2.5.2: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + figures@6.1.0: + dependencies: + is-unicode-supported: 2.0.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + focus-trap@7.5.4: + dependencies: + tabbable: 6.2.0 + + follow-redirects@1.15.6: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + for-in@1.0.2: {} + + foreground-child@3.1.1: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 4.1.0 + + form-data-encoder@2.1.4: {} + + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fp-and-or@0.1.4: {} + + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.2 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + gauge@4.0.4: + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.2.0: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-stdin@8.0.0: {} + + get-stream@6.0.1: {} + + get-stream@8.0.1: {} + + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + + get-value@2.0.6: {} + + giget@1.2.3: + dependencies: + citty: 0.1.6 + consola: 3.2.3 + defu: 6.1.4 + node-fetch-native: 1.6.4 + nypm: 0.3.8 + ohash: 1.1.3 + pathe: 1.1.2 + tar: 6.2.1 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.1: + dependencies: + foreground-child: 3.1.1 + jackspeak: 3.4.0 + minimatch: 9.0.4 + minipass: 7.1.2 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-dirs@3.0.1: + dependencies: + ini: 2.0.0 + + globals@11.12.0: {} + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globals@14.0.0: {} + + globals@15.3.0: {} + + globals@15.4.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.1 + merge2: 1.4.1 + slash: 3.0.0 + + good-listener@1.2.2: + dependencies: + delegate: 3.2.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + got@12.6.1: + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + + has-bigints@1.0.2: {} + + has-flag@1.0.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + has-unicode@2.0.1: {} + + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + + has-yarn@3.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + hookable@5.5.3: {} + + hosted-git-info@2.8.9: {} + + hosted-git-info@5.2.1: + dependencies: + lru-cache: 7.18.3 + + hosted-git-info@6.1.1: + dependencies: + lru-cache: 7.18.3 + + html-tags@3.3.1: {} + + htmlparser2@3.10.1: + dependencies: + domelementtype: 1.3.1 + domhandler: 2.4.2 + domutils: 1.7.0 + entities: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + + http-cache-semantics@4.1.1: {} + + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.5 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + human-signals@5.0.0: {} + + human-signals@7.0.0: {} + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + icss-replace-symbols@1.1.0: {} + + icss-utils@5.1.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + + ignore-walk@6.0.5: + dependencies: + minimatch: 9.0.4 + + ignore@5.3.1: {} + + image-size@0.5.5: {} + + immediate@3.0.6: {} + + immutable@4.3.6: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-lazy@4.0.0: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + infer-owner@1.0.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@2.0.0: {} + + ini@4.1.3: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + ip-address@9.0.5: + dependencies: + jsbn: 1.1.0 + sprintf-js: 1.1.3 + + is-accessor-descriptor@1.0.1: + dependencies: + hasown: 2.0.2 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.2.1: {} + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-callable@1.2.7: {} + + is-ci@3.0.1: + dependencies: + ci-info: 3.9.0 + + is-core-module@2.13.1: + dependencies: + hasown: 2.0.2 + + is-data-descriptor@1.0.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-descriptor@0.1.7: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-descriptor@1.0.3: + dependencies: + is-accessor-descriptor: 1.0.1 + is-data-descriptor: 1.0.1 + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-installed-globally@0.4.0: + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + + is-lambda@1.0.1: {} + + is-negative-zero@2.0.3: {} + + is-npm@6.0.0: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + + is-number@7.0.0: {} + + is-obj@2.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@1.1.0: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-plain-object@3.0.1: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-retry-allowed@2.2.0: {} + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-stream@4.0.1: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-there@4.5.1: {} + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-typedarray@1.0.0: {} + + is-unicode-supported@2.0.0: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-windows@1.0.2: {} + + is-yarn-global@0.4.1: {} + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + + isobject@3.0.1: {} + + jackspeak@3.4.0: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jiti@1.21.3: {} + + jju@1.4.0: {} + + js-base64@2.6.4: {} + + js-tokens@4.0.0: {} + + js-tokens@9.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsbn@1.1.0: {} + + jsesc@0.5.0: {} + + jsesc@2.5.2: {} + + jsesc@3.0.2: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-parse-even-better-errors@3.0.2: {} + + json-parse-helpfulerror@1.0.3: + dependencies: + jju: 1.4.0 + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonlines@0.1.1: {} + + jsonparse@1.3.1: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + + kind-of@5.1.0: {} + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + kolorist@1.8.0: {} + + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lie@3.1.1: + dependencies: + immediate: 3.0.6 + + lilconfig@3.1.1: {} + + lines-and-columns@1.2.4: {} + + lint-staged@15.2.5: + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + debug: 4.3.5 + execa: 8.0.1 + lilconfig: 3.1.1 + listr2: 8.2.1 + micromatch: 4.0.7 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.4.5 + transitivePeerDependencies: + - supports-color + + listr2@8.2.1: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.0.0 + rfdc: 1.3.1 + wrap-ansi: 9.0.0 + + loader-utils@1.4.2: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 1.0.2 + + local-pkg@0.5.0: + dependencies: + mlly: 1.7.1 + pkg-types: 1.1.1 + + localforage@1.10.0: + dependencies: + lie: 3.1.1 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.21: {} + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + log-update@6.0.0: + dependencies: + ansi-escapes: 6.2.1 + cli-cursor: 4.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lowercase-keys@3.0.0: {} + + lru-cache@10.2.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@7.18.3: {} + + magic-string@0.30.10: + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + magicast@0.3.4: + dependencies: + '@babel/parser': 7.24.7 + '@babel/types': 7.24.7 + source-map-js: 1.2.0 + + make-fetch-happen@10.2.1: + dependencies: + agentkeepalive: 4.5.0 + cacache: 16.1.3 + http-cache-semantics: 4.1.1 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 2.1.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 9.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + make-fetch-happen@11.1.1: + dependencies: + agentkeepalive: 4.5.0 + cacache: 17.1.4 + http-cache-semantics: 4.1.1 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 5.0.0 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + map-cache@0.2.2: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + + mark.js@8.11.1: {} + + mdast-util-from-markdown@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.2 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-decode-string: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.14: {} + + mdn-data@2.0.30: {} + + merge-options@1.0.1: + dependencies: + is-plain-obj: 1.1.0 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.1: + dependencies: + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-factory-destination: 2.0.0 + micromark-factory-label: 2.0.0 + micromark-factory-space: 2.0.0 + micromark-factory-title: 2.0.0 + micromark-factory-whitespace: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-classify-character: 2.0.0 + micromark-util-html-tag-name: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-destination@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-label@2.0.0: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-space@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-types: 2.0.0 + + micromark-factory-title@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-factory-whitespace@2.0.0: + dependencies: + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-character@2.1.0: + dependencies: + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-chunked@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-classify-character@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-combine-extensions@2.0.0: + dependencies: + micromark-util-chunked: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-decode-numeric-character-reference@2.0.1: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-decode-string@2.0.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 2.1.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-symbol: 2.0.0 + + micromark-util-encode@2.0.0: {} + + micromark-util-html-tag-name@2.0.0: {} + + micromark-util-normalize-identifier@2.0.0: + dependencies: + micromark-util-symbol: 2.0.0 + + micromark-util-resolve-all@2.0.0: + dependencies: + micromark-util-types: 2.0.0 + + micromark-util-sanitize-uri@2.0.0: + dependencies: + micromark-util-character: 2.1.0 + micromark-util-encode: 2.0.0 + micromark-util-symbol: 2.0.0 + + micromark-util-subtokenize@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + + micromark-util-symbol@2.0.0: {} + + micromark-util-types@2.0.0: {} + + micromark@4.0.0: + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.5 + decode-named-character-reference: 1.0.2 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.1 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-chunked: 2.0.0 + micromark-util-combine-extensions: 2.0.0 + micromark-util-decode-numeric-character-reference: 2.0.1 + micromark-util-encode: 2.0.0 + micromark-util-normalize-identifier: 2.0.0 + micromark-util-resolve-all: 2.0.0 + micromark-util-sanitize-uri: 2.0.0 + micromark-util-subtokenize: 2.0.1 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + transitivePeerDependencies: + - supports-color + + micromatch@3.1.0: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 1.0.0 + extend-shallow: 2.0.1 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 5.1.0 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.5: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + micromatch@4.0.7: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mimic-fn@2.1.0: {} + + mimic-fn@4.0.0: {} + + mimic-response@3.1.0: {} + + mimic-response@4.0.0: {} + + min-indent@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.4: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass-collect@1.0.2: + dependencies: + minipass: 3.3.6 + + minipass-fetch@2.1.2: + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-fetch@3.0.5: + dependencies: + minipass: 7.1.2 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.5: + dependencies: + minipass: 3.3.6 + + minipass-json-stream@1.0.1: + dependencies: + jsonparse: 1.3.1 + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minisearch@6.3.0: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mitt@3.0.1: {} + + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + mlly@1.7.1: + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.1 + ufo: 1.5.3 + + mrmime@2.0.0: {} + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + nanoid@3.3.7: {} + + nanoid@5.0.7: {} + + nanomatch@1.2.13: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + nanopop@2.4.2: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + node-fetch-native@1.6.4: {} + + node-gyp@9.4.1: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + make-fetch-happen: 10.2.1 + nopt: 6.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.6.2 + tar: 6.2.1 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + + node-releases@2.0.14: {} + + nopt@6.0.0: + dependencies: + abbrev: 1.1.1 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.8 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-package-data@5.0.0: + dependencies: + hosted-git-info: 6.1.1 + is-core-module: 2.13.1 + semver: 7.6.2 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + normalize-url@8.0.1: {} + + npm-bundled@3.0.1: + dependencies: + npm-normalize-package-bin: 3.0.1 + + npm-check-updates@16.14.20: + dependencies: + '@types/semver-utils': 1.1.3 + chalk: 5.3.0 + cli-table3: 0.6.5 + commander: 10.0.1 + fast-memoize: 2.5.2 + find-up: 5.0.0 + fp-and-or: 0.1.4 + get-stdin: 8.0.0 + globby: 11.1.0 + hosted-git-info: 5.2.1 + ini: 4.1.3 + js-yaml: 4.1.0 + json-parse-helpfulerror: 1.0.3 + jsonlines: 0.1.1 + lodash: 4.17.21 + make-fetch-happen: 11.1.1 + minimatch: 9.0.4 + p-map: 4.0.0 + pacote: 15.2.0 + parse-github-url: 1.0.2 + progress: 2.0.3 + prompts-ncu: 3.0.0 + rc-config-loader: 4.1.3 + remote-git-tags: 3.0.0 + rimraf: 5.0.7 + semver: 7.6.2 + semver-utils: 1.1.4 + source-map-support: 0.5.21 + spawn-please: 2.0.2 + strip-ansi: 7.1.0 + strip-json-comments: 5.0.1 + untildify: 4.0.0 + update-notifier: 6.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + + npm-install-checks@6.3.0: + dependencies: + semver: 7.6.2 + + npm-normalize-package-bin@3.0.1: {} + + npm-package-arg@10.1.0: + dependencies: + hosted-git-info: 6.1.1 + proc-log: 3.0.0 + semver: 7.6.2 + validate-npm-package-name: 5.0.1 + + npm-packlist@7.0.4: + dependencies: + ignore-walk: 6.0.5 + + npm-pick-manifest@8.0.2: + dependencies: + npm-install-checks: 6.3.0 + npm-normalize-package-bin: 3.0.1 + npm-package-arg: 10.1.0 + semver: 7.6.2 + + npm-registry-fetch@14.0.5: + dependencies: + make-fetch-happen: 11.1.1 + minipass: 5.0.0 + minipass-fetch: 3.0.5 + minipass-json-stream: 1.0.1 + minizlib: 2.1.2 + npm-package-arg: 10.1.0 + proc-log: 3.0.0 + transitivePeerDependencies: + - supports-color + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + npmlog@6.0.2: + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + nypm@0.3.8: + dependencies: + citty: 0.1.6 + consola: 3.2.3 + execa: 8.0.1 + pathe: 1.1.2 + ufo: 1.5.3 + + object-assign@4.1.1: {} + + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + + object-inspect@1.13.1: {} + + object-keys@1.1.1: {} + + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + ofetch@1.3.4: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.3 + + ohash@1.1.3: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-cancelable@3.0.0: {} + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@5.0.0: + dependencies: + yocto-queue: 1.0.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-try@2.2.0: {} + + package-json@8.1.1: + dependencies: + got: 12.6.1 + registry-auth-token: 5.0.2 + registry-url: 6.0.1 + semver: 7.6.2 + + pacote@15.2.0: + dependencies: + '@npmcli/git': 4.1.0 + '@npmcli/installed-package-contents': 2.1.0 + '@npmcli/promise-spawn': 6.0.2 + '@npmcli/run-script': 6.0.2 + cacache: 17.1.4 + fs-minipass: 3.0.3 + minipass: 5.0.0 + npm-package-arg: 10.1.0 + npm-packlist: 7.0.4 + npm-pick-manifest: 8.0.2 + npm-registry-fetch: 14.0.5 + proc-log: 3.0.0 + promise-retry: 2.0.1 + read-package-json: 6.0.4 + read-package-json-fast: 3.0.2 + sigstore: 1.9.0 + ssri: 10.0.6 + tar: 6.2.1 + transitivePeerDependencies: + - bluebird + - supports-color + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-github-url@1.0.2: {} + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.24.7 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-ms@4.0.0: {} + + pascalcase@0.1.1: {} + + path-browserify@1.0.1: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.2.2 + minipass: 7.1.2 + + path-type@4.0.0: {} + + pathe@0.2.0: {} + + pathe@1.1.2: {} + + pathval@1.1.1: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.0.1: {} + + picomatch@2.3.1: {} + + pidtree@0.6.0: {} + + pinia@2.1.7(typescript@5.4.5)(vue@3.4.27(typescript@5.4.5)): + dependencies: + '@vue/devtools-api': 6.6.3 + vue: 3.4.27(typescript@5.4.5) + vue-demi: 0.14.8(vue@3.4.27(typescript@5.4.5)) + optionalDependencies: + typescript: 5.4.5 + + pkg-types@1.1.1: + dependencies: + confbox: 0.1.7 + mlly: 1.7.1 + pathe: 1.1.2 + + pluralize@8.0.0: {} + + posix-character-classes@0.1.1: {} + + possible-typed-array-names@1.0.0: {} + + postcss-modules-extract-imports@3.1.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + + postcss-modules-local-by-default@4.0.5(postcss@8.4.38): + dependencies: + icss-utils: 5.1.0(postcss@8.4.38) + postcss: 8.4.38 + postcss-selector-parser: 6.1.0 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.0(postcss@8.4.38): + dependencies: + postcss: 8.4.38 + postcss-selector-parser: 6.1.0 + + postcss-modules-values@4.0.0(postcss@8.4.38): + dependencies: + icss-utils: 5.1.0(postcss@8.4.38) + postcss: 8.4.38 + + postcss-prefix-selector@1.16.1(postcss@5.2.18): + dependencies: + postcss: 5.2.18 + + postcss-selector-parser@6.1.0: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-value-parser@4.2.0: {} + + postcss@5.2.18: + dependencies: + chalk: 1.1.3 + js-base64: 2.6.4 + source-map: 0.5.7 + supports-color: 3.2.3 + + postcss@8.4.38: + dependencies: + nanoid: 3.3.7 + picocolors: 1.0.1 + source-map-js: 1.2.0 + + posthtml-parser@0.2.1: + dependencies: + htmlparser2: 3.10.1 + isobject: 2.1.0 + + posthtml-rename-id@1.0.12: + dependencies: + escape-string-regexp: 1.0.5 + + posthtml-render@1.4.0: {} + + posthtml-svg-mode@1.0.3: + dependencies: + merge-options: 1.0.1 + posthtml: 0.9.2 + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + + posthtml@0.9.2: + dependencies: + posthtml-parser: 0.2.1 + posthtml-render: 1.4.0 + + preact@10.22.0: {} + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier-plugin-jsdoc@1.3.0(prettier@3.3.0): + dependencies: + binary-searching: 2.0.5 + comment-parser: 1.4.1 + mdast-util-from-markdown: 2.0.1 + prettier: 3.3.0 + transitivePeerDependencies: + - supports-color + + prettier-plugin-json-sort@0.0.2(prettier@3.3.0): + dependencies: + prettier: 3.3.0 + + prettier@3.2.5: {} + + prettier@3.3.0: {} + + prettier@3.3.1: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + pretty-ms@9.0.0: + dependencies: + parse-ms: 4.0.0 + + proc-log@3.0.0: {} + + progress@2.0.3: {} + + promise-inflight@1.0.1: {} + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + prompts-ncu@3.0.0: + dependencies: + kleur: 4.1.5 + sisteransi: 1.0.5 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proto-list@1.2.4: {} + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + pupa@3.1.0: + dependencies: + escape-goat: 4.0.0 + + qs@6.12.1: + dependencies: + side-channel: 1.0.6 + + query-string@4.3.4: + dependencies: + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + rc-config-loader@4.1.3: + dependencies: + debug: 4.3.5 + js-yaml: 4.1.0 + json5: 2.2.3 + require-from-string: 2.0.2 + transitivePeerDependencies: + - supports-color + + rc9@2.1.2: + dependencies: + defu: 6.1.4 + destr: 2.0.3 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + rd@2.0.1: + dependencies: + '@types/node': 10.17.60 + + react-is@18.3.1: {} + + read-package-json-fast@3.0.2: + dependencies: + json-parse-even-better-errors: 3.0.2 + npm-normalize-package-bin: 3.0.1 + + read-package-json@6.0.4: + dependencies: + glob: 10.4.1 + json-parse-even-better-errors: 3.0.2 + normalize-package-data: 5.0.0 + npm-normalize-package-bin: 3.0.1 + + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + recast@0.23.7: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.6.3 + + regenerator-runtime@0.14.1: {} + + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + + regexp-tree@0.1.27: {} + + regexp.prototype.flags@1.5.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + registry-auth-token@5.0.2: + dependencies: + '@pnpm/npm-conf': 2.2.2 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + regjsparser@0.10.0: + dependencies: + jsesc: 0.5.0 + + remote-git-tags@3.0.0: {} + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + resize-observer-polyfill@1.5.1: {} + + resolve-alpn@1.2.1: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve-url@0.2.1: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + + restore-cursor@4.0.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + ret@0.1.15: {} + + retry@0.12.0: {} + + reusify@1.0.4: {} + + rfdc@1.3.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.7: + dependencies: + glob: 10.4.1 + + rollup@4.18.0: + dependencies: + '@types/estree': 1.0.5 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.18.0 + '@rollup/rollup-android-arm64': 4.18.0 + '@rollup/rollup-darwin-arm64': 4.18.0 + '@rollup/rollup-darwin-x64': 4.18.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.18.0 + '@rollup/rollup-linux-arm-musleabihf': 4.18.0 + '@rollup/rollup-linux-arm64-gnu': 4.18.0 + '@rollup/rollup-linux-arm64-musl': 4.18.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.18.0 + '@rollup/rollup-linux-riscv64-gnu': 4.18.0 + '@rollup/rollup-linux-s390x-gnu': 4.18.0 + '@rollup/rollup-linux-x64-gnu': 4.18.0 + '@rollup/rollup-linux-x64-musl': 4.18.0 + '@rollup/rollup-win32-arm64-msvc': 4.18.0 + '@rollup/rollup-win32-ia32-msvc': 4.18.0 + '@rollup/rollup-win32-x64-msvc': 4.18.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.2.1: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + + safer-buffer@2.1.2: + optional: true + + sass@1.77.4: + dependencies: + chokidar: 3.6.0 + immutable: 4.3.6 + source-map-js: 1.2.0 + + scroll-into-view-if-needed@2.2.31: + dependencies: + compute-scroll-into-view: 1.0.20 + + scule@1.3.0: {} + + search-insights@2.14.0: {} + + select@1.1.2: {} + + semver-diff@4.0.0: + dependencies: + semver: 7.6.2 + + semver-utils@1.1.4: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.6.2: {} + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + + shallow-equal@1.2.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shiki@1.6.3: + dependencies: + '@shikijs/core': 1.6.3 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + sigstore@1.9.0: + dependencies: + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + '@sigstore/sign': 1.0.0 + '@sigstore/tuf': 1.0.3 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + simple-git-hooks@2.11.1: {} + + simplebar-core@1.2.5: + dependencies: + '@types/lodash-es': 4.17.12 + can-use-dom: 0.1.0 + lodash: 4.17.21 + lodash-es: 4.17.21 + + simplebar-vue@2.3.4(vue@3.4.27(typescript@5.4.5)): + dependencies: + simplebar-core: 1.2.5 + vue: 3.4.27(typescript@5.4.5) + vue-demi: 0.13.11(vue@3.4.27(typescript@5.4.5)) + transitivePeerDependencies: + - '@vue/composition-api' + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.25 + mrmime: 2.0.0 + totalist: 3.0.1 + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + + smart-buffer@4.2.0: {} + + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2: + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + + socks-proxy-agent@7.0.0: + dependencies: + agent-base: 6.0.2 + debug: 4.3.5 + socks: 2.8.3 + transitivePeerDependencies: + - supports-color + + socks@2.8.3: + dependencies: + ip-address: 9.0.5 + smart-buffer: 4.2.0 + + source-map-js@1.2.0: {} + + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-url@0.4.1: {} + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + spawn-please@2.0.2: + dependencies: + cross-spawn: 7.0.3 + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.18 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.18 + + spdx-license-ids@3.0.18: {} + + speakingurl@14.0.1: {} + + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + sprintf-js@1.1.3: {} + + ssri@10.0.6: + dependencies: + minipass: 7.1.2 + + ssri@9.0.1: + dependencies: + minipass: 3.3.6 + + stable@0.1.8: {} + + stackback@0.0.2: {} + + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + + std-env@3.7.0: {} + + strict-uri-encode@1.1.0: {} + + string-argv@0.3.2: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string-width@7.1.0: + dependencies: + emoji-regex: 10.3.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.0.1 + + strip-bom@3.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-final-newline@4.0.0: {} + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + strip-json-comments@5.0.1: {} + + strip-literal@2.1.0: + dependencies: + js-tokens: 9.0.0 + + stylis@4.3.2: {} + + supports-color@2.0.0: {} + + supports-color@3.2.3: + dependencies: + has-flag: 1.0.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-baker@1.7.0: + dependencies: + bluebird: 3.7.2 + clone: 2.1.2 + he: 1.2.0 + image-size: 0.5.5 + loader-utils: 1.4.2 + merge-options: 1.0.1 + micromatch: 3.1.0 + postcss: 5.2.18 + postcss-prefix-selector: 1.16.1(postcss@5.2.18) + posthtml-rename-id: 1.0.12 + posthtml-svg-mode: 1.0.3 + query-string: 4.3.4 + traverse: 0.6.9 + transitivePeerDependencies: + - supports-color + + svg-tags@1.0.0: {} + + svgo@2.8.0: + dependencies: + '@trysound/sax': 0.2.0 + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.0.1 + stable: 0.1.8 + + synckit@0.8.8: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.3 + + synckit@0.9.0: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.6.3 + + tabbable@6.2.0: {} + + tapable@2.2.1: {} + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + text-table@0.2.0: {} + + throttle-debounce@5.0.0: {} + + tiny-emitter@2.1.0: {} + + tiny-invariant@1.3.3: {} + + tinybench@2.8.0: {} + + tinypool@0.8.4: {} + + tinyspy@2.2.1: {} + + to-fast-properties@2.0.0: {} + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + + totalist@3.0.1: {} + + traverse@0.6.9: + dependencies: + gopd: 1.0.1 + typedarray.prototype.slice: 1.0.3 + which-typed-array: 1.1.15 + + ts-api-utils@1.3.0(typescript@5.4.5): + dependencies: + typescript: 5.4.5 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.3.0: {} + + tslib@2.6.3: {} + + tsx@4.14.1: + dependencies: + esbuild: 0.20.2 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + + tuf-js@1.1.7: + dependencies: + '@tufjs/models': 1.0.4 + debug: 4.3.5 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.20.2: {} + + type-fest@0.6.0: {} + + type-fest@0.8.1: {} + + type-fest@1.4.0: {} + + type-fest@2.19.0: {} + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typed-css-modules@0.9.1: + dependencies: + camelcase: 6.3.0 + chalk: 4.1.2 + chokidar: 3.6.0 + glob: 10.4.1 + icss-replace-symbols: 1.1.0 + is-there: 4.5.1 + mkdirp: 3.0.1 + postcss: 8.4.38 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) + postcss-modules-local-by-default: 4.0.5(postcss@8.4.38) + postcss-modules-scope: 3.2.0(postcss@8.4.38) + postcss-modules-values: 4.0.0(postcss@8.4.38) + yargs: 17.7.2 + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typedarray.prototype.slice@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + typed-array-buffer: 1.0.2 + typed-array-byte-offset: 1.0.2 + + typescript@5.4.5: {} + + ufo@1.5.3: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + unconfig@0.3.13: + dependencies: + '@antfu/utils': 0.7.8 + defu: 6.1.4 + jiti: 1.21.3 + + undici-types@5.26.5: {} + + unimport@3.7.2(rollup@4.18.0): + dependencies: + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + acorn: 8.11.3 + escape-string-regexp: 5.0.0 + estree-walker: 3.0.3 + fast-glob: 3.3.2 + local-pkg: 0.5.0 + magic-string: 0.30.10 + mlly: 1.7.1 + pathe: 1.1.2 + pkg-types: 1.1.1 + scule: 1.3.0 + strip-literal: 2.1.0 + unplugin: 1.10.1 + transitivePeerDependencies: + - rollup + + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + + unique-filename@2.0.1: + dependencies: + unique-slug: 3.0.0 + + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + + unique-slug@3.0.0: + dependencies: + imurmurhash: 0.1.4 + + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + + unique-string@3.0.0: + dependencies: + crypto-random-string: 4.0.0 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.2 + + universalify@2.0.1: {} + + unplugin-auto-import@0.17.6(@vueuse/core@10.10.0(vue@3.4.27(typescript@5.4.5)))(rollup@4.18.0): + dependencies: + '@antfu/utils': 0.7.8 + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + fast-glob: 3.3.2 + local-pkg: 0.5.0 + magic-string: 0.30.10 + minimatch: 9.0.4 + unimport: 3.7.2(rollup@4.18.0) + unplugin: 1.10.1 + optionalDependencies: + '@vueuse/core': 10.10.0(vue@3.4.27(typescript@5.4.5)) + transitivePeerDependencies: + - rollup + + unplugin-icons@0.19.0(@vue/compiler-sfc@3.4.27)(vue-template-compiler@2.7.16): + dependencies: + '@antfu/install-pkg': 0.3.3 + '@antfu/utils': 0.7.8 + '@iconify/utils': 2.1.24 + debug: 4.3.5 + kolorist: 1.8.0 + local-pkg: 0.5.0 + unplugin: 1.10.1 + optionalDependencies: + '@vue/compiler-sfc': 3.4.27 + vue-template-compiler: 2.7.16 + transitivePeerDependencies: + - supports-color + + unplugin-vue-components@0.27.0(@babel/parser@7.24.7)(rollup@4.18.0)(vue@3.4.27(typescript@5.4.5)): + dependencies: + '@antfu/utils': 0.7.8 + '@rollup/pluginutils': 5.1.0(rollup@4.18.0) + chokidar: 3.6.0 + debug: 4.3.5 + fast-glob: 3.3.2 + local-pkg: 0.5.0 + magic-string: 0.30.10 + minimatch: 9.0.4 + resolve: 1.22.8 + unplugin: 1.10.1 + vue: 3.4.27(typescript@5.4.5) + optionalDependencies: + '@babel/parser': 7.24.7 + transitivePeerDependencies: + - rollup + - supports-color + + unplugin@1.10.1: + dependencies: + acorn: 8.11.3 + chokidar: 3.6.0 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.2 + + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + + untildify@4.0.0: {} + + update-browserslist-db@1.0.16(browserslist@4.23.1): + dependencies: + browserslist: 4.23.1 + escalade: 3.1.2 + picocolors: 1.0.1 + + update-notifier@6.0.2: + dependencies: + boxen: 7.1.1 + chalk: 5.3.0 + configstore: 6.0.0 + has-yarn: 3.0.0 + import-lazy: 4.0.0 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + is-npm: 6.0.0 + is-yarn-global: 0.4.1 + latest-version: 7.0.0 + pupa: 3.1.0 + semver: 7.6.2 + semver-diff: 4.0.0 + xdg-basedir: 5.1.0 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urix@0.1.0: {} + + use@3.1.1: {} + + util-deprecate@1.0.2: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@5.0.1: {} + + vary@1.1.2: {} + + vite-node@1.6.0(@types/node@20.14.2)(sass@1.77.4): + dependencies: + cac: 6.7.14 + debug: 4.3.5 + pathe: 1.1.2 + picocolors: 1.0.1 + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vite-plugin-progress@0.0.7(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)): + dependencies: + picocolors: 1.0.1 + progress: 2.0.3 + rd: 2.0.1 + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + + vite-plugin-svg-icons@2.0.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4)): + dependencies: + '@types/svgo': 2.6.4 + cors: 2.8.5 + debug: 4.3.5 + etag: 1.8.1 + fs-extra: 10.1.0 + pathe: 0.2.0 + svg-baker: 1.7.0 + svgo: 2.8.0 + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + transitivePeerDependencies: + - supports-color + + vite@5.2.13(@types/node@20.14.2)(sass@1.77.4): + dependencies: + esbuild: 0.20.2 + postcss: 8.4.38 + rollup: 4.18.0 + optionalDependencies: + '@types/node': 20.14.2 + fsevents: 2.3.3 + sass: 1.77.4 + + vitepress@1.2.3(@algolia/client-search@4.23.3)(@types/node@20.14.2)(async-validator@4.2.5)(axios@1.7.2)(nprogress@0.2.0)(postcss@8.4.38)(sass@1.77.4)(search-insights@2.14.0)(typescript@5.4.5): + dependencies: + '@docsearch/css': 3.6.0 + '@docsearch/js': 3.6.0(@algolia/client-search@4.23.3)(search-insights@2.14.0) + '@shikijs/core': 1.6.3 + '@shikijs/transformers': 1.6.3 + '@types/markdown-it': 14.1.1 + '@vitejs/plugin-vue': 5.0.5(vite@5.2.13(@types/node@20.14.2)(sass@1.77.4))(vue@3.4.27(typescript@5.4.5)) + '@vue/devtools-api': 7.2.1(vue@3.4.27(typescript@5.4.5)) + '@vue/shared': 3.4.27 + '@vueuse/core': 10.10.0(vue@3.4.27(typescript@5.4.5)) + '@vueuse/integrations': 10.10.0(async-validator@4.2.5)(axios@1.7.2)(focus-trap@7.5.4)(nprogress@0.2.0)(vue@3.4.27(typescript@5.4.5)) + focus-trap: 7.5.4 + mark.js: 8.11.1 + minisearch: 6.3.0 + shiki: 1.6.3 + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + vue: 3.4.27(typescript@5.4.5) + optionalDependencies: + postcss: 8.4.38 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - lightningcss + - nprogress + - qrcode + - react + - react-dom + - sass + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - typescript + - universal-cookie + + vitest@1.6.0(@types/node@20.14.2)(sass@1.77.4): + dependencies: + '@vitest/expect': 1.6.0 + '@vitest/runner': 1.6.0 + '@vitest/snapshot': 1.6.0 + '@vitest/spy': 1.6.0 + '@vitest/utils': 1.6.0 + acorn-walk: 8.3.2 + chai: 4.4.1 + debug: 4.3.5 + execa: 8.0.1 + local-pkg: 0.5.0 + magic-string: 0.30.10 + pathe: 1.1.2 + picocolors: 1.0.1 + std-env: 3.7.0 + strip-literal: 2.1.0 + tinybench: 2.8.0 + tinypool: 0.8.4 + vite: 5.2.13(@types/node@20.14.2)(sass@1.77.4) + vite-node: 1.6.0(@types/node@20.14.2)(sass@1.77.4) + why-is-node-running: 2.2.2 + optionalDependencies: + '@types/node': 20.14.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - stylus + - sugarss + - supports-color + - terser + + vscode-uri@3.0.8: {} + + vue-demi@0.13.11(vue@3.4.27(typescript@5.4.5)): + dependencies: + vue: 3.4.27(typescript@5.4.5) + + vue-demi@0.14.8(vue@3.4.27(typescript@5.4.5)): + dependencies: + vue: 3.4.27(typescript@5.4.5) + + vue-draggable-plus@0.5.0(@types/sortablejs@1.15.8): + dependencies: + '@types/sortablejs': 1.15.8 + + vue-eslint-parser@9.4.3(eslint@9.4.0): + dependencies: + debug: 4.3.5 + eslint: 9.4.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.5.0 + lodash: 4.17.21 + semver: 7.6.2 + transitivePeerDependencies: + - supports-color + + vue-i18n@9.13.1(vue@3.4.27(typescript@5.4.5)): + dependencies: + '@intlify/core-base': 9.13.1 + '@intlify/shared': 9.13.1 + '@vue/devtools-api': 6.6.3 + vue: 3.4.27(typescript@5.4.5) + + vue-router@4.3.2(vue@3.4.27(typescript@5.4.5)): + dependencies: + '@vue/devtools-api': 6.6.3 + vue: 3.4.27(typescript@5.4.5) + + vue-template-compiler@2.7.16: + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + vue-tsc@2.0.21(typescript@5.4.5): + dependencies: + '@volar/typescript': 2.3.0 + '@vue/language-core': 2.0.21(typescript@5.4.5) + semver: 7.6.2 + typescript: 5.4.5 + + vue-types@3.0.2(vue@3.4.27(typescript@5.4.5)): + dependencies: + is-plain-object: 3.0.1 + vue: 3.4.27(typescript@5.4.5) + + vue@3.4.27(typescript@5.4.5): + dependencies: + '@vue/compiler-dom': 3.4.27 + '@vue/compiler-sfc': 3.4.27 + '@vue/runtime-dom': 3.4.27 + '@vue/server-renderer': 3.4.27(vue@3.4.27(typescript@5.4.5)) + '@vue/shared': 3.4.27 + optionalDependencies: + typescript: 5.4.5 + + warning@4.0.3: + dependencies: + loose-envify: 1.4.0 + + webpack-sources@3.2.3: {} + + webpack-virtual-modules@0.6.2: {} + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@3.0.1: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.2.2: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + widest-line@4.0.1: + dependencies: + string-width: 5.1.2 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.1.0 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + + xdg-basedir@5.1.0: {} + + xml-name-validator@4.0.0: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yaml@2.4.5: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.1.2 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + yocto-queue@1.0.0: {} + + yoctocolors@2.0.2: {} + + zrender@5.5.0: + dependencies: + tslib: 2.3.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..dee51e9 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "packages/*" diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000..169b2ab --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 0000000..f332f04 Binary files /dev/null and b/public/logo.png differ diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..0ccf705 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/src/assets/imgs/soybean.jpg b/src/assets/imgs/soybean.jpg new file mode 100644 index 0000000..75457d5 Binary files /dev/null and b/src/assets/imgs/soybean.jpg differ diff --git a/src/assets/svg-icon/activity.svg b/src/assets/svg-icon/activity.svg new file mode 100644 index 0000000..abe892f --- /dev/null +++ b/src/assets/svg-icon/activity.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/at-sign.svg b/src/assets/svg-icon/at-sign.svg new file mode 100644 index 0000000..625214d --- /dev/null +++ b/src/assets/svg-icon/at-sign.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/avatar.svg b/src/assets/svg-icon/avatar.svg new file mode 100644 index 0000000..66fe6f2 --- /dev/null +++ b/src/assets/svg-icon/avatar.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/banner.svg b/src/assets/svg-icon/banner.svg new file mode 100644 index 0000000..192b637 --- /dev/null +++ b/src/assets/svg-icon/banner.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/cast.svg b/src/assets/svg-icon/cast.svg new file mode 100644 index 0000000..4f008d3 --- /dev/null +++ b/src/assets/svg-icon/cast.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/chrome.svg b/src/assets/svg-icon/chrome.svg new file mode 100644 index 0000000..6314173 --- /dev/null +++ b/src/assets/svg-icon/chrome.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/copy.svg b/src/assets/svg-icon/copy.svg new file mode 100644 index 0000000..ab25601 --- /dev/null +++ b/src/assets/svg-icon/copy.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/custom-icon.svg b/src/assets/svg-icon/custom-icon.svg new file mode 100644 index 0000000..b33a43f --- /dev/null +++ b/src/assets/svg-icon/custom-icon.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/empty-data.svg b/src/assets/svg-icon/empty-data.svg new file mode 100644 index 0000000..293486c --- /dev/null +++ b/src/assets/svg-icon/empty-data.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/expectation.svg b/src/assets/svg-icon/expectation.svg new file mode 100644 index 0000000..1d87d5e --- /dev/null +++ b/src/assets/svg-icon/expectation.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/svg-icon/heart.svg b/src/assets/svg-icon/heart.svg new file mode 100644 index 0000000..56e59b4 --- /dev/null +++ b/src/assets/svg-icon/heart.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/logo.svg b/src/assets/svg-icon/logo.svg new file mode 100644 index 0000000..341675d --- /dev/null +++ b/src/assets/svg-icon/logo.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/network-error.svg b/src/assets/svg-icon/network-error.svg new file mode 100644 index 0000000..52f97ab --- /dev/null +++ b/src/assets/svg-icon/network-error.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/no-icon.svg b/src/assets/svg-icon/no-icon.svg new file mode 100644 index 0000000..f6dcdd0 --- /dev/null +++ b/src/assets/svg-icon/no-icon.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/no-permission.svg b/src/assets/svg-icon/no-permission.svg new file mode 100644 index 0000000..4c408ca --- /dev/null +++ b/src/assets/svg-icon/no-permission.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/not-found.svg b/src/assets/svg-icon/not-found.svg new file mode 100644 index 0000000..a513656 --- /dev/null +++ b/src/assets/svg-icon/not-found.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/service-error.svg b/src/assets/svg-icon/service-error.svg new file mode 100644 index 0000000..0120f1e --- /dev/null +++ b/src/assets/svg-icon/service-error.svg @@ -0,0 +1 @@ + diff --git a/src/assets/svg-icon/wind.svg b/src/assets/svg-icon/wind.svg new file mode 100644 index 0000000..7c90590 --- /dev/null +++ b/src/assets/svg-icon/wind.svg @@ -0,0 +1 @@ + diff --git a/src/components/advanced/table-column-setting.vue b/src/components/advanced/table-column-setting.vue new file mode 100644 index 0000000..852a127 --- /dev/null +++ b/src/components/advanced/table-column-setting.vue @@ -0,0 +1,39 @@ + + + + + diff --git a/src/components/advanced/table-header-operation.vue b/src/components/advanced/table-header-operation.vue new file mode 100644 index 0000000..c1db9c3 --- /dev/null +++ b/src/components/advanced/table-header-operation.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/src/components/common/app-loading.vue b/src/components/common/app-loading.vue new file mode 100644 index 0000000..b4eba66 --- /dev/null +++ b/src/components/common/app-loading.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/common/app-provider.vue b/src/components/common/app-provider.vue new file mode 100644 index 0000000..3639215 --- /dev/null +++ b/src/components/common/app-provider.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/src/components/common/dark-mode-container.vue b/src/components/common/dark-mode-container.vue new file mode 100644 index 0000000..70f452f --- /dev/null +++ b/src/components/common/dark-mode-container.vue @@ -0,0 +1,17 @@ + + + + + diff --git a/src/components/common/exception-base.vue b/src/components/common/exception-base.vue new file mode 100644 index 0000000..801bd26 --- /dev/null +++ b/src/components/common/exception-base.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/components/common/full-screen.vue b/src/components/common/full-screen.vue new file mode 100644 index 0000000..41c1c56 --- /dev/null +++ b/src/components/common/full-screen.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/src/components/common/lang-switch.vue b/src/components/common/lang-switch.vue new file mode 100644 index 0000000..3ee65fc --- /dev/null +++ b/src/components/common/lang-switch.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/components/common/menu-toggler.vue b/src/components/common/menu-toggler.vue new file mode 100644 index 0000000..1c571e7 --- /dev/null +++ b/src/components/common/menu-toggler.vue @@ -0,0 +1,48 @@ + + + + + diff --git a/src/components/common/pin-toggler.vue b/src/components/common/pin-toggler.vue new file mode 100644 index 0000000..a61dcac --- /dev/null +++ b/src/components/common/pin-toggler.vue @@ -0,0 +1,22 @@ + + + + + diff --git a/src/components/common/reload-button.vue b/src/components/common/reload-button.vue new file mode 100644 index 0000000..2881d03 --- /dev/null +++ b/src/components/common/reload-button.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/src/components/common/system-logo.vue b/src/components/common/system-logo.vue new file mode 100644 index 0000000..7f23cc1 --- /dev/null +++ b/src/components/common/system-logo.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/src/components/common/theme-schema-switch.vue b/src/components/common/theme-schema-switch.vue new file mode 100644 index 0000000..9aa6d2a --- /dev/null +++ b/src/components/common/theme-schema-switch.vue @@ -0,0 +1,56 @@ + + + + + diff --git a/src/components/custom/better-scroll.vue b/src/components/custom/better-scroll.vue new file mode 100644 index 0000000..7d2559c --- /dev/null +++ b/src/components/custom/better-scroll.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/src/components/custom/button-icon.vue b/src/components/custom/button-icon.vue new file mode 100644 index 0000000..c024532 --- /dev/null +++ b/src/components/custom/button-icon.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/src/components/custom/count-to.vue b/src/components/custom/count-to.vue new file mode 100644 index 0000000..910b4cc --- /dev/null +++ b/src/components/custom/count-to.vue @@ -0,0 +1,88 @@ + + + + + diff --git a/src/components/custom/look-forward.vue b/src/components/custom/look-forward.vue new file mode 100644 index 0000000..d0494f9 --- /dev/null +++ b/src/components/custom/look-forward.vue @@ -0,0 +1,20 @@ + + + + + diff --git a/src/components/custom/soybean-avatar.vue b/src/components/custom/soybean-avatar.vue new file mode 100644 index 0000000..8d3278a --- /dev/null +++ b/src/components/custom/soybean-avatar.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/components/custom/svg-icon.vue b/src/components/custom/svg-icon.vue new file mode 100644 index 0000000..504763e --- /dev/null +++ b/src/components/custom/svg-icon.vue @@ -0,0 +1,54 @@ + + + + + diff --git a/src/components/custom/wave-bg.vue b/src/components/custom/wave-bg.vue new file mode 100644 index 0000000..534bb37 --- /dev/null +++ b/src/components/custom/wave-bg.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/src/constants/app.ts b/src/constants/app.ts new file mode 100644 index 0000000..ca4f927 --- /dev/null +++ b/src/constants/app.ts @@ -0,0 +1,52 @@ +import { transformRecordToOption } from '@/utils/common'; + +export const themeSchemaRecord: Record = { + light: 'theme.themeSchema.light', + dark: 'theme.themeSchema.dark', + auto: 'theme.themeSchema.auto' +}; + +export const themeSchemaOptions = transformRecordToOption(themeSchemaRecord); + +export const loginModuleRecord: Record = { + 'pwd-login': 'page.login.pwdLogin.title', + 'code-login': 'page.login.codeLogin.title', + register: 'page.login.register.title', + 'reset-pwd': 'page.login.resetPwd.title', + 'bind-wechat': 'page.login.bindWeChat.title' +}; + +export const themeLayoutModeRecord: Record = { + vertical: 'theme.layoutMode.vertical', + 'vertical-mix': 'theme.layoutMode.vertical-mix', + horizontal: 'theme.layoutMode.horizontal', + 'horizontal-mix': 'theme.layoutMode.horizontal-mix' +}; + +export const themeLayoutModeOptions = transformRecordToOption(themeLayoutModeRecord); + +export const themeScrollModeRecord: Record = { + wrapper: 'theme.scrollMode.wrapper', + content: 'theme.scrollMode.content' +}; + +export const themeScrollModeOptions = transformRecordToOption(themeScrollModeRecord); + +export const themeTabModeRecord: Record = { + chrome: 'theme.tab.mode.chrome', + button: 'theme.tab.mode.button' +}; + +export const themeTabModeOptions = transformRecordToOption(themeTabModeRecord); + +export const themePageAnimationModeRecord: Record = { + 'fade-slide': 'theme.page.mode.fade-slide', + fade: 'theme.page.mode.fade', + 'fade-bottom': 'theme.page.mode.fade-bottom', + 'fade-scale': 'theme.page.mode.fade-scale', + 'zoom-fade': 'theme.page.mode.zoom-fade', + 'zoom-out': 'theme.page.mode.zoom-out', + none: 'theme.page.mode.none' +}; + +export const themePageAnimationModeOptions = transformRecordToOption(themePageAnimationModeRecord); diff --git a/src/constants/business.ts b/src/constants/business.ts new file mode 100644 index 0000000..8e10205 --- /dev/null +++ b/src/constants/business.ts @@ -0,0 +1,15 @@ +import { transformRecordToOption } from '@/utils/common'; + +export const enableStatusRecord: Record = { + '0': 'page.manage.common.status.enable', + '1': 'page.manage.common.status.disable' +}; + +export const enableStatusOptions = transformRecordToOption(enableStatusRecord); + +export const menuIconTypeRecord: Record = { + '1': 'page.manage.menu.iconType.iconify', + '2': 'page.manage.menu.iconType.local' +}; + +export const menuIconTypeOptions = transformRecordToOption(menuIconTypeRecord); diff --git a/src/constants/common.ts b/src/constants/common.ts new file mode 100644 index 0000000..2d5e05e --- /dev/null +++ b/src/constants/common.ts @@ -0,0 +1,8 @@ +import { transformRecordToOption } from '@/utils/common'; + +export const yesOrNoRecord: Record = { + Y: 'common.yesOrNo.yes', + N: 'common.yesOrNo.no' +}; + +export const yesOrNoOptions = transformRecordToOption(yesOrNoRecord); diff --git a/src/constants/http-status.ts b/src/constants/http-status.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/constants/reg.ts b/src/constants/reg.ts new file mode 100644 index 0000000..8805ca8 --- /dev/null +++ b/src/constants/reg.ts @@ -0,0 +1,25 @@ +export const REG_USER_NAME = /^[\u4E00-\u9FA5a-zA-Z0-9_-]{4,16}$/; + +/** Phone reg */ +export const REG_PHONE = + /^[1](([3][0-9])|([4][01456789])|([5][012356789])|([6][2567])|([7][0-8])|([8][0-9])|([9][012356789]))[0-9]{8}$/; + +/** + * Password reg + * + * 6-18 characters, including letters, numbers, and underscores + */ +export const REG_PWD = /^\w{6,18}$/; + +/** Email reg */ +export const REG_EMAIL = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/; + +/** Six digit code reg */ +export const REG_CODE_SIX = /^\d{6}$/; + +/** Four digit code reg */ +export const REG_CODE_FOUR = /^\d{4}$/; + +/** Url reg */ +export const REG_URL = + /(((^https?:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[\w]*))?)$/; diff --git a/src/enum/index.ts b/src/enum/index.ts new file mode 100644 index 0000000..2739b3a --- /dev/null +++ b/src/enum/index.ts @@ -0,0 +1,7 @@ +export enum SetupStoreId { + App = 'app-store', + Theme = 'theme-store', + Auth = 'auth-store', + Route = 'route-store', + Tab = 'tab-store' +} diff --git a/src/hooks/business/auth.ts b/src/hooks/business/auth.ts new file mode 100644 index 0000000..f8fc749 --- /dev/null +++ b/src/hooks/business/auth.ts @@ -0,0 +1,21 @@ +import { useAuthStore } from '@/store/modules/auth'; + +export function useAuth() { + const authStore = useAuthStore(); + + function hasAuth(codes: string | string[]) { + if (!authStore.isLogin) { + return false; + } + + if (typeof codes === 'string') { + return authStore.userInfo.buttons.includes(codes); + } + + return codes.some(code => authStore.userInfo.buttons.includes(code)); + } + + return { + hasAuth + }; +} diff --git a/src/hooks/business/captcha.ts b/src/hooks/business/captcha.ts new file mode 100644 index 0000000..b041c17 --- /dev/null +++ b/src/hooks/business/captcha.ts @@ -0,0 +1,71 @@ +import { computed } from 'vue'; +import { useCountDown, useLoading } from '@sa/hooks'; +import { $t } from '@/locales'; +import { REG_PHONE } from '@/constants/reg'; + +export function useCaptcha() { + const { loading, startLoading, endLoading } = useLoading(); + const { count, start, stop, isCounting } = useCountDown(10); + + const label = computed(() => { + let text = $t('page.login.codeLogin.getCode'); + + const countingLabel = $t('page.login.codeLogin.reGetCode', { time: count.value }); + + if (loading.value) { + text = ''; + } + + if (isCounting.value) { + text = countingLabel; + } + + return text; + }); + + function isPhoneValid(phone: string) { + if (phone.trim() === '') { + $message?.error?.($t('form.phone.required')); + + return false; + } + + if (!REG_PHONE.test(phone)) { + $message?.error?.($t('form.phone.invalid')); + + return false; + } + + return true; + } + + async function getCaptcha(phone: string) { + const valid = isPhoneValid(phone); + + if (!valid || loading.value) { + return; + } + + startLoading(); + + // request + await new Promise(resolve => { + setTimeout(resolve, 500); + }); + + $message?.success?.($t('page.login.codeLogin.sendCodeSuccess')); + + start(); + + endLoading(); + } + + return { + label, + start, + stop, + isCounting, + loading, + getCaptcha + }; +} diff --git a/src/hooks/common/echarts.ts b/src/hooks/common/echarts.ts new file mode 100644 index 0000000..eecc3d3 --- /dev/null +++ b/src/hooks/common/echarts.ts @@ -0,0 +1,230 @@ +import { computed, effectScope, nextTick, onScopeDispose, ref, watch } from 'vue'; +import * as echarts from 'echarts/core'; +import { BarChart, GaugeChart, LineChart, PictorialBarChart, PieChart, RadarChart, ScatterChart } from 'echarts/charts'; +import type { + BarSeriesOption, + GaugeSeriesOption, + LineSeriesOption, + PictorialBarSeriesOption, + PieSeriesOption, + RadarSeriesOption, + ScatterSeriesOption +} from 'echarts/charts'; +import { + DatasetComponent, + GridComponent, + LegendComponent, + TitleComponent, + ToolboxComponent, + TooltipComponent, + TransformComponent +} from 'echarts/components'; +import type { + DatasetComponentOption, + GridComponentOption, + LegendComponentOption, + TitleComponentOption, + ToolboxComponentOption, + TooltipComponentOption +} from 'echarts/components'; +import { LabelLayout, UniversalTransition } from 'echarts/features'; +import { CanvasRenderer } from 'echarts/renderers'; +import { useElementSize } from '@vueuse/core'; +import { useThemeStore } from '@/store/modules/theme'; + +export type ECOption = echarts.ComposeOption< + | BarSeriesOption + | LineSeriesOption + | PieSeriesOption + | ScatterSeriesOption + | PictorialBarSeriesOption + | RadarSeriesOption + | GaugeSeriesOption + | TitleComponentOption + | LegendComponentOption + | TooltipComponentOption + | GridComponentOption + | ToolboxComponentOption + | DatasetComponentOption +>; + +echarts.use([ + TitleComponent, + LegendComponent, + TooltipComponent, + GridComponent, + DatasetComponent, + TransformComponent, + ToolboxComponent, + BarChart, + LineChart, + PieChart, + ScatterChart, + PictorialBarChart, + RadarChart, + GaugeChart, + LabelLayout, + UniversalTransition, + CanvasRenderer +]); + +interface ChartHooks { + onRender?: (chart: echarts.ECharts) => void | Promise; + onUpdated?: (chart: echarts.ECharts) => void | Promise; + onDestroy?: (chart: echarts.ECharts) => void | Promise; +} + +/** + * use echarts + * + * @param optionsFactory echarts options factory function + * @param darkMode dark mode + */ +export function useEcharts(optionsFactory: () => T, hooks: ChartHooks = {}) { + const scope = effectScope(); + + const themeStore = useThemeStore(); + const darkMode = computed(() => themeStore.darkMode); + + const domRef = ref(null); + const initialSize = { width: 0, height: 0 }; + const { width, height } = useElementSize(domRef, initialSize); + + let chart: echarts.ECharts | null = null; + const chartOptions: T = optionsFactory(); + + const { + onRender = instance => { + const textColor = darkMode.value ? 'rgb(224, 224, 224)' : 'rgb(31, 31, 31)'; + const maskColor = darkMode.value ? 'rgba(0, 0, 0, 0.4)' : 'rgba(255, 255, 255, 0.8)'; + + instance.showLoading({ + color: themeStore.themeColor, + textColor, + fontSize: 14, + maskColor + }); + }, + onUpdated = instance => { + instance.hideLoading(); + }, + onDestroy + } = hooks; + + /** + * whether can render chart + * + * when domRef is ready and initialSize is valid + */ + function canRender() { + return domRef.value && initialSize.width > 0 && initialSize.height > 0; + } + + /** is chart rendered */ + function isRendered() { + return Boolean(domRef.value && chart); + } + + /** + * update chart options + * + * @param callback callback function + */ + async function updateOptions(callback: (opts: T, optsFactory: () => T) => ECOption = () => chartOptions) { + if (!isRendered()) return; + + const updatedOpts = callback(chartOptions, optionsFactory); + + Object.assign(chartOptions, updatedOpts); + + if (isRendered()) { + chart?.clear(); + } + + chart?.setOption({ ...updatedOpts, backgroundColor: 'transparent' }); + + await onUpdated?.(chart!); + } + + /** render chart */ + async function render() { + if (!isRendered()) { + const chartTheme = darkMode.value ? 'dark' : 'light'; + + await nextTick(); + + chart = echarts.init(domRef.value, chartTheme); + + chart.setOption({ ...chartOptions, backgroundColor: 'transparent' }); + + await onRender?.(chart); + } + } + + /** resize chart */ + function resize() { + chart?.resize(); + } + + /** destroy chart */ + async function destroy() { + if (!chart) return; + + await onDestroy?.(chart); + chart?.dispose(); + chart = null; + } + + /** change chart theme */ + async function changeTheme() { + await destroy(); + await render(); + await onUpdated?.(chart!); + } + + /** + * render chart by size + * + * @param w width + * @param h height + */ + async function renderChartBySize(w: number, h: number) { + initialSize.width = w; + initialSize.height = h; + + // size is abnormal, destroy chart + if (!canRender()) { + await destroy(); + + return; + } + + // resize chart + if (isRendered()) { + resize(); + } + + // render chart + await render(); + } + + scope.run(() => { + watch([width, height], ([newWidth, newHeight]) => { + renderChartBySize(newWidth, newHeight); + }); + + watch(darkMode, () => { + changeTheme(); + }); + }); + + onScopeDispose(() => { + destroy(); + scope.stop(); + }); + + return { + domRef, + updateOptions + }; +} diff --git a/src/hooks/common/form.ts b/src/hooks/common/form.ts new file mode 100644 index 0000000..dbb5f72 --- /dev/null +++ b/src/hooks/common/form.ts @@ -0,0 +1,97 @@ +import { ref, toValue } from 'vue'; +import type { ComputedRef, Ref } from 'vue'; +import type { FormInstance } from 'ant-design-vue'; +import { REG_CODE_SIX, REG_EMAIL, REG_PHONE, REG_PWD, REG_USER_NAME } from '@/constants/reg'; +import { $t } from '@/locales'; + +export function useFormRules() { + const patternRules = { + username: { + pattern: REG_USER_NAME, + message: $t('form.username.invalid'), + trigger: 'change' + }, + phone: { + pattern: REG_PHONE, + message: $t('form.phone.invalid'), + trigger: 'change' + }, + pwd: { + pattern: REG_PWD, + message: $t('form.pwd.invalid'), + trigger: 'change' + }, + code: { + pattern: REG_CODE_SIX, + message: $t('form.code.invalid'), + trigger: 'change' + }, + email: { + pattern: REG_EMAIL, + message: $t('form.email.invalid'), + trigger: 'change' + } + } satisfies Record; + + const formRules = { + username: [createRequiredRule($t('form.username.required')), patternRules.username], + phone: [createRequiredRule($t('form.phone.required')), patternRules.phone], + pwd: [createRequiredRule($t('form.pwd.required')), patternRules.pwd], + code: [createRequiredRule($t('form.code.required')), patternRules.code], + email: [createRequiredRule($t('form.email.required')), patternRules.email] + } satisfies Record; + + /** the default required rule */ + const defaultRequiredRule = createRequiredRule($t('form.required')); + + function createRequiredRule(message: string) { + return { + required: true, + message + }; + } + + /** create a rule for confirming the password */ + function createConfirmPwdRule(pwd: string | Ref | ComputedRef) { + const confirmPwdRule: App.Global.FormRule[] = [ + { required: true, message: $t('form.confirmPwd.required') }, + { + validator: (rule, value) => { + if (value.trim() !== '' && value !== toValue(pwd)) { + return Promise.reject(rule.message); + } + return Promise.resolve(); + }, + message: $t('form.confirmPwd.invalid'), + trigger: 'change' + } + ]; + return confirmPwdRule; + } + + return { + patternRules, + formRules, + defaultRequiredRule, + createRequiredRule, + createConfirmPwdRule + }; +} + +export function useAntdForm() { + const formRef = ref(null); + + async function validate() { + await formRef.value?.validate(); + } + + function resetFields() { + formRef.value?.resetFields(); + } + + return { + formRef, + validate, + resetFields + }; +} diff --git a/src/hooks/common/icon.ts b/src/hooks/common/icon.ts new file mode 100644 index 0000000..8998f60 --- /dev/null +++ b/src/hooks/common/icon.ts @@ -0,0 +1,10 @@ +import { useSvgIconRender } from '@sa/hooks'; +import SvgIcon from '@/components/custom/svg-icon.vue'; + +export function useSvgIcon() { + const { SvgIconVNode } = useSvgIconRender(SvgIcon); + + return { + SvgIconVNode + }; +} diff --git a/src/hooks/common/index.ts b/src/hooks/common/index.ts new file mode 100644 index 0000000..c1ae95d --- /dev/null +++ b/src/hooks/common/index.ts @@ -0,0 +1,4 @@ +export * from './echarts'; +export * from './table'; +export * from './form'; +export * from './router'; diff --git a/src/hooks/common/router.ts b/src/hooks/common/router.ts new file mode 100644 index 0000000..bc5277d --- /dev/null +++ b/src/hooks/common/router.ts @@ -0,0 +1,103 @@ +import { useRouter } from 'vue-router'; +import type { RouteLocationRaw } from 'vue-router'; +import type { RouteKey } from '@elegant-router/types'; +import { router as globalRouter } from '@/router'; + +/** + * Router push + * + * Jump to the specified route, it can replace function router.push + * + * @param inSetup Whether is in vue script setup + */ +export function useRouterPush(inSetup = true) { + const router = inSetup ? useRouter() : globalRouter; + const route = globalRouter.currentRoute; + + const routerPush = router.push; + + const routerBack = router.back; + + interface RouterPushOptions { + query?: Record; + params?: Record; + } + + async function routerPushByKey(key: RouteKey, options?: RouterPushOptions) { + const { query, params } = options || {}; + + const routeLocation: RouteLocationRaw = { + name: key + }; + + if (query) { + routeLocation.query = query; + } + + if (params) { + routeLocation.params = params; + } + + return routerPush(routeLocation); + } + + async function toHome() { + return routerPushByKey('root'); + } + + /** + * Navigate to login page + * + * @param loginModule The login module + * @param redirectUrl The redirect url, if not specified, it will be the current route fullPath + */ + async function toLogin(loginModule?: UnionKey.LoginModule, redirectUrl?: string) { + const module = loginModule || 'pwd-login'; + + const options: RouterPushOptions = { + params: { + module + } + }; + + const redirect = redirectUrl || route.value.fullPath; + + options.query = { + redirect + }; + + return routerPushByKey('login', options); + } + + /** + * Toggle login module + * + * @param module + */ + async function toggleLoginModule(module: UnionKey.LoginModule) { + const query = route.value.query as Record; + + return routerPushByKey('login', { query, params: { module } }); + } + + /** Redirect from login */ + async function redirectFromLogin() { + const redirect = route.value.query?.redirect as string; + + if (redirect) { + routerPush(redirect); + } else { + toHome(); + } + } + + return { + route, + routerPush, + routerBack, + routerPushByKey, + toLogin, + toggleLoginModule, + redirectFromLogin + }; +} diff --git a/src/hooks/common/table.ts b/src/hooks/common/table.ts new file mode 100644 index 0000000..f37dcd2 --- /dev/null +++ b/src/hooks/common/table.ts @@ -0,0 +1,201 @@ +import { computed, effectScope, onScopeDispose, reactive, ref, watch } from 'vue'; +import type { Ref } from 'vue'; +import type { TablePaginationConfig } from 'ant-design-vue'; +import { useBoolean, useHookTable } from '@sa/hooks'; +import { useAppStore } from '@/store/modules/app'; +import { $t } from '@/locales'; + +type TableData = AntDesign.TableData; +type GetTableData = AntDesign.GetTableData; +type TableColumn = AntDesign.TableColumn; + +export function useTable(config: AntDesign.AntDesignTableConfig) { + const scope = effectScope(); + const appStore = useAppStore(); + + const { apiFn, apiParams, immediate, rowKey } = config; + + const { + loading, + empty, + data, + columns, + columnChecks, + reloadColumns, + getData, + searchParams, + updateSearchParams, + resetSearchParams + } = useHookTable, TableColumn>>>({ + apiFn, + apiParams, + columns: config.columns, + transformer: res => { + const { rows = [], total = 0 } = res.data || {}; + return { + rows: rows.map((row, index) => ({ ...row, id: rowKey ? row[rowKey] : index })), + total + }; + }, + getColumnChecks: cols => { + const checks: AntDesign.TableColumnCheck[] = []; + + cols.forEach(column => { + if (column.key) { + checks.push({ + key: column.key as string, + title: column.title as string, + checked: true + }); + } + }); + + return checks; + }, + getColumns: (cols, checks) => { + const columnMap = new Map>>(); + + cols.forEach(column => { + if (column.key) { + columnMap.set(column.key as string, column); + } + }); + + const filteredColumns = checks + .filter(item => item.checked) + .map(check => columnMap.get(check.key) as TableColumn>); + + return filteredColumns; + }, + onFetched: async transformed => { + const { total } = transformed; + + updatePagination({ + total + }); + }, + immediate + }); + + const pagination: TablePaginationConfig = reactive({ + showSizeChanger: true, + pageSizeOptions: [10, 15, 20, 25, 30], + total: 0, + simple: false, + // size: 'f', + current: 1, + pageSize: 10, + onChange: async (current: number, pageSize: number) => { + pagination.current = current; + + updateSearchParams({ + pageNum: current, + pageSize + }); + + getData(); + } + }); + + // this is for mobile, if the system does not support mobile, you can use `pagination` directly + const mobilePagination = computed(() => { + const p: TablePaginationConfig = { + ...pagination, + simple: appStore.isMobile + }; + + return p; + }); + + function updatePagination(update: Partial) { + Object.assign(pagination, update); + } + + scope.run(() => { + watch( + () => appStore.locale, + () => { + reloadColumns(); + } + ); + }); + + onScopeDispose(() => { + scope.stop(); + }); + + return { + loading, + empty, + data, + columns, + columnChecks, + reloadColumns, + pagination, + mobilePagination, + updatePagination, + getData, + searchParams, + updateSearchParams, + resetSearchParams + }; +} + +export function useTableOperate>( + data: Ref, + options: { + getData: () => Promise; + idKey?: string; + } +) { + const { bool: drawerVisible, setTrue: openDrawer, setFalse: closeDrawer } = useBoolean(); + + const operateType = ref('add'); + const { getData, idKey = 'id' } = options; + /** the editing row data */ + const editingData: Ref = ref(null); + + function handleAdd() { + operateType.value = 'add'; + editingData.value = null; + openDrawer(); + } + + function handleEdit(id: any) { + operateType.value = 'edit'; + editingData.value = data.value.find(item => item[idKey] === id) || null; + openDrawer(); + } + + /** the checked row keys of table */ + const checkedRowKeys = ref([]); + + /** the hook after the batch delete operation is completed */ + async function onBatchDeleted() { + $message?.success($t('common.deleteSuccess')); + + checkedRowKeys.value = []; + + await getData(); + } + + /** the hook after the delete operation is completed */ + async function onDeleted() { + $message?.success($t('common.deleteSuccess')); + + await getData(); + } + + return { + drawerVisible, + openDrawer, + closeDrawer, + operateType, + handleAdd, + editingData, + handleEdit, + checkedRowKeys, + onBatchDeleted, + onDeleted + }; +} diff --git a/src/layouts/base-layout/index.vue b/src/layouts/base-layout/index.vue new file mode 100644 index 0000000..845c42b --- /dev/null +++ b/src/layouts/base-layout/index.vue @@ -0,0 +1,132 @@ + + + + + diff --git a/src/layouts/blank-layout/index.vue b/src/layouts/blank-layout/index.vue new file mode 100644 index 0000000..2e393f0 --- /dev/null +++ b/src/layouts/blank-layout/index.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/layouts/context/index.ts b/src/layouts/context/index.ts new file mode 100644 index 0000000..7108b9f --- /dev/null +++ b/src/layouts/context/index.ts @@ -0,0 +1,4 @@ +import { useContext } from '@sa/hooks'; +import { useMixMenu } from '../hooks'; + +export const { setupStore: setupMixMenuContext, useStore: useMixMenuContext } = useContext('mix-menu', useMixMenu); diff --git a/src/layouts/hooks/index.ts b/src/layouts/hooks/index.ts new file mode 100644 index 0000000..474d878 --- /dev/null +++ b/src/layouts/hooks/index.ts @@ -0,0 +1,44 @@ +import { computed, ref, watch } from 'vue'; +import { useRoute } from 'vue-router'; +import { useRouteStore } from '@/store/modules/route'; + +export function useMixMenu() { + const route = useRoute(); + const routeStore = useRouteStore(); + + const activeFirstLevelMenuKey = ref(''); + + function setActiveFirstLevelMenuKey(key: string) { + activeFirstLevelMenuKey.value = key; + } + + function getActiveFirstLevelMenuKey() { + const { hideInMenu, activeMenu } = route.meta; + const name = route.name as string; + + const routeName = (hideInMenu ? activeMenu : name) || name; + + const [firstLevelRouteName] = routeName.split('_'); + + setActiveFirstLevelMenuKey(firstLevelRouteName); + } + + const menus = computed( + () => routeStore.menus.find(menu => menu.key === activeFirstLevelMenuKey.value)?.children || [] + ); + + watch( + () => route.name, + () => { + getActiveFirstLevelMenuKey(); + }, + { immediate: true } + ); + + return { + activeFirstLevelMenuKey, + setActiveFirstLevelMenuKey, + getActiveFirstLevelMenuKey, + menus + }; +} diff --git a/src/layouts/hooks/use-mix-menu.ts b/src/layouts/hooks/use-mix-menu.ts new file mode 100644 index 0000000..8aa6d3d --- /dev/null +++ b/src/layouts/hooks/use-mix-menu.ts @@ -0,0 +1,47 @@ +import { computed, ref, watch } from 'vue'; +import { useRoute } from 'vue-router'; +import { useContext } from '@sa/hooks'; +import { useRouteStore } from '@/store/modules/route'; + +export function useMixMenu() { + const route = useRoute(); + const routeStore = useRouteStore(); + + const activeFirstLevelMenuKey = ref(''); + + function setActiveFirstLevelMenuKey(key: string) { + activeFirstLevelMenuKey.value = key; + } + + function getActiveFirstLevelMenuKey() { + const { hideInMenu, activeMenu } = route.meta; + const name = route.name as string; + + const routeName = (hideInMenu ? activeMenu : name) || name; + + const [firstLevelRouteName] = routeName.split('_'); + + setActiveFirstLevelMenuKey(firstLevelRouteName); + } + + const menus = computed( + () => routeStore.menus.find(menu => menu.key === activeFirstLevelMenuKey.value)?.children || [] + ); + + watch( + () => route.name, + () => { + getActiveFirstLevelMenuKey(); + }, + { immediate: true } + ); + + return { + activeFirstLevelMenuKey, + setActiveFirstLevelMenuKey, + getActiveFirstLevelMenuKey, + menus + }; +} + +export const { setupStore: setupMixMenuContext, useStore: useMixMenuContext } = useContext('mix-menu', useMixMenu); diff --git a/src/layouts/modules/global-breadcrumb/index.vue b/src/layouts/modules/global-breadcrumb/index.vue new file mode 100644 index 0000000..c9b9190 --- /dev/null +++ b/src/layouts/modules/global-breadcrumb/index.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/src/layouts/modules/global-content/index.vue b/src/layouts/modules/global-content/index.vue new file mode 100644 index 0000000..ef40088 --- /dev/null +++ b/src/layouts/modules/global-content/index.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/layouts/modules/global-footer/index.vue b/src/layouts/modules/global-footer/index.vue new file mode 100644 index 0000000..26273b5 --- /dev/null +++ b/src/layouts/modules/global-footer/index.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/src/layouts/modules/global-header/components/theme-button.vue b/src/layouts/modules/global-header/components/theme-button.vue new file mode 100644 index 0000000..732c1b0 --- /dev/null +++ b/src/layouts/modules/global-header/components/theme-button.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/src/layouts/modules/global-header/components/user-avatar.vue b/src/layouts/modules/global-header/components/user-avatar.vue new file mode 100644 index 0000000..8bfaf93 --- /dev/null +++ b/src/layouts/modules/global-header/components/user-avatar.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/src/layouts/modules/global-header/index.vue b/src/layouts/modules/global-header/index.vue new file mode 100644 index 0000000..9d5da33 --- /dev/null +++ b/src/layouts/modules/global-header/index.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/layouts/modules/global-logo/index.vue b/src/layouts/modules/global-logo/index.vue new file mode 100644 index 0000000..40ec52b --- /dev/null +++ b/src/layouts/modules/global-logo/index.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/src/layouts/modules/global-menu/base-menu.vue b/src/layouts/modules/global-menu/base-menu.vue new file mode 100644 index 0000000..affac46 --- /dev/null +++ b/src/layouts/modules/global-menu/base-menu.vue @@ -0,0 +1,149 @@ + + + + + diff --git a/src/layouts/modules/global-menu/first-level-menu.vue b/src/layouts/modules/global-menu/first-level-menu.vue new file mode 100644 index 0000000..17c1081 --- /dev/null +++ b/src/layouts/modules/global-menu/first-level-menu.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/src/layouts/modules/global-menu/horizontal-mix-menu.vue b/src/layouts/modules/global-menu/horizontal-mix-menu.vue new file mode 100644 index 0000000..1a57b2d --- /dev/null +++ b/src/layouts/modules/global-menu/horizontal-mix-menu.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/src/layouts/modules/global-menu/vertical-mix-menu.vue b/src/layouts/modules/global-menu/vertical-mix-menu.vue new file mode 100644 index 0000000..fc600b8 --- /dev/null +++ b/src/layouts/modules/global-menu/vertical-mix-menu.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/layouts/modules/global-sider/index.vue b/src/layouts/modules/global-sider/index.vue new file mode 100644 index 0000000..d843a76 --- /dev/null +++ b/src/layouts/modules/global-sider/index.vue @@ -0,0 +1,40 @@ + + + + + diff --git a/src/layouts/modules/global-tab/context-menu.vue b/src/layouts/modules/global-tab/context-menu.vue new file mode 100644 index 0000000..84c4091 --- /dev/null +++ b/src/layouts/modules/global-tab/context-menu.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/src/layouts/modules/global-tab/index.vue b/src/layouts/modules/global-tab/index.vue new file mode 100644 index 0000000..b3ceb08 --- /dev/null +++ b/src/layouts/modules/global-tab/index.vue @@ -0,0 +1,157 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/components/layout-mode-card.vue b/src/layouts/modules/theme-drawer/components/layout-mode-card.vue new file mode 100644 index 0000000..cc7ba16 --- /dev/null +++ b/src/layouts/modules/theme-drawer/components/layout-mode-card.vue @@ -0,0 +1,91 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/components/setting-item.vue b/src/layouts/modules/theme-drawer/components/setting-item.vue new file mode 100644 index 0000000..fd2111e --- /dev/null +++ b/src/layouts/modules/theme-drawer/components/setting-item.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/index.vue b/src/layouts/modules/theme-drawer/index.vue new file mode 100644 index 0000000..2118714 --- /dev/null +++ b/src/layouts/modules/theme-drawer/index.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/modules/config-operation.vue b/src/layouts/modules/theme-drawer/modules/config-operation.vue new file mode 100644 index 0000000..95d5d1a --- /dev/null +++ b/src/layouts/modules/theme-drawer/modules/config-operation.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/modules/dark-mode.vue b/src/layouts/modules/theme-drawer/modules/dark-mode.vue new file mode 100644 index 0000000..d00780c --- /dev/null +++ b/src/layouts/modules/theme-drawer/modules/dark-mode.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/modules/layout-mode.vue b/src/layouts/modules/theme-drawer/modules/layout-mode.vue new file mode 100644 index 0000000..53379a9 --- /dev/null +++ b/src/layouts/modules/theme-drawer/modules/layout-mode.vue @@ -0,0 +1,69 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/modules/page-fun.vue b/src/layouts/modules/theme-drawer/modules/page-fun.vue new file mode 100644 index 0000000..18ef1bf --- /dev/null +++ b/src/layouts/modules/theme-drawer/modules/page-fun.vue @@ -0,0 +1,118 @@ + + + + + diff --git a/src/layouts/modules/theme-drawer/modules/theme-color.vue b/src/layouts/modules/theme-drawer/modules/theme-color.vue new file mode 100644 index 0000000..f22fc8f --- /dev/null +++ b/src/layouts/modules/theme-drawer/modules/theme-color.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/src/locales/antd.ts b/src/locales/antd.ts new file mode 100644 index 0000000..5726ce3 --- /dev/null +++ b/src/locales/antd.ts @@ -0,0 +1,8 @@ +import type { Locale } from 'ant-design-vue/es/locale'; +import zhCN from 'ant-design-vue/es/locale/zh_CN'; +import enUS from 'ant-design-vue/es/locale/en_US'; + +export const antdLocales: Record = { + 'zh-CN': zhCN, + 'en-US': enUS +}; diff --git a/src/locales/dayjs.ts b/src/locales/dayjs.ts new file mode 100644 index 0000000..7dc8f8b --- /dev/null +++ b/src/locales/dayjs.ts @@ -0,0 +1,20 @@ +import { locale } from 'dayjs'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/en'; +import { localStg } from '@/utils/storage'; + +/** + * Set dayjs locale + * + * @param lang + */ +export function setDayjsLocale(lang: App.I18n.LangType = 'zh-CN') { + const localMap = { + 'zh-CN': 'zh-cn', + 'en-US': 'en' + } satisfies Record; + + const l = lang || localStg.get('lang') || 'zh-CN'; + + locale(localMap[l]); +} diff --git a/src/locales/index.ts b/src/locales/index.ts new file mode 100644 index 0000000..40af8a9 --- /dev/null +++ b/src/locales/index.ts @@ -0,0 +1,26 @@ +import type { App } from 'vue'; +import { createI18n } from 'vue-i18n'; +import { localStg } from '@/utils/storage'; +import messages from './locale'; + +const i18n = createI18n({ + locale: localStg.get('lang') || 'zh-CN', + fallbackLocale: 'en', + messages, + legacy: false +}); + +/** + * Setup plugin i18n + * + * @param app + */ +export function setupI18n(app: App) { + app.use(i18n); +} + +export const $t = i18n.global.t as App.I18n.$T; + +export function setLocale(locale: App.I18n.LangType) { + i18n.global.locale.value = locale; +} diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts new file mode 100644 index 0000000..abaa285 --- /dev/null +++ b/src/locales/langs/en-us.ts @@ -0,0 +1,492 @@ +const local: App.I18n.Schema = { + system: { + title: 'Vue-AntD-Web' + }, + common: { + action: 'Action', + add: 'Add', + addSuccess: 'Add Success', + backToHome: 'Back to home', + batchDelete: 'Batch Delete', + cancel: 'Cancel', + close: 'Close', + check: 'Check', + columnSetting: 'Column Setting', + config: 'Config', + confirm: 'Confirm', + delete: 'Delete', + deleteSuccess: 'Delete Success', + confirmDelete: 'Are you sure you want to delete?', + edit: 'Edit', + index: 'Index', + keywordSearch: 'Please enter keyword', + logout: 'Logout', + logoutConfirm: 'Are you sure you want to log out?', + lookForward: 'Coming soon', + modify: 'Modify', + modifySuccess: 'Modify Success', + noData: 'No Data', + operate: 'Operate', + pleaseCheckValue: 'Please check whether the value is valid', + refresh: 'Refresh', + reset: 'Reset', + search: 'Search', + switch: 'Switch', + tip: 'Tip', + trigger: 'Trigger', + update: 'Update', + updateSuccess: 'Update Success', + userCenter: 'User Center', + yesOrNo: { + yes: 'Yes', + no: 'No' + } + }, + request: { + logout: 'Logout user after request failed', + logoutMsg: 'User status is invalid, please log in again', + logoutWithModal: 'Pop up modal after request failed and then log out user', + logoutWithModalMsg: 'User status is invalid, please log in again', + refreshToken: 'The requested token has expired, refresh the token', + tokenExpired: 'The requested token has expired' + }, + theme: { + themeSchema: { + title: 'Theme Schema', + light: 'Light', + dark: 'Dark', + auto: 'Follow System' + }, + layoutMode: { + title: 'Layout Mode', + vertical: 'Vertical Menu Mode', + horizontal: 'Horizontal Menu Mode', + 'vertical-mix': 'Vertical Mix Menu Mode', + 'horizontal-mix': 'Horizontal Mix menu Mode' + }, + themeColor: { + title: 'Theme Color', + primary: 'Primary', + info: 'Info', + success: 'Success', + warning: 'Warning', + error: 'Error', + followPrimary: 'Follow Primary' + }, + scrollMode: { + title: 'Scroll Mode', + wrapper: 'Wrapper', + content: 'Content' + }, + page: { + animate: 'Page Animate', + mode: { + title: 'Page Animate Mode', + fade: 'Fade', + 'fade-slide': 'Slide', + 'fade-bottom': 'Fade Zoom', + 'fade-scale': 'Fade Scale', + 'zoom-fade': 'Zoom Fade', + 'zoom-out': 'Zoom Out', + none: 'None' + } + }, + fixedHeaderAndTab: 'Fixed Header And Tab', + header: { + height: 'Header Height', + breadcrumb: { + visible: 'Breadcrumb Visible', + showIcon: 'Breadcrumb Icon Visible' + } + }, + tab: { + visible: 'Tab Visible', + cache: 'Tab Cache', + height: 'Tab Height', + mode: { + title: 'Tab Mode', + chrome: 'Chrome', + button: 'Button' + } + }, + sider: { + inverted: 'Dark Sider', + width: 'Sider Width', + collapsedWidth: 'Sider Collapsed Width', + mixWidth: 'Mix Sider Width', + mixCollapsedWidth: 'Mix Sider Collapse Width', + mixChildMenuWidth: 'Mix Child Menu Width' + }, + footer: { + visible: 'Footer Visible', + fixed: 'Fixed Footer', + height: 'Footer Height', + right: 'Right Footer' + }, + themeDrawerTitle: 'Theme Configuration', + pageFunTitle: 'Page Function', + configOperation: { + copyConfig: 'Copy Config', + copySuccessMsg: 'Copy Success, Please replace the variable "themeSettings" in "src/theme/settings.ts"', + resetConfig: 'Reset Config', + resetSuccessMsg: 'Reset Success' + } + }, + route: { + login: 'Login', + 403: 'No Permission', + 404: 'Page Not Found', + 500: 'Server Error', + home: 'Home', + 'user-center': 'User Center', + about: 'About', + function: 'System Function', + function_tab: 'Tab', + 'function_multi-tab': 'Multi Tab', + 'function_hide-child': 'Hide Child', + 'function_hide-child_one': 'Hide Child', + 'function_hide-child_two': 'Two', + 'function_hide-child_three': 'Three', + function_request: 'Request', + 'function_toggle-auth': 'Toggle Auth', + 'function_super-page': 'Super Admin Visible', + manage: 'System Manage', + manage_user: 'User Manage', + 'manage_user-detail': 'User Detail', + manage_role: 'Role Manage', + manage_menu: 'Menu Manage', + exception: 'Exception', + exception_403: '403', + exception_404: '404', + exception_500: '500', + manage_dept: 'Dept Manage', + manage_route: 'Route Manage', + manage_post: 'Post Manage', + manage_dict: 'Dict Manage' + }, + page: { + login: { + common: { + loginOrRegister: 'Login / Register', + userNamePlaceholder: 'Please enter user name', + phonePlaceholder: 'Please enter phone number', + codePlaceholder: 'Please enter verification code', + passwordPlaceholder: 'Please enter password', + confirmPasswordPlaceholder: 'Please enter password again', + codeLogin: 'Verification code login', + confirm: 'Confirm', + back: 'Back', + validateSuccess: 'Verification passed', + loginSuccess: 'Login successfully', + welcomeBack: 'Welcome back, {username} !', + checkCode: 'Please check the verification code' + }, + pwdLogin: { + title: 'Password Login', + rememberMe: 'Remember me', + forgetPassword: 'Forget password?', + register: 'Register', + otherAccountLogin: 'Other Account Login', + otherLoginMode: 'Other Login Mode', + superAdmin: 'Super Admin', + admin: 'Admin', + user: 'User' + }, + codeLogin: { + title: 'Verification Code Login', + getCode: 'Get verification code', + reGetCode: 'Reacquire after {time}s', + sendCodeSuccess: 'Verification code sent successfully', + imageCodePlaceholder: 'Please enter image verification code' + }, + register: { + title: 'Register', + agreement: 'I have read and agree to', + protocol: '《User Agreement》', + policy: '《Privacy Policy》' + }, + resetPwd: { + title: 'Reset Password' + }, + bindWeChat: { + title: 'Bind WeChat' + } + }, + about: { + title: 'About', + introduction: `Soybean Admin is an elegant and powerful admin template, based on the latest front-end technology stack, including Vue3, Vite5, TypeScript, Pinia and UnoCSS. It has built-in rich theme configuration and components, strict code specifications, and an automated file routing system. In addition, it also uses the online mock data solution based on ApiFox. Soybean Admin provides you with a one-stop admin solution, no additional configuration, and out of the box. It is also a best practice for learning cutting-edge technologies quickly.`, + projectInfo: { + title: 'Project Info', + version: 'Version', + latestBuildTime: 'Latest Build Time', + githubLink: 'Github Link', + previewLink: 'Preview Link' + }, + prdDep: 'Production Dependency', + devDep: 'Development Dependency' + }, + home: { + greeting: 'Good morning, {username}, today is another day full of vitality!', + weatherDesc: 'Today is cloudy to clear, 20℃ - 25℃!', + projectCount: 'Project Count', + todo: 'Todo', + message: 'Message', + downloadCount: 'Download Count', + registerCount: 'Register Count', + schedule: 'Work and rest Schedule', + study: 'Study', + work: 'Work', + rest: 'Rest', + entertainment: 'Entertainment', + visitCount: 'Visit Count', + turnover: 'Turnover', + dealCount: 'Deal Count', + projectNews: { + title: 'Project News', + moreNews: 'More News', + desc1: 'Soybean created the open source project soybean-admin on May 28, 2021!', + desc2: 'zyh submitted a bug to soybean-admin, the multi-tab bar will not adapt.', + desc3: 'Soybean is ready to do sufficient preparation for the release of soybean-admin!', + desc4: 'Soybean is busy writing project documentation for soybean-admin!', + desc5: 'Soybean just wrote some of the workbench pages casually, and it was enough to see!' + }, + creativity: 'Creativity' + }, + function: { + tab: { + tabOperate: { + title: 'Tab Operation', + addTab: 'Add Tab', + addTabDesc: 'To about page', + closeTab: 'Close Tab', + closeCurrentTab: 'Close Current Tab', + closeAboutTab: 'Close "About" Tab', + addMultiTab: 'Add Multi Tab', + addMultiTabDesc1: 'To MultiTab page', + addMultiTabDesc2: 'To MultiTab page(with query params)' + }, + tabTitle: { + title: 'Tab Title', + changeTitle: 'Change Title', + change: 'Change', + resetTitle: 'Reset Title', + reset: 'Reset' + } + }, + multiTab: { + routeParam: 'Route Param', + backTab: 'Back function_tab' + }, + toggleAuth: { + toggleAccount: 'Toggle Account', + authHook: 'Auth Hook Function `hasAuth`', + superAdminVisible: 'Super Admin Visible', + adminVisible: 'Admin Visible', + adminOrUserVisible: 'Admin and User Visible' + } + }, + manage: { + common: { + status: { + enable: 'Enable', + disable: 'Disable' + } + }, + role: { + title: 'Role List', + roleName: 'Role Name', + roleCode: 'Role Code', + roleStatus: 'Role Status', + roleDesc: 'Role Description', + menuAuth: 'Menu Auth', + buttonAuth: 'Button Auth', + form: { + roleName: 'Please enter role name', + roleCode: 'Please enter role code', + roleStatus: 'Please select role status', + roleDesc: 'Please enter role description' + }, + addRole: 'Add Role', + editRole: 'Edit Role' + }, + user: { + userName: 'Username', + nickName: 'Nickname', + email: 'Email', + phonenumber: 'Phone number', + status: 'Status', + dept: 'Department', + title: 'User Management', + addUser: 'Add User', + editUser: 'Edit User', + remark: 'Remark', + password: 'Password', + post: 'Post', + role: 'Role', + form: { + userName: 'Please enter username', + email: 'Please enter email', + status: 'Please select status', + nickName: 'Please enter nickname', + phonenumber: 'Please enter phone number', + remark: 'Please enter remark', + password: 'Please enter password', + dept: 'Please select department' + } + }, + menu: { + home: 'Home', + title: 'Menu List', + id: 'ID', + parentId: 'Parent ID', + menuType: 'Menu Type', + menuName: 'Menu Name', + routeName: 'Route Name', + routePath: 'Route Path', + routeParams: 'Route Params', + layout: 'Layout Component', + page: 'Page Component', + i18nKey: 'I18n Key', + icon: 'Icon', + localIcon: 'Local Icon', + iconTypeTitle: 'Icon Type', + order: 'Order', + keepAlive: 'Keep Alive', + href: 'Href', + hideInMenu: 'Hide In Menu', + activeMenu: 'Active Menu', + multiTab: 'Multi Tab', + fixedIndexInTab: 'Fixed Index In Tab', + button: 'Button', + buttonCode: 'Button Code', + buttonDesc: 'Button Desc', + menuStatus: 'Menu Status', + form: { + home: 'Please select home', + menuType: 'Please select menu type', + menuName: 'Please enter menu name', + routeName: 'Please enter route name', + routePath: 'Please enter route path', + page: 'Please select page component', + layout: 'Please select layout component', + i18nKey: 'Please enter i18n key', + icon: 'Please enter iconify name', + localIcon: 'Please enter local icon name', + order: 'Please enter order', + keepAlive: 'Please select whether to cache route', + href: 'Please enter href', + hideInMenu: 'Please select whether to hide menu', + activeMenu: 'Please enter the route name of the highlighted menu', + multiTab: 'Please select whether to support multiple tabs', + fixedInTab: 'Please select whether to fix in the tab', + fixedIndexInTab: 'Please enter the index fixed in the tab', + button: 'Please select whether it is a button', + buttonCode: 'Please enter button code', + buttonDesc: 'Please enter button description', + menuStatus: 'Please select menu status' + }, + addMenu: 'Add Menu', + editMenu: 'Edit Menu', + addChildMenu: 'Add Child Menu', + type: { + directory: 'Directory', + menu: 'Menu' + }, + iconType: { + iconify: 'Iconify Icon', + local: 'Local Icon' + } + }, + dept: { + deptName: 'Department Name', + leader: 'Leader', + status: 'Status', + form: { + deptName: 'Please enter department name', + leader: 'Please enter leader name', + status: 'Please select status' + } + }, + post: { + addPost: 'Add Post', + editPost: 'Edit Post', + postCode: 'Post Code', + postName: 'Post Name', + postSort: 'Post Sort', + status: 'Status', + remark: 'Remark', + title: 'Post list', + form: { + postCode: 'Please enter the post code', + postName: 'Please enter the post name', + postSort: 'Please enter the post sort', + remark: 'Please enter the remark', + status: 'Please select status' + } + }, + dict: { + title: 'Dictionary Management', + dictName: 'Dictionary Name', + dictType: 'Dictionary Type', + status: 'Status', + remark: 'Remark', + form: { + dictName: 'Please enter dictionary name', + dictType: 'Please enter dictionary type', + status: 'Please select status', + remark: 'Please enter remark' + }, + addDict: 'Add Dictionary', + editDict: 'Edit Dictionary' + } + } + }, + form: { + required: 'Cannot be empty', + username: { + required: 'Please enter user name', + invalid: 'User name format is incorrect' + }, + phone: { + required: 'Please enter phone number', + invalid: 'Phone number format is incorrect' + }, + pwd: { + required: 'Please enter password', + invalid: '6-18 characters, including letters, numbers, and underscores' + }, + confirmPwd: { + required: 'Please enter password again', + invalid: 'The two passwords are inconsistent' + }, + code: { + required: 'Please enter verification code', + invalid: 'Verification code format is incorrect' + }, + email: { + required: 'Please enter email', + invalid: 'Email format is incorrect' + } + }, + dropdown: { + closeCurrent: 'Close Current', + closeOther: 'Close Other', + closeLeft: 'Close Left', + closeRight: 'Close Right', + closeAll: 'Close All' + }, + icon: { + themeConfig: 'Theme Configuration', + themeSchema: 'Theme Schema', + lang: 'Switch Language', + fullscreen: 'Fullscreen', + fullscreenExit: 'Exit Fullscreen', + reload: 'Reload Page', + collapse: 'Collapse Menu', + expand: 'Expand Menu', + pin: 'Pin', + unpin: 'Unpin' + } +}; + +export default local; diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts new file mode 100644 index 0000000..5859284 --- /dev/null +++ b/src/locales/langs/zh-cn.ts @@ -0,0 +1,492 @@ +const local: App.I18n.Schema = { + system: { + title: 'Vue-AntD-Web' + }, + common: { + action: '操作', + add: '新增', + addSuccess: '添加成功', + backToHome: '返回首页', + batchDelete: '批量删除', + cancel: '取消', + close: '关闭', + check: '勾选', + columnSetting: '列设置', + config: '配置', + confirm: '确认', + delete: '删除', + deleteSuccess: '删除成功', + confirmDelete: '确认删除吗?', + edit: '编辑', + index: '序号', + keywordSearch: '请输入关键词搜索', + logout: '退出登录', + logoutConfirm: '确认退出登录吗?', + lookForward: '敬请期待', + modify: '修改', + modifySuccess: '修改成功', + noData: '无数据', + operate: '操作', + pleaseCheckValue: '请检查输入的值是否合法', + refresh: '刷新', + reset: '重置', + search: '搜索', + switch: '切换', + tip: '提示', + trigger: '触发', + update: '更新', + updateSuccess: '更新成功', + userCenter: '个人中心', + yesOrNo: { + yes: '是', + no: '否' + } + }, + request: { + logout: '请求失败后登出用户', + logoutMsg: '用户状态失效,请重新登录', + logoutWithModal: '请求失败后弹出模态框再登出用户', + logoutWithModalMsg: '用户状态失效,请重新登录', + refreshToken: '请求的token已过期,刷新token', + tokenExpired: 'token已过期' + }, + theme: { + themeSchema: { + title: '主题模式', + light: '亮色模式', + dark: '暗黑模式', + auto: '跟随系统' + }, + layoutMode: { + title: '布局模式', + vertical: '左侧菜单模式', + 'vertical-mix': '左侧菜单混合模式', + horizontal: '顶部菜单模式', + 'horizontal-mix': '顶部菜单混合模式' + }, + themeColor: { + title: '主题颜色', + primary: '主色', + info: '信息色', + success: '成功色', + warning: '警告色', + error: '错误色', + followPrimary: '跟随主色' + }, + scrollMode: { + title: '滚动模式', + wrapper: '外层滚动', + content: '主体滚动' + }, + page: { + animate: '页面切换动画', + mode: { + title: '页面切换动画类型', + 'fade-slide': '滑动', + fade: '淡入淡出', + 'fade-bottom': '底部消退', + 'fade-scale': '缩放消退', + 'zoom-fade': '渐变', + 'zoom-out': '闪现', + none: '无' + } + }, + fixedHeaderAndTab: '固定头部和标签栏', + header: { + height: '头部高度', + breadcrumb: { + visible: '显示面包屑', + showIcon: '显示面包屑图标' + } + }, + tab: { + visible: '显示标签栏', + cache: '缓存标签页', + height: '标签栏高度', + mode: { + title: '标签栏风格', + chrome: '谷歌风格', + button: '按钮风格' + } + }, + sider: { + inverted: '深色侧边栏', + width: '侧边栏宽度', + collapsedWidth: '侧边栏折叠宽度', + mixWidth: '混合布局侧边栏宽度', + mixCollapsedWidth: '混合布局侧边栏折叠宽度', + mixChildMenuWidth: '混合布局子菜单宽度' + }, + footer: { + visible: '显示底部', + fixed: '固定底部', + height: '底部高度', + right: '底部局右' + }, + themeDrawerTitle: '主题配置', + pageFunTitle: '页面功能', + configOperation: { + copyConfig: '复制配置', + copySuccessMsg: '复制成功,请替换 src/theme/settings.ts 中的变量 themeSettings', + resetConfig: '重置配置', + resetSuccessMsg: '重置成功' + } + }, + route: { + login: '登录', + 403: '无权限', + 404: '页面不存在', + 500: '服务器错误', + home: '首页', + 'user-center': '个人中心', + about: '关于', + function: '系统功能', + function_tab: '标签页', + 'function_multi-tab': '多标签页', + 'function_hide-child': '隐藏子菜单', + 'function_hide-child_one': '隐藏子菜单', + 'function_hide-child_two': '菜单二', + 'function_hide-child_three': '菜单三', + function_request: '请求', + 'function_toggle-auth': '切换权限', + 'function_super-page': '超级管理员可见', + manage: '系统管理', + manage_user: '用户管理', + 'manage_user-detail': '用户详情', + manage_role: '角色管理', + manage_menu: '菜单管理', + exception: '异常页', + exception_403: '403', + exception_404: '404', + exception_500: '500', + manage_dept: '部门管理', + manage_route: '路由管理', + manage_post: '岗位管理', + manage_dict: '字典管理' + }, + page: { + login: { + common: { + loginOrRegister: '登录 / 注册', + userNamePlaceholder: '请输入用户名', + phonePlaceholder: '请输入手机号', + codePlaceholder: '请输入验证码', + passwordPlaceholder: '请输入密码', + confirmPasswordPlaceholder: '请再次输入密码', + codeLogin: '验证码登录', + confirm: '确定', + back: '返回', + validateSuccess: '验证成功', + loginSuccess: '登录成功', + welcomeBack: '欢迎回来,{username} !', + checkCode: '请输入验证码' + }, + pwdLogin: { + title: '密码登录', + rememberMe: '记住我', + forgetPassword: '忘记密码?', + register: '注册账号', + otherAccountLogin: '其他账号登录', + otherLoginMode: '其他登录方式', + superAdmin: '超级管理员', + admin: '管理员', + user: '普通用户' + }, + codeLogin: { + title: '验证码登录', + getCode: '获取验证码', + reGetCode: '{time}秒后重新获取', + sendCodeSuccess: '验证码发送成功', + imageCodePlaceholder: '请输入图片验证码' + }, + register: { + title: '注册账号', + agreement: '我已经仔细阅读并接受', + protocol: '《用户协议》', + policy: '《隐私权政策》' + }, + resetPwd: { + title: '重置密码' + }, + bindWeChat: { + title: '绑定微信' + } + }, + about: { + title: '关于', + introduction: `Soybean Admin 是一个优雅且功能强大的后台管理模板,基于最新的前端技术栈,包括 Vue3, Vite5, TypeScript, Pinia 和 UnoCSS。它内置了丰富的主题配置和组件,代码规范严谨,实现了自动化的文件路由系统。此外,它还采用了基于 ApiFox 的在线Mock数据方案。Soybean Admin 为您提供了一站式的后台管理解决方案,无需额外配置,开箱即用。同样是一个快速学习前沿技术的最佳实践。`, + projectInfo: { + title: '项目信息', + version: '版本', + latestBuildTime: '最新构建时间', + githubLink: 'Github 地址', + previewLink: '预览地址' + }, + prdDep: '生产依赖', + devDep: '开发依赖' + }, + home: { + greeting: '早安,{username}, 今天又是充满活力的一天!', + weatherDesc: '今日多云转晴,20℃ - 25℃!', + projectCount: '项目数', + todo: '待办', + message: '消息', + downloadCount: '下载量', + registerCount: '注册量', + schedule: '作息安排', + study: '学习', + work: '工作', + rest: '休息', + entertainment: '娱乐', + visitCount: '访问量', + turnover: '成交额', + dealCount: '成交量', + projectNews: { + title: '项目动态', + moreNews: '更多动态', + desc1: 'Soybean 在2021年5月28日创建了开源项目 soybean-admin!', + desc2: 'soybean-admin 提交了一个bug,多标签栏不会自适应。', + desc3: 'Soybean 准备为 soybean-admin 的发布做充分的准备工作!', + desc4: 'Soybean 正在忙于为soybean-admin写项目说明文档!', + desc5: 'Soybean 刚才把工作台页面随便写了一些,凑合能看了!' + }, + creativity: '创意' + }, + function: { + tab: { + tabOperate: { + title: '标签页操作', + addTab: '添加标签页', + addTabDesc: '跳转到关于页面', + closeTab: '关闭标签页', + closeCurrentTab: '关闭当前标签页', + closeAboutTab: '关闭"关于"标签页', + addMultiTab: '添加多标签页', + addMultiTabDesc1: '跳转到多标签页页面', + addMultiTabDesc2: '跳转到多标签页页面(带有查询参数)' + }, + tabTitle: { + title: '标签页标题', + changeTitle: '修改标题', + change: '修改', + resetTitle: '重置标题', + reset: '重置' + } + }, + multiTab: { + routeParam: '路由参数', + backTab: '返回 function_tab' + }, + toggleAuth: { + toggleAccount: '切换账号', + authHook: '权限钩子函数 `hasAuth`', + superAdminVisible: '超级管理员可见', + adminVisible: '管理员可见', + adminOrUserVisible: '管理员和用户可见' + } + }, + manage: { + common: { + status: { + enable: '启用', + disable: '禁用' + } + }, + role: { + title: '角色列表', + roleName: '角色名称', + roleCode: '角色编码', + roleStatus: '角色状态', + roleDesc: '角色描述', + menuAuth: '菜单权限', + buttonAuth: '按钮权限', + form: { + roleName: '请输入角色名称', + roleCode: '请输入角色编码', + roleStatus: '请选择角色状态', + roleDesc: '请输入角色描述' + }, + addRole: '新增角色', + editRole: '编辑角色' + }, + user: { + userName: '用户名', + nickName: '昵称', + email: '电子邮件', + phonenumber: '电话号码', + status: '状态', + dept: '部门', + title: '用户管理', + addUser: '新增用户', + editUser: '编辑用户', + remark: '备注', + password: '密码', + role: '角色', + post: '岗位', + form: { + userName: '请输入用户名', + email: '请输入电子邮件', + status: '请选择状态', + nickName: '请输入昵称', + phonenumber: '请输入电话号码', + remark: '请输入备注', + password: '请输入密码', + dept: '请选择部门' + } + }, + menu: { + home: '首页', + title: '菜单列表', + id: 'ID', + parentId: '父级菜单ID', + menuType: '菜单类型', + menuName: '菜单名称', + routeName: '路由名称', + routePath: '路由路径', + routeParams: '路由参数', + layout: '布局', + page: '页面组件', + i18nKey: '国际化key', + icon: '图标', + localIcon: '本地图标', + iconTypeTitle: '图标类型', + order: '排序', + keepAlive: '缓存路由', + href: '外链', + hideInMenu: '隐藏菜单', + activeMenu: '高亮的菜单', + multiTab: '支持多页签', + fixedIndexInTab: '固定在页签中的序号', + button: '按钮', + buttonCode: '按钮编码', + buttonDesc: '按钮描述', + menuStatus: '菜单状态', + form: { + home: '请选择首页', + menuType: '请选择菜单类型', + menuName: '请输入菜单名称', + routeName: '请输入路由名称', + routePath: '请输入路由路径', + page: '请选择页面组件', + layout: '请选择布局组件', + i18nKey: '请输入国际化key', + icon: '请输入图标', + localIcon: '请选择本地图标', + order: '请输入排序', + keepAlive: '请选择是否缓存路由', + href: '请输入外链', + hideInMenu: '请选择是否隐藏菜单', + activeMenu: '请输入高亮的菜单的路由名称', + multiTab: '请选择是否支持多标签', + fixedInTab: '请选择是否固定在页签中', + fixedIndexInTab: '请输入固定在页签中的序号', + button: '请选择是否按钮', + buttonCode: '请输入按钮编码', + buttonDesc: '请输入按钮描述', + menuStatus: '请选择菜单状态' + }, + addMenu: '新增菜单', + editMenu: '编辑菜单', + addChildMenu: '新增子菜单', + type: { + directory: '目录', + menu: '菜单' + }, + iconType: { + iconify: 'iconify图标', + local: '本地图标' + } + }, + dept: { + deptName: '部门名称', + leader: '负责人', + status: '状态', + form: { + deptName: '请输入部门名称', + leader: '请输入负责人', + status: '请选择状态' + } + }, + post: { + addPost: '新增岗位', + editPost: '编辑岗位', + postCode: '岗位编码', + postName: '岗位名称', + postSort: '岗位顺序', + status: '状态', + title: '岗位列表', + remark: '备注', + form: { + postCode: '请输入岗位编码', + postName: '请输入岗位名称', + postSort: '请输入岗位顺序', + remark: '请输入备注', + status: '请选择状态' + } + }, + dict: { + title: '字典管理', + dictName: '字典名称', + dictType: '字典类型', + status: '状态', + remark: '备注', + form: { + dictName: '请输入字典名称', + dictType: '请输入字典类型', + status: '请选择状态', + remark: '请输入备注' + }, + addDict: '新增字典', + editDict: '编辑字典' + } + } + }, + form: { + required: '不能为空', + username: { + required: '请输入用户名', + invalid: '用户名格式不正确' + }, + phone: { + required: '请输入手机号', + invalid: '手机号格式不正确' + }, + pwd: { + required: '请输入密码', + invalid: '密码格式不正确,6-18位字符,包含字母、数字、下划线' + }, + confirmPwd: { + required: '请输入确认密码', + invalid: '两次输入密码不一致' + }, + code: { + required: '请输入验证码', + invalid: '验证码格式不正确' + }, + email: { + required: '请输入邮箱', + invalid: '邮箱格式不正确' + } + }, + dropdown: { + closeCurrent: '关闭', + closeOther: '关闭其它', + closeLeft: '关闭左侧', + closeRight: '关闭右侧', + closeAll: '关闭所有' + }, + icon: { + themeConfig: '主题配置', + themeSchema: '主题模式', + lang: '切换语言', + fullscreen: '全屏', + fullscreenExit: '退出全屏', + reload: '刷新页面', + collapse: '折叠菜单', + expand: '展开菜单', + pin: '固定', + unpin: '取消固定' + } +}; + +export default local; diff --git a/src/locales/locale.ts b/src/locales/locale.ts new file mode 100644 index 0000000..dc38010 --- /dev/null +++ b/src/locales/locale.ts @@ -0,0 +1,9 @@ +import zhCN from './langs/zh-cn'; +import enUS from './langs/en-us'; + +const locales: Record = { + 'zh-CN': zhCN, + 'en-US': enUS +}; + +export default locales; diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..efb97f8 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,29 @@ +import { createApp } from 'vue'; +import './plugins/assets'; +import { setupDayjs, setupIconifyOffline, setupLoading, setupNProgress } from './plugins'; +import { setupStore } from './store'; +import { setupRouter } from './router'; +import { setupI18n } from './locales'; +import App from './App.vue'; + +async function setupApp() { + setupLoading(); + + setupNProgress(); + + setupIconifyOffline(); + + setupDayjs(); + + const app = createApp(App); + + setupStore(app); + + await setupRouter(app); + + setupI18n(app); + + app.mount('#app'); +} + +setupApp(); diff --git a/src/plugins/assets.ts b/src/plugins/assets.ts new file mode 100644 index 0000000..904aa6a --- /dev/null +++ b/src/plugins/assets.ts @@ -0,0 +1,3 @@ +import 'virtual:svg-icons-register'; +import 'uno.css'; +import '../styles/css/global.css'; diff --git a/src/plugins/dayjs.ts b/src/plugins/dayjs.ts new file mode 100644 index 0000000..d3f96ee --- /dev/null +++ b/src/plugins/dayjs.ts @@ -0,0 +1,9 @@ +import { extend } from 'dayjs'; +import localeData from 'dayjs/plugin/localeData'; +import { setDayjsLocale } from '../locales/dayjs'; + +export function setupDayjs() { + extend(localeData); + + setDayjsLocale(); +} diff --git a/src/plugins/iconify.ts b/src/plugins/iconify.ts new file mode 100644 index 0000000..f58d669 --- /dev/null +++ b/src/plugins/iconify.ts @@ -0,0 +1,12 @@ +import { addAPIProvider, disableCache } from '@iconify/vue'; + +/** Setup the iconify offline */ +export function setupIconifyOffline() { + const { VITE_ICONIFY_URL } = import.meta.env; + + if (VITE_ICONIFY_URL) { + addAPIProvider('', { resources: [VITE_ICONIFY_URL] }); + + disableCache('all'); + } +} diff --git a/src/plugins/index.ts b/src/plugins/index.ts new file mode 100644 index 0000000..5d10c3a --- /dev/null +++ b/src/plugins/index.ts @@ -0,0 +1,4 @@ +export * from './loading'; +export * from './nprogress'; +export * from './iconify'; +export * from './dayjs'; diff --git a/src/plugins/loading.ts b/src/plugins/loading.ts new file mode 100644 index 0000000..d61bc58 --- /dev/null +++ b/src/plugins/loading.ts @@ -0,0 +1,45 @@ +// @unocss-include +import { getRgbOfColor } from '@sa/utils'; +import { $t } from '@/locales'; +import { localStg } from '@/utils/storage'; +import systemLogo from '@/assets/svg-icon/logo.svg?raw'; + +export function setupLoading() { + const themeColor = localStg.get('themeColor') || '#646cff'; + + const { r, g, b } = getRgbOfColor(themeColor); + + const primaryColor = `--primary-color: ${r} ${g} ${b}`; + + const loadingClasses = [ + 'left-0 top-0', + 'left-0 bottom-0 animate-delay-500', + 'right-0 top-0 animate-delay-1000', + 'right-0 bottom-0 animate-delay-1500' + ]; + + const logoWithClass = systemLogo.replace(' { + return `
`; + }) + .join('\n'); + + const loading = ` +
+ ${logoWithClass} +
+
+ ${dot} +
+
+

${$t('system.title')}

+
`; + + const app = document.getElementById('app'); + + if (app) { + app.innerHTML = loading; + } +} diff --git a/src/plugins/nprogress.ts b/src/plugins/nprogress.ts new file mode 100644 index 0000000..841ae1e --- /dev/null +++ b/src/plugins/nprogress.ts @@ -0,0 +1,9 @@ +import NProgress from 'nprogress'; + +/** Setup plugin NProgress */ +export function setupNProgress() { + NProgress.configure({ easing: 'ease', speed: 500 }); + + // mount on window + window.NProgress = NProgress; +} diff --git a/src/router/elegant/imports.ts b/src/router/elegant/imports.ts new file mode 100644 index 0000000..a6e8b01 --- /dev/null +++ b/src/router/elegant/imports.ts @@ -0,0 +1,41 @@ +/* eslint-disable */ +/* prettier-ignore */ +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +import type { RouteComponent } from "vue-router"; +import type { LastLevelRouteKey, RouteLayout } from "@elegant-router/types"; + +import BaseLayout from "@/layouts/base-layout/index.vue"; +import BlankLayout from "@/layouts/blank-layout/index.vue"; + +export const layouts: Record Promise)> = { + base: BaseLayout, + blank: BlankLayout, +}; + +export const views: Record Promise)> = { + 403: () => import("@/views/_builtin/403/index.vue"), + 404: () => import("@/views/_builtin/404/index.vue"), + 500: () => import("@/views/_builtin/500/index.vue"), + login: () => import("@/views/_builtin/login/index.vue"), + about: () => import("@/views/about/index.vue"), + "function_hide-child_one": () => import("@/views/function/hide-child/one/index.vue"), + "function_hide-child_three": () => import("@/views/function/hide-child/three/index.vue"), + "function_hide-child_two": () => import("@/views/function/hide-child/two/index.vue"), + "function_multi-tab": () => import("@/views/function/multi-tab/index.vue"), + function_request: () => import("@/views/function/request/index.vue"), + "function_super-page": () => import("@/views/function/super-page/index.vue"), + function_tab: () => import("@/views/function/tab/index.vue"), + "function_toggle-auth": () => import("@/views/function/toggle-auth/index.vue"), + home: () => import("@/views/home/index.vue"), + manage_dept: () => import("@/views/manage/dept/index.vue"), + manage_dict: () => import("@/views/manage/dict/index.vue"), + manage_menu: () => import("@/views/manage/menu/index.vue"), + manage_post: () => import("@/views/manage/post/index.vue"), + manage_role: () => import("@/views/manage/role/index.vue"), + manage_route: () => import("@/views/manage/route/index.vue"), + "manage_user-detail": () => import("@/views/manage/user-detail/[id].vue"), + manage_user: () => import("@/views/manage/user/index.vue"), + "user-center": () => import("@/views/user-center/index.vue"), +}; diff --git a/src/router/elegant/routes.ts b/src/router/elegant/routes.ts new file mode 100644 index 0000000..1d033e0 --- /dev/null +++ b/src/router/elegant/routes.ts @@ -0,0 +1,306 @@ +/* eslint-disable */ +/* prettier-ignore */ +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +import type { GeneratedRoute } from '@elegant-router/types'; + +export const generatedRoutes: GeneratedRoute[] = [ + { + name: '403', + path: '/403', + component: 'layout.blank$view.403', + meta: { + title: '403', + i18nKey: 'route.403', + constant: true, + hideInMenu: true + } + }, + { + name: '404', + path: '/404', + component: 'layout.blank$view.404', + meta: { + title: '404', + i18nKey: 'route.404', + constant: true, + hideInMenu: true + } + }, + { + name: '500', + path: '/500', + component: 'layout.blank$view.500', + meta: { + title: '500', + i18nKey: 'route.500', + constant: true, + hideInMenu: true + } + }, + { + name: 'about', + path: '/about', + component: 'layout.base$view.about', + meta: { + title: 'about', + i18nKey: 'route.about', + icon: 'fluent:book-information-24-regular', + order: 10 + } + }, + { + name: 'function', + path: '/function', + component: 'layout.base', + meta: { + title: 'function', + i18nKey: 'route.function', + icon: 'icon-park-outline:all-application', + order: 6 + }, + children: [ + { + name: 'function_hide-child', + path: '/function/hide-child', + meta: { + title: 'function_hide-child', + i18nKey: 'route.function_hide-child', + icon: 'material-symbols:filter-list-off', + order: 2 + }, + redirect: '/function/hide-child/one', + children: [ + { + name: 'function_hide-child_one', + path: '/function/hide-child/one', + component: 'view.function_hide-child_one', + meta: { + title: 'function_hide-child_one', + i18nKey: 'route.function_hide-child_one', + icon: 'material-symbols:filter-list-off', + hideInMenu: true, + activeMenu: 'function_hide-child' + } + }, + { + name: 'function_hide-child_three', + path: '/function/hide-child/three', + component: 'view.function_hide-child_three', + meta: { + title: 'function_hide-child_three', + i18nKey: 'route.function_hide-child_three', + hideInMenu: true, + activeMenu: 'function_hide-child' + } + }, + { + name: 'function_hide-child_two', + path: '/function/hide-child/two', + component: 'view.function_hide-child_two', + meta: { + title: 'function_hide-child_two', + i18nKey: 'route.function_hide-child_two', + hideInMenu: true, + activeMenu: 'function_hide-child' + } + } + ] + }, + { + name: 'function_multi-tab', + path: '/function/multi-tab', + component: 'view.function_multi-tab', + meta: { + title: 'function_multi-tab', + i18nKey: 'route.function_multi-tab', + icon: 'ic:round-tab', + multiTab: true, + hideInMenu: true, + activeMenu: 'function_tab' + } + }, + { + name: 'function_request', + path: '/function/request', + component: 'view.function_request', + meta: { + title: 'function_request', + i18nKey: 'route.function_request', + icon: 'carbon:network-overlay', + order: 3 + } + }, + { + name: 'function_super-page', + path: '/function/super-page', + component: 'view.function_super-page', + meta: { + title: 'function_super-page', + i18nKey: 'route.function_super-page', + icon: 'ic:round-supervisor-account', + order: 5, + roles: ['R_SUPER'] + } + }, + { + name: 'function_tab', + path: '/function/tab', + component: 'view.function_tab', + meta: { + title: 'function_tab', + i18nKey: 'route.function_tab', + icon: 'ic:round-tab', + order: 1 + } + }, + { + name: 'function_toggle-auth', + path: '/function/toggle-auth', + component: 'view.function_toggle-auth', + meta: { + title: 'function_toggle-auth', + i18nKey: 'route.function_toggle-auth', + icon: 'ic:round-construction', + order: 4 + } + } + ] + }, + { + name: 'home', + path: '/home', + component: 'layout.base$view.home', + meta: { + title: 'home', + i18nKey: 'route.home', + icon: 'mdi:monitor-dashboard', + order: 1 + } + }, + { + name: 'login', + path: '/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?', + component: 'layout.blank$view.login', + props: true, + meta: { + title: 'login', + i18nKey: 'route.login', + constant: true, + hideInMenu: true + } + }, + { + name: 'manage', + path: '/manage', + component: 'layout.base', + meta: { + title: 'manage', + i18nKey: 'route.manage', + icon: 'carbon:cloud-service-management', + order: 9, + roles: ['R_ADMIN'] + }, + children: [ + { + name: 'manage_dept', + path: '/manage/dept', + component: 'view.manage_dept', + meta: { + title: 'manage_dept', + i18nKey: 'route.manage_dept' + } + }, + { + name: 'manage_dict', + path: '/manage/dict', + component: 'view.manage_dict', + meta: { + title: 'manage_dict', + i18nKey: 'route.manage_dict' + } + }, + { + name: 'manage_menu', + path: '/manage/menu', + component: 'view.manage_menu', + meta: { + title: 'manage_menu', + i18nKey: 'route.manage_menu', + icon: 'material-symbols:route', + order: 3, + roles: ['R_ADMIN'], + keepAlive: true + } + }, + { + name: 'manage_post', + path: '/manage/post', + component: 'view.manage_post', + meta: { + title: 'manage_post', + i18nKey: 'route.manage_post' + } + }, + { + name: 'manage_role', + path: '/manage/role', + component: 'view.manage_role', + meta: { + title: 'manage_role', + i18nKey: 'route.manage_role', + icon: 'carbon:user-role', + order: 2, + roles: ['R_SUPER'] + } + }, + { + name: 'manage_route', + path: '/manage/route', + component: 'view.manage_route', + meta: { + title: 'manage_route', + i18nKey: 'route.manage_route' + } + }, + { + name: 'manage_user', + path: '/manage/user', + component: 'view.manage_user', + meta: { + title: 'manage_user', + i18nKey: 'route.manage_user', + icon: 'ic:round-manage-accounts', + order: 1, + roles: ['R_ADMIN'] + } + }, + { + name: 'manage_user-detail', + path: '/manage/user-detail/:id', + component: 'view.manage_user-detail', + props: true, + meta: { + title: 'manage_user-detail', + i18nKey: 'route.manage_user-detail', + hideInMenu: true, + roles: ['R_ADMIN'], + activeMenu: 'manage_user' + } + } + ] + }, + { + name: 'user-center', + path: '/user-center', + component: 'layout.base$view.user-center', + meta: { + title: 'user-center', + hideInMenu: true, + constant: true, + keepAlive: false, + i18nKey: 'route.user-center' + } + } +]; diff --git a/src/router/elegant/transform.ts b/src/router/elegant/transform.ts new file mode 100644 index 0000000..d40c3d7 --- /dev/null +++ b/src/router/elegant/transform.ts @@ -0,0 +1,214 @@ +/* eslint-disable */ +/* prettier-ignore */ +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +import type { RouteRecordRaw, RouteComponent } from 'vue-router'; +import type { ElegantConstRoute } from '@elegant-router/vue'; +import type { RouteMap, RouteKey, RoutePath } from '@elegant-router/types'; + +/** + * transform elegant const routes to vue routes + * @param routes elegant const routes + * @param layouts layout components + * @param views view components + */ +export function transformElegantRoutesToVueRoutes( + routes: ElegantConstRoute[], + layouts: Record Promise)>, + views: Record Promise)> +) { + return routes.flatMap(route => transformElegantRouteToVueRoute(route, layouts, views)); +} + +/** + * transform elegant route to vue route + * @param route elegant const route + * @param layouts layout components + * @param views view components + */ +function transformElegantRouteToVueRoute( + route: ElegantConstRoute, + layouts: Record Promise)>, + views: Record Promise)> +) { + const LAYOUT_PREFIX = 'layout.'; + const VIEW_PREFIX = 'view.'; + const ROUTE_DEGREE_SPLITTER = '_'; + const FIRST_LEVEL_ROUTE_COMPONENT_SPLIT = '$'; + + function isLayout(component: string) { + return component.startsWith(LAYOUT_PREFIX); + } + + function getLayoutName(component: string) { + const layout = component.replace(LAYOUT_PREFIX, ''); + + if(!layouts[layout]) { + throw new Error(`Layout component "${layout}" not found`); + } + + return layout; + } + + function isView(component: string) { + return component.startsWith(VIEW_PREFIX); + } + + function getViewName(component: string) { + const view = component.replace(VIEW_PREFIX, ''); + + if(!views[view]) { + throw new Error(`View component "${view}" not found`); + } + + return view; + } + + function isFirstLevelRoute(item: ElegantConstRoute) { + return !item.name.includes(ROUTE_DEGREE_SPLITTER); + } + + function isSingleLevelRoute(item: ElegantConstRoute) { + return isFirstLevelRoute(item) && !item.children?.length; + } + + function getSingleLevelRouteComponent(component: string) { + const [layout, view] = component.split(FIRST_LEVEL_ROUTE_COMPONENT_SPLIT); + + return { + layout: getLayoutName(layout), + view: getViewName(view) + }; + } + + const vueRoutes: RouteRecordRaw[] = []; + + // add props: true to route + if (route.path.includes(':') && !route.props) { + route.props = true; + } + + const { name, path, component, children, ...rest } = route; + + const vueRoute = { name, path, ...rest } as RouteRecordRaw; + + try { + if (component) { + if (isSingleLevelRoute(route)) { + const { layout, view } = getSingleLevelRouteComponent(component); + + const singleLevelRoute: RouteRecordRaw = { + path, + component: layouts[layout], + children: [ + { + name, + path: '', + component: views[view], + ...rest + } as RouteRecordRaw + ] + }; + + return [singleLevelRoute]; + } + + if (isLayout(component)) { + const layoutName = getLayoutName(component); + + vueRoute.component = layouts[layoutName]; + } + + if (isView(component)) { + const viewName = getViewName(component); + + vueRoute.component = views[viewName]; + } + + } + } catch (error: any) { + console.error(`Error transforming route "${route.name}": ${error.toString()}`); + return []; + } + + + // add redirect to child + if (children?.length && !vueRoute.redirect) { + vueRoute.redirect = { + name: children[0].name + }; + } + + if (children?.length) { + const childRoutes = children.flatMap(child => transformElegantRouteToVueRoute(child, layouts, views)); + + if(isFirstLevelRoute(route)) { + vueRoute.children = childRoutes; + } else { + vueRoutes.push(...childRoutes); + } + } + + vueRoutes.unshift(vueRoute); + + return vueRoutes; +} + +/** + * map of route name and route path + */ +const routeMap: RouteMap = { + "root": "/", + "not-found": "/:pathMatch(.*)*", + "exception": "/exception", + "exception_403": "/exception/403", + "exception_404": "/exception/404", + "exception_500": "/exception/500", + "403": "/403", + "404": "/404", + "500": "/500", + "about": "/about", + "function": "/function", + "function_hide-child": "/function/hide-child", + "function_hide-child_one": "/function/hide-child/one", + "function_hide-child_three": "/function/hide-child/three", + "function_hide-child_two": "/function/hide-child/two", + "function_multi-tab": "/function/multi-tab", + "function_request": "/function/request", + "function_super-page": "/function/super-page", + "function_tab": "/function/tab", + "function_toggle-auth": "/function/toggle-auth", + "home": "/home", + "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?", + "manage": "/manage", + "manage_dept": "/manage/dept", + "manage_dict": "/manage/dict", + "manage_menu": "/manage/menu", + "manage_post": "/manage/post", + "manage_role": "/manage/role", + "manage_route": "/manage/route", + "manage_user": "/manage/user", + "manage_user-detail": "/manage/user-detail/:id", + "user-center": "/user-center" +}; + +/** + * get route path by route name + * @param name route name + */ +export function getRoutePath(name: T) { + return routeMap[name]; +} + +/** + * get route name by route path + * @param path route path + */ +export function getRouteName(path: RoutePath) { + const routeEntries = Object.entries(routeMap) as [RouteKey, RoutePath][]; + + const routeName: RouteKey | null = routeEntries.find(([, routePath]) => routePath === path)?.[0] || null; + + return routeName; +} diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts new file mode 100644 index 0000000..9f91c9b --- /dev/null +++ b/src/router/guard/index.ts @@ -0,0 +1,15 @@ +import type { Router } from 'vue-router'; +import { createRouteGuard } from './route'; +import { createProgressGuard } from './progress'; +import { createDocumentTitleGuard } from './title'; + +/** + * Router guard + * + * @param router - Router instance + */ +export function createRouterGuard(router: Router) { + createProgressGuard(router); + createRouteGuard(router); + createDocumentTitleGuard(router); +} diff --git a/src/router/guard/progress.ts b/src/router/guard/progress.ts new file mode 100644 index 0000000..a1d4aee --- /dev/null +++ b/src/router/guard/progress.ts @@ -0,0 +1,11 @@ +import type { Router } from 'vue-router'; + +export function createProgressGuard(router: Router) { + router.beforeEach((_to, _from, next) => { + window.NProgress?.start?.(); + next(); + }); + router.afterEach(_to => { + window.NProgress?.done?.(); + }); +} diff --git a/src/router/guard/route.ts b/src/router/guard/route.ts new file mode 100644 index 0000000..5c6cf78 --- /dev/null +++ b/src/router/guard/route.ts @@ -0,0 +1,199 @@ +import type { + LocationQueryRaw, + NavigationGuardNext, + RouteLocationNormalized, + RouteLocationRaw, + Router +} from 'vue-router'; +import type { RouteKey } from '@elegant-router/types'; +import { useAuthStore } from '@/store/modules/auth'; +import { useRouteStore } from '@/store/modules/route'; +import { localStg } from '@/utils/storage'; + +/** + * create route guard + * + * @param router router instance + */ +export function createRouteGuard(router: Router) { + router.beforeEach(async (to, from, next) => { + const location = await checkRoute(to); + + if (location) { + next(location); + return; + } + + const authStore = useAuthStore(); + + const rootRoute: RouteKey = 'root'; + const loginRoute: RouteKey = 'login'; + const noAuthorizationRoute: RouteKey = '403'; + + const isLogin = Boolean(localStg.get('token')); + const needLogin = !to.meta.constant; + const routeRoles = to.meta.roles || []; + + // const hasRole = authStore.userInfo.roles?.some(role => routeRoles.includes(role)); + const hasAuth = authStore.isStaticSuper || !routeRoles.length; + + const routeSwitches: CommonType.StrategicPattern[] = [ + // if it is login route when logged in, then switch to the root page + { + condition: isLogin && to.name === loginRoute, + callback: () => { + next({ name: rootRoute }); + } + }, + // if is is constant route, then it is allowed to access directly + { + condition: !needLogin, + callback: () => { + handleRouteSwitch(to, from, next); + } + }, + // if the route need login but the user is not logged in, then switch to the login page + { + condition: !isLogin && needLogin, + callback: () => { + next({ name: loginRoute, query: { redirect: to.fullPath } }); + } + }, + // if the user is logged in and has authorization, then it is allowed to access + { + condition: isLogin && needLogin && (hasAuth ?? false), + callback: () => { + handleRouteSwitch(to, from, next); + } + }, + // if the user is logged in but does not have authorization, then switch to the 403 page + { + condition: isLogin && needLogin && !hasAuth, + callback: () => { + next({ name: noAuthorizationRoute }); + } + } + ]; + + routeSwitches.some(({ condition, callback }) => { + if (condition) { + callback(); + } + + return condition; + }); + }); +} + +/** + * initialize route + * + * @param to to route + */ +async function checkRoute(to: RouteLocationNormalized): Promise { + const routeStore = useRouteStore(); + + const notFoundRoute: RouteKey = 'not-found'; + const isNotFoundRoute = to.name === notFoundRoute; + + // if the constant route is not initialized, then initialize the constant route + if (!routeStore.isInitConstantRoute) { + await routeStore.initConstantRoute(); + + // the route is captured by the "not-found" route because the constant route is not initialized + // after the constant route is initialized, redirect to the original route + if (isNotFoundRoute) { + const path = to.fullPath; + + const location: RouteLocationRaw = { + path, + replace: true, + query: to.query, + hash: to.hash + }; + + return location; + } + } + + // if the route is the constant route but is not the "not-found" route, then it is allowed to access. + if (to.meta.constant && !isNotFoundRoute) { + return null; + } + + // the auth route is initialized + // it is not the "not-found" route, then it is allowed to access + if (routeStore.isInitAuthRoute && !isNotFoundRoute) { + return null; + } + // it is captured by the "not-found" route, then check whether the route exists + if (routeStore.isInitAuthRoute && isNotFoundRoute) { + // const exist = await routeStore.getIsAuthRouteExist(to.path as RoutePath); + const noPermissionRoute: RouteKey = '403'; + + return { + name: noPermissionRoute + } as RouteLocationRaw; + + // if (exist) { + // const location: RouteLocationRaw = { + // name: noPermissionRoute + // }; + + // return location; + // } + + // return null; + } + + // if the auth route is not initialized, then initialize the auth route + const isLogin = Boolean(localStg.get('token')); + // initialize the auth route requires the user to be logged in, if not, redirect to the login page + if (!isLogin) { + const loginRoute: RouteKey = 'login'; + const redirect = to.fullPath; + + const query: LocationQueryRaw = to.name !== loginRoute ? { redirect } : {}; + + const location: RouteLocationRaw = { + name: loginRoute, + query + }; + + return location; + } + + // initialize the auth route + await routeStore.initAuthRoute(); + + // the route is captured by the "not-found" route because the auth route is not initialized + // after the auth route is initialized, redirect to the original route + if (isNotFoundRoute) { + const rootRoute: RouteKey = 'root'; + const path = to.redirectedFrom?.name === rootRoute ? '/' : to.fullPath; + + const location: RouteLocationRaw = { + path, + replace: true, + query: to.query, + hash: to.hash + }; + + return location; + } + + return null; +} + +function handleRouteSwitch(to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) { + // route with href + if (to.meta.href) { + window.open(to.meta.href, '_blank'); + + next({ path: from.fullPath, replace: true, query: from.query, hash: to.hash }); + + return; + } + + next(); +} diff --git a/src/router/guard/title.ts b/src/router/guard/title.ts new file mode 100644 index 0000000..5b60368 --- /dev/null +++ b/src/router/guard/title.ts @@ -0,0 +1,13 @@ +import { useTitle } from '@vueuse/core'; +import type { Router } from 'vue-router'; +import { $t } from '@/locales'; + +export function createDocumentTitleGuard(router: Router) { + router.afterEach(to => { + const { i18nKey, title } = to.meta; + + const documentTitle = i18nKey ? $t(i18nKey) : title; + + useTitle(documentTitle); + }); +} diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..ec1b925 --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,30 @@ +import type { App } from 'vue'; +import { + type RouterHistory, + createMemoryHistory, + createRouter, + createWebHashHistory, + createWebHistory +} from 'vue-router'; +import { createBuiltinVueRoutes } from './routes/builtin'; +import { createRouterGuard } from './guard'; + +const { VITE_ROUTER_HISTORY_MODE = 'history', VITE_BASE_URL } = import.meta.env; + +const historyCreatorMap: Record RouterHistory> = { + hash: createWebHashHistory, + history: createWebHistory, + memory: createMemoryHistory +}; + +export const router = createRouter({ + history: historyCreatorMap[VITE_ROUTER_HISTORY_MODE](VITE_BASE_URL), + routes: createBuiltinVueRoutes() +}); + +/** Setup Vue Router */ +export async function setupRouter(app: App) { + app.use(router); + createRouterGuard(router); + await router.isReady(); +} diff --git a/src/router/routes/builtin.ts b/src/router/routes/builtin.ts new file mode 100644 index 0000000..953df9f --- /dev/null +++ b/src/router/routes/builtin.ts @@ -0,0 +1,31 @@ +import type { CustomRoute } from '@elegant-router/types'; +import { layouts, views } from '../elegant/imports'; +import { getRoutePath, transformElegantRoutesToVueRoutes } from '../elegant/transform'; + +export const ROOT_ROUTE: CustomRoute = { + name: 'root', + path: '/', + redirect: getRoutePath(import.meta.env.VITE_ROUTE_HOME) || 'manage_user', + meta: { + title: 'root', + constant: true + } +}; + +const NOT_FOUND_ROUTE: CustomRoute = { + name: 'not-found', + path: '/:pathMatch(.*)*', + component: 'layout.blank$view.404', + meta: { + title: 'not-found', + constant: true + } +}; + +/** builtin routes, it must be constant and setup in vue-router */ +const builtinRoutes: CustomRoute[] = [ROOT_ROUTE, NOT_FOUND_ROUTE]; + +/** create builtin vue routes */ +export function createBuiltinVueRoutes() { + return transformElegantRoutesToVueRoutes(builtinRoutes, layouts, views); +} diff --git a/src/router/routes/index.ts b/src/router/routes/index.ts new file mode 100644 index 0000000..8984785 --- /dev/null +++ b/src/router/routes/index.ts @@ -0,0 +1,84 @@ +import type { CustomRoute, ElegantConstRoute, ElegantRoute } from '@elegant-router/types'; +import { generatedRoutes } from '../elegant/routes'; +import { layouts, views } from '../elegant/imports'; +import { transformElegantRoutesToVueRoutes } from '../elegant/transform'; + +/** + * custom routes + * + * @link https://github.com/soybeanjs/elegant-router?tab=readme-ov-file#custom-route + */ +const customRoutes: CustomRoute[] = [ + { + name: 'exception', + path: '/exception', + component: 'layout.base', + meta: { + title: 'exception', + i18nKey: 'route.exception', + icon: 'ant-design:exception-outlined', + order: 7 + }, + children: [ + { + name: 'exception_403', + path: '/exception/403', + component: 'view.403', + meta: { + title: 'exception_403', + i18nKey: 'route.exception_403', + icon: 'ic:baseline-block' + } + }, + { + name: 'exception_404', + path: '/exception/404', + component: 'view.404', + meta: { + title: 'exception_404', + i18nKey: 'route.exception_404', + icon: 'ic:baseline-web-asset-off' + } + }, + { + name: 'exception_500', + path: '/exception/500', + component: 'view.500', + meta: { + title: 'exception_500', + i18nKey: 'route.exception_500', + icon: 'ic:baseline-wifi-off' + } + } + ] + } +]; + +/** create routes when the auth route mode is static */ +export function createStaticRoutes() { + const constantRoutes: ElegantRoute[] = []; + + const authRoutes: ElegantRoute[] = []; + + [...customRoutes, ...generatedRoutes].forEach(item => { + if (item.meta?.constant) { + constantRoutes.push(item); + } else { + authRoutes.push(item); + } + }); + + return { + constantRoutes, + authRoutes + }; +} + +/** + * Get auth vue routes + * + * @param routes Elegant routes + */ +export function getAuthVueRoutes(routes: ElegantConstRoute[]) { + return transformElegantRoutesToVueRoutes(routes, layouts, views); +} diff --git a/src/service/api/auth.ts b/src/service/api/auth.ts new file mode 100644 index 0000000..1272330 --- /dev/null +++ b/src/service/api/auth.ts @@ -0,0 +1,60 @@ +import { request } from '../request'; + +/** + * Login + * + * @param username User name + * @param password Password + */ +export function fetchLogin(body: Api.Auth.LoginBody) { + return request({ + url: '/auth/login', + method: 'post', + data: body + }); +} + +/** logout */ +export function doDeleteLogout() { + return request>({ + url: '/auth/logout', + method: 'delete' + }); +} + +/** Get user info */ +export function doGetUserInfo() { + return request({ url: '/system/user/getInfo' }); +} + +/** + * Refresh token + * + * @param refreshToken Refresh token + */ +export function fetchRefreshToken(refreshToken: string) { + return request({ + url: '/auth/refreshToken', + method: 'post', + data: { + refreshToken + } + }); +} + +/** + * return custom backend error + * + * @param code error code + * @param msg error message + */ +export function fetchCustomBackendError(code: string, msg: string) { + return request({ url: '/auth/error', params: { code, msg } }); +} + +/** Get check code */ +export function doGetCheckCode() { + return request<{ uuid: string; img: string }>({ + url: '/code' + }); +} diff --git a/src/service/api/dept.ts b/src/service/api/dept.ts new file mode 100644 index 0000000..e588c7c --- /dev/null +++ b/src/service/api/dept.ts @@ -0,0 +1,63 @@ +import { request } from '../request'; + +export type DeptFormType = Pick< + Api.SystemManage.Dept, + 'deptName' | 'parentId' | 'orderNum' | 'leader' | 'phone' | 'email' | 'status' | 'remark' +>; + +/** 获取部门列表 */ +export function doGetDeptList(params: Api.SystemManage.DeptSearchParams) { + return request({ + url: '/system/dept/list', + params + }); +} + +/** + * 获取部门详情 + * + * @param deptId 部门id + */ +export function doGetDeptInfo(deptId: number) { + return request({ + url: `/system/dept/${deptId}` + }); +} + +/** + * 添加部门 + * + * @param body 部门信息 + */ +export function doAddDept(body: DeptFormType) { + return request({ + url: '/system/dept', + method: 'post', + data: body + }); +} + +/** + * 修改部门 + * + * @param body 部门信息 + */ +export function doEditDept(body: DeptFormType & { deptId: number }) { + return request({ + url: '/system/dept', + method: 'put', + data: body + }); +} + +/** + * 删除部门 + * + * @param deptId 部门id + */ +export function doDeleteDept(deptId: string | number) { + return request({ + url: `/system/dept/${deptId}`, + method: 'delete' + }); +} diff --git a/src/service/api/dict.ts b/src/service/api/dict.ts new file mode 100644 index 0000000..57f48c8 --- /dev/null +++ b/src/service/api/dict.ts @@ -0,0 +1,36 @@ +import { request } from '../request'; + +export type DictSubmitModel = Partial< + Pick +>; + +export const doGetDictList = (params: Api.SystemManage.DictSearchParams) => { + return request({ + url: '/system/dict/type/list', + method: 'get', + params + }); +}; + +export const doAddDict = (data: DictSubmitModel) => { + return request({ + url: '/system/dict/type', + method: 'post', + data + }); +}; + +export const doEditDict = (data: DictSubmitModel) => { + return request({ + url: '/system/dict/type', + method: 'put', + data + }); +}; + +export const doDeleteDict = (dictId: string | number) => { + return request({ + url: `/system/dict/type/${dictId}`, + method: 'post' + }); +}; diff --git a/src/service/api/menu.ts b/src/service/api/menu.ts new file mode 100644 index 0000000..60657f9 --- /dev/null +++ b/src/service/api/menu.ts @@ -0,0 +1,61 @@ +import type { MenuModelType } from '@/views/manage/menu/modules/form'; +import { request } from '../request'; + +export type MenuListQuery = Partial< + Pick +> & + Api.SystemManage.CommonSearchParams; + +export function doGetMenuList(params: MenuListQuery) { + return request({ url: '/system/menu/list', method: 'get', params }); +} + +/** get all pages */ +export function fetchGetAllPages() { + return request[]>({ + url: '/system/menu/list', + method: 'get', + params: { + menuType: 'C' + } + }); +} + +/** get menu tree */ +export function fetchGetMenuTree() { + return request({ + url: '/system/menu/treeselect', + method: 'get' + }); +} + +/** get role menu list */ +export function doGetRoleMenuList(roleId: number) { + return request<{ + checkedKeys: number[]; + menus: Api.SystemManage.MenuTree[]; + }>({ + url: `/system/menu/roleMenuTreeselect/${roleId}`, + method: 'get' + }); +} + +/** add menu */ +export function doAddMenu(data: MenuModelType) { + return request({ url: '/system/menu', method: 'post', data }); +} + +/** delete menu */ +export function doDeleteMenu(menuId: number) { + return request({ url: `/system/menu/${menuId}`, method: 'delete' }); +} + +/** get menu detail */ +export function doGetMenuDetail(menuId: number) { + return request({ url: `/system/menu/${menuId}`, method: 'get' }); +} + +/** edit menu */ +export function doEditMenu(data: MenuModelType) { + return request({ url: '/system/menu', method: 'put', data }); +} diff --git a/src/service/api/post.ts b/src/service/api/post.ts new file mode 100644 index 0000000..549adfb --- /dev/null +++ b/src/service/api/post.ts @@ -0,0 +1,43 @@ +import { request } from '../request'; + +export type PostSubmitModel = Partial< + Pick +>; + +export function doGetPostList(params: Api.SystemManage.PostSearchParams) { + return request({ + url: '/system/post/list', + method: 'get', + params + }); +} + +export function doGetPostDetail(postId: number) { + return request({ + url: `/system/post/${postId}`, + method: 'get' + }); +} + +export function doAddPost(data: PostSubmitModel) { + return request({ + url: '/system/post', + method: 'post', + data + }); +} + +export function doEditPost(data: PostSubmitModel) { + return request({ + url: '/system/post', + method: 'put', + data + }); +} + +export function doDeletePost(postId: string | number) { + return request({ + url: `/system/post/${postId}`, + method: 'delete' + }); +} diff --git a/src/service/api/role.ts b/src/service/api/role.ts new file mode 100644 index 0000000..5bd252f --- /dev/null +++ b/src/service/api/role.ts @@ -0,0 +1,39 @@ +import { request } from '../request'; + +/** + * edit role info + * + * @param role role info + * @returns + */ +export function doPutRole(role: Api.SystemManage.Role) { + return request({ url: '/system/role', method: 'put', data: role }); +} + +/** + * add role + * + * @param role role info + * @returns + */ +export function doPostRole(role: Api.SystemManage.Role) { + return request({ url: '/system/role', method: 'post', data: role }); +} + +/** + * delete role + * + * @param roleId role id + * @returns + */ +export function doDeleteRole(roleId: number | string) { + return request({ url: `/system/role/${roleId}`, method: 'delete' }); +} + +export function doGetRoleList(params?: Api.SystemManage.RoleSearchParams) { + return request({ + url: '/system/role/list', + method: 'get', + params + }); +} diff --git a/src/service/api/route.ts b/src/service/api/route.ts new file mode 100644 index 0000000..378a755 --- /dev/null +++ b/src/service/api/route.ts @@ -0,0 +1,20 @@ +import { request } from '../request'; + +/** get constant routes */ +export function fetchGetConstantRoutes() { + return request({ url: '/route/getConstantRoutes' }); +} + +/** get user routes */ +export function doGetUserRoutes() { + return request({ url: '/system/menu/getRouters' }); +} + +/** + * whether the route is exist + * + * @param routeName route name + */ +export function fetchIsRouteExist(routeName: string) { + return request({ url: '/route/isRouteExist', params: { routeName } }); +} diff --git a/src/service/api/user.ts b/src/service/api/user.ts new file mode 100644 index 0000000..6ec6de6 --- /dev/null +++ b/src/service/api/user.ts @@ -0,0 +1,54 @@ +import { request } from '../request'; + +// user api +export function doPutUser(user: Api.Auth.User) { + return request({ url: '/system/user', method: 'put', data: user }); +} + +export function doPostUser(user: Api.Auth.User) { + return request({ url: '/system/user', method: 'post', data: user }); +} + +export function doDeleteUser(userId: number | string) { + return request({ url: `/system/user/${userId}`, method: 'delete' }); +} + +export function doGetUserList(params?: Api.SystemManage.UserSearchParams) { + return request({ + url: '/system/user/list', + method: 'get', + params + }); +} + +/** + * 获取用户信息 + * + * @returns 用户信息[posts & roles] + */ +export function doGetUserPostsAndRoles(userId: number | string | undefined) { + if (!userId) { + return request({ + url: '/system/user/', + method: 'get' + }); + } + return request({ + url: `/system/user/${userId}`, + method: 'get' + }); +} + +export function doGetAdminUserPostsAndRoles() { + return request({ + url: `/system/user`, + method: 'get' + }); +} + +export function doGetUserDeptTree() { + return request({ + url: '/system/user/deptTree', + method: 'get' + }); +} diff --git a/src/service/request/index.ts b/src/service/request/index.ts new file mode 100644 index 0000000..348b03c --- /dev/null +++ b/src/service/request/index.ts @@ -0,0 +1,133 @@ +import { BACKEND_ERROR_CODE, createFlatRequest } from '@sa/axios'; +import { useAuthStore } from '@/store/modules/auth'; +import { localStg } from '@/utils/storage'; +import { getServiceBaseURL } from '@/utils/service'; +import { $t } from '@/locales'; +import { clearAuthStorage } from '@/store/modules/auth/shared'; + +const isHttpProxy = import.meta.env.DEV && import.meta.env.VITE_HTTP_PROXY === 'Y'; +const { baseURL } = getServiceBaseURL(import.meta.env, isHttpProxy); + +interface InstanceState { + /** whether the request is refreshing token */ + isRefreshingToken: boolean; +} + +export const request = createFlatRequest( + { + baseURL, + 'axios-retry': { + retries: 0 + } + }, + { + async onRequest(config) { + const { headers } = config; + + // set token + const token = localStg.get('token'); + const Authorization = token ? `Bearer ${token}` : null; + Object.assign(headers, { Authorization }); + + return config; + }, + isBackendSuccess(response) { + // when the backend response code is "0000"(default), it means the request is success + // to change this logic by yourself, you can modify the `VITE_SERVICE_SUCCESS_CODE` in `.env` file + return String(response.data.code) === import.meta.env.VITE_SERVICE_SUCCESS_CODE; + }, + async onBackendFail(response, _instance) { + const authStore = useAuthStore(); + + function handleLogout() { + authStore.resetStore(); + } + + function logoutAndCleanup() { + handleLogout(); + window.removeEventListener('beforeunload', handleLogout); + } + + // when the backend response code is in `logoutCodes`, it means the user will be logged out and redirected to login page + const logoutCodes = import.meta.env.VITE_SERVICE_LOGOUT_CODES?.split(',') || []; + if (logoutCodes.includes(String(response.data.code))) { + handleLogout(); + return null; + } + + // when the backend response code is in `modalLogoutCodes`, it means the user will be logged out by displaying a modal + const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || []; + if (modalLogoutCodes.includes(String(response.data.code))) { + // prevent the user from refreshing the page + window.addEventListener('beforeunload', handleLogout); + + $modal?.error({ + title: 'Error', + content: response.data.msg, + okText: $t('common.confirm'), + maskClosable: false, + onOk() { + logoutAndCleanup(); + }, + onCancel() { + logoutAndCleanup(); + } + }); + + return null; + } + + // when the backend response code is in `expiredTokenCodes`, it means the token is expired, and refresh token + // the api `refreshToken` can not return error code in `expiredTokenCodes`, otherwise it will be a dead loop, should return `logoutCodes` or `modalLogoutCodes` + // eslint-disable-next-line no-warning-comments + // TODO: fix when back code is 403 the page redirect to login + // const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || []; + // if (expiredTokenCodes.includes(String(response.data.code)) && !request.state.isRefreshingToken) { + // request.state.isRefreshingToken = true; + + // const refreshConfig = await handleRefreshToken(response.config); + + // request.state.isRefreshingToken = false; + + // if (refreshConfig) { + // return instance.request(refreshConfig) as Promise; + // } + // } + + return null; + }, + transformBackendResponse(response) { + return response.data.data; + }, + onError(error) { + // when the request is fail, you can show error message + let message = error.message; + let backendErrorCode = ''; + + // get backend error message and code + if (error.code === BACKEND_ERROR_CODE) { + message = error.response?.data?.msg || message; + backendErrorCode = error.response?.data?.code || ''; + } + + // the error message is displayed in the modal + const modalLogoutCodes = import.meta.env.VITE_SERVICE_MODAL_LOGOUT_CODES?.split(',') || []; + if (modalLogoutCodes.includes(backendErrorCode)) { + return; + } + + // when the token is expired, refresh token and retry request, so no need to show error message + const expiredTokenCodes = import.meta.env.VITE_SERVICE_EXPIRED_TOKEN_CODES?.split(',') || []; + if (expiredTokenCodes.includes(backendErrorCode)) { + return; + } + + if (backendErrorCode === import.meta.env.VITE_SERVICE_SERVER_ERROR_CODE) { + clearAuthStorage(); + return; + } + + $message?.error?.(message); + } + } +); diff --git a/src/service/request/shared.ts b/src/service/request/shared.ts new file mode 100644 index 0000000..12b3de1 --- /dev/null +++ b/src/service/request/shared.ts @@ -0,0 +1,31 @@ +import type { AxiosRequestConfig } from 'axios'; +import { useAuthStore } from '@/store/modules/auth'; +import { localStg } from '@/utils/storage'; +import { fetchRefreshToken } from '../api'; + +/** + * refresh token + * + * @param axiosConfig - request config when the token is expired + */ +export async function handleRefreshToken(axiosConfig: AxiosRequestConfig) { + const { resetStore } = useAuthStore(); + + const refreshToken = localStg.get('refreshToken') || ''; + const { error, data } = await fetchRefreshToken(refreshToken); + if (!error) { + localStg.set('token', data.access_token); + localStg.set('refreshToken', data.refreshToken); + + const config = { ...axiosConfig }; + if (config.headers) { + config.headers.Authorization = data.access_token; + } + + return config; + } + + resetStore(); + + return null; +} diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..df57302 --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,12 @@ +import type { App } from 'vue'; +import { createPinia } from 'pinia'; +import { resetSetupStore } from './plugins'; + +/** Setup Vue store plugin pinia */ +export function setupStore(app: App) { + const store = createPinia(); + + store.use(resetSetupStore); + + app.use(store); +} diff --git a/src/store/modules/app/index.ts b/src/store/modules/app/index.ts new file mode 100644 index 0000000..c58cb64 --- /dev/null +++ b/src/store/modules/app/index.ts @@ -0,0 +1,139 @@ +import { effectScope, onScopeDispose, ref, watch } from 'vue'; +import { defineStore } from 'pinia'; +import { breakpointsTailwind, useBreakpoints, useTitle } from '@vueuse/core'; +import { useBoolean } from '@sa/hooks'; +import { SetupStoreId } from '@/enum'; +import { router } from '@/router'; +import { $t, setLocale } from '@/locales'; +import { setDayjsLocale } from '@/locales/dayjs'; +import { localStg } from '@/utils/storage'; +import { useRouteStore } from '../route'; +import { useTabStore } from '../tab'; +import { useThemeStore } from '../theme'; + +export const useAppStore = defineStore(SetupStoreId.App, () => { + const themeStore = useThemeStore(); + const routeStore = useRouteStore(); + const tabStore = useTabStore(); + const scope = effectScope(); + const breakpoints = useBreakpoints(breakpointsTailwind); + const { bool: themeDrawerVisible, setTrue: openThemeDrawer, setFalse: closeThemeDrawer } = useBoolean(); + const { bool: reloadFlag, setBool: setReloadFlag } = useBoolean(true); + const { bool: fullContent, toggle: toggleFullContent } = useBoolean(); + const { bool: contentXScrollable, setBool: setContentXScrollable } = useBoolean(); + const { bool: siderCollapse, setBool: setSiderCollapse, toggle: toggleSiderCollapse } = useBoolean(); + const { bool: mixSiderFixed, setBool: setMixSiderFixed, toggle: toggleMixSiderFixed } = useBoolean(); + + /** Is mobile layout */ + const isMobile = breakpoints.smaller('sm'); + + /** + * Reload page + * + * @param duration Duration time + */ + async function reloadPage(duration = 300) { + setReloadFlag(false); + + if (duration > 0) { + await new Promise(resolve => { + setTimeout(resolve, duration); + }); + } + + setReloadFlag(true); + } + + const locale = ref(localStg.get('lang') || 'zh-CN'); + + const localeOptions: App.I18n.LangOption[] = [ + { + label: '中文', + key: 'zh-CN' + }, + { + label: 'English', + key: 'en-US' + } + ]; + + function changeLocale(lang: App.I18n.LangType) { + locale.value = lang; + setLocale(lang); + localStg.set('lang', lang); + } + + /** Update document title by locale */ + function updateDocumentTitleByLocale() { + const { i18nKey, title } = router.currentRoute.value.meta; + + const documentTitle = i18nKey ? $t(i18nKey) : title; + + useTitle(documentTitle); + } + + function init() { + setDayjsLocale(locale.value); + } + + // watch store + scope.run(() => { + // watch isMobile, if is mobile, collapse sider + watch( + isMobile, + newValue => { + if (newValue) { + setSiderCollapse(true); + + themeStore.setThemeLayout('vertical'); + } + }, + { immediate: true } + ); + + // watch locale + watch(locale, () => { + // update document title by locale + updateDocumentTitleByLocale(); + + // update global menus by locale + routeStore.updateGlobalMenusByLocale(); + + // update tabs by locale + tabStore.updateTabsByLocale(); + + // sey dayjs locale + setDayjsLocale(locale.value); + }); + }); + + /** On scope dispose */ + onScopeDispose(() => { + scope.stop(); + }); + + // init + init(); + + return { + isMobile, + reloadFlag, + reloadPage, + fullContent, + locale, + localeOptions, + changeLocale, + themeDrawerVisible, + openThemeDrawer, + closeThemeDrawer, + toggleFullContent, + contentXScrollable, + setContentXScrollable, + siderCollapse, + setSiderCollapse, + toggleSiderCollapse, + mixSiderFixed, + setMixSiderFixed, + toggleMixSiderFixed + }; +}); diff --git a/src/store/modules/auth/index.ts b/src/store/modules/auth/index.ts new file mode 100644 index 0000000..e9f6b77 --- /dev/null +++ b/src/store/modules/auth/index.ts @@ -0,0 +1,136 @@ +import { computed, reactive, ref } from 'vue'; +import { defineStore } from 'pinia'; +import { useLoading } from '@sa/hooks'; +import { SetupStoreId } from '@/enum'; +import { useRouterPush } from '@/hooks/common/router'; +import { localStg } from '@/utils/storage'; +import { $t } from '@/locales'; +import { useRouteStore } from '../route'; +import { clearAuthStorage, emptyInfo, getToken } from './shared'; + +export const useAuthStore = defineStore(SetupStoreId.Auth, () => { + const routeStore = useRouteStore(); + const { route, toLogin, redirectFromLogin } = useRouterPush(false); + const { loading: loginLoading, startLoading, endLoading } = useLoading(); + + const token = ref(getToken()); + + const userInfo: Api.Auth.UserInfo = reactive(emptyInfo); + const permissions = computed(() => userInfo.permissions); + + watch( + () => token.value, + async value => { + if (value && !userInfo.user && !route.value.path.includes('login')) { + refreshUserInfo(); + } + }, + { + immediate: true + } + ); + + /** is super role in static route */ + const isStaticSuper = computed(() => { + const { VITE_AUTH_ROUTE_MODE, VITE_STATIC_SUPER_ROLE } = import.meta.env; + + return VITE_AUTH_ROUTE_MODE === 'static' && userInfo.roles?.includes(VITE_STATIC_SUPER_ROLE); + }); + + /** Is login */ + const isLogin = computed(() => Boolean(token.value)); + + /** + * Reset auth store + * + * @param isMe [isMe=false] Whether to reset the store by yourself. Default is `false` + */ + async function resetStore(isMe = false) { + if (isMe) { + doDeleteLogout(); + } + + const authStore = useAuthStore(); + authStore.$reset(); + clearAuthStorage(); + + if (!route.value.meta.constant) { + await toLogin(); + } + + routeStore.resetStore(); + } + + /** + * Login + * + * @param username User name + * @param password Password + * @param [redirect=true] Whether to redirect after login. Default is `true` + */ + async function login( + params: { loginForm: Api.Auth.LoginBody; onError?: () => void; onSuccess?: () => void }, + redirect = true + ) { + const { loginForm, onError, onSuccess } = params; + startLoading(); + + const { data: loginToken, error } = await fetchLogin(loginForm); + + if (!error) { + const pass = await loginByToken(loginToken); + onSuccess && onSuccess(); + if (pass) { + await routeStore.initAuthRoute(); + + if (redirect) { + await redirectFromLogin(); + } + + if (routeStore.isInitAuthRoute) { + $notification?.success({ + message: $t('page.login.common.loginSuccess'), + description: $t('page.login.common.welcomeBack', { username: userInfo?.user?.nickName }) + }); + } + } + } else { + onError && onError(); + resetStore(); + } + + endLoading(); + } + + async function loginByToken(loginToken: Api.Auth.LoginToken) { + // 1. stored in the localStorage, the later requests need it in headers + localStg.set('token', loginToken.access_token); + localStg.set('refreshToken', loginToken.refreshToken); + token.value = loginToken.access_token; + + const isSuccess = await refreshUserInfo(); + + return isSuccess; + } + + async function refreshUserInfo() { + const { data: info, error } = await doGetUserInfo(); + if (!error) { + Object.assign(userInfo, info); + return true; + } + return false; + } + + return { + token, + userInfo, + isStaticSuper, + isLogin, + loginLoading, + resetStore, + permissions, + login, + refreshUserInfo + }; +}); diff --git a/src/store/modules/auth/shared.ts b/src/store/modules/auth/shared.ts new file mode 100644 index 0000000..bc0ab24 --- /dev/null +++ b/src/store/modules/auth/shared.ts @@ -0,0 +1,19 @@ +import { localStg } from '@/utils/storage'; + +/** Get token */ +export function getToken() { + return localStg.get('token') || ''; +} + +export const emptyInfo: Api.Auth.UserInfo = { + roles: [], + buttons: [], + permissions: [], + user: null +}; + +/** Clear auth storage */ +export function clearAuthStorage() { + localStg.remove('token'); + localStg.remove('refreshToken'); +} diff --git a/src/store/modules/route/index.ts b/src/store/modules/route/index.ts new file mode 100644 index 0000000..f73e1b9 --- /dev/null +++ b/src/store/modules/route/index.ts @@ -0,0 +1,349 @@ +import { computed, ref, shallowRef } from 'vue'; +import type { RouteRecordRaw } from 'vue-router'; +import { defineStore } from 'pinia'; +import { useBoolean } from '@sa/hooks'; +import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types'; +import { SetupStoreId } from '@/enum'; +import { router } from '@/router'; +import { createStaticRoutes, getAuthVueRoutes } from '@/router/routes'; +import { ROOT_ROUTE } from '@/router/routes/builtin'; +import { getRouteName, getRoutePath } from '@/router/elegant/transform'; +import { useAppStore } from '../app'; +import { useAuthStore } from '../auth'; +import { useTabStore } from '../tab'; +import { + filterAuthRoutesByRoles, + getBreadcrumbsByRoute, + getCacheRouteNames, + getGlobalMenusByAuthRoutes, + getSelectedMenuKeyPathByKey, + isRouteExistByRouteName, + sortRoutesByOrder, + transformMenuToSearchMenus, + updateLocaleOfGlobalMenus +} from './shared'; + +export const useRouteStore = defineStore(SetupStoreId.Route, () => { + const appStore = useAppStore(); + const authStore = useAuthStore(); + const tabStore = useTabStore(); + const { bool: isInitConstantRoute, setBool: setIsInitConstantRoute } = useBoolean(); + const { bool: isInitAuthRoute, setBool: setIsInitAuthRoute } = useBoolean(); + + /** + * Auth route mode + * + * It recommends to use static mode in the development environment, and use dynamic mode in the production + * environment, if use static mode in development environment, the auth routes will be auto generated by plugin + * "@elegant-router/vue" + */ + const authRouteMode = ref(import.meta.env.VITE_AUTH_ROUTE_MODE); + + /** Home route key */ + const routeHome = ref(import.meta.env.VITE_ROUTE_HOME); + + /** + * Set route home + * + * @param routeKey Route key + */ + function setRouteHome(routeKey: LastLevelRouteKey) { + routeHome.value = routeKey; + } + + /** auth routes */ + const authRoutes = shallowRef([]); + + function addAuthRoutes(routes: ElegantConstRoute[]) { + const authRoutesMap = new Map(authRoutes.value.map(route => [route.name, route])); + + routes.forEach(route => { + authRoutesMap.set(route.name, route); + }); + + authRoutes.value = Array.from(authRoutesMap.values()); + } + + const removeRouteFns: (() => void)[] = []; + + /** Global menus */ + const menus = ref([]); + const searchMenus = computed(() => transformMenuToSearchMenus(menus.value)); + + /** Get global menus */ + function getGlobalMenus(routes: ElegantConstRoute[]) { + menus.value = getGlobalMenusByAuthRoutes(routes); + } + + /** Update global menus by locale */ + function updateGlobalMenusByLocale() { + menus.value = updateLocaleOfGlobalMenus(menus.value); + } + + /** Cache routes */ + const cacheRoutes = ref([]); + + /** + * Get cache routes + * + * @param routes Vue routes + */ + function getCacheRoutes(routes: RouteRecordRaw[]) { + cacheRoutes.value = getCacheRouteNames(routes); + } + + /** + * Add cache routes + * + * @param routeKey + */ + function addCacheRoutes(routeKey: RouteKey) { + if (cacheRoutes.value.includes(routeKey)) return; + + cacheRoutes.value.push(routeKey); + } + + /** + * Remove cache routes + * + * @param routeKey + */ + function removeCacheRoutes(routeKey: RouteKey) { + const index = cacheRoutes.value.findIndex(item => item === routeKey); + + if (index === -1) return; + + cacheRoutes.value.splice(index, 1); + } + + /** + * Re cache routes by route key + * + * @param routeKey + */ + async function reCacheRoutesByKey(routeKey: RouteKey) { + removeCacheRoutes(routeKey); + + await appStore.reloadPage(); + + addCacheRoutes(routeKey); + } + + /** + * Re cache routes by route keys + * + * @param routeKeys + */ + async function reCacheRoutesByKeys(routeKeys: RouteKey[]) { + for await (const key of routeKeys) { + await reCacheRoutesByKey(key); + } + } + + /** Global breadcrumbs */ + const breadcrumbs = computed(() => getBreadcrumbsByRoute(router.currentRoute.value, menus.value)); + + /** Reset store */ + async function resetStore() { + const routeStore = useRouteStore(); + + routeStore.$reset(); + + resetVueRoutes(); + + // after reset store, need to re-init constant route + await initConstantRoute(); + } + + /** Reset vue routes */ + function resetVueRoutes() { + removeRouteFns.forEach(fn => fn()); + removeRouteFns.length = 0; + } + + /** init constant route */ + async function initConstantRoute() { + if (isInitConstantRoute.value) return; + + // if (authRouteMode.value === 'static') { + const { constantRoutes } = createStaticRoutes(); + + addAuthRoutes(constantRoutes); + // } else { + // const { data, error } = await fetchGetConstantRoutes(); + + // if (!error) { + // addAuthRoutes(data); + // } + // } + + handleAuthRoutes(); + + setIsInitConstantRoute(true); + } + + /** Init auth route */ + async function initAuthRoute() { + if (authRouteMode.value === 'static') { + await initStaticAuthRoute(); + } else { + await initDynamicAuthRoute(); + } + + tabStore.initHomeTab(); + } + + /** Init static auth route */ + async function initStaticAuthRoute() { + const { authRoutes: staticAuthRoutes } = createStaticRoutes(); + + if (authStore.isStaticSuper) { + addAuthRoutes(staticAuthRoutes); + } else { + const filteredAuthRoutes = filterAuthRoutesByRoles(staticAuthRoutes, authStore.userInfo.roles ?? []); + + addAuthRoutes(filteredAuthRoutes); + } + + handleAuthRoutes(); + + setIsInitAuthRoute(true); + } + + /** Init dynamic auth route */ + async function initDynamicAuthRoute() { + const { data: routes, error } = await doGetUserRoutes(); + + if (!error) { + addAuthRoutes(routes); + + handleAuthRoutes(); + + setRouteHome('manage_role'); + + handleUpdateRootRouteRedirect('manage_role'); + + setIsInitAuthRoute(true); + } else { + await authStore.resetStore(); + } + } + + /** handle auth routes */ + function handleAuthRoutes() { + const sortRoutes = sortRoutesByOrder(authRoutes.value); + + const vueRoutes = getAuthVueRoutes(sortRoutes); + + resetVueRoutes(); + + addRoutesToVueRouter(vueRoutes); + + getGlobalMenus(sortRoutes); + + getCacheRoutes(vueRoutes); + } + + /** + * Add routes to vue router + * + * @param routes Vue routes + */ + function addRoutesToVueRouter(routes: RouteRecordRaw[]) { + routes.forEach(route => { + const removeFn = router.addRoute(route); + addRemoveRouteFn(removeFn); + }); + } + + /** + * Add remove route fn + * + * @param fn + */ + function addRemoveRouteFn(fn: () => void) { + removeRouteFns.push(fn); + } + + /** + * Update root route redirect when auth route mode is dynamic + * + * @param redirectKey Redirect route key + */ + function handleUpdateRootRouteRedirect(redirectKey: LastLevelRouteKey) { + const redirect = getRoutePath(redirectKey); + + if (redirect) { + const rootRoute: CustomRoute = { ...ROOT_ROUTE, redirect }; + + router.removeRoute(rootRoute.name); + + const [rootVueRoute] = getAuthVueRoutes([rootRoute]); + + router.addRoute(rootVueRoute); + } + } + + /** + * Get is auth route exist + * + * @param routePath Route path + */ + async function getIsAuthRouteExist(routePath: RouteMap[RouteKey]) { + const routeName = getRouteName(routePath); + + if (!routeName) { + return false; + } + + if (authRouteMode.value === 'static') { + const { authRoutes: staticAuthRoutes } = createStaticRoutes(); + return isRouteExistByRouteName(routeName, staticAuthRoutes); + } + + const { data } = await fetchIsRouteExist(routeName); + + return data; + } + + /** + * Get selected menu key path + * + * @param selectedKey Selected menu key + */ + function getSelectedMenuKeyPath(selectedKey: string) { + return getSelectedMenuKeyPathByKey(selectedKey, menus.value); + } + + /** + * Get selected menu meta by key + * + * @param selectedKey Selected menu key + */ + function getSelectedMenuMetaByKey(selectedKey: string) { + // The routes in router.options.routes are static, you need to use router.getRoutes() to get all the routes. + const allRoutes = router.getRoutes(); + + return allRoutes.find(route => route.name === selectedKey)?.meta || null; + } + + return { + resetStore, + routeHome, + menus, + searchMenus, + updateGlobalMenusByLocale, + cacheRoutes, + reCacheRoutesByKey, + reCacheRoutesByKeys, + breadcrumbs, + initConstantRoute, + isInitConstantRoute, + initAuthRoute, + isInitAuthRoute, + setIsInitAuthRoute, + getIsAuthRouteExist, + getSelectedMenuKeyPath, + getSelectedMenuMetaByKey + }; +}); diff --git a/src/store/modules/route/shared.ts b/src/store/modules/route/shared.ts new file mode 100644 index 0000000..958d6d3 --- /dev/null +++ b/src/store/modules/route/shared.ts @@ -0,0 +1,304 @@ +import type { RouteLocationNormalizedLoaded, RouteRecordRaw, _RouteRecordBase } from 'vue-router'; +import type { ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types'; +import { $t } from '@/locales'; +import { useSvgIcon } from '@/hooks/common/icon'; + +/** + * Filter auth routes by roles + * + * @param routes Auth routes + * @param roles Roles + */ +export function filterAuthRoutesByRoles(routes: ElegantConstRoute[], roles: string[]) { + return routes.flatMap(route => filterAuthRouteByRoles(route, roles)); +} + +/** + * Filter auth route by roles + * + * @param route Auth route + * @param roles Roles + */ +function filterAuthRouteByRoles(route: ElegantConstRoute, roles: string[]) { + const routeRoles = (route.meta && route.meta.roles) || []; + + // if the route's "roles" is empty, then it is allowed to access + const isEmptyRoles = !routeRoles.length; + + // if the user's role is included in the route's "roles", then it is allowed to access + const hasPermission = routeRoles.some(role => roles.includes(role)); + + const filterRoute = { ...route }; + + if (filterRoute.children?.length) { + filterRoute.children = filterRoute.children.flatMap(item => filterAuthRouteByRoles(item, roles)); + } + + return hasPermission || isEmptyRoles ? [filterRoute] : []; +} + +/** + * sort route by order + * + * @param route route + */ +function sortRouteByOrder(route: ElegantConstRoute) { + if (route.children?.length) { + route.children.sort((next, prev) => (Number(next.meta?.order) || 0) - (Number(prev.meta?.order) || 0)); + route.children.forEach(sortRouteByOrder); + } + + return route; +} + +/** + * sort routes by order + * + * @param routes routes + */ +export function sortRoutesByOrder(routes: ElegantConstRoute[]) { + routes.sort((next, prev) => (Number(next.meta?.order) || 0) - (Number(prev.meta?.order) || 0)); + routes.forEach(sortRouteByOrder); + + return routes; +} + +/** + * Get global menus by auth routes + * + * @param routes Auth routes + */ +export function getGlobalMenusByAuthRoutes(routes: ElegantConstRoute[]) { + const menus: App.Global.Menu[] = []; + + routes.forEach(route => { + if (!route.meta?.hideInMenu) { + const menu = getGlobalMenuByBaseRoute(route); + + if (route.children?.some(child => !child.meta?.hideInMenu)) { + menu.children = getGlobalMenusByAuthRoutes(route.children); + } + + menus.push(menu); + } + }); + + return menus; +} + +/** + * Update locale of global menus + * + * @param menus + */ +export function updateLocaleOfGlobalMenus(menus: App.Global.Menu[]) { + const result: App.Global.Menu[] = []; + + menus.forEach(menu => { + const { i18nKey, label, children } = menu; + + const newLabel = i18nKey ? $t(i18nKey) : label; + + const newMenu: App.Global.Menu = { + ...menu, + label: newLabel, + title: newLabel + }; + + if (children?.length) { + newMenu.children = updateLocaleOfGlobalMenus(children); + } + + result.push(newMenu); + }); + + return result; +} + +/** + * Get global menu by route + * + * @param route + */ +function getGlobalMenuByBaseRoute(route: RouteLocationNormalizedLoaded | ElegantConstRoute) { + const { SvgIconVNode } = useSvgIcon(); + + const { name, path } = route; + const { title, i18nKey, icon = import.meta.env.VITE_MENU_ICON, localIcon } = route.meta ?? {}; + + const label = i18nKey ? $t(i18nKey) : title!; + + const menu: App.Global.Menu = { + key: name as string, + label, + i18nKey, + routeKey: name as RouteKey, + routePath: path as RouteMap[RouteKey], + icon: SvgIconVNode({ icon, localIcon, fontSize: 20 }), + title: label + }; + + return menu; +} + +/** + * Get cache route names + * + * @param routes Vue routes (two levels) + */ +export function getCacheRouteNames(routes: RouteRecordRaw[]) { + const cacheNames: LastLevelRouteKey[] = []; + + routes.forEach(route => { + // only get last two level route, which has component + route.children?.forEach(child => { + if (child.component && child.meta?.keepAlive) { + cacheNames.push(child.name as LastLevelRouteKey); + } + }); + }); + + return cacheNames; +} + +/** + * Is route exist by route name + * + * @param routeName + * @param routes + */ +export function isRouteExistByRouteName(routeName: RouteKey, routes: ElegantConstRoute[]) { + return routes.some(route => recursiveGetIsRouteExistByRouteName(route, routeName)); +} + +/** + * Recursive get is route exist by route name + * + * @param route + * @param routeName + */ +function recursiveGetIsRouteExistByRouteName(route: ElegantConstRoute, routeName: RouteKey) { + let isExist = route.name === routeName; + + if (isExist) { + return true; + } + + if (route.children && route.children.length) { + isExist = route.children.some(item => recursiveGetIsRouteExistByRouteName(item, routeName)); + } + + return isExist; +} + +/** + * Get selected menu key path + * + * @param selectedKey + * @param menus + */ +export function getSelectedMenuKeyPathByKey(selectedKey: string, menus: App.Global.Menu[]) { + const keyPath: string[] = []; + + menus.some(menu => { + const path = findMenuPath(selectedKey, menu); + + const find = Boolean(path?.length); + + if (find) { + keyPath.push(...path!); + } + + return find; + }); + + return keyPath; +} + +/** + * Find menu path + * + * @param targetKey Target menu key + * @param menu Menu + */ +function findMenuPath(targetKey: string, menu: App.Global.Menu): string[] | null { + const path: string[] = []; + + function dfs(item: App.Global.Menu): boolean { + path.push(item.key); + + if (item.key === targetKey) { + return true; + } + + if (item.children) { + for (const child of item.children) { + if (dfs(child)) { + return true; + } + } + } + + path.pop(); + + return false; + } + + if (dfs(menu)) { + return path; + } + + return null; +} + +/** + * Get breadcrumbs by route + * + * @param route + * @param menus + */ +export function getBreadcrumbsByRoute( + route: RouteLocationNormalizedLoaded, + menus: App.Global.Menu[] +): App.Global.Menu[] { + const key = route.name as string; + const activeKey = route.meta?.activeMenu; + + const menuKey = activeKey || key; + + for (const menu of menus) { + if (menu.key === menuKey) { + const breadcrumb = menuKey !== activeKey ? menu : getGlobalMenuByBaseRoute(route); + + return [breadcrumb]; + } + + if (menu.children?.length) { + const result = getBreadcrumbsByRoute(route, menu.children); + if (result.length > 0) { + return [menu, ...result]; + } + } + } + + return []; +} + +/** + * Transform menu to searchMenus + * + * @param menus - menus + * @param treeMap + */ +export function transformMenuToSearchMenus(menus: App.Global.Menu[], treeMap: App.Global.Menu[] = []) { + if (menus && menus.length === 0) return []; + return menus.reduce((acc, cur) => { + if (!cur.children) { + acc.push(cur); + } + if (cur.children && cur.children.length > 0) { + transformMenuToSearchMenus(cur.children, treeMap); + } + return acc; + }, treeMap); +} diff --git a/src/store/modules/tab/index.ts b/src/store/modules/tab/index.ts new file mode 100644 index 0000000..7e7d71e --- /dev/null +++ b/src/store/modules/tab/index.ts @@ -0,0 +1,298 @@ +import { computed, ref } from 'vue'; +import { useRouter } from 'vue-router'; +import { defineStore } from 'pinia'; +import { useEventListener } from '@vueuse/core'; +import type { RouteKey } from '@elegant-router/types'; +import { SetupStoreId } from '@/enum'; +import { useRouterPush } from '@/hooks/common/router'; +import { localStg } from '@/utils/storage'; +import { useRouteStore } from '@/store/modules/route'; +import { useThemeStore } from '../theme'; +import { + extractTabsByAllRoutes, + filterTabsById, + filterTabsByIds, + findTabByRouteName, + getAllTabs, + getDefaultHomeTab, + getFixedTabIds, + getTabByRoute, + isTabInTabs, + updateTabByI18nKey, + updateTabsByI18nKey +} from './shared'; + +export const useTabStore = defineStore(SetupStoreId.Tab, () => { + const router = useRouter(); + const routeStore = useRouteStore(); + const themeStore = useThemeStore(); + const { routerPush } = useRouterPush(false); + + /** Tabs */ + const tabs = ref([]); + + /** Get active tab */ + const homeTab = ref(); + + /** + * Init home tab + * + * @param router Router instance + */ + function initHomeTab() { + homeTab.value = getDefaultHomeTab(router, routeStore.routeHome); + } + + /** Get all tabs */ + const allTabs = computed(() => getAllTabs(tabs.value, homeTab.value)); + + /** Active tab id */ + const activeTabId = ref(''); + + /** + * Set active tab id + * + * @param id Tab id + */ + function setActiveTabId(id: string) { + activeTabId.value = id; + } + + /** + * Init tab store + * + * @param currentRoute Current route + */ + function initTabStore(currentRoute: App.Global.TabRoute) { + const storageTabs = localStg.get('globalTabs'); + + if (themeStore.tab.cache && storageTabs) { + const filteredTabs = extractTabsByAllRoutes(router, storageTabs); + tabs.value = updateTabsByI18nKey(filteredTabs); + } + + addTab(currentRoute); + } + + /** + * Add tab + * + * @param route Tab route + * @param active Whether to activate the added tab + */ + function addTab(route: App.Global.TabRoute, active = true) { + const tab = getTabByRoute(route); + + const isHomeTab = tab.id === homeTab.value?.id; + + if (!isHomeTab && !isTabInTabs(tab.id, tabs.value)) { + tabs.value.push(tab); + } + + if (active) { + setActiveTabId(tab.id); + } + } + + /** + * Remove tab + * + * @param tabId Tab id + */ + async function removeTab(tabId: string) { + const isRemoveActiveTab = activeTabId.value === tabId; + const updatedTabs = filterTabsById(tabId, tabs.value); + + function update() { + tabs.value = updatedTabs; + } + + if (!isRemoveActiveTab) { + update(); + return; + } + + const activeTab = updatedTabs.at(-1) || homeTab.value; + + if (activeTab) { + await switchRouteByTab(activeTab); + update(); + } + } + + /** remove active tab */ + async function removeActiveTab() { + await removeTab(activeTabId.value); + } + + /** + * remove tab by route name + * + * @param routeName route name + */ + async function removeTabByRouteName(routeName: RouteKey) { + const tab = findTabByRouteName(routeName, tabs.value); + if (!tab) return; + + await removeTab(tab.id); + } + + /** + * Clear tabs + * + * @param excludes Exclude tab ids + */ + async function clearTabs(excludes: string[] = []) { + const remainTabIds = [...getFixedTabIds(tabs.value), ...excludes]; + const removedTabsIds = tabs.value.map(tab => tab.id).filter(id => !remainTabIds.includes(id)); + + const isRemoveActiveTab = removedTabsIds.includes(activeTabId.value); + const updatedTabs = filterTabsByIds(removedTabsIds, tabs.value); + + function update() { + tabs.value = updatedTabs; + } + + if (!isRemoveActiveTab) { + update(); + return; + } + + const activeTab = updatedTabs[updatedTabs.length - 1] || homeTab.value; + + await switchRouteByTab(activeTab); + update(); + } + + /** + * Switch route by tab + * + * @param tab + */ + async function switchRouteByTab(tab: App.Global.Tab) { + const fail = await routerPush(tab.fullPath); + if (!fail) { + setActiveTabId(tab.id); + } + } + + /** + * Clear left tabs + * + * @param tabId + */ + async function clearLeftTabs(tabId: string) { + const tabIds = tabs.value.map(tab => tab.id); + const index = tabIds.indexOf(tabId); + if (index === -1) return; + + const excludes = tabIds.slice(index); + await clearTabs(excludes); + } + + /** + * Clear right tabs + * + * @param tabId + */ + async function clearRightTabs(tabId: string) { + const isHomeTab = tabId === homeTab.value?.id; + if (isHomeTab) { + clearTabs(); + return; + } + + const tabIds = tabs.value.map(tab => tab.id); + const index = tabIds.indexOf(tabId); + if (index === -1) return; + + const excludes = tabIds.slice(0, index + 1); + await clearTabs(excludes); + } + + /** + * Set new label of tab + * + * @default activeTabId + * @param label New tab label + * @param tabId Tab id + */ + function setTabLabel(label: string, tabId?: string) { + const id = tabId || activeTabId.value; + + const tab = tabs.value.find(item => item.id === id); + if (!tab) return; + + tab.oldLabel = tab.label; + tab.newLabel = label; + } + + /** + * Reset tab label + * + * @default activeTabId + * @param tabId Tab id + */ + function resetTabLabel(tabId?: string) { + const id = tabId || activeTabId.value; + + const tab = tabs.value.find(item => item.id === id); + if (!tab) return; + + tab.newLabel = undefined; + } + + /** + * Is tab retain + * + * @param tabId + */ + function isTabRetain(tabId: string) { + if (tabId === homeTab.value?.id) return true; + + const fixedTabIds = getFixedTabIds(tabs.value); + + return fixedTabIds.includes(tabId); + } + + /** Update tabs by locale */ + function updateTabsByLocale() { + tabs.value = updateTabsByI18nKey(tabs.value); + + if (homeTab.value) { + homeTab.value = updateTabByI18nKey(homeTab.value); + } + } + + /** Cache tabs */ + function cacheTabs() { + if (!themeStore.tab.cache) return; + + localStg.set('globalTabs', tabs.value); + } + + // cache tabs when page is closed or refreshed + useEventListener(window, 'beforeunload', () => { + cacheTabs(); + }); + + return { + /** All tabs */ + tabs: allTabs, + activeTabId, + initHomeTab, + initTabStore, + addTab, + removeTab, + removeActiveTab, + removeTabByRouteName, + clearTabs, + clearLeftTabs, + clearRightTabs, + switchRouteByTab, + setTabLabel, + resetTabLabel, + isTabRetain, + updateTabsByLocale + }; +}); diff --git a/src/store/modules/tab/shared.ts b/src/store/modules/tab/shared.ts new file mode 100644 index 0000000..a8dc775 --- /dev/null +++ b/src/store/modules/tab/shared.ts @@ -0,0 +1,243 @@ +import type { Router } from 'vue-router'; +import type { LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types'; +import { $t } from '@/locales'; +import { getRoutePath } from '@/router/elegant/transform'; + +/** + * Get all tabs + * + * @param tabs Tabs + * @param homeTab Home tab + */ +export function getAllTabs(tabs: App.Global.Tab[], homeTab?: App.Global.Tab) { + if (!homeTab) { + return []; + } + + const filterHomeTabs = tabs.filter(tab => tab.id !== homeTab.id); + + const fixedTabs = filterHomeTabs + .filter(tab => tab.fixedIndex !== undefined) + .sort((a, b) => a.fixedIndex! - b.fixedIndex!); + + const remainTabs = filterHomeTabs.filter(tab => tab.fixedIndex === undefined); + + const allTabs = [homeTab, ...fixedTabs, ...remainTabs]; + + return updateTabsLabel(allTabs); +} + +/** + * Get tab id by route + * + * @param route + */ +export function getTabIdByRoute(route: App.Global.TabRoute) { + const { path, query = {}, meta } = route; + + let id = path; + + if (meta.multiTab) { + const queryKeys = Object.keys(query).sort(); + const qs = queryKeys.map(key => `${key}=${query[key]}`).join('&'); + + id = `${path}?${qs}`; + } + + return id; +} + +/** + * Get tab by route + * + * @param route + */ +export function getTabByRoute(route: App.Global.TabRoute) { + const { name, path, fullPath = path, meta } = route; + const { title, i18nKey, fixedIndexInTab } = meta; + + // Get icon and localIcon from getRouteIcons function + const { icon, localIcon } = getRouteIcons(route); + + const label = i18nKey ? $t(i18nKey) : title; + + const tab: App.Global.Tab = { + id: getTabIdByRoute(route), + label, + routeKey: name as LastLevelRouteKey, + routePath: path as RouteMap[LastLevelRouteKey], + fullPath, + fixedIndex: fixedIndexInTab, + icon, + localIcon, + i18nKey + }; + + return tab; +} + +/** + * The vue router will automatically merge the meta of all matched items, and the icons here may be affected by other + * matching items, so they need to be processed separately + * + * @param route + */ +export function getRouteIcons(route: App.Global.TabRoute) { + // Set default value for icon at the beginning + let icon: string = route?.meta?.icon || import.meta.env.VITE_MENU_ICON; + let localIcon: string | undefined = route?.meta?.localIcon; + + // Route.matched only appears when there are multiple matches,so check if route.matched exists + if (route.matched) { + // Find the meta of the current route from matched + const currentRoute = route.matched.find(r => r.name === route.name); + // If icon exists in currentRoute.meta, it will overwrite the default value + icon = currentRoute?.meta?.icon || icon; + localIcon = currentRoute?.meta?.localIcon; + } + + return { icon, localIcon }; +} + +/** + * Get default home tab + * + * @param router + * @param homeRouteName routeHome in useRouteStore + */ +export function getDefaultHomeTab(router: Router, homeRouteName: LastLevelRouteKey) { + const homeRoutePath = getRoutePath(homeRouteName); + const i18nLabel = $t(`route.${homeRouteName}`); + + let homeTab: App.Global.Tab = { + id: getRoutePath(homeRouteName), + label: i18nLabel || homeRouteName, + routeKey: homeRouteName, + routePath: homeRoutePath, + fullPath: homeRoutePath + }; + + const routes = router.getRoutes(); + const homeRoute = routes.find(route => route.name === homeRouteName); + if (homeRoute) { + homeTab = getTabByRoute(homeRoute); + } + + return homeTab; +} + +/** + * Is tab in tabs + * + * @param tab + * @param tabs + */ +export function isTabInTabs(tabId: string, tabs: App.Global.Tab[]) { + return tabs.some(tab => tab.id === tabId); +} + +/** + * Filter tabs by id + * + * @param tabId + * @param tabs + */ +export function filterTabsById(tabId: string, tabs: App.Global.Tab[]) { + return tabs.filter(tab => tab.id !== tabId); +} + +/** + * Filter tabs by ids + * + * @param tabIds + * @param tabs + */ +export function filterTabsByIds(tabIds: string[], tabs: App.Global.Tab[]) { + return tabs.filter(tab => !tabIds.includes(tab.id)); +} + +/** + * extract tabs by all routes + * + * @param router + * @param tabs + */ +export function extractTabsByAllRoutes(router: Router, tabs: App.Global.Tab[]) { + const routes = router.getRoutes(); + + const routeNames = routes.map(route => route.name); + + return tabs.filter(tab => routeNames.includes(tab.routeKey)); +} + +/** + * Get fixed tabs + * + * @param tabs + */ +export function getFixedTabs(tabs: App.Global.Tab[]) { + return tabs.filter(tab => tab.fixedIndex !== undefined); +} + +/** + * Get fixed tab ids + * + * @param tabs + */ +export function getFixedTabIds(tabs: App.Global.Tab[]) { + const fixedTabs = getFixedTabs(tabs); + + return fixedTabs.map(tab => tab.id); +} + +/** + * Update tabs label + * + * @param tabs + */ +function updateTabsLabel(tabs: App.Global.Tab[]) { + const updated = tabs.map(tab => ({ + ...tab, + label: tab.newLabel || tab.oldLabel || tab.label + })); + + return updated; +} + +/** + * Update tab by i18n key + * + * @param tab + */ +export function updateTabByI18nKey(tab: App.Global.Tab) { + const { i18nKey, label } = tab; + + return { + ...tab, + label: i18nKey ? $t(i18nKey) : label + }; +} + +/** + * Update tabs by i18n key + * + * @param tabs + */ +export function updateTabsByI18nKey(tabs: App.Global.Tab[]) { + return tabs.map(tab => updateTabByI18nKey(tab)); +} + +/** + * find tab by route name + * + * @param name + * @param tabs + */ +export function findTabByRouteName(name: RouteKey, tabs: App.Global.Tab[]) { + const routePath = getRoutePath(name); + + const tabId = routePath; + const multiTabId = `${routePath}?`; + + return tabs.find(tab => tab.id === tabId || tab.id.startsWith(multiTabId)); +} diff --git a/src/store/modules/theme/index.ts b/src/store/modules/theme/index.ts new file mode 100644 index 0000000..7e390ae --- /dev/null +++ b/src/store/modules/theme/index.ts @@ -0,0 +1,158 @@ +import { computed, effectScope, onScopeDispose, ref, toRefs, watch } from 'vue'; +import type { Ref } from 'vue'; +import { defineStore } from 'pinia'; +import { useEventListener, usePreferredColorScheme } from '@vueuse/core'; +import { SetupStoreId } from '@/enum'; +import { localStg } from '@/utils/storage'; +import { addThemeVarsToHtml, createThemeToken, getAntdTheme, initThemeSettings, toggleCssDarkMode } from './shared'; + +/** Theme store */ +export const useThemeStore = defineStore(SetupStoreId.Theme, () => { + const scope = effectScope(); + const osTheme = usePreferredColorScheme(); + + /** Theme settings */ + const settings: Ref = ref(initThemeSettings()); + + /** Reset store */ + function resetStore() { + const themeStore = useThemeStore(); + + themeStore.$reset(); + } + + /** Theme colors */ + const themeColors = computed(() => { + const { themeColor, otherColor, isInfoFollowPrimary } = settings.value; + const colors: App.Theme.ThemeColor = { + primary: themeColor, + ...otherColor, + info: isInfoFollowPrimary ? themeColor : otherColor.info + }; + return colors; + }); + + /** Dark mode */ + const darkMode = computed(() => { + if (settings.value.themeScheme === 'auto') { + return osTheme.value === 'dark'; + } + return settings.value.themeScheme === 'dark'; + }); + + /** Antd theme */ + const antdTheme = computed(() => getAntdTheme(themeColors.value, darkMode.value)); + + /** + * Settings json + * + * It is for copy settings + */ + const settingsJson = computed(() => JSON.stringify(settings.value)); + + /** + * Set theme scheme + * + * @param themeScheme + */ + function setThemeScheme(themeScheme: UnionKey.ThemeScheme) { + settings.value.themeScheme = themeScheme; + } + + /** Toggle theme scheme */ + function toggleThemeScheme() { + const themeSchemes: UnionKey.ThemeScheme[] = ['light', 'dark', 'auto']; + + const index = themeSchemes.findIndex(item => item === settings.value.themeScheme); + + const nextIndex = index === themeSchemes.length - 1 ? 0 : index + 1; + + const nextThemeScheme = themeSchemes[nextIndex]; + + setThemeScheme(nextThemeScheme); + } + + /** + * Set theme layout + * + * @param mode Theme layout mode + */ + function setThemeLayout(mode: UnionKey.ThemeLayoutMode) { + settings.value.layout.mode = mode; + } + + /** + * Update theme colors + * + * @param key Theme color key + * @param color Theme color + */ + function updateThemeColors(key: App.Theme.ThemeColorKey, color: string) { + if (key === 'primary') { + settings.value.themeColor = color; + } else { + settings.value.otherColor[key] = color; + } + } + + /** Setup theme vars to html */ + function setupThemeVarsToHtml() { + const { themeTokens, darkThemeTokens } = createThemeToken(themeColors.value); + addThemeVarsToHtml(themeTokens, darkThemeTokens); + } + + /** Cache theme settings */ + function cacheThemeSettings() { + const isProd = import.meta.env.PROD; + + if (!isProd) return; + + localStg.set('themeSettings', settings.value); + } + + // cache theme settings when page is closed or refreshed + useEventListener(window, 'beforeunload', () => { + cacheThemeSettings(); + }); + + // watch store + scope.run(() => { + // watch dark mode + watch( + darkMode, + val => { + toggleCssDarkMode(val); + }, + { immediate: true } + ); + + // themeColors change, update css vars and storage theme color + watch( + themeColors, + val => { + setupThemeVarsToHtml(); + + localStg.set('themeColor', val.primary); + }, + { immediate: true } + ); + }); + + /** On scope dispose */ + onScopeDispose(() => { + scope.stop(); + }); + + return { + ...toRefs(settings.value), + resetStore, + settingsJson, + darkMode, + themeColors, + antdTheme, + toggleThemeScheme, + setThemeScheme, + updateThemeColors, + setThemeLayout + }; +}); diff --git a/src/store/modules/theme/shared.ts b/src/store/modules/theme/shared.ts new file mode 100644 index 0000000..8f086fa --- /dev/null +++ b/src/store/modules/theme/shared.ts @@ -0,0 +1,217 @@ +import { theme as antdTheme } from 'ant-design-vue'; +import type { ConfigProviderProps } from 'ant-design-vue'; +import { getColorPalette } from '@sa/color-palette'; +import { getRgbOfColor } from '@sa/utils'; +import { overrideThemeSettings, themeSettings } from '@/theme/settings'; +import { themeVars } from '@/theme/vars'; +import { localStg } from '@/utils/storage'; + +const DARK_CLASS = 'dark'; + +/** Init theme settings */ +export function initThemeSettings() { + const isProd = import.meta.env.PROD; + + // if it is development mode, the theme settings will not be cached, by update `themeSettings` in `src/theme/settings.ts` to update theme settings + if (!isProd) return themeSettings; + + // if it is production mode, the theme settings will be cached in localStorage + // if want to update theme settings when publish new version, please update `overrideThemeSettings` in `src/theme/settings.ts` + + const settings = localStg.get('themeSettings') || themeSettings; + + const isOverride = localStg.get('overrideThemeFlag') === BUILD_TIME; + + if (!isOverride) { + Object.assign(settings, overrideThemeSettings); + localStg.set('overrideThemeFlag', BUILD_TIME); + } + + return settings; +} + +/** + * Create theme token + * + * @param colors Theme colors + */ +export function createThemeToken(colors: App.Theme.ThemeColor) { + const paletteColors = createThemePaletteColors(colors); + + const themeTokens: App.Theme.ThemeToken = { + colors: { + ...paletteColors, + nprogress: paletteColors.primary, + container: 'rgb(255, 255, 255)', + layout: 'rgb(247, 250, 252)', + inverted: 'rgb(0, 20, 40)', + base_text: 'rgb(31, 31, 31)' + }, + boxShadow: { + header: '0 1px 2px rgb(0, 21, 41, 0.08)', + sider: '2px 0 8px 0 rgb(29, 35, 41, 0.05)', + tab: '0 1px 2px rgb(0, 21, 41, 0.08)' + } + }; + + const darkThemeTokens: App.Theme.ThemeToken = { + colors: { + ...themeTokens.colors, + container: 'rgb(28, 28, 28)', + layout: 'rgb(18, 18, 18)', + base_text: 'rgb(224, 224, 224)' + }, + boxShadow: { + ...themeTokens.boxShadow + } + }; + + return { + themeTokens, + darkThemeTokens + }; +} + +/** + * Create theme palette colors + * + * @param colors Theme colors + */ +function createThemePaletteColors(colors: App.Theme.ThemeColor) { + const colorKeys = Object.keys(colors) as App.Theme.ThemeColorKey[]; + const colorPaletteVar = {} as App.Theme.ThemePaletteColor; + + colorKeys.forEach(key => { + const { palettes, main } = getColorPalette(colors[key], key); + + colorPaletteVar[key] = main.hexcode; + + palettes.forEach(item => { + colorPaletteVar[`${key}-${item.number}`] = item.hexcode; + }); + }); + + return colorPaletteVar; +} + +/** + * Get css var by tokens + * + * @param tokens Theme base tokens + */ +function getCssVarByTokens(tokens: App.Theme.BaseToken) { + const styles: string[] = []; + + function removeVarPrefix(value: string) { + return value.replace('var(', '').replace(')', ''); + } + + function removeRgbPrefix(value: string) { + return value.replace('rgb(', '').replace(')', ''); + } + + for (const [key, tokenValues] of Object.entries(themeVars)) { + for (const [tokenKey, tokenValue] of Object.entries(tokenValues)) { + let cssVarsKey = removeVarPrefix(tokenValue); + let cssValue = tokens[key][tokenKey]; + + if (key === 'colors') { + cssVarsKey = removeRgbPrefix(cssVarsKey); + const { r, g, b } = getRgbOfColor(cssValue); + cssValue = `${r} ${g} ${b}`; + } + + styles.push(`${cssVarsKey}: ${cssValue}`); + } + } + + const styleStr = styles.join(';'); + + return styleStr; +} + +/** + * Add theme vars to html + * + * @param tokens + */ +export function addThemeVarsToHtml(tokens: App.Theme.BaseToken, darkTokens: App.Theme.BaseToken) { + const cssVarStr = getCssVarByTokens(tokens); + const darkCssVarStr = getCssVarByTokens(darkTokens); + + const css = ` + html { + ${cssVarStr} + } + `; + + const darkCss = ` + html.${DARK_CLASS} { + ${darkCssVarStr} + } + `; + + const styleId = 'theme-vars'; + + const style = document.querySelector(`#${styleId}`) || document.createElement('style'); + + style.id = styleId; + + style.textContent = css + darkCss; + + document.head.appendChild(style); +} + +/** + * Toggle css dark mode + * + * @param darkMode Is dark mode + */ +export function toggleCssDarkMode(darkMode = false) { + function addDarkClass() { + document.documentElement.classList.add(DARK_CLASS); + } + + function removeDarkClass() { + document.documentElement.classList.remove(DARK_CLASS); + } + + if (darkMode) { + addDarkClass(); + } else { + removeDarkClass(); + } +} + +/** + * Get antd theme + * + * @param colors Theme colors + * @param darkMode Is dark mode + */ +export function getAntdTheme(colors: App.Theme.ThemeColor, darkMode: boolean) { + const { defaultAlgorithm, darkAlgorithm } = antdTheme; + + const { primary, info, success, warning, error } = colors; + + const theme: ConfigProviderProps['theme'] = { + token: { + colorPrimary: primary, + colorInfo: info, + colorSuccess: success, + colorWarning: warning, + colorError: error + }, + algorithm: [darkMode ? darkAlgorithm : defaultAlgorithm], + components: { + Button: { + controlHeightSM: 28 + }, + Menu: { + colorSubItemBg: 'transparent' + } + } + }; + + return theme; +} diff --git a/src/store/plugins/index.ts b/src/store/plugins/index.ts new file mode 100644 index 0000000..8b9566b --- /dev/null +++ b/src/store/plugins/index.ts @@ -0,0 +1,22 @@ +import type { PiniaPluginContext } from 'pinia'; +import { cloneDeep } from 'lodash-es'; +import { SetupStoreId } from '@/enum'; + +/** + * The plugin reset the state of the store which is written by setup syntax + * + * @param context + */ +export function resetSetupStore(context: PiniaPluginContext) { + const setupSyntaxIds = Object.values(SetupStoreId) as string[]; + + if (setupSyntaxIds.includes(context.store.$id)) { + const { $state } = context.store; + + const defaultStore = cloneDeep($state); + + context.store.$reset = () => { + context.store.$patch(defaultStore); + }; + } +} diff --git a/src/styles/css/global.css b/src/styles/css/global.css new file mode 100644 index 0000000..3121a31 --- /dev/null +++ b/src/styles/css/global.css @@ -0,0 +1,13 @@ +@import './reset.css'; +@import './nprogress.css'; +@import './transition.css'; + +html, +body, +#app { + height: 100%; +} + +html { + overflow-x: hidden; +} diff --git a/src/styles/css/nprogress.css b/src/styles/css/nprogress.css new file mode 100644 index 0000000..3e631b5 --- /dev/null +++ b/src/styles/css/nprogress.css @@ -0,0 +1,83 @@ +/* Make clicks pass-through */ +#nprogress { + pointer-events: none; +} + +#nprogress .bar { + background: rgb(var(--nprogress-color)); + + position: fixed; + z-index: 1031; + top: 0; + left: 0; + + width: 100%; + height: 2px; +} + +/* Fancy blur effect */ +#nprogress .peg { + display: block; + position: absolute; + right: 0px; + width: 100px; + height: 100%; + box-shadow: + 0 0 10px rgb(var(--nprogress-color)), + 0 0 5px rgb(var(--nprogress-color)); + opacity: 1; + + -webkit-transform: rotate(3deg) translate(0px, -4px); + -ms-transform: rotate(3deg) translate(0px, -4px); + transform: rotate(3deg) translate(0px, -4px); +} + +/* Remove these to get rid of the spinner */ +#nprogress .spinner { + display: block; + position: fixed; + z-index: 1031; + top: 15px; + right: 15px; +} + +#nprogress .spinner-icon { + width: 18px; + height: 18px; + box-sizing: border-box; + + border: solid 2px transparent; + border-top-color: rgb(var(--nprogress-color)); + border-left-color: rgb(var(--nprogress-color)); + border-radius: 50%; + + -webkit-animation: nprogress-spinner 400ms linear infinite; + animation: nprogress-spinner 400ms linear infinite; +} + +.nprogress-custom-parent { + overflow: hidden; + position: relative; +} + +.nprogress-custom-parent #nprogress .spinner, +.nprogress-custom-parent #nprogress .bar { + position: absolute; +} + +@-webkit-keyframes nprogress-spinner { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + } +} +@keyframes nprogress-spinner { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} diff --git a/src/styles/css/reset.css b/src/styles/css/reset.css new file mode 100644 index 0000000..4219e17 --- /dev/null +++ b/src/styles/css/reset.css @@ -0,0 +1,374 @@ +/* +1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4) +2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116) +2. [UnoCSS]: allow to override the default border color with css var `--un-default-border-color` +*/ + +*, +::before, +::after { + box-sizing: border-box; /* 1 */ + border-width: 0; /* 2 */ + border-style: solid; /* 2 */ + border-color: var(--un-default-border-color, #e5e7eb); /* 2 */ +} + +/* +1. Use a consistent sensible line-height in all browsers. +2. Prevent adjustments of font size after orientation changes in iOS. +3. Use a more readable tab size. +4. Use the user's configured `sans` font-family by default. +*/ + +html { + line-height: 1.5; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ + -moz-tab-size: 4; /* 3 */ + tab-size: 4; /* 3 */ + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + 'Helvetica Neue', + Arial, + 'Noto Sans', + sans-serif, + 'Apple Color Emoji', + 'Segoe UI Emoji', + 'Segoe UI Symbol', + 'Noto Color Emoji'; /* 4 */ +} + +/* +1. Remove the margin in all browsers. +2. Inherit line-height from `html` so users can set them as a class directly on the `html` element. +*/ + +body { + margin: 0; /* 1 */ + line-height: inherit; /* 2 */ +} + +/* +1. Add the correct height in Firefox. +2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655) +3. Ensure horizontal rules are visible by default. +*/ + +hr { + height: 0; /* 1 */ + color: inherit; /* 2 */ + border-top-width: 1px; /* 3 */ +} + +/* +Add the correct text decoration in Chrome, Edge, and Safari. +*/ + +abbr:where([title]) { + text-decoration: underline dotted; +} + +/* +Remove the default font size and weight for headings. +*/ + +h1, +h2, +h3, +h4, +h5, +h6 { + font-size: inherit; + font-weight: inherit; +} + +/* +Reset links to optimize for opt-in styling instead of opt-out. +*/ + +a { + color: inherit; + text-decoration: inherit; +} + +/* +Add the correct font weight in Edge and Safari. +*/ + +b, +strong { + font-weight: bolder; +} + +/* +1. Use the user's configured `mono` font family by default. +2. Correct the odd `em` font sizing in all browsers. +*/ + +code, +kbd, +samp, +pre { + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* +Add the correct font size in all browsers. +*/ + +small { + font-size: 80%; +} + +/* +Prevent `sub` and `sup` elements from affecting the line height in all browsers. +*/ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* +1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) +2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) +3. Remove gaps between table borders by default. +*/ + +table { + text-indent: 0; /* 1 */ + border-color: inherit; /* 2 */ + border-collapse: collapse; /* 3 */ +} + +/* +1. Change the font styles in all browsers. +2. Remove the margin in Firefox and Safari. +3. Remove default padding in all browsers. +*/ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-feature-settings: inherit; /* 1 */ + font-variation-settings: inherit; /* 1 */ + font-size: 100%; /* 1 */ + font-weight: inherit; /* 1 */ + line-height: inherit; /* 1 */ + color: inherit; /* 1 */ + margin: 0; /* 2 */ + padding: 0; /* 3 */ +} + +/* +Remove the inheritance of text transform in Edge and Firefox. +*/ + +button, +select { + text-transform: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Remove default button styles. +*/ + +button, +[type='button'], +[type='reset'], +[type='submit'] { + /* background-color: transparent; */ + background-image: none; /* 2 */ +} + +/* +Use the modern Firefox focus style for all focusable elements. +*/ + +:-moz-focusring { + outline: auto; +} + +/* +Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737) +*/ + +:-moz-ui-invalid { + box-shadow: none; +} + +/* +Add the correct vertical alignment in Chrome and Firefox. +*/ + +progress { + vertical-align: baseline; +} + +/* +Correct the cursor style of increment and decrement buttons in Safari. +*/ + +::-webkit-inner-spin-button, +::-webkit-outer-spin-button { + height: auto; +} + +/* +1. Correct the odd appearance in Chrome and Safari. +2. Correct the outline style in Safari. +*/ + +[type='search'] { + outline-offset: -2px; /* 2 */ +} + +/* +Remove the inner padding in Chrome and Safari on macOS. +*/ + +::-webkit-search-decoration { + -webkit-appearance: none; +} + +/* +1. Correct the inability to style clickable types in iOS and Safari. +2. Change font properties to `inherit` in Safari. +*/ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* +Add the correct display in Chrome and Safari. +*/ + +summary { + display: list-item; +} + +/* +Removes the default spacing and border for appropriate elements. +*/ + +blockquote, +dl, +dd, +h1, +h2, +h3, +h4, +h5, +h6, +hr, +figure, +p, +pre { + margin: 0; +} + +fieldset { + margin: 0; + padding: 0; +} + +legend { + padding: 0; +} + +ol, +ul, +menu { + list-style: none; + margin: 0; + padding: 0; +} + +/* +Prevent resizing textareas horizontally by default. +*/ + +textarea { + resize: vertical; +} + +/* +1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300) +2. Set the default placeholder color to the user's configured gray 400 color. +*/ + +input::placeholder, +textarea::placeholder { + opacity: 1; /* 1 */ + color: #9ca3af; /* 2 */ +} + +/* +Set the default cursor for buttons. +*/ + +button, +[role='button'] { + cursor: pointer; +} + +/* +Make sure disabled buttons don't get the pointer cursor. +*/ +:disabled { + cursor: default; +} + +/* +1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14) +2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210) + This can trigger a poorly considered lint error in some tools but is included by design. +*/ + +img, +svg, +video, +canvas, +audio, +iframe, +embed, +object { + display: block; /* 1 */ +} + +/* +Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14) +*/ + +img, +video { + max-width: 100%; + height: auto; +} + +/* Make elements with the HTML hidden attribute stay hidden by default */ +[hidden] { + display: none; +} diff --git a/src/styles/css/transition.css b/src/styles/css/transition.css new file mode 100644 index 0000000..9e2a50b --- /dev/null +++ b/src/styles/css/transition.css @@ -0,0 +1,82 @@ +/* fade */ +.fade-enter-active, +.fade-leave-active { + transition: opacity 0.3s ease-in-out; +} +.fade-enter-from, +.fade-leave-to { + opacity: 0; +} + +/* fade-slide */ +.fade-slide-leave-active, +.fade-slide-enter-active { + transition: all 0.3s; +} +.fade-slide-enter-from { + opacity: 0; + transform: translateX(-30px); +} +.fade-slide-leave-to { + opacity: 0; + transform: translateX(30px); +} + +/* fade-bottom */ +.fade-bottom-enter-active, +.fade-bottom-leave-active { + transition: + opacity 0.25s, + transform 0.3s; +} +.fade-bottom-enter-from { + opacity: 0; + transform: translateY(-10%); +} +.fade-bottom-leave-to { + opacity: 0; + transform: translateY(10%); +} + +/* fade-scale */ +.fade-scale-leave-active, +.fade-scale-enter-active { + transition: all 0.28s; +} +.fade-scale-enter-from { + opacity: 0; + transform: scale(1.2); +} +.fade-scale-leave-to { + opacity: 0; + transform: scale(0.8); +} + +/* zoom-fade */ +.zoom-fade-enter-active, +.zoom-fade-leave-active { + transition: + transform 0.2s, + opacity 0.3s ease-out; +} +.zoom-fade-enter-from { + opacity: 0; + transform: scale(0.92); +} +.zoom-fade-leave-to { + opacity: 0; + transform: scale(1.06); +} + +/* zoom-out */ +.zoom-out-enter-active, +.zoom-out-leave-active { + transition: + opacity 0.1s ease-in-out, + transform 0.15s ease-out; +} +.zoom-out-enter-from, +.zoom-out-leave-to { + opacity: 0; + transform: scale(0); +} diff --git a/src/styles/scss/global.scss b/src/styles/scss/global.scss new file mode 100644 index 0000000..e99a781 --- /dev/null +++ b/src/styles/scss/global.scss @@ -0,0 +1 @@ +@import './scrollbar.scss'; diff --git a/src/styles/scss/scrollbar.scss b/src/styles/scss/scrollbar.scss new file mode 100644 index 0000000..2e5ec45 --- /dev/null +++ b/src/styles/scss/scrollbar.scss @@ -0,0 +1,21 @@ +@mixin scrollbar($size: 7px, $color: rgba(0, 0, 0, 0.5)) { + scrollbar-width: thin; + scrollbar-color: $color transparent; + + &::-webkit-scrollbar-thumb { + background-color: $color; + border-radius: $size; + } + &::-webkit-scrollbar-thumb:hover { + background-color: $color; + border-radius: $size; + } + &::-webkit-scrollbar { + width: $size; + height: $size; + } + &::-webkit-scrollbar-track-piece { + background-color: rgba(0, 0, 0, 0); + border-radius: 0; + } +} diff --git a/src/theme/settings.ts b/src/theme/settings.ts new file mode 100644 index 0000000..6fbf003 --- /dev/null +++ b/src/theme/settings.ts @@ -0,0 +1,55 @@ +/** Default theme settings */ +export const themeSettings: App.Theme.ThemeSetting = { + themeScheme: 'light', + themeColor: '#646cff', + otherColor: { + info: '#2080f0', + success: '#52c41a', + warning: '#faad14', + error: '#f5222d' + }, + isInfoFollowPrimary: true, + layout: { + mode: 'vertical', + scrollMode: 'content' + }, + page: { + animate: true, + animateMode: 'fade-slide' + }, + header: { + height: 56, + breadcrumb: { + visible: true, + showIcon: true + } + }, + tab: { + visible: true, + cache: true, + height: 44, + mode: 'chrome' + }, + fixedHeaderAndTab: true, + sider: { + inverted: false, + width: 220, + collapsedWidth: 64, + mixWidth: 90, + mixCollapsedWidth: 64, + mixChildMenuWidth: 200 + }, + footer: { + visible: false, + fixed: false, + height: 48, + right: true + } +}; + +/** + * Override theme settings + * + * If publish new version, use `overrideThemeSettings` to override certain theme settings + */ +export const overrideThemeSettings: Partial = {}; diff --git a/src/theme/vars.ts b/src/theme/vars.ts new file mode 100644 index 0000000..19a3404 --- /dev/null +++ b/src/theme/vars.ts @@ -0,0 +1,35 @@ +/** Create color palette vars */ +function createColorPaletteVars() { + const colors: App.Theme.ThemeColorKey[] = ['primary', 'info', 'success', 'warning', 'error']; + const colorPaletteNumbers: App.Theme.ColorPaletteNumber[] = [50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950]; + + const colorPaletteVar = {} as App.Theme.ThemePaletteColor; + + colors.forEach(color => { + colorPaletteVar[color] = `rgb(var(--${color}-color))`; + colorPaletteNumbers.forEach(number => { + colorPaletteVar[`${color}-${number}`] = `rgb(var(--${color}-${number}-color))`; + }); + }); + + return colorPaletteVar; +} + +const colorPaletteVars = createColorPaletteVars(); + +/** Theme vars */ +export const themeVars: App.Theme.ThemeToken = { + colors: { + ...colorPaletteVars, + nprogress: 'rgb(var(--nprogress-color))', + container: 'rgb(var(--container-bg-color))', + layout: 'rgb(var(--layout-bg-color))', + inverted: 'rgb(var(--inverted-bg-color))', + base_text: 'rgb(var(--base-text-color))' + }, + boxShadow: { + header: 'var(--header-box-shadow)', + sider: 'var(--sider-box-shadow)', + tab: 'var(--tab-box-shadow)' + } +}; diff --git a/src/typings/antd.d.ts b/src/typings/antd.d.ts new file mode 100644 index 0000000..8dfe40b --- /dev/null +++ b/src/typings/antd.d.ts @@ -0,0 +1,40 @@ +declare namespace AntDesign { + type TableColumnType = import('ant-design-vue').TableColumnType; + type TableColumnGroupType = import('ant-design-vue').TableColumnGroupType; + type TablePaginationConfig = import('ant-design-vue').TablePaginationConfig; + type TableColumnCheck = import('@sa/hooks').TableColumnCheck; + type TableDataWithIndex = import('@sa/hooks').TableDataWithIndex; + type FlatResponseData = import('@sa/axios').FlatResponseData; + + type TableData = Api.Common.CommonRecord; + + /** + * the custom column key + * + * if you want to add a custom column, you should add a key to this type + */ + type CustomColumnKey = 'operate'; + + type SetTableColumnKey = Omit & { key?: keyof T | CustomColumnKey }; + + type TableColumn = SetTableColumnKey, T> | SetTableColumnKey, T>; + + type TableApiFn = ( + params: R + ) => Promise>>; + + /** + * the type of table operation + * + * - add: add table item + * - edit: edit table item + */ + type TableOperateType = 'add' | 'edit'; + + type GetTableData
= A extends TableApiFn ? T : never; + + type AntDesignTableConfig = Pick< + import('@sa/hooks').TableConfig, TableColumn>>>, + 'apiFn' | 'apiParams' | 'columns' | 'immediate' | 'rowKey' + >; +} diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts new file mode 100644 index 0000000..eccdbda --- /dev/null +++ b/src/typings/api.d.ts @@ -0,0 +1,406 @@ +/** + * Namespace Api + * + * All backend api type + */ +declare namespace Api { + namespace Common { + /** common params of paginating */ + interface PaginatingCommonParams { + /** total count */ + total: number; + } + + /** common params of paginating query list data */ + interface PaginatingQueryRecord extends PaginatingCommonParams { + rows: T[]; + } + + /** + * enable status + * + * - "0": enabled + * - "1": disabled + */ + type EnableStatus = '1' | '0'; + + /** common record */ + type CommonRecord = { + /** record creator */ + createBy: string; + /** record create time */ + createTime: string; + /** record updater */ + updateBy: string; + /** record update time */ + updateTime: string; + /** record status */ + status: EnableStatus; + } & T; + + type CommonTree = { + id: number; + label: string; + children?: CommonTree[]; + }[]; + } + + namespace Department { + interface Dept { + createBy: any; + createTime: any; + updateBy: any; + updateTime: any; + remark: any; + deptId: number; + parentId: number; + ancestors: string; + deptName: string; + orderNum: number; + leader: string; + phone: any; + email: any; + status: string; + delFlag: any; + parentName: any; + children: any[]; + } + } + + /** + * Namespace Auth + * + * Backend api module: "auth" + */ + namespace Auth { + interface LoginToken { + access_token: string; + refreshToken: string; + } + /** User info */ + interface UserInfo { + user: User | null; + roles: string[]; + buttons: string[]; + /** permissions */ + permissions: string[]; + } + + interface User { + createBy: string; + createTime: string; + updateBy: any; + updateTime: any; + remark: string; + userId: number; + deptId: number; + userName: string; + nickName: string; + email: string; + phonenumber: string; + sex: string; + avatar: string; + password: string; + status: '0' | '1'; + delFlag: string; + loginIp: string; + loginDate: string; + dept: Department.Dept; + roles: Role[]; + roleId: string; + postIds: number[]; + roleIds: number[]; + admin: boolean; + } + + interface Role { + remark: any; + roleId: number; + roleName: string; + roleKey: string; + roleSort: number; + dataScope: string; + menuCheckStrictly: boolean; + deptCheckStrictly: boolean; + status: string; + delFlag: '0' | '1'; + flag: boolean; + menuIds: number[] | null; + deptIds: number[] | null; + permissions: any; + admin: boolean; + } + + interface LoginBody { + username: string; + password: string; + code: string; + uuid: string; + } + } + + /** + * Namespace Route + * + * Backend api module: "route" + */ + namespace Route { + type ElegantConstRoute = import('@elegant-router/types').ElegantConstRoute; + + interface MenuRoute extends ElegantConstRoute { + id: string; + } + + interface UserRoute { + routes: MenuRoute[]; + home: import('@elegant-router/types').LastLevelRouteKey; + } + } + + /** + * namespace SystemManage + * + * backend api module: "systemManage" + */ + namespace SystemManage { + type CommonSearchParams = { + /** page number */ + pageNum: number; + /** page size */ + pageSize: number; + }; + + /** role */ + type Role = Common.CommonRecord<{ + remark: string; + roleId: number; + roleName: string; + roleKey: string; + roleSort: number; + dataScope: string; + menuCheckStrictly: boolean; + deptCheckStrictly: boolean; + status: string; + delFlag: '0' | '1'; + flag: boolean; + menuIds: number[] | null; + deptIds: number[] | null; + permissions: string; + admin: boolean; + }>; + + /** role search params */ + type RoleSearchParams = Partial< + Pick & CommonSearchParams + >; + + /** role list */ + type RoleList = Common.PaginatingQueryRecord; + + /** all role */ + type AllRole = Pick; + + /** + * user gender + * + * - "1": "male" + * - "2": "female" + */ + type UserGender = '1' | '2'; + + /** user */ + type UserInfo = Common.CommonRecord<{ + /** user name */ + username: string; + /** user gender */ + userGender: UserGender | null; + /** user nick name */ + nickName: string; + /** user phone */ + userPhone: string; + /** user email */ + userEmail: string; + /** user role code collection */ + userRoles: string[]; + }>; + + /** user search params */ + type UserSearchParams = Partial< + Pick & + CommonSearchParams + >; + + /** user list */ + type UserList = Common.PaginatingQueryRecord; + + type UserPostsAndRoles = { + posts: Post[]; + roles: Role[]; + postIds: number[]; + roleIds: number[]; + }; + + /** + * menu type + * + * - "1": directory + * - "2": menu + */ + type MenuType = 'M' | 'C' | 'F'; + + type MenuButton = { + /** + * button code + * + * it can be used to control the button permission + */ + code: string; + /** button description */ + desc: string; + }; + + /** + * icon type + * + * - "1": iconify icon + * - "2": local icon + */ + type IconType = '1' | '2'; + + type Menu = Common.CommonRecord<{ + /** parent menu id */ + parentId: number; + /** menu type */ + menuType: MenuType; + /** menu name */ + menuName: string; + /** route name */ + routeName: string; + /** route path */ + routePath: string; + /** component */ + component?: string; + menuId: number; + path: string; + /** + * i18n key + * + * it is for internationalization + */ + i18nKey?: App.I18n.I18nKey; + /** iconify icon name or local icon name */ + icon: string; + /** icon type */ + iconType: IconType; + /** menu order */ + orderNum: number; + /** whether to cache the route */ + keepAlive?: '0' | '1'; + /** outer link */ + href?: string; + /** whether to retain the route */ + status: '0' | '1'; + /** whether to hide the route in the menu */ + hideInMenu?: '0' | '1'; + /** + * The menu key will be activated when entering the route + * + * The route is not in the menu + * + * @example + * the route is "user_detail", if it is set to "user_list", the menu "user_list" will be activated + */ + activeMenu?: import('@elegant-router/types').LastLevelRouteKey; + /** By default, the same route path will use one tab, if set to true, it will use multiple tabs */ + multiTab?: boolean; + /** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */ + fixedIndexInTab?: number; + /** menu buttons */ + buttons?: MenuButton[]; + /** children menu */ + children?: Menu[]; + /** is external link */ + isFrame: '0' | '1'; + /** perms to request api */ + perms: string; + /** menu name(path combine) */ + name: string; + isCache: '0' | '1'; + visible: '0' | '1'; + }>; + + /** menu list */ + type MenuList = Common.PaginatingQueryRecord; + + type MenuTree = { + id: number; + label: string; + pId: number; + children?: MenuTree[]; + }; + + // dept api + /** dept */ + type Dept = { + createBy: string; + createTime: string; + updateBy: string; + updateTime: string; + remark: string; + deptId: number; + parentId: number; + ancestors: string; + deptName: string; + orderNum: number; + leader: string; + phone: string; + email: string; + status: '0' | '1'; + delFlag: string; + parentName: string; + children: Dept[]; + }; + + type DeptList = Common.PaginatingQueryRecord; + + /** dept search params */ + type DeptSearchParams = Partial & CommonSearchParams>; + + // post api + type Post = { + createBy: string; + createTime: string; + updateBy: any; + updateTime: any; + remark: string; + postId: number; + postCode: string; + postName: string; + postSort: number; + status: '0' | '1'; + flag: boolean; + }; + + type PostSearchParams = Partial & CommonSearchParams>; + + type PostList = Common.PaginatingQueryRecord; + + // dict api + type Dict = { + createBy: string; + createTime: string; + updateBy: string; + updateTime: string; + remark: string; + dictId: number; + dictName: string; + dictType: string; + status: '0' | '1'; + delFlag: string; + }; + + type DictSearchParams = Partial & CommonSearchParams>; + + type DictList = Common.PaginatingQueryRecord; + } +} diff --git a/src/typings/app.d.ts b/src/typings/app.d.ts new file mode 100644 index 0000000..65c56f0 --- /dev/null +++ b/src/typings/app.d.ts @@ -0,0 +1,718 @@ +/** The global namespace for the app */ +declare namespace App { + /** Theme namespace */ + namespace Theme { + type ColorPaletteNumber = import('@sa/color-palette').ColorPaletteNumber; + + /** Theme token */ + type ThemeToken = { + colors: ThemeTokenColor; + boxShadow: { + header: string; + sider: string; + tab: string; + }; + }; + + /** Theme setting */ + interface ThemeSetting { + /** Theme scheme */ + themeScheme: UnionKey.ThemeScheme; + /** Theme color */ + themeColor: string; + /** Other color */ + otherColor: OtherColor; + /** Whether info color is followed by the primary color */ + isInfoFollowPrimary: boolean; + /** Layout */ + layout: { + /** Layout mode */ + mode: UnionKey.ThemeLayoutMode; + /** Scroll mode */ + scrollMode: UnionKey.ThemeScrollMode; + }; + /** Page */ + page: { + /** Whether to show the page transition */ + animate: boolean; + /** Page animate mode */ + animateMode: UnionKey.ThemePageAnimateMode; + }; + /** Header */ + header: { + /** Header height */ + height: number; + /** Header breadcrumb */ + breadcrumb: { + /** Whether to show the breadcrumb */ + visible: boolean; + /** Whether to show the breadcrumb icon */ + showIcon: boolean; + }; + }; + /** Tab */ + tab: { + /** Whether to show the tab */ + visible: boolean; + /** + * Whether to cache the tab + * + * If cache, the tabs will get from the local storage when the page is refreshed + */ + cache: boolean; + /** Tab height */ + height: number; + /** Tab mode */ + mode: UnionKey.ThemeTabMode; + }; + /** Fixed header and tab */ + fixedHeaderAndTab: boolean; + /** Sider */ + sider: { + /** Inverted sider */ + inverted: boolean; + /** Sider width */ + width: number; + /** Collapsed sider width */ + collapsedWidth: number; + /** Sider width when the layout is 'vertical-mix' or 'horizontal-mix' */ + mixWidth: number; + /** Collapsed sider width when the layout is 'vertical-mix' or 'horizontal-mix' */ + mixCollapsedWidth: number; + /** Child menu width when the layout is 'vertical-mix' or 'horizontal-mix' */ + mixChildMenuWidth: number; + }; + /** Footer */ + footer: { + /** Whether to show the footer */ + visible: boolean; + /** Whether fixed the footer */ + fixed: boolean; + /** Footer height */ + height: number; + /** Whether float the footer to the right when the layout is 'horizontal-mix' */ + right: boolean; + }; + } + + interface OtherColor { + info: string; + success: string; + warning: string; + error: string; + } + + interface ThemeColor extends OtherColor { + primary: string; + } + + type ThemeColorKey = keyof ThemeColor; + + type ThemePaletteColor = { + [key in ThemeColorKey | `${ThemeColorKey}-${ColorPaletteNumber}`]: string; + }; + + type BaseToken = Record>; + + interface ThemeTokenColor extends ThemePaletteColor { + nprogress: string; + container: string; + layout: string; + inverted: string; + base_text: string; + [key: string]: string; + } + } + + /** Global namespace */ + namespace Global { + type VNode = import('vue').VNode; + type RouteLocationNormalizedLoaded = import('vue-router').RouteLocationNormalizedLoaded; + type RouteKey = import('@elegant-router/types').RouteKey; + type RouteMap = import('@elegant-router/types').RouteMap; + type RoutePath = import('@elegant-router/types').RoutePath; + type LastLevelRouteKey = import('@elegant-router/types').LastLevelRouteKey; + + /** The global header props */ + interface HeaderProps { + /** Whether to show the logo */ + showLogo?: boolean; + /** Whether to show the menu toggler */ + showMenuToggler?: boolean; + /** Whether to show the menu */ + showMenu?: boolean; + } + + /** The global menu */ + interface Menu { + /** + * The menu key + * + * Equal to the route key + */ + key: string; + /** The menu label */ + label: string; + /** The menu i18n key */ + i18nKey?: I18n.I18nKey; + /** The route key */ + routeKey: RouteKey; + /** The route path */ + routePath: RoutePath; + /** The menu icon */ + icon?: () => VNode; + /** The tooltip title */ + title?: string; + /** The menu children */ + children?: Menu[]; + } + + /** Tab route */ + type TabRoute = Pick & + Partial>; + + /** The global tab */ + type Tab = { + /** The tab id */ + id: string; + /** The tab label */ + label: string; + /** + * The new tab label + * + * If set, the tab label will be replaced by this value + */ + newLabel?: string; + /** + * The old tab label + * + * when reset the tab label, the tab label will be replaced by this value + */ + oldLabel?: string; + /** The tab route key */ + routeKey: LastLevelRouteKey; + /** The tab route path */ + routePath: RouteMap[LastLevelRouteKey]; + /** The tab route full path */ + fullPath: string; + /** The tab fixed index */ + fixedIndex?: number; + /** + * Tab icon + * + * Iconify icon + */ + icon?: string; + /** + * Tab local icon + * + * Local icon + */ + localIcon?: string; + /** I18n key */ + i18nKey?: I18n.I18nKey; + }; + + /** Form rule */ + type FormRule = import('ant-design-vue/es/form/interface.d.ts').Rule; + + /** The global dropdown key */ + type DropdownKey = 'closeCurrent' | 'closeOther' | 'closeLeft' | 'closeRight' | 'closeAll'; + } + + /** + * I18n namespace + * + * Locales type + */ + namespace I18n { + type RouteKey = import('@elegant-router/types').RouteKey; + + type LangType = 'en-US' | 'zh-CN'; + + type LangOption = { + label: string; + key: LangType; + }; + + type I18nRouteKey = Exclude; + + type FormMsg = { + required: string; + invalid: string; + }; + + type Schema = { + system: { + title: string; + }; + common: { + action: string; + add: string; + addSuccess: string; + backToHome: string; + batchDelete: string; + cancel: string; + close: string; + check: string; + columnSetting: string; + config: string; + confirm: string; + delete: string; + deleteSuccess: string; + confirmDelete: string; + edit: string; + index: string; + keywordSearch: string; + logout: string; + logoutConfirm: string; + lookForward: string; + modify: string; + modifySuccess: string; + noData: string; + operate: string; + pleaseCheckValue: string; + refresh: string; + reset: string; + search: string; + switch: string; + tip: string; + trigger: string; + update: string; + updateSuccess: string; + userCenter: string; + yesOrNo: { + yes: string; + no: string; + }; + }; + request: { + logout: string; + logoutMsg: string; + logoutWithModal: string; + logoutWithModalMsg: string; + refreshToken: string; + tokenExpired: string; + }; + theme: { + themeSchema: { title: string } & Record; + layoutMode: { title: string } & Record; + themeColor: { + title: string; + followPrimary: string; + } & Theme.ThemeColor; + scrollMode: { title: string } & Record; + page: { + animate: string; + mode: { title: string } & Record; + }; + fixedHeaderAndTab: string; + header: { + height: string; + breadcrumb: { + visible: string; + showIcon: string; + }; + }; + tab: { + visible: string; + cache: string; + height: string; + mode: { title: string } & Record; + }; + sider: { + inverted: string; + width: string; + collapsedWidth: string; + mixWidth: string; + mixCollapsedWidth: string; + mixChildMenuWidth: string; + }; + footer: { + visible: string; + fixed: string; + height: string; + right: string; + }; + themeDrawerTitle: string; + pageFunTitle: string; + configOperation: { + copyConfig: string; + copySuccessMsg: string; + resetConfig: string; + resetSuccessMsg: string; + }; + }; + route: Record; + page: { + login: { + common: { + loginOrRegister: string; + userNamePlaceholder: string; + phonePlaceholder: string; + codePlaceholder: string; + passwordPlaceholder: string; + confirmPasswordPlaceholder: string; + codeLogin: string; + confirm: string; + back: string; + validateSuccess: string; + loginSuccess: string; + welcomeBack: string; + checkCode: string; + }; + pwdLogin: { + title: string; + rememberMe: string; + forgetPassword: string; + register: string; + otherAccountLogin: string; + otherLoginMode: string; + superAdmin: string; + admin: string; + user: string; + }; + codeLogin: { + title: string; + getCode: string; + reGetCode: string; + sendCodeSuccess: string; + imageCodePlaceholder: string; + }; + register: { + title: string; + agreement: string; + protocol: string; + policy: string; + }; + resetPwd: { + title: string; + }; + bindWeChat: { + title: string; + }; + }; + about: { + title: string; + introduction: string; + projectInfo: { + title: string; + version: string; + latestBuildTime: string; + githubLink: string; + previewLink: string; + }; + prdDep: string; + devDep: string; + }; + home: { + greeting: string; + weatherDesc: string; + projectCount: string; + todo: string; + message: string; + downloadCount: string; + registerCount: string; + schedule: string; + study: string; + work: string; + rest: string; + entertainment: string; + visitCount: string; + turnover: string; + dealCount: string; + projectNews: { + title: string; + moreNews: string; + desc1: string; + desc2: string; + desc3: string; + desc4: string; + desc5: string; + }; + creativity: string; + }; + function: { + tab: { + tabOperate: { + title: string; + addTab: string; + addTabDesc: string; + closeTab: string; + closeCurrentTab: string; + closeAboutTab: string; + addMultiTab: string; + addMultiTabDesc1: string; + addMultiTabDesc2: string; + }; + tabTitle: { + title: string; + changeTitle: string; + change: string; + resetTitle: string; + reset: string; + }; + }; + multiTab: { + routeParam: string; + backTab: string; + }; + toggleAuth: { + toggleAccount: string; + authHook: string; + superAdminVisible: string; + adminVisible: string; + adminOrUserVisible: string; + }; + }; + manage: { + common: { + status: { + enable: string; + disable: string; + }; + }; + role: { + title: string; + roleName: string; + roleCode: string; + roleStatus: string; + roleDesc: string; + form: { + roleName: string; + roleCode: string; + roleStatus: string; + roleDesc: string; + }; + addRole: string; + editRole: string; + menuAuth: string; + buttonAuth: string; + }; + user: { + userName: string; + nickName: string; + email: string; + phonenumber: string; + status: string; + dept: string; + title: string; + addUser: string; + remark: string; + editUser: string; + post: string; + role: string; + password: string; + form: { + userName: string; + email: string; + status: string; + nickName: string; + phonenumber: string; + remark: string; + password: string; + dept: string; + }; + }; + menu: { + home: string; + title: string; + id: string; + parentId: string; + menuType: string; + menuName: string; + routeName: string; + routePath: string; + routeParams: string; + layout: string; + page: string; + i18nKey: string; + icon: string; + localIcon: string; + iconTypeTitle: string; + order: string; + keepAlive: string; + href: string; + hideInMenu: string; + activeMenu: string; + multiTab: string; + fixedIndexInTab: string; + button: string; + buttonCode: string; + buttonDesc: string; + menuStatus: string; + form: { + home: string; + menuType: string; + menuName: string; + routeName: string; + routePath: string; + layout: string; + page: string; + i18nKey: string; + icon: string; + localIcon: string; + order: string; + keepAlive: string; + href: string; + hideInMenu: string; + activeMenu: string; + multiTab: string; + fixedInTab: string; + fixedIndexInTab: string; + button: string; + buttonCode: string; + buttonDesc: string; + menuStatus: string; + }; + addMenu: string; + editMenu: string; + addChildMenu: string; + type: { + directory: string; + menu: string; + }; + iconType: { + iconify: string; + local: string; + }; + }; + dept: { + deptName: string; + leader: string; + status: string; + form: { + deptName: string; + leader: string; + status: string; + }; + }; + post: { + addPost: string; + editPost: string; + postName: string; + postCode: string; + postSort: string; + status: string; + remark: string; + title: string; + form: { + postName: string; + postCode: string; + postSort: string; + remark: string; + status: string; + }; + }; + + dict: { + title: string; + dictName: string; + dictType: string; + status: string; + remark: string; + form: { + dictName: string; + dictType: string; + status: string; + remark: string; + }; + addDict: string; + editDict: string; + }; + }; + }; + form: { + required: string; + username: FormMsg; + phone: FormMsg; + pwd: FormMsg; + confirmPwd: FormMsg; + code: FormMsg; + email: FormMsg; + }; + dropdown: Record; + icon: { + themeConfig: string; + themeSchema: string; + lang: string; + fullscreen: string; + fullscreenExit: string; + reload: string; + collapse: string; + expand: string; + pin: string; + unpin: string; + }; + }; + + type GetI18nKey, K extends keyof T = keyof T> = K extends string + ? T[K] extends Record + ? `${K}.${GetI18nKey}` + : K + : never; + + type I18nKey = GetI18nKey; + + type TranslateOptions = import('vue-i18n').TranslateOptions; + + interface $T { + (key: I18nKey): string; + (key: I18nKey, plural: number, options?: TranslateOptions): string; + (key: I18nKey, defaultMsg: string, options?: TranslateOptions): string; + (key: I18nKey, list: unknown[], options?: TranslateOptions): string; + (key: I18nKey, list: unknown[], plural: number): string; + (key: I18nKey, list: unknown[], defaultMsg: string): string; + (key: I18nKey, named: Record, options?: TranslateOptions): string; + (key: I18nKey, named: Record, plural: number): string; + (key: I18nKey, named: Record, defaultMsg: string): string; + } + } + + /** Service namespace */ + namespace Service { + /** Other baseURL key */ + type OtherBaseURLKey = 'demo'; + + interface ServiceConfigItem { + /** The backend service base url */ + baseURL: string; + /** The proxy pattern of the backend service base url */ + proxyPattern: string; + } + + interface OtherServiceConfigItem extends ServiceConfigItem { + key: OtherBaseURLKey; + } + + /** The backend service config */ + interface ServiceConfig extends ServiceConfigItem { + /** Other backend service config */ + other: OtherServiceConfigItem[]; + } + + interface SimpleServiceConfig extends Pick { + other: Record; + } + + /** The backend service response data */ + type Response = { + /** The backend service response code */ + code: string; + /** The backend service response message */ + msg: string; + /** The backend service response data */ + data: T; + }; + + /** The demo backend service response data */ + type DemoResponse = { + /** The backend service response code */ + status: string; + /** The backend service response message */ + message: string; + /** The backend service response data */ + result: T; + }; + } +} diff --git a/src/typings/auto-imports.d.ts b/src/typings/auto-imports.d.ts new file mode 100644 index 0000000..889b2c3 --- /dev/null +++ b/src/typings/auto-imports.d.ts @@ -0,0 +1,420 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// noinspection JSUnusedGlobalSymbols +// Generated by unplugin-auto-import +export {} +declare global { + const $message: typeof import('ant-design-vue')['message'] + const $modal: typeof import('ant-design-vue')['Modal'] + const $notification: typeof import('ant-design-vue')['notification'] + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const addThemeVarsToHtml: typeof import('../store/modules/theme/shared')['addThemeVarsToHtml'] + const afterAll: typeof import('vitest')['afterAll'] + const afterEach: typeof import('vitest')['afterEach'] + const assert: typeof import('vitest')['assert'] + const assign: typeof import('lodash-es')['assign'] + const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] + const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] + const beforeAll: typeof import('vitest')['beforeAll'] + const beforeEach: typeof import('vitest')['beforeEach'] + const chai: typeof import('vitest')['chai'] + const clearAuthStorage: typeof import('../store/modules/auth/shared')['clearAuthStorage'] + const cloneDeep: typeof import('lodash-es')['cloneDeep'] + 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 createPinia: typeof import('pinia')['createPinia'] + const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] + const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate'] + const createServiceConfig: typeof import('../utils/service')['createServiceConfig'] + const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] + const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] + const createThemeToken: typeof import('../store/modules/theme/shared')['createThemeToken'] + 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 defineStore: typeof import('pinia')['defineStore'] + const describe: typeof import('vitest')['describe'] + const doAddDept: typeof import('../service/api/dept')['doAddDept'] + const doAddDict: typeof import('../service/api/dict')['doAddDict'] + const doAddMenu: typeof import('../service/api/menu')['doAddMenu'] + const doAddPost: typeof import('../service/api/post')['doAddPost'] + const doDeleteDept: typeof import('../service/api/dept')['doDeleteDept'] + const doDeleteDict: typeof import('../service/api/dict')['doDeleteDict'] + const doDeleteLogout: typeof import('../service/api/auth')['doDeleteLogout'] + const doDeleteMenu: typeof import('../service/api/menu')['doDeleteMenu'] + const doDeletePost: typeof import('../service/api/post')['doDeletePost'] + const doDeleteRole: typeof import('../service/api/role')['doDeleteRole'] + const doDeleteUser: typeof import('../service/api/user')['doDeleteUser'] + const doEditDept: typeof import('../service/api/dept')['doEditDept'] + const doEditDict: typeof import('../service/api/dict')['doEditDict'] + const doEditMenu: typeof import('../service/api/menu')['doEditMenu'] + const doEditPost: typeof import('../service/api/post')['doEditPost'] + const doGetAdminUserPostsAndRoles: typeof import('../service/api/user')['doGetAdminUserPostsAndRoles'] + const doGetCheckCode: typeof import('../service/api/auth')['doGetCheckCode'] + const doGetDeptInfo: typeof import('../service/api/dept')['doGetDeptInfo'] + const doGetDeptList: typeof import('../service/api/dept')['doGetDeptList'] + const doGetDictList: typeof import('../service/api/dict')['doGetDictList'] + const doGetMenuDetail: typeof import('../service/api/menu')['doGetMenuDetail'] + const doGetMenuList: typeof import('../service/api/menu')['doGetMenuList'] + const doGetPostDetail: typeof import('../service/api/post')['doGetPostDetail'] + const doGetPostList: typeof import('../service/api/post')['doGetPostList'] + const doGetRoleList: typeof import('../service/api/role')['doGetRoleList'] + const doGetRoleMenuList: typeof import('../service/api/menu')['doGetRoleMenuList'] + const doGetUserDeptTree: typeof import('../service/api/user')['doGetUserDeptTree'] + const doGetUserInfo: typeof import('../service/api/auth')['doGetUserInfo'] + const doGetUserList: typeof import('../service/api/user')['doGetUserList'] + const doGetUserPostsAndRoles: typeof import('../service/api/user')['doGetUserPostsAndRoles'] + const doGetUserRoutes: typeof import('../service/api/route')['doGetUserRoutes'] + const doPostRole: typeof import('../service/api/role')['doPostRole'] + const doPostUser: typeof import('../service/api/user')['doPostUser'] + const doPutRole: typeof import('../service/api/role')['doPutRole'] + const doPutUser: typeof import('../service/api/user')['doPutUser'] + const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] + const effectScope: typeof import('vue')['effectScope'] + const emptyInfo: typeof import('../store/modules/auth/shared')['emptyInfo'] + const expect: typeof import('vitest')['expect'] + const extendRef: typeof import('@vueuse/core')['extendRef'] + const extractTabsByAllRoutes: typeof import('../store/modules/tab/shared')['extractTabsByAllRoutes'] + const fetchCustomBackendError: typeof import('../service/api/auth')['fetchCustomBackendError'] + const fetchGetAllPages: typeof import('../service/api/menu')['fetchGetAllPages'] + const fetchGetConstantRoutes: typeof import('../service/api/route')['fetchGetConstantRoutes'] + const fetchGetMenuTree: typeof import('../service/api/menu')['fetchGetMenuTree'] + const fetchIsRouteExist: typeof import('../service/api/route')['fetchIsRouteExist'] + const fetchLogin: typeof import('../service/api/auth')['fetchLogin'] + const fetchRefreshToken: typeof import('../service/api/auth')['fetchRefreshToken'] + const filterAuthRoutesByRoles: typeof import('../store/modules/route/shared')['filterAuthRoutesByRoles'] + const filterTabsById: typeof import('../store/modules/tab/shared')['filterTabsById'] + const filterTabsByIds: typeof import('../store/modules/tab/shared')['filterTabsByIds'] + const findTabByRouteName: typeof import('../store/modules/tab/shared')['findTabByRouteName'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getAllTabs: typeof import('../store/modules/tab/shared')['getAllTabs'] + const getAntdTheme: typeof import('../store/modules/theme/shared')['getAntdTheme'] + const getBreadcrumbsByRoute: typeof import('../store/modules/route/shared')['getBreadcrumbsByRoute'] + const getCacheRouteNames: typeof import('../store/modules/route/shared')['getCacheRouteNames'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const getDefaultHomeTab: typeof import('../store/modules/tab/shared')['getDefaultHomeTab'] + const getFixedTabIds: typeof import('../store/modules/tab/shared')['getFixedTabIds'] + const getFixedTabs: typeof import('../store/modules/tab/shared')['getFixedTabs'] + const getGlobalMenusByAuthRoutes: typeof import('../store/modules/route/shared')['getGlobalMenusByAuthRoutes'] + const getRouteIcons: typeof import('../store/modules/tab/shared')['getRouteIcons'] + const getSelectedMenuKeyPathByKey: typeof import('../store/modules/route/shared')['getSelectedMenuKeyPathByKey'] + const getServiceBaseURL: typeof import('../utils/service')['getServiceBaseURL'] + const getTabByRoute: typeof import('../store/modules/tab/shared')['getTabByRoute'] + const getTabIdByRoute: typeof import('../store/modules/tab/shared')['getTabIdByRoute'] + const getToken: typeof import('../store/modules/auth/shared')['getToken'] + const h: typeof import('vue')['h'] + const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] + const initThemeSettings: typeof import('../store/modules/theme/shared')['initThemeSettings'] + const inject: typeof import('vue')['inject'] + const injectLocal: typeof import('@vueuse/core')['injectLocal'] + 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 isRouteExistByRouteName: typeof import('../store/modules/route/shared')['isRouteExistByRouteName'] + const isShowBtn: typeof import('../utils/permission')['isShowBtn'] + const isTabInTabs: typeof import('../store/modules/tab/shared')['isTabInTabs'] + const it: typeof import('vitest')['it'] + const localStg: typeof import('../utils/storage')['localStg'] + const localforage: typeof import('../utils/storage')['localforage'] + const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const omit: typeof import('lodash-es')['omit'] + 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 pick: typeof import('lodash-es')['pick'] + const provide: typeof import('vue')['provide'] + const provideLocal: typeof import('@vueuse/core')['provideLocal'] + 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 removeEmptyChildren: typeof import('../utils/menu')['removeEmptyChildren'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const resolveRef: typeof import('@vueuse/core')['resolveRef'] + const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] + const sessionStg: typeof import('../utils/storage')['sessionStg'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const sortRoutesByOrder: typeof import('../store/modules/route/shared')['sortRoutesByOrder'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const suite: typeof import('vitest')['suite'] + const syncRef: typeof import('@vueuse/core')['syncRef'] + const syncRefs: typeof import('@vueuse/core')['syncRefs'] + const templateRef: typeof import('@vueuse/core')['templateRef'] + const test: typeof import('vitest')['test'] + 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 toggleCssDarkMode: typeof import('../store/modules/theme/shared')['toggleCssDarkMode'] + const transformListToTree: typeof import('../utils/menu')['transformListToTree'] + const transformMenuChildWithRootIds: typeof import('../utils/menu')['transformMenuChildWithRootIds'] + const transformMenuToSearchMenus: typeof import('../store/modules/route/shared')['transformMenuToSearchMenus'] + const transformRecordToOption: typeof import('../utils/common')['transformRecordToOption'] + const translateOptions: typeof import('../utils/common')['translateOptions'] + 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 updateLocaleOfGlobalMenus: typeof import('../store/modules/route/shared')['updateLocaleOfGlobalMenus'] + const updateTabByI18nKey: typeof import('../store/modules/tab/shared')['updateTabByI18nKey'] + const updateTabsByI18nKey: typeof import('../store/modules/tab/shared')['updateTabsByI18nKey'] + const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] + const useAnimate: typeof import('@vueuse/core')['useAnimate'] + const useAntdForm: typeof import('../hooks/common/form')['useAntdForm'] + const useAppStore: typeof import('../store/modules/app/index')['useAppStore'] + 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 useAuthStore: typeof import('../store/modules/auth/index')['useAuthStore'] + 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 useClipboardItems: typeof import('@vueuse/core')['useClipboardItems'] + 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 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 useEcharts: typeof import('../hooks/common/echarts')['useEcharts'] + 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 useFormRules: typeof import('../hooks/common/form')['useFormRules'] + 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 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 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 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 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 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 useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] + const useRoute: typeof import('vue-router')['useRoute'] + const useRouteStore: typeof import('../store/modules/route/index')['useRouteStore'] + const useRouter: typeof import('vue-router')['useRouter'] + const useRouterPush: typeof import('../hooks/common/router')['useRouterPush'] + 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 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 useSvgIcon: typeof import('../hooks/common/icon')['useSvgIcon'] + const useSwipe: typeof import('@vueuse/core')['useSwipe'] + const useTabStore: typeof import('../store/modules/tab/index')['useTabStore'] + const useTable: typeof import('../hooks/common/table')['useTable'] + const useTableOperate: typeof import('../hooks/common/table')['useTableOperate'] + 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 useThemeStore: typeof import('../store/modules/theme/index')['useThemeStore'] + 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 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 vi: typeof import('vitest')['vi'] + const vitest: typeof import('vitest')['vitest'] + 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, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue' + import('vue') +} diff --git a/src/typings/common.d.ts b/src/typings/common.d.ts new file mode 100644 index 0000000..06b526c --- /dev/null +++ b/src/typings/common.d.ts @@ -0,0 +1,25 @@ +/** The common type namespace */ +declare namespace CommonType { + /** The strategic pattern */ + interface StrategicPattern { + /** The condition */ + condition: boolean; + /** If the condition is true, then call the action function */ + callback: () => void; + } + + /** + * The option type + * + * @property value: The option value + * @property label: The option label + */ + type Option = { value: K; label: string }; + + type YesOrNo = 'Y' | 'N'; + + /** add null to all properties */ + type RecordNullable = { + [K in keyof T]?: T[K] | null; + }; +} diff --git a/src/typings/components.d.ts b/src/typings/components.d.ts new file mode 100644 index 0000000..820dcad --- /dev/null +++ b/src/typings/components.d.ts @@ -0,0 +1,90 @@ +/* eslint-disable */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +export {} + +/* prettier-ignore */ +declare module 'vue' { + export interface GlobalComponents { + ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb'] + ABreadcrumbItem: typeof import('ant-design-vue/es')['BreadcrumbItem'] + AButton: typeof import('ant-design-vue/es')['Button'] + ACard: typeof import('ant-design-vue/es')['Card'] + ACheckbox: typeof import('ant-design-vue/es')['Checkbox'] + ACol: typeof import('ant-design-vue/es')['Col'] + ADescriptions: typeof import('ant-design-vue/es')['Descriptions'] + ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem'] + ADivider: typeof import('ant-design-vue/es')['Divider'] + ADrawer: typeof import('ant-design-vue/es')['Drawer'] + ADropdown: typeof import('ant-design-vue/es')['Dropdown'] + AForm: typeof import('ant-design-vue/es')['Form'] + AFormItem: typeof import('ant-design-vue/es')['FormItem'] + AImage: typeof import('ant-design-vue/es')['Image'] + AInput: typeof import('ant-design-vue/es')['Input'] + AInputNumber: typeof import('ant-design-vue/es')['InputNumber'] + AInputPassword: typeof import('ant-design-vue/es')['InputPassword'] + AInputSearch: typeof import('ant-design-vue/es')['InputSearch'] + AList: typeof import('ant-design-vue/es')['List'] + AListItem: typeof import('ant-design-vue/es')['ListItem'] + AListItemMeta: typeof import('ant-design-vue/es')['ListItemMeta'] + AMenu: typeof import('ant-design-vue/es')['Menu'] + AMenuDivider: typeof import('ant-design-vue/es')['MenuDivider'] + AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] + AModal: typeof import('ant-design-vue/es')['Modal'] + AntTree: typeof import('./../components/custom/ant-tree.vue')['default'] + APopconfirm: typeof import('ant-design-vue/es')['Popconfirm'] + APopover: typeof import('ant-design-vue/es')['Popover'] + AppLoading: typeof import('./../components/common/app-loading.vue')['default'] + AppProvider: typeof import('./../components/common/app-provider.vue')['default'] + ARadio: typeof import('ant-design-vue/es')['Radio'] + ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] + ARow: typeof import('ant-design-vue/es')['Row'] + ASegmented: typeof import('ant-design-vue/es')['Segmented'] + ASelect: typeof import('ant-design-vue/es')['Select'] + ASelectOption: typeof import('ant-design-vue/es')['SelectOption'] + ASpace: typeof import('ant-design-vue/es')['Space'] + ASpin: typeof import('ant-design-vue/es')['Spin'] + AStatistic: typeof import('ant-design-vue/es')['Statistic'] + ASwitch: typeof import('ant-design-vue/es')['Switch'] + ATable: typeof import('ant-design-vue/es')['Table'] + ATag: typeof import('ant-design-vue/es')['Tag'] + ATextarea: typeof import('ant-design-vue/es')['Textarea'] + ATooltip: typeof import('ant-design-vue/es')['Tooltip'] + ATree: typeof import('ant-design-vue/es')['Tree'] + ATreeSelect: typeof import('ant-design-vue/es')['TreeSelect'] + BetterScroll: typeof import('./../components/custom/better-scroll.vue')['default'] + ButtonIcon: typeof import('./../components/custom/button-icon.vue')['default'] + CountTo: typeof import('./../components/custom/count-to.vue')['default'] + DarkModeContainer: typeof import('./../components/common/dark-mode-container.vue')['default'] + ExceptionBase: typeof import('./../components/common/exception-base.vue')['default'] + FullScreen: typeof import('./../components/common/full-screen.vue')['default'] + IconAntDesignReloadOutlined: typeof import('~icons/ant-design/reload-outlined')['default'] + IconAntDesignSettingOutlined: typeof import('~icons/ant-design/setting-outlined')['default'] + IconGridiconsFullscreen: typeof import('~icons/gridicons/fullscreen')['default'] + IconGridiconsFullscreenExit: typeof import('~icons/gridicons/fullscreen-exit')['default'] + IconIcRoundDelete: typeof import('~icons/ic/round-delete')['default'] + IconIcRoundMenu: typeof import('~icons/ic/round-menu')['default'] + IconIcRoundPlus: typeof import('~icons/ic/round-plus')['default'] + IconIcRoundRefresh: typeof import('~icons/ic/round-refresh')['default'] + IconIcRoundSearch: typeof import('~icons/ic/round-search')['default'] + IconLocalBanner: typeof import('~icons/local/banner')['default'] + IconLocalLogo: typeof import('~icons/local/logo')['default'] + IconMdiDrag: typeof import('~icons/mdi/drag')['default'] + IconMdiRefresh: typeof import('~icons/mdi/refresh')['default'] + LangSwitch: typeof import('./../components/common/lang-switch.vue')['default'] + LookForward: typeof import('./../components/custom/look-forward.vue')['default'] + MenuToggler: typeof import('./../components/common/menu-toggler.vue')['default'] + PinToggler: typeof import('./../components/common/pin-toggler.vue')['default'] + ReloadButton: typeof import('./../components/common/reload-button.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + SoybeanAvatar: typeof import('./../components/custom/soybean-avatar.vue')['default'] + SvgIcon: typeof import('./../components/custom/svg-icon.vue')['default'] + SystemLogo: typeof import('./../components/common/system-logo.vue')['default'] + TableColumnSetting: typeof import('./../components/advanced/table-column-setting.vue')['default'] + TableHeaderOperation: typeof import('./../components/advanced/table-header-operation.vue')['default'] + ThemeSchemaSwitch: typeof import('./../components/common/theme-schema-switch.vue')['default'] + WaveBg: typeof import('./../components/custom/wave-bg.vue')['default'] + } +} diff --git a/src/typings/elegant-router.d.ts b/src/typings/elegant-router.d.ts new file mode 100644 index 0000000..f4767a5 --- /dev/null +++ b/src/typings/elegant-router.d.ts @@ -0,0 +1,292 @@ +/* eslint-disable */ +/* prettier-ignore */ +// Generated by elegant-router +// Read more: https://github.com/soybeanjs/elegant-router + +declare module "@elegant-router/types" { + type ElegantConstRoute = import('@elegant-router/vue').ElegantConstRoute; + + /** + * route layout + */ + export type RouteLayout = "base" | "blank"; + + /** + * route map + */ + export type RouteMap = { + "root": "/"; + "not-found": "/:pathMatch(.*)*"; + "exception": "/exception"; + "exception_403": "/exception/403"; + "exception_404": "/exception/404"; + "exception_500": "/exception/500"; + "403": "/403"; + "404": "/404"; + "500": "/500"; + "about": "/about"; + "function": "/function"; + "function_hide-child": "/function/hide-child"; + "function_hide-child_one": "/function/hide-child/one"; + "function_hide-child_three": "/function/hide-child/three"; + "function_hide-child_two": "/function/hide-child/two"; + "function_multi-tab": "/function/multi-tab"; + "function_request": "/function/request"; + "function_super-page": "/function/super-page"; + "function_tab": "/function/tab"; + "function_toggle-auth": "/function/toggle-auth"; + "home": "/home"; + "login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?"; + "manage": "/manage"; + "manage_dept": "/manage/dept"; + "manage_dict": "/manage/dict"; + "manage_menu": "/manage/menu"; + "manage_post": "/manage/post"; + "manage_role": "/manage/role"; + "manage_route": "/manage/route"; + "manage_user": "/manage/user"; + "manage_user-detail": "/manage/user-detail/:id"; + "user-center": "/user-center"; + }; + + /** + * route key + */ + export type RouteKey = keyof RouteMap; + + /** + * route path + */ + export type RoutePath = RouteMap[RouteKey]; + + /** + * custom route key + */ + export type CustomRouteKey = Extract< + RouteKey, + | "root" + | "not-found" + | "exception" + | "exception_403" + | "exception_404" + | "exception_500" + >; + + /** + * the generated route key + */ + export type GeneratedRouteKey = Exclude; + + /** + * the first level route key, which contain the layout of the route + */ + export type FirstLevelRouteKey = Extract< + RouteKey, + | "403" + | "404" + | "500" + | "about" + | "function" + | "home" + | "login" + | "manage" + | "user-center" + >; + + /** + * the custom first level route key + */ + export type CustomFirstLevelRouteKey = Extract< + CustomRouteKey, + | "root" + | "not-found" + | "exception" + >; + + /** + * the last level route key, which has the page file + */ + export type LastLevelRouteKey = Extract< + RouteKey, + | "403" + | "404" + | "500" + | "login" + | "about" + | "function_hide-child_one" + | "function_hide-child_three" + | "function_hide-child_two" + | "function_multi-tab" + | "function_request" + | "function_super-page" + | "function_tab" + | "function_toggle-auth" + | "home" + | "manage_dept" + | "manage_dict" + | "manage_menu" + | "manage_post" + | "manage_role" + | "manage_route" + | "manage_user-detail" + | "manage_user" + | "user-center" + >; + + /** + * the custom last level route key + */ + export type CustomLastLevelRouteKey = Extract< + CustomRouteKey, + | "root" + | "not-found" + | "exception_403" + | "exception_404" + | "exception_500" + >; + + /** + * the single level route key + */ + export type SingleLevelRouteKey = FirstLevelRouteKey & LastLevelRouteKey; + + /** + * the custom single level route key + */ + export type CustomSingleLevelRouteKey = CustomFirstLevelRouteKey & CustomLastLevelRouteKey; + + /** + * the first level route key, but not the single level + */ + export type FirstLevelRouteNotSingleKey = Exclude; + + /** + * the custom first level route key, but not the single level + */ + export type CustomFirstLevelRouteNotSingleKey = Exclude; + + /** + * the center level route key + */ + export type CenterLevelRouteKey = Exclude; + + /** + * the custom center level route key + */ + export type CustomCenterLevelRouteKey = Exclude; + + /** + * the center level route key + */ + type GetChildRouteKey = T extends `${K}_${infer R}` + ? R extends `${string}_${string}` + ? never + : T + : never; + + /** + * the single level route + */ + type SingleLevelRoute = K extends string + ? Omit & { + name: K; + path: RouteMap[K]; + component: `layout.${RouteLayout}$view.${K}`; + } + : never; + + /** + * the last level route + */ + type LastLevelRoute = K extends LastLevelRouteKey + ? Omit & { + name: K; + path: RouteMap[K]; + component: `view.${K}`; + } + : never; + + /** + * the center level route + */ + type CenterLevelRoute = K extends CenterLevelRouteKey + ? Omit & { + name: K; + path: RouteMap[K]; + children: (CenterLevelRoute> | LastLevelRoute>)[]; + } + : never; + + /** + * the multi level route + */ + type MultiLevelRoute = K extends string + ? ElegantConstRoute & { + name: K; + path: RouteMap[K]; + component: `layout.${RouteLayout}`; + children: (CenterLevelRoute> | LastLevelRoute>)[]; + } + : never; + + /** + * the custom first level route + */ + type CustomSingleLevelRoute = K extends string + ? Omit & { + name: K; + path: RouteMap[K]; + component?: `layout.${RouteLayout}$view.${LastLevelRouteKey}`; + } + : never; + + /** + * the custom last level route + */ + type CustomLastLevelRoute = K extends CustomLastLevelRouteKey + ? Omit & { + name: K; + path: RouteMap[K]; + component?: `view.${LastLevelRouteKey}`; + } + : never; + + /** + * the custom center level route + */ + type CustomCenterLevelRoute = K extends CustomCenterLevelRouteKey + ? Omit & { + name: K; + path: RouteMap[K]; + children: (CustomCenterLevelRoute> | CustomLastLevelRoute>)[]; + } + : never; + + /** + * the custom multi level route + */ + type CustomMultiLevelRoute = + K extends string + ? ElegantConstRoute & { + name: K; + path: RouteMap[K]; + component: `layout.${RouteLayout}`; + children: (CustomCenterLevelRoute> | CustomLastLevelRoute>)[]; + } + : never; + + /** + * the custom route + */ + type CustomRoute = CustomSingleLevelRoute | CustomMultiLevelRoute; + + /** + * the generated route + */ + type GeneratedRoute = SingleLevelRoute | MultiLevelRoute; + + /** + * the elegant route + */ + type ElegantRoute = GeneratedRoute | CustomRoute; +} diff --git a/src/typings/env.d.ts b/src/typings/env.d.ts new file mode 100644 index 0000000..d151ffb --- /dev/null +++ b/src/typings/env.d.ts @@ -0,0 +1,105 @@ +/** + * Namespace Env + * + * It is used to declare the type of the import.meta object + */ +declare namespace Env { + /** The router history mode */ + type RouterHistoryMode = 'hash' | 'history' | 'memory'; + + /** Interface for import.meta */ + interface ImportMeta extends ImportMetaEnv { + /** The base url of the application */ + readonly VITE_BASE_URL: string; + /** The title of the application */ + readonly VITE_APP_TITLE: string; + /** The description of the application */ + readonly VITE_APP_DESC: string; + /** The router history mode */ + readonly VITE_ROUTER_HISTORY_MODE?: RouterHistoryMode; + /** The prefix of the iconify icon */ + readonly VITE_ICON_PREFIX: 'icon'; + /** + * The prefix of the local icon + * + * This prefix is start with the icon prefix + */ + readonly VITE_ICON_LOCAL_PREFIX: 'local-icon'; + /** backend service base url */ + readonly VITE_SERVICE_BASE_URL: string; + /** + * success code of backend service + * + * when the code is received, the request is successful + */ + readonly VITE_SERVICE_SUCCESS_CODE: string; + /** + * logout codes of backend service + * + * when the code is received, the user will be logged out and redirected to login page + * + * use "," to separate multiple codes + */ + readonly VITE_SERVICE_LOGOUT_CODES: string; + /** + * modal logout codes of backend service + * + * when the code is received, the user will be logged out by displaying a modal + * + * use "," to separate multiple codes + */ + readonly VITE_SERVICE_MODAL_LOGOUT_CODES: string; + /** + * token expired codes of backend service + * + * when the code is received, it will refresh the token and resend the request + * + * use "," to separate multiple codes + */ + readonly VITE_SERVICE_EXPIRED_TOKEN_CODES: string; + /** when the route mode is static, the defined super role */ + readonly VITE_STATIC_SUPER_ROLE: string; + /** + * other backend service base url + * + * the value is a json + */ + readonly VITE_OTHER_SERVICE_BASE_URL: string; + /** + * Whether to enable the http proxy + * + * Only valid in the development environment + */ + readonly VITE_HTTP_PROXY?: CommonType.YesOrNo; + /** + * The auth route mode + * + * - Static: the auth routes is generated in front-end + * - Dynamic: the auth routes is generated in back-end + */ + readonly VITE_AUTH_ROUTE_MODE: 'static' | 'dynamic'; + /** + * The home route key + * + * It only has effect when the auth route mode is static, if the route mode is dynamic, the home route key is + * defined in the back-end + */ + readonly VITE_ROUTE_HOME: import('@elegant-router/types').LastLevelRouteKey; + /** + * Default menu icon if menu icon is not set + * + * Iconify icon name + */ + readonly VITE_MENU_ICON: string; + /** Whether to build with sourcemap */ + readonly VITE_SOURCE_MAP?: CommonType.YesOrNo; + /** + * Iconify api provider url + * + * If the project is deployed in intranet, you can set the api provider url to the local iconify server + * + * @link https://docs.iconify.design/api/providers.html + */ + readonly VITE_ICONIFY_URL?: string; + } +} diff --git a/src/typings/global.d.ts b/src/typings/global.d.ts new file mode 100644 index 0000000..cca9b93 --- /dev/null +++ b/src/typings/global.d.ts @@ -0,0 +1,25 @@ +interface Window { + /** NProgress instance */ + NProgress?: import('nprogress').NProgress; + /** Ant-design-vue message instance */ + $message?: import('ant-design-vue/es/message/interface').MessageInstance; + /** Ant-design-vue modal instance */ + $modal?: Omit; + /** Ant-design-vue notification instance */ + $notification?: import('ant-design-vue/es/notification/interface').NotificationInstance; +} + +interface ViewTransition { + ready: Promise; +} + +interface Document { + startViewTransition?: (callback: () => Promise | void) => ViewTransition; +} + +interface ImportMeta { + readonly env: Env.ImportMeta; +} + +/** Build time of the project */ +declare const BUILD_TIME: string; diff --git a/src/typings/router.d.ts b/src/typings/router.d.ts new file mode 100644 index 0000000..ffa804c --- /dev/null +++ b/src/typings/router.d.ts @@ -0,0 +1,65 @@ +import 'vue-router'; + +declare module 'vue-router' { + interface RouteMeta { + /** + * Title of the route + * + * It can be used in document title + */ + title: string; + /** + * I18n key of the route + * + * It's used in i18n, if it is set, the title will be ignored + */ + i18nKey?: App.I18n.I18nKey; + /** + * Roles of the route + * + * Route can be accessed if the current user has at least one of the roles + */ + roles?: string[]; + /** Whether to cache the route */ + keepAlive?: boolean; + /** + * Is constant route + * + * Does not need to login, and the route is defined in the front-end + */ + constant?: boolean; + /** + * Iconify icon + * + * It can be used in the menu or breadcrumb + */ + icon?: string; + /** + * Local icon + * + * In "src/assets/svg-icon", if it is set, the icon will be ignored + */ + localIcon?: string; + /** Router order */ + order?: number; + /** The outer link of the route */ + href?: string; + /** Whether to hide the route in the menu */ + hideInMenu?: boolean; + /** + * The menu key will be activated when entering the route + * + * The route is not in the menu + * + * @example + * the route is "user_detail", if it is set to "user_list", the menu "user_list" will be activated + */ + activeMenu?: import('@elegant-router/types').RouteKey; + /** By default, the same route path will use one tab, if set to true, it will use multiple tabs */ + multiTab?: boolean; + /** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */ + fixedIndexInTab?: number; + /** if set query parameters, it will be automatically carried when entering the route */ + query?: Record; + } +} diff --git a/src/typings/storage.d.ts b/src/typings/storage.d.ts new file mode 100644 index 0000000..c9ea420 --- /dev/null +++ b/src/typings/storage.d.ts @@ -0,0 +1,34 @@ +/** The storage namespace */ +declare namespace StorageType { + interface Session { + /** The theme color */ + themeColor: string; + // /** + // * the theme settings + // */ + // themeSettings: App.Theme.ThemeSetting; + } + + interface Local { + /** The i18n language */ + lang: App.I18n.LangType; + /** The token */ + token: string; + /** The refresh token */ + refreshToken: string; + /** The user info */ + userInfo: Api.Auth.UserInfo; + /** The theme color */ + themeColor: string; + /** The theme settings */ + themeSettings: App.Theme.ThemeSetting; + /** + * The override theme flags + * + * The value is the build time of the project + */ + overrideThemeFlag: string; + /** The global tabs */ + globalTabs: App.Global.Tab[]; + } +} diff --git a/src/typings/union-key.d.ts b/src/typings/union-key.d.ts new file mode 100644 index 0000000..ff5020b --- /dev/null +++ b/src/typings/union-key.d.ts @@ -0,0 +1,149 @@ +/** The union key namespace */ +declare namespace UnionKey { + /** + * The login module + * + * - pwd-login: password login + * - code-login: phone code login + * - register: register + * - reset-pwd: reset password + * - bind-wechat: bind wechat + */ + type LoginModule = 'pwd-login' | 'code-login' | 'register' | 'reset-pwd' | 'bind-wechat'; + + /** Theme scheme */ + type ThemeScheme = 'light' | 'dark' | 'auto'; + + /** + * The layout mode + * + * - vertical: the vertical menu in left + * - horizontal: the horizontal menu in top + * - vertical-mix: two vertical mixed menus in left + * - horizontal-mix: the vertical menu in left and horizontal menu in top + */ + type ThemeLayoutMode = 'vertical' | 'horizontal' | 'vertical-mix' | 'horizontal-mix'; + + /** + * The scroll mode when content overflow + * + * - wrapper: the wrapper component's root element overflow + * - content: the content component overflow + */ + type ThemeScrollMode = import('@sa/materials').LayoutScrollMode; + + /** Page animate mode */ + type ThemePageAnimateMode = 'fade' | 'fade-slide' | 'fade-bottom' | 'fade-scale' | 'zoom-fade' | 'zoom-out' | 'none'; + + /** + * Tab mode + * + * - chrome: chrome style + * - button: button style + */ + type ThemeTabMode = import('@sa/materials').PageTabMode; + + /** Unocss animate key */ + type UnoCssAnimateKey = + | 'pulse' + | 'bounce' + | 'spin' + | 'ping' + | 'bounce-alt' + | 'flash' + | 'pulse-alt' + | 'rubber-band' + | 'shake-x' + | 'shake-y' + | 'head-shake' + | 'swing' + | 'tada' + | 'wobble' + | 'jello' + | 'heart-beat' + | 'hinge' + | 'jack-in-the-box' + | 'light-speed-in-left' + | 'light-speed-in-right' + | 'light-speed-out-left' + | 'light-speed-out-right' + | 'flip' + | 'flip-in-x' + | 'flip-in-y' + | 'flip-out-x' + | 'flip-out-y' + | 'rotate-in' + | 'rotate-in-down-left' + | 'rotate-in-down-right' + | 'rotate-in-up-left' + | 'rotate-in-up-right' + | 'rotate-out' + | 'rotate-out-down-left' + | 'rotate-out-down-right' + | 'rotate-out-up-left' + | 'rotate-out-up-right' + | 'roll-in' + | 'roll-out' + | 'zoom-in' + | 'zoom-in-down' + | 'zoom-in-left' + | 'zoom-in-right' + | 'zoom-in-up' + | 'zoom-out' + | 'zoom-out-down' + | 'zoom-out-left' + | 'zoom-out-right' + | 'zoom-out-up' + | 'bounce-in' + | 'bounce-in-down' + | 'bounce-in-left' + | 'bounce-in-right' + | 'bounce-in-up' + | 'bounce-out' + | 'bounce-out-down' + | 'bounce-out-left' + | 'bounce-out-right' + | 'bounce-out-up' + | 'slide-in-down' + | 'slide-in-left' + | 'slide-in-right' + | 'slide-in-up' + | 'slide-out-down' + | 'slide-out-left' + | 'slide-out-right' + | 'slide-out-up' + | 'fade-in' + | 'fade-in-down' + | 'fade-in-down-big' + | 'fade-in-left' + | 'fade-in-left-big' + | 'fade-in-right' + | 'fade-in-right-big' + | 'fade-in-up' + | 'fade-in-up-big' + | 'fade-in-top-left' + | 'fade-in-top-right' + | 'fade-in-bottom-left' + | 'fade-in-bottom-right' + | 'fade-out' + | 'fade-out-down' + | 'fade-out-down-big' + | 'fade-out-left' + | 'fade-out-left-big' + | 'fade-out-right' + | 'fade-out-right-big' + | 'fade-out-up' + | 'fade-out-up-big' + | 'fade-out-top-left' + | 'fade-out-top-right' + | 'fade-out-bottom-left' + | 'fade-out-bottom-right' + | 'back-in-up' + | 'back-in-down' + | 'back-in-right' + | 'back-in-left' + | 'back-out-up' + | 'back-out-down' + | 'back-out-right' + | 'back-out-left'; +} diff --git a/src/utils/common.ts b/src/utils/common.ts new file mode 100644 index 0000000..ddb3125 --- /dev/null +++ b/src/utils/common.ts @@ -0,0 +1,38 @@ +import { $t } from '@/locales'; + +/** + * Transform record to option + * + * @example + * ```ts + * const record = { + * key1: 'label1', + * key2: 'label2' + * }; + * const options = transformRecordToOption(record); + * // [ + * // { value: 'key1', label: 'label1' }, + * // { value: 'key2', label: 'label2' } + * // ] + * ```; + * + * @param record + */ +export function transformRecordToOption>(record: T) { + return Object.entries(record).map(([value, label]) => ({ + value, + label + })) as CommonType.Option[]; +} + +/** + * Translate options + * + * @param options + */ +export function translateOptions(options: CommonType.Option[]) { + return options.map(option => ({ + ...option, + label: $t(option.label as App.I18n.I18nKey) + })); +} diff --git a/src/utils/menu.ts b/src/utils/menu.ts new file mode 100644 index 0000000..fd3e676 --- /dev/null +++ b/src/utils/menu.ts @@ -0,0 +1,74 @@ +import type { DataNode } from 'ant-design-vue/es/tree'; + +/** + * Antd tree component don't add root array key to checkedKeys(only in select all), so we need to add root node id to + * checkedKeys + * + * @param menuList menu list + * @param checkedKeys checked keys + * @returns + */ +export function transformMenuChildWithRootIds(menuList: DataNode[], checkedKeys: number[]): number[] { + const checkedKeysSet = new Set(checkedKeys); + + function changeCheckedKeys(menus: DataNode[]) { + menus.forEach(menu => { + if (menu.children) { + changeCheckedKeys(menu.children); + checkedKeysSet.add(menu.key as number); + } + }); + } + + changeCheckedKeys(menuList); + + return Array.from(checkedKeysSet); +} + +export function transformListToTree( + list: T[], + rowKey: Exclude +) { + const tree = cloneDeep(list); + const map = new Map(); + tree.forEach(item => { + map.set(item[rowKey] as string, item); + }); + + const treeData: T[] = []; + tree.forEach(item => { + if (item.parentId === 0) { + treeData.push(item); + } else { + const parent = map.get(item.parentId); + if (parent) { + if (!parent.children) { + parent.children = []; + } + parent.children.push(item); + } + } + }); + return removeEmptyChildren(treeData); +} + +/** + * Remove empty children + * + * @param treeDataGet tree data + */ +export function removeEmptyChildren( + treeDataGet: T[], + isClone = false +) { + const tree = isClone ? cloneDeep(treeDataGet) : treeDataGet; + tree.forEach(item => { + if (item.children && item.children.length) { + item.children = item.children.sort((a, b) => a.orderNum - b.orderNum); + removeEmptyChildren(item.children); + } else { + delete item.children; + } + }); + return tree; +} diff --git a/src/utils/permission.ts b/src/utils/permission.ts new file mode 100644 index 0000000..8cd3084 --- /dev/null +++ b/src/utils/permission.ts @@ -0,0 +1,7 @@ +import { useAuthStore } from '@/store/modules/auth'; + +export function isShowBtn(permission: string) { + const { permissions, userInfo } = storeToRefs(useAuthStore()); + + return userInfo.value.roles.includes('admin') || permissions.value.includes(permission); +} diff --git a/src/utils/service.ts b/src/utils/service.ts new file mode 100644 index 0000000..5ae09fb --- /dev/null +++ b/src/utils/service.ts @@ -0,0 +1,73 @@ +/** + * Create service config by current env + * + * @param env The current env + */ +export function createServiceConfig(env: Env.ImportMeta) { + const { VITE_SERVICE_BASE_URL, VITE_OTHER_SERVICE_BASE_URL } = env; + + let other = {} as Record; + try { + other = JSON.parse(VITE_OTHER_SERVICE_BASE_URL); + } catch (error) { + // eslint-disable-next-line no-console + console.error('VITE_OTHER_SERVICE_BASE_URL is not a valid JSON string'); + } + + const httpConfig: App.Service.SimpleServiceConfig = { + baseURL: VITE_SERVICE_BASE_URL, + other + }; + + const otherHttpKeys = Object.keys(httpConfig.other) as App.Service.OtherBaseURLKey[]; + + const otherConfig: App.Service.OtherServiceConfigItem[] = otherHttpKeys.map(key => { + return { + key, + baseURL: httpConfig.other[key], + proxyPattern: createProxyPattern(key) + }; + }); + + const config: App.Service.ServiceConfig = { + baseURL: httpConfig.baseURL, + proxyPattern: createProxyPattern(), + other: otherConfig + }; + + return config; +} + +/** + * get backend service base url + * + * @param env - the current env + * @param isProxy - if use proxy + */ +export function getServiceBaseURL(env: Env.ImportMeta, isProxy: boolean) { + const { baseURL, other } = createServiceConfig(env); + + const otherBaseURL = {} as Record; + + other.forEach(item => { + otherBaseURL[item.key] = isProxy ? item.proxyPattern : item.baseURL; + }); + + return { + baseURL: isProxy ? createProxyPattern() : baseURL, + otherBaseURL + }; +} + +/** + * Get proxy pattern of backend service base url + * + * @param key If not set, will use the default key + */ +function createProxyPattern(key?: App.Service.OtherBaseURLKey) { + if (!key) { + return '/proxy-default'; + } + + return `/proxy-${key}`; +} diff --git a/src/utils/storage.ts b/src/utils/storage.ts new file mode 100644 index 0000000..0cc5168 --- /dev/null +++ b/src/utils/storage.ts @@ -0,0 +1,7 @@ +import { createLocalforage, createStorage } from '@sa/utils'; + +export const localStg = createStorage('local'); + +export const sessionStg = createStorage('session'); + +export const localforage = createLocalforage('local'); diff --git a/src/views/_builtin/403/index.vue b/src/views/_builtin/403/index.vue new file mode 100644 index 0000000..3c59ddf --- /dev/null +++ b/src/views/_builtin/403/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/_builtin/404/index.vue b/src/views/_builtin/404/index.vue new file mode 100644 index 0000000..4b4bf5b --- /dev/null +++ b/src/views/_builtin/404/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/_builtin/500/index.vue b/src/views/_builtin/500/index.vue new file mode 100644 index 0000000..0028cf2 --- /dev/null +++ b/src/views/_builtin/500/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/_builtin/login/index.vue b/src/views/_builtin/login/index.vue new file mode 100644 index 0000000..d218af7 --- /dev/null +++ b/src/views/_builtin/login/index.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/views/_builtin/login/modules/bind-wechat.vue b/src/views/_builtin/login/modules/bind-wechat.vue new file mode 100644 index 0000000..cb417bf --- /dev/null +++ b/src/views/_builtin/login/modules/bind-wechat.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/src/views/_builtin/login/modules/code-login.vue b/src/views/_builtin/login/modules/code-login.vue new file mode 100644 index 0000000..6e50ec0 --- /dev/null +++ b/src/views/_builtin/login/modules/code-login.vue @@ -0,0 +1,66 @@ + + + + + diff --git a/src/views/_builtin/login/modules/pwd-login.vue b/src/views/_builtin/login/modules/pwd-login.vue new file mode 100644 index 0000000..fe74363 --- /dev/null +++ b/src/views/_builtin/login/modules/pwd-login.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/src/views/_builtin/login/modules/register.vue b/src/views/_builtin/login/modules/register.vue new file mode 100644 index 0000000..608fb39 --- /dev/null +++ b/src/views/_builtin/login/modules/register.vue @@ -0,0 +1,86 @@ + + + + + diff --git a/src/views/_builtin/login/modules/reset-pwd.vue b/src/views/_builtin/login/modules/reset-pwd.vue new file mode 100644 index 0000000..ecc4104 --- /dev/null +++ b/src/views/_builtin/login/modules/reset-pwd.vue @@ -0,0 +1,80 @@ + + + + + diff --git a/src/views/about/index.vue b/src/views/about/index.vue new file mode 100644 index 0000000..1160b9d --- /dev/null +++ b/src/views/about/index.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/src/views/function/hide-child/one/index.vue b/src/views/function/hide-child/one/index.vue new file mode 100644 index 0000000..2a654c5 --- /dev/null +++ b/src/views/function/hide-child/one/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/function/hide-child/three/index.vue b/src/views/function/hide-child/three/index.vue new file mode 100644 index 0000000..f9b42b4 --- /dev/null +++ b/src/views/function/hide-child/three/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/function/hide-child/two/index.vue b/src/views/function/hide-child/two/index.vue new file mode 100644 index 0000000..2fa26a8 --- /dev/null +++ b/src/views/function/hide-child/two/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/function/multi-tab/index.vue b/src/views/function/multi-tab/index.vue new file mode 100644 index 0000000..d26d727 --- /dev/null +++ b/src/views/function/multi-tab/index.vue @@ -0,0 +1,24 @@ + + + + + diff --git a/src/views/function/request/index.vue b/src/views/function/request/index.vue new file mode 100644 index 0000000..2e460de --- /dev/null +++ b/src/views/function/request/index.vue @@ -0,0 +1,30 @@ + + + + + diff --git a/src/views/function/super-page/index.vue b/src/views/function/super-page/index.vue new file mode 100644 index 0000000..2a654c5 --- /dev/null +++ b/src/views/function/super-page/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/function/tab/index.vue b/src/views/function/tab/index.vue new file mode 100644 index 0000000..0ffb2d4 --- /dev/null +++ b/src/views/function/tab/index.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/src/views/function/toggle-auth/index.vue b/src/views/function/toggle-auth/index.vue new file mode 100644 index 0000000..a66c85b --- /dev/null +++ b/src/views/function/toggle-auth/index.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/views/home/index.vue b/src/views/home/index.vue new file mode 100644 index 0000000..0c7da6b --- /dev/null +++ b/src/views/home/index.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/src/views/home/modules/card-data.vue b/src/views/home/modules/card-data.vue new file mode 100644 index 0000000..ba6a15a --- /dev/null +++ b/src/views/home/modules/card-data.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/src/views/home/modules/creativity-banner.vue b/src/views/home/modules/creativity-banner.vue new file mode 100644 index 0000000..36c0d62 --- /dev/null +++ b/src/views/home/modules/creativity-banner.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/src/views/home/modules/header-banner.vue b/src/views/home/modules/header-banner.vue new file mode 100644 index 0000000..df1e80c --- /dev/null +++ b/src/views/home/modules/header-banner.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/src/views/home/modules/line-chart.vue b/src/views/home/modules/line-chart.vue new file mode 100644 index 0000000..7cae56f --- /dev/null +++ b/src/views/home/modules/line-chart.vue @@ -0,0 +1,151 @@ + + + + + diff --git a/src/views/home/modules/pie-chart.vue b/src/views/home/modules/pie-chart.vue new file mode 100644 index 0000000..6714f8a --- /dev/null +++ b/src/views/home/modules/pie-chart.vue @@ -0,0 +1,109 @@ + + + + + diff --git a/src/views/home/modules/project-news.vue b/src/views/home/modules/project-news.vue new file mode 100644 index 0000000..212e3a0 --- /dev/null +++ b/src/views/home/modules/project-news.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/src/views/manage/dept/index.vue b/src/views/manage/dept/index.vue new file mode 100644 index 0000000..e7d4cfd --- /dev/null +++ b/src/views/manage/dept/index.vue @@ -0,0 +1,162 @@ + + + + + diff --git a/src/views/manage/dept/modules/dept-operate-modal.vue b/src/views/manage/dept/modules/dept-operate-modal.vue new file mode 100644 index 0000000..376aaae --- /dev/null +++ b/src/views/manage/dept/modules/dept-operate-modal.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/src/views/manage/dept/modules/dept-search.vue b/src/views/manage/dept/modules/dept-search.vue new file mode 100644 index 0000000..adfff32 --- /dev/null +++ b/src/views/manage/dept/modules/dept-search.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/views/manage/dept/modules/form.ts b/src/views/manage/dept/modules/form.ts new file mode 100644 index 0000000..865d2a6 --- /dev/null +++ b/src/views/manage/dept/modules/form.ts @@ -0,0 +1,37 @@ +import type { DeptFormType } from '@/service/api/dept'; + +const { defaultRequiredRule } = useFormRules(); + +export function resetForm(): DeptFormType { + return { + deptName: '', + parentId: 100, + orderNum: 0, + leader: '', + phone: '', + email: '', + status: '0', + remark: '' + }; +} + +export const statusOptions = [ + { label: '启用', value: '0' }, + { label: '禁用', value: '1' } +]; + +export const formRules = { + deptName: defaultRequiredRule, + parentId: defaultRequiredRule, + orderNum: [ + defaultRequiredRule, + { + validator: (rule, value) => { + if (value < 0) { + return Promise.reject(rule.message || '排序必须大于等于0'); + } + return Promise.resolve(); + } + } + ] +} as Record; diff --git a/src/views/manage/dict/index.vue b/src/views/manage/dict/index.vue new file mode 100644 index 0000000..0c6812e --- /dev/null +++ b/src/views/manage/dict/index.vue @@ -0,0 +1,166 @@ + + + + + diff --git a/src/views/manage/dict/modules/dict-operate-drawer.vue b/src/views/manage/dict/modules/dict-operate-drawer.vue new file mode 100644 index 0000000..c26f06e --- /dev/null +++ b/src/views/manage/dict/modules/dict-operate-drawer.vue @@ -0,0 +1,140 @@ + + + + + diff --git a/src/views/manage/dict/modules/dict-search.vue b/src/views/manage/dict/modules/dict-search.vue new file mode 100644 index 0000000..73562ae --- /dev/null +++ b/src/views/manage/dict/modules/dict-search.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/src/views/manage/menu/index.vue b/src/views/manage/menu/index.vue new file mode 100644 index 0000000..5e0272b --- /dev/null +++ b/src/views/manage/menu/index.vue @@ -0,0 +1,171 @@ + + + + + diff --git a/src/views/manage/menu/modules/form.ts b/src/views/manage/menu/modules/form.ts new file mode 100644 index 0000000..ea056a6 --- /dev/null +++ b/src/views/manage/menu/modules/form.ts @@ -0,0 +1,70 @@ +const { defaultRequiredRule } = useFormRules(); + +export type MenuModelType = Pick< + Api.SystemManage.Menu, + | 'menuName' + | 'menuType' + | 'icon' + | 'path' + | 'component' + | 'orderNum' + | 'status' + | 'parentId' + | 'hideInMenu' + | 'fixedIndexInTab' + | 'iconType' + | 'isFrame' + | 'perms' + | 'isCache' + | 'name' +>; + +export function resetAddForm(): MenuModelType { + return { + menuName: '', + menuType: 'M', + icon: '', + path: '', + component: '', + orderNum: 0, + status: '0', + parentId: 0, + iconType: '1', + hideInMenu: '0', + isFrame: '1', + perms: '', + name: '', + isCache: '0' + }; +} + +export const formRules = { + menuName: defaultRequiredRule, + menuType: defaultRequiredRule, + icon: defaultRequiredRule, + path: defaultRequiredRule, + component: defaultRequiredRule, + status: defaultRequiredRule, + orderNum: [ + defaultRequiredRule, + { + validator: (rule, value) => { + if (value < 0) { + return Promise.reject(rule.message || '排序必须大于等于0'); + } + return Promise.resolve(); + } + } + ] +} as Record; + +export const menuTypeOptions = [ + { label: '目录', value: 'M' }, + { label: '菜单', value: 'C' }, + { label: '按钮', value: 'F' } +]; + +export const menuStatusOptions = [ + { label: '正常', value: '0' }, + { label: '停用', value: '1' } +]; diff --git a/src/views/manage/menu/modules/icon-select.vue b/src/views/manage/menu/modules/icon-select.vue new file mode 100644 index 0000000..63ad2b8 --- /dev/null +++ b/src/views/manage/menu/modules/icon-select.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/src/views/manage/menu/modules/icon.ts b/src/views/manage/menu/modules/icon.ts new file mode 100644 index 0000000..b64297f --- /dev/null +++ b/src/views/manage/menu/modules/icon.ts @@ -0,0 +1,39 @@ +export const icons = [ + 'carbon:3d-cursor', + 'carbon:account', + 'carbon:ai-results-low', + 'carbon:assembly-cluster', + 'carbon:battery-charging', + 'carbon:battery-full', + 'carbon:bicycle', + 'carbon:building-insights-3', + 'carbon:calendar', + 'carbon:carbon', + 'carbon:carbon-for-ibm-product', + 'carbon:category', + 'carbon:center-to-fit', + 'carbon:chart-area-smooth', + 'carbon:chart-median', + 'carbon:chat-bot', + 'carbon:cics-system-group', + 'carbon:database-messaging', + 'carbon:document', + 'carbon:document-multiple-01', + 'carbon:earth-americas-filled', + 'carbon:folder', + 'carbon:forum', + 'carbon:group', + 'carbon:ibm-cloud-bare-metal-server', + 'carbon:ibm-telehealth', + 'carbon:image-search-alt', + 'carbon:laptop', + 'carbon:machine-learning', + 'carbon:report', + 'carbon:rocket', + 'carbon:settings', + 'carbon:settings-services', + 'carbon:shopping-cart', + 'carbon:user-avatar', + 'carbon:user-multiple', + 'carbon:volume-block-storage' +]; diff --git a/src/views/manage/menu/modules/menu-operate-modal.vue b/src/views/manage/menu/modules/menu-operate-modal.vue new file mode 100644 index 0000000..11bbb76 --- /dev/null +++ b/src/views/manage/menu/modules/menu-operate-modal.vue @@ -0,0 +1,185 @@ + + + + + diff --git a/src/views/manage/post/index.vue b/src/views/manage/post/index.vue new file mode 100644 index 0000000..4793518 --- /dev/null +++ b/src/views/manage/post/index.vue @@ -0,0 +1,173 @@ + + + + + diff --git a/src/views/manage/post/modules/post-operate-drawer.vue b/src/views/manage/post/modules/post-operate-drawer.vue new file mode 100644 index 0000000..01f7c6d --- /dev/null +++ b/src/views/manage/post/modules/post-operate-drawer.vue @@ -0,0 +1,144 @@ + + + + + diff --git a/src/views/manage/post/modules/post-search.vue b/src/views/manage/post/modules/post-search.vue new file mode 100644 index 0000000..f41e019 --- /dev/null +++ b/src/views/manage/post/modules/post-search.vue @@ -0,0 +1,75 @@ + + + + + diff --git a/src/views/manage/role/index.vue b/src/views/manage/role/index.vue new file mode 100644 index 0000000..6a51e50 --- /dev/null +++ b/src/views/manage/role/index.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/src/views/manage/role/modules/menu-auth.vue b/src/views/manage/role/modules/menu-auth.vue new file mode 100644 index 0000000..9a4919f --- /dev/null +++ b/src/views/manage/role/modules/menu-auth.vue @@ -0,0 +1,123 @@ + + + + + diff --git a/src/views/manage/role/modules/role-operate-drawer.vue b/src/views/manage/role/modules/role-operate-drawer.vue new file mode 100644 index 0000000..3b6f010 --- /dev/null +++ b/src/views/manage/role/modules/role-operate-drawer.vue @@ -0,0 +1,167 @@ + + + + + diff --git a/src/views/manage/role/modules/role-search.vue b/src/views/manage/role/modules/role-search.vue new file mode 100644 index 0000000..09b09fd --- /dev/null +++ b/src/views/manage/role/modules/role-search.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/src/views/manage/route/index.vue b/src/views/manage/route/index.vue new file mode 100644 index 0000000..8899ad9 --- /dev/null +++ b/src/views/manage/route/index.vue @@ -0,0 +1,7 @@ + + + + + diff --git a/src/views/manage/user-detail/[id].vue b/src/views/manage/user-detail/[id].vue new file mode 100644 index 0000000..c7f6751 --- /dev/null +++ b/src/views/manage/user-detail/[id].vue @@ -0,0 +1,15 @@ + + + + + diff --git a/src/views/manage/user/index.vue b/src/views/manage/user/index.vue new file mode 100644 index 0000000..e9f64e6 --- /dev/null +++ b/src/views/manage/user/index.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/src/views/manage/user/modules/user-operate-drawer.vue b/src/views/manage/user/modules/user-operate-drawer.vue new file mode 100644 index 0000000..74cad02 --- /dev/null +++ b/src/views/manage/user/modules/user-operate-drawer.vue @@ -0,0 +1,216 @@ + + + + + diff --git a/src/views/manage/user/modules/user-search.vue b/src/views/manage/user/modules/user-search.vue new file mode 100644 index 0000000..8bf1302 --- /dev/null +++ b/src/views/manage/user/modules/user-search.vue @@ -0,0 +1,90 @@ + + + + + diff --git a/src/views/user-center/index.vue b/src/views/user-center/index.vue new file mode 100644 index 0000000..6c9affb --- /dev/null +++ b/src/views/user-center/index.vue @@ -0,0 +1,11 @@ + + + + + diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..362dbb8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ESNext", + "jsx": "preserve", + "jsxImportSource": "vue", + "lib": ["DOM", "ESNext"], + "baseUrl": ".", + "module": "ESNext", + "moduleResolution": "node", + "paths": { + "@/*": ["./src/*"], + "~/*": ["./*"] + }, + "resolveJsonModule": true, + "types": ["vite/client", "node", "unplugin-icons/types/vue", "ant-design-vue/typings/global.d.ts"], + "strict": true, + "strictNullChecks": true, + "noUnusedLocals": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + "forceConsistentCasingInFileNames": true, + "isolatedModules": true + }, + "include": ["./**/*.ts", "./**/*.tsx", "./**/*.vue"], + "exclude": ["node_modules", "dist"] +} diff --git a/uno.config.ts b/uno.config.ts new file mode 100644 index 0000000..c3ab916 --- /dev/null +++ b/uno.config.ts @@ -0,0 +1,33 @@ +import { defineConfig } from '@unocss/vite'; +import transformerDirectives from '@unocss/transformer-directives'; +import transformerVariantGroup from '@unocss/transformer-variant-group'; +import presetUno from '@unocss/preset-uno'; +import type { Theme } from '@unocss/preset-uno'; +import { presetSoybeanAdmin } from '@sa/uno-preset'; +import presetAttributify from '@unocss/preset-attributify'; +import { themeVars } from './src/theme/vars'; + +export default defineConfig({ + content: { + pipeline: { + exclude: ['node_modules', 'dist'] + } + }, + theme: { + ...themeVars, + fontSize: { + 'icon-xs': '0.875rem', + 'icon-small': '1rem', + icon: '1.125rem', + 'icon-large': '1.5rem', + 'icon-xl': '2rem' + } + }, + shortcuts: { + 'card-wrapper': 'rd-8px shadow-sm', + 'flex-between': 'flex justify-between' + }, + transformers: [transformerDirectives(), transformerVariantGroup()], + // @ts-expect-error presetUno is not compatible with the new API + presets: [presetUno({ dark: 'class' }), presetSoybeanAdmin(), presetAttributify()] +}); diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..1393de1 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,52 @@ +import process from 'node:process'; +import { URL, fileURLToPath } from 'node:url'; +import { defineConfig, loadEnv } from 'vite'; +import dayjs from 'dayjs'; +import { setupVitePlugins } from './build/plugins'; +import { createViteProxy } from './build/config'; + +export default defineConfig(configEnv => { + const viteEnv = loadEnv(configEnv.mode, process.cwd()) as unknown as Env.ImportMeta; + + const buildTime = dayjs().format('YYYY-MM-DD HH:mm:ss'); + + return { + base: viteEnv.VITE_BASE_URL, + resolve: { + alias: { + '~': fileURLToPath(new URL('./', import.meta.url)), + '@': fileURLToPath(new URL('./src', import.meta.url)) + } + }, + css: { + preprocessorOptions: { + scss: { + additionalData: `@use "./src/styles/scss/global.scss" as *;` + } + } + }, + plugins: setupVitePlugins(viteEnv), + define: { + BUILD_TIME: JSON.stringify(buildTime) + }, + server: { + host: '0.0.0.0', + port: 9527, + open: true, + proxy: createViteProxy(viteEnv, configEnv.command === 'serve'), + fs: { + cachedChecks: false + } + }, + preview: { + port: 9725 + }, + build: { + reportCompressedSize: false, + sourcemap: viteEnv.VITE_SOURCE_MAP === 'Y', + commonjsOptions: { + ignoreTryCatch: false + } + } + }; +}); diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..cb8191c --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + test: { + + } +})