diff --git a/.env.example b/.env.example index 67049f6..43c8496 100644 --- a/.env.example +++ b/.env.example @@ -1,38 +1,6 @@ -# 程序配置 -## 程序名称 -MAIN_VITE_TITLE = "SPlayer" -## 程序主端口 -MAIN_VITE_MAIN_PORT = 7899 -## 程序开发环境运行端口 -MAIN_VITE_DEV_PORT = 6944 - -# 全局 API 配置 -## API 运行地址 -MAIN_VITE_SERVER_HOST = 127.0.0.1 -## API 运行端口 -MAIN_VITE_SERVER_PORT = 11451 -## API 在线地址( 网址结尾不要加 / ) -### 用于非客户端( 浏览器环境 ) -RENDERER_VITE_SERVER_URL = /api - -# 程序信息 -RENDERER_VITE_SITE_TITLE = "SPlayer" -RENDERER_VITE_SITE_ANTHOR = "無名" -RENDERER_VITE_SITE_KEYWORDS = "SPlayer,云音乐,播放器,在线音乐,在线播放器,音乐播放器" -RENDERER_VITE_SITE_DES = "一个简约的在线音乐播放器,具有音乐搜索、播放、每日推荐、私人FM、歌词显示、歌曲评论、网易云登录与云盘等功能" -RENDERER_VITE_SITE_URL = "imsyy.top" - -# Cookie -## 咪咕音乐 Cookie -MAIN_VITE_MIGU_COOKIE = "" - -# 公告配置 -## 若无需公告,请将标题或内容任意一项设为空即可 -## 公告类型 -RENDERER_VITE_ANN_TYPE = "info" -## 公告标题 -RENDERER_VITE_ANN_TITLE = "" -## 公告内容 -RENDERER_VITE_ANN_CONTENT = "" -## 公告时长(毫秒)不可超过 999999 -RENDERER_VITE_ANN_DURATION = 8000 +## WEB 端口 +VITE_WEB_PORT = 14558 +## API 端口 +VITE_SERVER_PORT = 25884 +## API 地址 - 结尾不要加 / +VITE_API_URL = /api/netease diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json new file mode 100644 index 0000000..821c41c --- /dev/null +++ b/.eslintrc-auto-import.json @@ -0,0 +1,297 @@ +{ + "globals": { + "Component": true, + "ComponentPublicInstance": true, + "ComputedRef": true, + "EffectScope": true, + "ExtractDefaultPropTypes": true, + "ExtractPropTypes": true, + "ExtractPublicPropTypes": true, + "InjectionKey": true, + "PropType": true, + "Ref": true, + "VNode": true, + "WritableComputedRef": true, + "asyncComputed": true, + "autoResetRef": true, + "computed": true, + "computedAsync": true, + "computedEager": true, + "computedInject": true, + "computedWithControl": true, + "controlledComputed": true, + "controlledRef": true, + "createApp": true, + "createEventHook": true, + "createGlobalState": true, + "createInjectionState": true, + "createReactiveFn": true, + "createReusableTemplate": true, + "createSharedComposable": true, + "createTemplatePromise": true, + "createUnrefFn": true, + "customRef": true, + "debouncedRef": true, + "debouncedWatch": true, + "defineAsyncComponent": true, + "defineComponent": true, + "eagerComputed": true, + "effectScope": true, + "extendRef": true, + "getCurrentInstance": true, + "getCurrentScope": true, + "h": true, + "ignorableWatch": true, + "inject": true, + "injectLocal": true, + "isDefined": true, + "isProxy": true, + "isReactive": true, + "isReadonly": true, + "isRef": true, + "makeDestructurable": true, + "markRaw": true, + "nextTick": true, + "onActivated": true, + "onBeforeMount": true, + "onBeforeRouteLeave": true, + "onBeforeRouteUpdate": true, + "onBeforeUnmount": true, + "onBeforeUpdate": true, + "onClickOutside": true, + "onDeactivated": true, + "onErrorCaptured": true, + "onKeyStroke": true, + "onLongPress": true, + "onMounted": true, + "onRenderTracked": true, + "onRenderTriggered": true, + "onScopeDispose": true, + "onServerPrefetch": true, + "onStartTyping": true, + "onUnmounted": true, + "onUpdated": true, + "pausableWatch": true, + "provide": true, + "provideLocal": true, + "reactify": true, + "reactifyObject": true, + "reactive": true, + "reactiveComputed": true, + "reactiveOmit": true, + "reactivePick": true, + "readonly": true, + "ref": true, + "refAutoReset": true, + "refDebounced": true, + "refDefault": true, + "refThrottled": true, + "refWithControl": true, + "resolveComponent": true, + "resolveRef": true, + "resolveUnref": true, + "shallowReactive": true, + "shallowReadonly": true, + "shallowRef": true, + "syncRef": true, + "syncRefs": true, + "templateRef": true, + "throttledRef": true, + "throttledWatch": true, + "toRaw": true, + "toReactive": true, + "toRef": true, + "toRefs": true, + "toValue": true, + "triggerRef": true, + "tryOnBeforeMount": true, + "tryOnBeforeUnmount": true, + "tryOnMounted": true, + "tryOnScopeDispose": true, + "tryOnUnmounted": true, + "unref": true, + "unrefElement": true, + "until": true, + "useActiveElement": true, + "useAnimate": true, + "useArrayDifference": true, + "useArrayEvery": true, + "useArrayFilter": true, + "useArrayFind": true, + "useArrayFindIndex": true, + "useArrayFindLast": true, + "useArrayIncludes": true, + "useArrayJoin": true, + "useArrayMap": true, + "useArrayReduce": true, + "useArraySome": true, + "useArrayUnique": true, + "useAsyncQueue": true, + "useAsyncState": true, + "useAttrs": true, + "useBase64": true, + "useBattery": true, + "useBluetooth": true, + "useBreakpoints": true, + "useBroadcastChannel": true, + "useBrowserLocation": true, + "useCached": true, + "useClipboard": true, + "useClipboardItems": true, + "useCloned": true, + "useColorMode": true, + "useConfirmDialog": true, + "useCounter": true, + "useCssModule": true, + "useCssVar": true, + "useCssVars": true, + "useCurrentElement": true, + "useCycleList": true, + "useDark": true, + "useDateFormat": true, + "useDebounce": true, + "useDebounceFn": true, + "useDebouncedRefHistory": true, + "useDeviceMotion": true, + "useDeviceOrientation": true, + "useDevicePixelRatio": true, + "useDevicesList": true, + "useDialog": true, + "useDisplayMedia": true, + "useDocumentVisibility": true, + "useDraggable": true, + "useDropZone": true, + "useElementBounding": true, + "useElementByPoint": true, + "useElementHover": true, + "useElementSize": true, + "useElementVisibility": true, + "useEventBus": true, + "useEventListener": true, + "useEventSource": true, + "useEyeDropper": true, + "useFavicon": true, + "useFetch": true, + "useFileDialog": true, + "useFileSystemAccess": true, + "useFocus": true, + "useFocusWithin": true, + "useFps": true, + "useFullscreen": true, + "useGamepad": true, + "useGeolocation": true, + "useIdle": true, + "useImage": true, + "useInfiniteScroll": true, + "useIntersectionObserver": true, + "useInterval": true, + "useIntervalFn": true, + "useKeyModifier": true, + "useLastChanged": true, + "useLink": true, + "useLoadingBar": true, + "useLocalStorage": true, + "useMagicKeys": true, + "useManualRefHistory": true, + "useMediaControls": true, + "useMediaQuery": true, + "useMemoize": true, + "useMemory": true, + "useMessage": true, + "useMounted": true, + "useMouse": true, + "useMouseInElement": true, + "useMousePressed": true, + "useMutationObserver": true, + "useNavigatorLanguage": true, + "useNetwork": true, + "useNotification": true, + "useNow": true, + "useObjectUrl": true, + "useOffsetPagination": true, + "useOnline": true, + "usePageLeave": true, + "useParallax": true, + "useParentElement": true, + "usePerformanceObserver": true, + "usePermission": true, + "usePointer": true, + "usePointerLock": true, + "usePointerSwipe": true, + "usePreferredColorScheme": true, + "usePreferredContrast": true, + "usePreferredDark": true, + "usePreferredLanguages": true, + "usePreferredReducedMotion": true, + "usePrevious": true, + "useRafFn": true, + "useRefHistory": true, + "useResizeObserver": true, + "useRoute": true, + "useRouter": true, + "useScreenOrientation": true, + "useScreenSafeArea": true, + "useScriptTag": true, + "useScroll": true, + "useScrollLock": true, + "useSessionStorage": true, + "useShare": true, + "useSlots": true, + "useSorted": true, + "useSpeechRecognition": true, + "useSpeechSynthesis": true, + "useStepper": true, + "useStorage": true, + "useStorageAsync": true, + "useStyleTag": true, + "useSupported": true, + "useSwipe": true, + "useTemplateRefsList": true, + "useTextDirection": true, + "useTextSelection": true, + "useTextareaAutosize": true, + "useThrottle": true, + "useThrottleFn": true, + "useThrottledRefHistory": true, + "useTimeAgo": true, + "useTimeout": true, + "useTimeoutFn": true, + "useTimeoutPoll": true, + "useTimestamp": true, + "useTitle": true, + "useToNumber": true, + "useToString": true, + "useToggle": true, + "useTransition": true, + "useUrlSearchParams": true, + "useUserMedia": true, + "useVModel": true, + "useVModels": true, + "useVibrate": true, + "useVirtualList": true, + "useWakeLock": true, + "useWebNotification": true, + "useWebSocket": true, + "useWebWorker": true, + "useWebWorkerFn": true, + "useWindowFocus": true, + "useWindowScroll": true, + "useWindowSize": true, + "watch": true, + "watchArray": true, + "watchAtMost": true, + "watchDebounced": true, + "watchDeep": true, + "watchEffect": true, + "watchIgnorable": true, + "watchImmediate": true, + "watchOnce": true, + "watchPausable": true, + "watchPostEffect": true, + "watchSyncEffect": true, + "watchThrottled": true, + "watchTriggerable": true, + "watchWithFilter": true, + "whenever": true + } +} diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 9ffb4b4..48c2706 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,56 +1,51 @@ -/* eslint-env node */ -require("@rushstack/eslint-patch/modern-module-resolution"); - module.exports = { + env: { + browser: true, + es2021: true, + node: true, + }, extends: [ "eslint:recommended", - "plugin:vue/vue3-recommended", - "@electron-toolkit", - "@vue/eslint-config-prettier", + "plugin:@typescript-eslint/recommended", + "plugin:vue/vue3-essential", ], - rules: { - "vue/v-on-event-hyphenation": "off", - "vue/require-default-prop": "off", - "vue/multi-word-component-names": "off", - "vue/attribute-hyphenation": "off", + overrides: [ + { + env: { + node: true, + }, + files: [".eslintrc.{js,cjs}"], + parserOptions: { + sourceType: "script", + }, + }, + ], + parserOptions: { + ecmaVersion: "latest", + parser: "@typescript-eslint/parser", + sourceType: "module", }, - ignorePatterns: [ - "node_modules/", - "build/", - "dist/", - "out/", - "components.d.ts", - "auto-imports.d.ts", - ], - globals: { - defineProps: true, - defineEmits: true, - withDefaults: true, - h: true, - vue: true, - ref: true, - reactive: true, - computed: true, - watch: true, - provide: true, - inject: true, - defineComponent: true, - onBeforeMount: true, - onBeforeUnmount: true, - onUnmounted: true, - onMounted: true, - nextTick: true, - watchEffect: true, - electron: true, - $message: true, - $dialog: true, - $loadingBar: true, - $changeLogin: true, - $notification: true, - $changeThemeColor: true, - $canNotConnect: true, - $refreshCloudCatch: true, - $cleanAll: true, - $player: true, + plugins: ["@typescript-eslint", "vue"], + rules: { + "@typescript-eslint/no-explicit-any": "off", + "vue/multi-word-component-names": "off", + }, + global: { + h: "readonly", + ref: "readonly", + computed: "readonly", + watch: "readonly", + watchEffect: "readonly", + onBeforeMount: "readonly", + onBeforeUnmount: "readonly", + onBeforeUpdate: "readonly", + reactive: "readonly", + onMounted: "readonly", + onUnmounted: "readonly", + onActivated: "readonly", + onDeactivated: "readonly", + onRenderTracked: "readonly", + onRenderTriggered: "readonly", + onServerPrefetch: "readonly", }, }; diff --git a/.gitignore b/.gitignore index a6761da..85bd525 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ coverage *.local out .env +auto-imports.d.ts +components.d.ts # Editor directories and files .vscode/* diff --git a/.npmrc b/.npmrc index 43fbaed..9c2226f 100644 --- a/.npmrc +++ b/.npmrc @@ -1,5 +1,5 @@ registry=https://registry.npmmirror.com disturl=https://registry.npmmirror.com/-/binary/node -# ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/ -ELECTRON_MIRROR=https://registry.npmmirror.com/-/binary/electron/ +electron_mirror=https://npmmirror.com/mirrors/electron/ +electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/ shamefully-hoist=true diff --git a/.prettierignore b/.prettierignore index 13cff43..9c80841 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,7 +2,7 @@ out dist pnpm-lock.yaml LICENSE.md -tsconfig.json -tsconfig.*.json auto-imports.d.ts components.d.ts +# tsconfig.json +# tsconfig.*.json diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..9cd715c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,7 @@ +{ + "singleQuote": false, + "trailingComma": "all", + "tabWidth": 2, + "semi": true, + "printWidth": 100 +} diff --git a/.prettierrc.yaml b/.prettierrc.yaml deleted file mode 100644 index 2232686..0000000 --- a/.prettierrc.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# 是否使用单引号而不是双引号 -singleQuote: false -# 是否在语句末尾使用分号 -semi: true -# 每行的最大打印宽度 -printWidth: 100 -# 是否在对象和数组的末尾加上逗号 -trailingComma: all diff --git a/Dockerfile b/Dockerfile index 0dd2ab3..1afef4a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # build -FROM node:18-alpine as builder +FROM node:20-alpine AS builder RUN apk update && apk add --no-cache git @@ -11,12 +11,13 @@ RUN npm install COPY . . +# add .env.example to .env RUN [ ! -e ".env" ] && cp .env.example .env || true RUN npm run build # nginx -FROM nginx:1.25.3-alpine-slim as app +FROM nginx:1.27-alpine-slim AS app COPY --from=builder /app/out/renderer /usr/share/nginx/html diff --git a/README.md b/README.md index 45d88d6..dabecce 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ > > - 请务必遵守 [GNU Affero General Public License (AGPL-3.0)](https://www.gnu.org/licenses/agpl-3.0.html) 许可协议 > - 在您的修改、演绎、分发或派生项目中,必须同样采用 **AGPL-3.0** 许可协议,**并在适当的位置包含本项目的许可和版权信息** -> - **禁止用于售卖或其他商业用途**,如若发现,作者保留追究法律责任的权利 -> - 若发现未遵守 **AGPL-3.0** 许可协议的行为,**本项目将永久停更** +> - **禁止用于售卖或其他盈利用途**,如若发现,作者保留追究法律责任的权利 +> - 禁止在二开项目中修改程序原版权信息( 您可以添加二开作者信息 ) > - 感谢您的尊重与理解 -- 本项目采用 [Vue 3](https://cn.vuejs.org/) 全家桶和 [Naïve UI](https://www.naiveui.com/) 组件库及 [Electron](https://www.electronjs.org/zh/docs/latest/) 开发 +- 本项目采用 [Vue 3](https://cn.vuejs.org/) + [TypeScript](https://www.typescriptlang.org/) + [Naïve UI](https://www.naiveui.com/) + [Electron](https://www.electronjs.org/zh/docs/latest/) 开发 - 支持网页端与客户端,由于设备有限,目前仅适配 `Win`,其他平台可自行解决兼容性后进行构建 - 仅对移动端做了基础适配,**不保证功能全部可用** @@ -33,11 +33,13 @@ - ✨ 支持扫码登录 - 📱 支持手机号登录 - 📅 自动进行每日签到及云贝签到 -- 🎨 封面主题色自适应 -- 🌚 Light / Dark 模式自动切换 +- 💻 支持切换为本地播放器,此模式将不会连接网络 +- 🎨 封面主题色自适应,支持全站着色 +- 🌚 Light / Dark / Auto 模式自动切换 - 📁 本地歌曲管理及分类(建议先使用 [音乐标签](https://www.cnblogs.com/vinlxc/p/11347744.html) 进行匹配后再使用) +- 📁 简易的本地音乐标签编辑及封面修改 - 🎵 **支持播放部分无版权歌曲(可能会与原曲不匹配,客户端独占功能)** -- ⬇️ 下载歌曲(最高支持 Hi-Res) +- ⬇️ 下载歌曲( 最高支持 Hi-Res,需具有相应会员账号 ) - ➕ 新建歌单及歌单编辑 - ❤️ 收藏 / 取消收藏歌单或歌手 - 🎶 每日推荐歌曲 @@ -52,8 +54,7 @@ - 🎶 音乐频谱显示 - ⏭️ 音乐渐入渐出 - 🔄 支持 PWA -- 💬 支持评论区及评论点赞 -- 🌓 明暗模式自动 / 手动切换 +- 💬 支持评论区 - 📱 移动端基础适配 - ~~🌐 `i18n` 支持~~ @@ -128,7 +129,7 @@ docker build -t splayer . # 运行 -docker run -d --name SPlayer -p 7899:7899 splayer +docker run -d --name SPlayer -p 25884:25884 splayer # 或使用 Docker Compose docker-compose up -d ``` @@ -142,10 +143,10 @@ docker pull imsyy/splayer:latest docker pull ghcr.io/imsyy/splayer:latest # 运行 -docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest +docker run -d --name SPlayer -p 25884:25884 imsyy/splayer:latest ``` -以上步骤成功后,将会在本地 [localhost:7899](http://localhost:7899/) 启动,如需更换端口,请自行修改命令行中的端口号 +以上步骤成功后,将会在本地 [localhost:25884](http://localhost:25884/) 启动,如需更换端口,请自行修改命令行中的端口号 ## ⚙️ Vercel 部署 @@ -154,10 +155,10 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest 1. 本程序依赖 [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) 运行,请确保您已成功部署该项目,并成功取得在线访问地址 2. 点击本仓库右上角的 `Fork`,复制本仓库到你的 `GitHub` 账号 3. 复制 `/.env.example` 文件并重命名为 `/.env` -4. 将 `.env` 文件中的 `RENDERER_VITE_SERVER_URL` 改为第一步得到的 API 地址 +4. 将 `.env` 文件中的 `VITE_API_URL` 改为第一步得到的 API 地址 ```js - RENDERER_VITE_SERVER_URL = "https://example.com"; + VITE_API_URL = "https://example.com"; ``` 5. 将 `Build and Output Settings` 中的 `Output Directory` 改为 `out/renderer` @@ -171,19 +172,17 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest 1. 重复 `⚙️ Vercel 部署` 中的 1 - 4 步骤 2. 克隆仓库 - > 将链接中的 example/repository.git 替换为你要克隆的实际仓库的地址 - ```bash - git clone https://github.com/example/repository.git + git clone https://github.com/imsyy/SPlayer.git ``` 3. 安装依赖 ```bash pnpm install - # 或者 + # 或 yarn install - # 或者 + # 或 npm install ``` @@ -191,9 +190,9 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest ```bash pnpm build - # 或者 + # 或 yarn build - # 或者 + # 或 npm build ``` @@ -226,6 +225,7 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest - [NeteaseCloudMusicApi](https://github.com/Binaryify/NeteaseCloudMusicApi) - [YesPlayMusic](https://github.com/qier222/YesPlayMusic) - [UnblockNeteaseMusic](https://github.com/UnblockNeteaseMusic/server) +- [applemusic-like-lyrics](https://github.com/Steve-xmh/applemusic-like-lyrics) - [Vue-mmPlayer](https://github.com/maomao1996/Vue-mmPlayer) - [refined-now-playing-netease](https://github.com/solstice23/refined-now-playing-netease) - [material-color-utilities](https://github.com/material-foundation/material-color-utilities) @@ -251,179 +251,6 @@ docker run -d --name SPlayer -p 7899:7899 imsyy/splayer:latest 5. **社区参与:** 欢迎社区的参与和贡献,我们鼓励开发者一同改进和维护本项目 6. **许可证链接:** 请阅读 [GNU Affero General Public License (AGPL-3.0)](https://www.gnu.org/licenses/agpl-3.0.html) 了解更多详情 -## 📂 目录结构 - -
-查看目录结构详情 - -> ChatGPT 写的,如有错误,请见谅 - -```dir -├── auto-imports.d.ts # 自动导入 -├── components.d.ts # 自动导入 -├── docker-compose.yml # Docker Compose -├── Dockerfile # Docker -├── electron # Electron -│   ├── main # Electron 主进程 -│   │   ├── index.js # 主进程入口 -│   │   ├── mainIpcMain.js # 主进程与渲染进程通信 -│   │   ├── startMainServer.js # 启动主进程服务器 -│   │   ├── startNcmServer.js # 启动网易云音乐服务 -│   │   └── utils # 主进程工具函数 -│   │   ├── checkUpdates.js # 检查更新 -│   │   ├── createGlobalShortcut.js # 创建全局快捷键 -│   │   ├── createSystemTray.js # 创建系统托盘 -│   │   ├── getNeteaseMusicUrl.js # 解灰 -│   │   ├── kwDES.js # DES加密算法 -│   │   └── readDirAsync.js # 异步读取目录 -│   └── preload # Electron 预加载脚本 -│   └── index.js # 预加载脚本入口文件 -├── electron-builder.yml # Electron Builder -├── electron.vite.config.js # Electron Vite -├── index.html # 主页面 HTML -├── LICENSE # 项目许可证 -├── nginx.conf # Nginx 配置 -├── src # 项目源代码 -│   ├── api # API 相关 -│   │   ├── ./.. -│   ├── App.vue # 根组件 -│   ├── assets # 静态资源 -│   │   ├── emoji.json # 表情数据 -│   │   ├── icon.json # 图标数据 -│   │   └── themeColor.json # 主题颜色数据 -│   ├── components # 组件目录 -│   │   ├── Cover # 封面相关组件目录 -│   │   │   ├── CoverDropdown.vue # 封面下拉组件 -│   │   │   ├── MainCover.vue # 主封面组件 -│   │   │   ├── SpecialCoverCard.vue # 特殊封面卡片组件 -│   │   │   └── SpecialCover.vue # 特殊封面组件 -│   │   ├── Global # 全局组件目录 -│   │   │   ├── MainLayout.vue # 主布局组件 -│   │   │   ├── Menu.vue # 菜单组件 -│   │   │   ├── Pagination.vue # 分页组件 -│   │   │   ├── Playlist.vue # 歌单组件 -│   │   │   ├── Provider.vue # 全局化配置组件 -│   │   │   └── SvgIcon.vue # SVG 图标组件 -│   │   ├── List # 列表组件目录 -│   │   │   ├── CommentList.vue # 评论列表组件 -│   │   │   ├── SongListDropdown.vue # 歌曲下拉组件 -│   │   │   └── SongList.vue # 歌曲列表组件 -│   │   ├── Modal # 弹窗相关组件目录 -│   │   │   ├── AddPlaylist.vue # 添加歌单组件 -│   │   │   ├── CloudSongMatch.vue # 云盘歌曲匹配组件 -│   │   │   ├── CreatePlaylist.vue # 创建歌单组件 -│   │   │   ├── DownloadSong.vue # 下载歌曲组件 -│   │   │   ├── LoginPhone.vue # 手机登录组件 -│   │   │   ├── LoginQRCode.vue # 二维码登录组件 -│   │   │   ├── Login.vue # 登录组件 -│   │   │   ├── PlaylistUpdate.vue # 歌单编辑组件 -│   │   │   └── UpCloudSong.vue # 上传云盘歌曲组件 -│   │   ├── Nav # 导航相关组件目录 -│   │   │   ├── MainNav.vue # 主导航组件 -│   │   │   └── UserData.vue # 用户数据组件 -│   │   ├── Player # 播放器相关组件目录 -│   │   │   ├── CountDown.vue # 倒计时组件 -│   │   │   ├── FullPlayer.vue # 全屏播放器组件 -│   │   │   ├── Lyric.vue # 歌词组件 -│   │   │   ├── MainControl.vue # 主控制组件 -│   │   │   ├── PlayerControl.vue # 播放器控制组件 -│   │   │   ├── PlayerCover.vue # 播放器封面组件 -│ │ │ └── PrivateFm.vue # 私人 FM 组件 -│ │ ├── Search # 搜索相关组件 -│ │ │ ├── SearchHot.vue # 热门搜索组件 -│ │ │ ├── SearchInp.vue # 搜索输入组件 -│ │ │ └── SearchSuggestions.vue # 搜索建议组件 -│ │ └── WinDom # 窗口 DOM 相关组件 -│ │ └── TitleBar.vue # 标题栏组件 -│ ├── main.js # Vue 应用的入口文件 -│ ├── router # Vue Router 相关文件夹 -│ │ ├── index.js # Vue Router 入口文件 -│ │ └── routes.js # 路由配置文件 -│ ├── stores # Vuex Store 相关文件夹 -│ │ ├── indexedDB.js # IndexedDB 数据库相关文件 -│ │ ├── index.js # Vuex Store 入口文件 -│ │ ├── musicData.js # 音乐数据相关文件 -│ │ ├── siteData.js # 网站数据相关文件 -│ │ ├── siteSettings.js # 网站设置相关文件 -│ │ └── siteStatus.js # 网站状态相关文件 -│ ├── style # 样式相关文件夹 -│ │ ├── animate.scss # 动画样式文件 -│ │ └── main.scss # 主样式文件 -│ ├── utils # 工具函数文件夹 -│ │ ├── auth.js # 认证相关函数 -│ │ ├── base64.js # Base64编码解码相关函数 -│ │ ├── color-utils.js # 颜色工具函数 -│ │ ├── cover-color.js # 封面颜色相关函数 -│ │ ├── debounce.js # 防抖函数 -│ │ ├── formatData.js # 数据格式化函数 -│ │ ├── formRules.js # 表单验证规则 -│ │ ├── globalEvents.js # 全局事件处理函数 -│ │ ├── globalShortcut.js # 全局快捷键相关函数 -│ │ ├── helper.js # 辅助函数 -│ │ ├── parseLyric.js # 解析歌词函数 -│ │ ├── Player.js # 播放器控制相关函数 -│ │ ├── request.js # 网络请求相关函数 -│ │ ├── throttle.js # 节流函数 -│ │ ├── timeTools.js # 时间工具函数 -│ │ └── userSignIn.js # 用户登录相关函数 -│ └── views # Vue组件文件夹 -│ ├── Artist # 艺术家相关组件 -│ │ ├── albums.vue # 艺术家专辑组件 -│ │ ├── hot.vue # 艺术家热门组件 -│ │ ├── index.vue # 艺术家主组件 -│ │ ├── songs.vue # 艺术家歌曲组件 -│ │ └── videos.vue # 艺术家视频组件 -│ ├── Cloud.vue # 云盘组件 -│ ├── Comment.vue # 评论组件 -│ ├── DailySongs.vue # 每日推荐组件 -│ ├── Discover # 发现音乐相关组件 -│ │ ├── artists.vue # 发现音乐艺术家组件 -│ │ ├── index.vue # 发现音乐主组件 -│ │ ├── new.vue # 发现音乐新歌组件 -│ │ ├── playlists.vue # 发现音乐歌单组件 -│ │ └── toplists.vue # 发现音乐排行榜组件 -│ ├── History.vue # 历史记录组件 -│ ├── Home.vue # 主页组件 -│ ├── Like # 我喜欢的相关组件 -│ │ ├── albums.vue # 我喜欢的专辑组件 -│ │ ├── artists.vue # 我喜欢的艺术家组件 -│ │ ├── index.vue # 我喜欢的主组件 -│ │ ├── playlists.vue # 我喜欢的歌单组件 -│ │ └── videos.vue # 我喜欢的视频组件 -│ ├── List # 列表相关组件 -│ │ ├── album.vue # 专辑组件 -│ │ └── playlist.vue # 歌单组件 -│ │ └── dj.vue # 电台组件 -│ ├── Local # 本地音乐相关组件 -│ │ ├── albums.vue # 本地音乐专辑组件 -│ │ ├── artists.vue # 本地音乐艺术家组件 -│ │ ├── index.vue # 本地音乐主组件 -│ │ └── songs.vue # 本地音乐歌曲组件 -│ ├── Player.vue # 视频播放器组件 -│ ├── Dj # 电台相关组件 -│ │ └── index.vue # 电台主组件 -│ │ └── type.vue # 电台分类组件 -│ ├── Search # 搜索相关组件 -│ │ ├── albums.vue # 搜索专辑组件 -│ │ ├── artists.vue # 搜索艺术家组件 -│   │   ├── index.vue # 搜索主组件 -│   │   ├── playlists.vue # 搜索歌单组件 -│   │   ├── songs.vue # 搜索歌曲组件 -│   │   └── videos.vue # 搜索视频组件 -│   │   └── djs.vue # 搜索电台组件 -│   ├── Setting # 设置相关组件 -│   │   └── index.vue # 设置主组件 -│   ├── Song.vue -│   ├── State -│   │   ├── 403.vue -│   │   ├── 404.vue -│   │   └── 500.vue -│   └── Test.vue -└── vercel.json # Vercel 部署配置 -``` - -
- ## ⭐ Star History [![Star History Chart](https://api.star-history.com/svg?repos=imsyy/SPlayer&type=Date)](https://star-history.com/#imsyy/SPlayer&Date) diff --git a/auto-imports.d.ts b/auto-imports.d.ts index 7007359..b792d3f 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -6,61 +6,287 @@ export {} declare global { const EffectScope: typeof import('vue')['EffectScope'] + const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] + const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] const computed: typeof import('vue')['computed'] + const computedAsync: typeof import('@vueuse/core')['computedAsync'] + const computedEager: typeof import('@vueuse/core')['computedEager'] + const computedInject: typeof import('@vueuse/core')['computedInject'] + const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] + const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] + const controlledRef: typeof import('@vueuse/core')['controlledRef'] const createApp: typeof import('vue')['createApp'] + const createEventHook: typeof import('@vueuse/core')['createEventHook'] + const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] + const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] + const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] + const createReusableTemplate: typeof import('@vueuse/core')['createReusableTemplate'] + const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] + const createTemplatePromise: typeof import('@vueuse/core')['createTemplatePromise'] + const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] const customRef: typeof import('vue')['customRef'] + const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] + const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] const defineComponent: typeof import('vue')['defineComponent'] + const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] const effectScope: typeof import('vue')['effectScope'] + const extendRef: typeof import('@vueuse/core')['extendRef'] const getCurrentInstance: typeof import('vue')['getCurrentInstance'] const getCurrentScope: typeof import('vue')['getCurrentScope'] const h: typeof import('vue')['h'] + const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] const inject: typeof import('vue')['inject'] + const 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 makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] const markRaw: typeof import('vue')['markRaw'] const nextTick: typeof import('vue')['nextTick'] const onActivated: typeof import('vue')['onActivated'] const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router')['onBeforeRouteUpdate'] const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] const onDeactivated: typeof import('vue')['onDeactivated'] const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] + const onLongPress: typeof import('@vueuse/core')['onLongPress'] const onMounted: typeof import('vue')['onMounted'] const onRenderTracked: typeof import('vue')['onRenderTracked'] const onRenderTriggered: typeof import('vue')['onRenderTriggered'] const onScopeDispose: typeof import('vue')['onScopeDispose'] const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] const onUnmounted: typeof import('vue')['onUnmounted'] const onUpdated: typeof import('vue')['onUpdated'] + const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] const 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 resolveComponent: typeof import('vue')['resolveComponent'] + const resolveRef: typeof import('@vueuse/core')['resolveRef'] + const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] const shallowReactive: typeof import('vue')['shallowReactive'] const shallowReadonly: typeof import('vue')['shallowReadonly'] const shallowRef: typeof import('vue')['shallowRef'] + const syncRef: typeof import('@vueuse/core')['syncRef'] + const syncRefs: typeof import('@vueuse/core')['syncRefs'] + const templateRef: typeof import('@vueuse/core')['templateRef'] + const throttledRef: typeof import('@vueuse/core')['throttledRef'] + const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] const toRaw: typeof import('vue')['toRaw'] + const toReactive: typeof import('@vueuse/core')['toReactive'] const toRef: typeof import('vue')['toRef'] const toRefs: typeof import('vue')['toRefs'] const toValue: typeof import('vue')['toValue'] const triggerRef: typeof import('vue')['triggerRef'] + const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] + const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] + const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] + const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] + const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] const unref: typeof import('vue')['unref'] + const unrefElement: typeof import('@vueuse/core')['unrefElement'] + const until: typeof import('@vueuse/core')['until'] + const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] + const useAnimate: typeof import('@vueuse/core')['useAnimate'] + const useArrayDifference: typeof import('@vueuse/core')['useArrayDifference'] + const useArrayEvery: typeof import('@vueuse/core')['useArrayEvery'] + const useArrayFilter: typeof import('@vueuse/core')['useArrayFilter'] + const useArrayFind: typeof import('@vueuse/core')['useArrayFind'] + const useArrayFindIndex: typeof import('@vueuse/core')['useArrayFindIndex'] + const useArrayFindLast: typeof import('@vueuse/core')['useArrayFindLast'] + const useArrayIncludes: typeof import('@vueuse/core')['useArrayIncludes'] + const useArrayJoin: typeof import('@vueuse/core')['useArrayJoin'] + const useArrayMap: typeof import('@vueuse/core')['useArrayMap'] + const useArrayReduce: typeof import('@vueuse/core')['useArrayReduce'] + const useArraySome: typeof import('@vueuse/core')['useArraySome'] + const useArrayUnique: typeof import('@vueuse/core')['useArrayUnique'] + const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] + const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] const useAttrs: typeof import('vue')['useAttrs'] + const useBase64: typeof import('@vueuse/core')['useBase64'] + const useBattery: typeof import('@vueuse/core')['useBattery'] + const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] + const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] + const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] + const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] + const useCached: typeof import('@vueuse/core')['useCached'] + const useClipboard: typeof import('@vueuse/core')['useClipboard'] + const 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 useDialog: typeof import('naive-ui')['useDialog'] + const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] + const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] + const useDraggable: typeof import('@vueuse/core')['useDraggable'] + const useDropZone: typeof import('@vueuse/core')['useDropZone'] + const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] + const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] + const useElementHover: typeof import('@vueuse/core')['useElementHover'] + const useElementSize: typeof import('@vueuse/core')['useElementSize'] + const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] + const useEventBus: typeof import('@vueuse/core')['useEventBus'] + const useEventListener: typeof import('@vueuse/core')['useEventListener'] + const useEventSource: typeof import('@vueuse/core')['useEventSource'] + const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] + const useFavicon: typeof import('@vueuse/core')['useFavicon'] + const useFetch: typeof import('@vueuse/core')['useFetch'] + const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] + const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] + const useFocus: typeof import('@vueuse/core')['useFocus'] + const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] + const useFps: typeof import('@vueuse/core')['useFps'] + const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] + const useGamepad: typeof import('@vueuse/core')['useGamepad'] + const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] + const 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 useLoadingBar: typeof import('naive-ui')['useLoadingBar'] + const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] + const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] + const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] + const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] + const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] + const useMemoize: typeof import('@vueuse/core')['useMemoize'] + const useMemory: typeof import('@vueuse/core')['useMemory'] const useMessage: typeof import('naive-ui')['useMessage'] + const useMounted: typeof import('@vueuse/core')['useMounted'] + const useMouse: typeof import('@vueuse/core')['useMouse'] + const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] + const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] + const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] + const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] + const useNetwork: typeof import('@vueuse/core')['useNetwork'] const useNotification: typeof import('naive-ui')['useNotification'] + const useNow: typeof import('@vueuse/core')['useNow'] + const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] + const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] + const useOnline: typeof import('@vueuse/core')['useOnline'] + const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] + const 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 useRouter: typeof import('vue-router')['useRouter'] + const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] + const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] + const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] + const useScroll: typeof import('@vueuse/core')['useScroll'] + const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] + const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] + const useShare: typeof import('@vueuse/core')['useShare'] const useSlots: typeof import('vue')['useSlots'] + const useSorted: typeof import('@vueuse/core')['useSorted'] + const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] + const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] + const useStepper: typeof import('@vueuse/core')['useStepper'] + const useStorage: typeof import('@vueuse/core')['useStorage'] + const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] + const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] + const useSupported: typeof import('@vueuse/core')['useSupported'] + const useSwipe: typeof import('@vueuse/core')['useSwipe'] + const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] + const useTextDirection: typeof import('@vueuse/core')['useTextDirection'] + const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] + const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] + const useThrottle: typeof import('@vueuse/core')['useThrottle'] + const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] + const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] + const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] + const useTimeout: typeof import('@vueuse/core')['useTimeout'] + const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] + const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] + const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] + const useTitle: typeof import('@vueuse/core')['useTitle'] + const useToNumber: typeof import('@vueuse/core')['useToNumber'] + const useToString: typeof import('@vueuse/core')['useToString'] + const useToggle: typeof import('@vueuse/core')['useToggle'] + const useTransition: typeof import('@vueuse/core')['useTransition'] + const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] + const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] + const useVModel: typeof import('@vueuse/core')['useVModel'] + const useVModels: typeof import('@vueuse/core')['useVModels'] + const useVibrate: typeof import('@vueuse/core')['useVibrate'] + const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] + const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] + const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] + const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] + const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] + const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] + const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] + const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] + const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] const watch: typeof import('vue')['watch'] + const watchArray: typeof import('@vueuse/core')['watchArray'] + const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] + const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] + const watchDeep: typeof import('@vueuse/core')['watchDeep'] const watchEffect: typeof import('vue')['watchEffect'] + const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] + const watchImmediate: typeof import('@vueuse/core')['watchImmediate'] + const watchOnce: typeof import('@vueuse/core')['watchOnce'] + const watchPausable: typeof import('@vueuse/core')['watchPausable'] const watchPostEffect: typeof import('vue')['watchPostEffect'] const watchSyncEffect: typeof import('vue')['watchSyncEffect'] + const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] + const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] + const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] + const whenever: typeof import('@vueuse/core')['whenever'] } // for type re-export declare global { diff --git a/components.d.ts b/components.d.ts index 425ce8f..7315925 100644 --- a/components.d.ts +++ b/components.d.ts @@ -1,38 +1,52 @@ /* eslint-disable */ -/* prettier-ignore */ // @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 { - AddPlaylist: typeof import('./src/components/Modal/AddPlaylist.vue')['default'] - CloudSongMatch: typeof import('./src/components/Modal/CloudSongMatch.vue')['default'] + AboutSetting: typeof import('./src/components/Setting/AboutSetting.vue')['default'] + ArtistList: typeof import('./src/components/List/ArtistList.vue')['default'] + BatchList: typeof import('./src/components/Modal/batchList.vue')['default'] + CloudMatch: typeof import('./src/components/Modal/CloudMatch.vue')['default'] CommentList: typeof import('./src/components/List/CommentList.vue')['default'] CountDown: typeof import('./src/components/Player/CountDown.vue')['default'] - CoverDropdown: typeof import('./src/components/Cover/CoverDropdown.vue')['default'] - CoverPlayBtn: typeof import('./src/components/Cover/CoverPlayBtn.vue')['default'] + CoverList: typeof import('./src/components/List/CoverList.vue')['default'] + CoverMenu: typeof import('./src/components/Menu/CoverMenu.vue')['default'] CreatePlaylist: typeof import('./src/components/Modal/CreatePlaylist.vue')['default'] DownloadSong: typeof import('./src/components/Modal/DownloadSong.vue')['default'] FullPlayer: typeof import('./src/components/Player/FullPlayer.vue')['default'] + GeneralSetting: typeof import('./src/components/Setting/GeneralSetting.vue')['default'] + JumpArtist: typeof import('./src/components/Modal/JumpArtist.vue')['default'] + KeyboardSetting: typeof import('./src/components/Setting/KeyboardSetting.vue')['default'] + LocalSetting: typeof import('./src/components/Setting/LocalSetting.vue')['default'] Login: typeof import('./src/components/Modal/Login.vue')['default'] - LoginPhone: typeof import('./src/components/Modal/LoginPhone.vue')['default'] - LoginQRCode: typeof import('./src/components/Modal/LoginQRCode.vue')['default'] - Lyric: typeof import('./src/components/Player/Lyric.vue')['default'] - MainControl: typeof import('./src/components/Player/MainControl.vue')['default'] - MainCover: typeof import('./src/components/Cover/MainCover.vue')['default'] - MainLayout: typeof import('./src/components/Global/MainLayout.vue')['default'] - MainNav: typeof import('./src/components/Nav/MainNav.vue')['default'] - Menu: typeof import('./src/components/Global/Menu.vue')['default'] + LoginPhone: typeof import('./src/components/Modal/loginPhone.vue')['default'] + LoginQRCode: typeof import('./src/components/Modal/loginQRCode.vue')['default'] + LyricsSetting: typeof import('./src/components/Setting/LyricsSetting.vue')['default'] + MainAMLyric: typeof import('./src/components/Player/MainAMLyric.vue')['default'] + MainLyric: typeof import('./src/components/Player/MainLyric.vue')['default'] + MainPlayer: typeof import('./src/components/Player/MainPlayer.vue')['default'] + MainPlayList: typeof import('./src/components/Player/MainPlayList.vue')['default'] + MainSetting: typeof import('./src/components/Setting/MainSetting.vue')['default'] + Menu: typeof import('./src/components/Layout/Menu.vue')['default'] + NA: typeof import('naive-ui')['NA'] NAlert: typeof import('naive-ui')['NAlert'] + Nav: typeof import('./src/components/Layout/Nav.vue')['default'] NAvatar: typeof import('naive-ui')['NAvatar'] NBackTop: typeof import('naive-ui')['NBackTop'] NBadge: typeof import('naive-ui')['NBadge'] NButton: typeof import('naive-ui')['NButton'] NCard: typeof import('naive-ui')['NCard'] NCheckbox: typeof import('naive-ui')['NCheckbox'] + NCollapse: typeof import('naive-ui')['NCollapse'] + NCollapseItem: typeof import('naive-ui')['NCollapseItem'] + NCollapseTransition: typeof import('naive-ui')['NCollapseTransition'] + NColorPicker: typeof import('naive-ui')['NColorPicker'] NConfigProvider: typeof import('naive-ui')['NConfigProvider'] + NDataTable: typeof import('naive-ui')['NDataTable'] NDialogProvider: typeof import('naive-ui')['NDialogProvider'] NDivider: typeof import('naive-ui')['NDivider'] NDrawer: typeof import('naive-ui')['NDrawer'] @@ -41,32 +55,37 @@ declare module 'vue' { NEllipsis: typeof import('naive-ui')['NEllipsis'] NEmpty: typeof import('naive-ui')['NEmpty'] NFlex: typeof import('naive-ui')['NFlex'] + NFloatButton: typeof import('naive-ui')['NFloatButton'] + NFloatButtonGroup: typeof import('naive-ui')['NFloatButtonGroup'] NForm: typeof import('naive-ui')['NForm'] NFormItem: typeof import('naive-ui')['NFormItem'] + NFormItemGi: typeof import('naive-ui')['NFormItemGi'] NGi: typeof import('naive-ui')['NGi'] NGlobalStyle: typeof import('naive-ui')['NGlobalStyle'] NGrid: typeof import('naive-ui')['NGrid'] NH1: typeof import('naive-ui')['NH1'] + NH2: typeof import('naive-ui')['NH2'] NH3: typeof import('naive-ui')['NH3'] - NH4: typeof import('naive-ui')['NH4'] - NH6: typeof import('naive-ui')['NH6'] NIcon: typeof import('naive-ui')['NIcon'] NImage: typeof import('naive-ui')['NImage'] NInput: typeof import('naive-ui')['NInput'] + NInputGroup: typeof import('naive-ui')['NInputGroup'] NInputNumber: typeof import('naive-ui')['NInputNumber'] NLayout: typeof import('naive-ui')['NLayout'] - NLayoutContent: typeof import('naive-ui')['NLayoutContent'] NLayoutHeader: typeof import('naive-ui')['NLayoutHeader'] NLayoutSider: typeof import('naive-ui')['NLayoutSider'] + NLi: typeof import('naive-ui')['NLi'] NList: typeof import('naive-ui')['NList'] NListItem: typeof import('naive-ui')['NListItem'] NLoadingBarProvider: typeof import('naive-ui')['NLoadingBarProvider'] NMenu: typeof import('naive-ui')['NMenu'] NMessageProvider: typeof import('naive-ui')['NMessageProvider'] NModal: typeof import('naive-ui')['NModal'] + NModalProvider: typeof import('naive-ui')['NModalProvider'] NNotificationProvider: typeof import('naive-ui')['NNotificationProvider'] NNumberAnimation: typeof import('naive-ui')['NNumberAnimation'] - NPagination: typeof import('naive-ui')['NPagination'] + NOl: typeof import('naive-ui')['NOl'] + NP: typeof import('naive-ui')['NP'] NPopover: typeof import('naive-ui')['NPopover'] NProgress: typeof import('naive-ui')['NProgress'] NQrCode: typeof import('naive-ui')['NQrCode'] @@ -86,27 +105,35 @@ declare module 'vue' { NText: typeof import('naive-ui')['NText'] NThing: typeof import('naive-ui')['NThing'] NVirtualList: typeof import('naive-ui')['NVirtualList'] - Pagination: typeof import('./src/components/Global/Pagination.vue')['default'] + OtherSetting: typeof import('./src/components/Setting/OtherSetting.vue')['default'] + PersonalFM: typeof import('./src/components/Player/PersonalFM.vue')['default'] + PlayerBackground: typeof import('./src/components/Player/PlayerBackground.vue')['default'] + PlayerComment: typeof import('./src/components/Player/PlayerComment.vue')['default'] PlayerControl: typeof import('./src/components/Player/PlayerControl.vue')['default'] PlayerCover: typeof import('./src/components/Player/PlayerCover.vue')['default'] - Playlist: typeof import('./src/components/Global/Playlist.vue')['default'] - PlaylistUpdate: typeof import('./src/components/Modal/PlaylistUpdate.vue')['default'] - PrivateFm: typeof import('./src/components/Player/PrivateFm.vue')['default'] + PlayerData: typeof import('./src/components/Player/PlayerData.vue')['default'] + PlayerMenu: typeof import('./src/components/Player/PlayerMenu.vue')['default'] + PlayerSpectrum: typeof import('./src/components/Player/PlayerSpectrum.vue')['default'] + PlaylistAdd: typeof import('./src/components/Modal/PlaylistAdd.vue')['default'] + PlaySetting: typeof import('./src/components/Setting/PlaySetting.vue')['default'] Provider: typeof import('./src/components/Global/Provider.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] - SearchHot: typeof import('./src/components/Search/SearchHot.vue')['default'] + SearchDefault: typeof import('./src/components/Search/SearchDefault.vue')['default'] SearchInp: typeof import('./src/components/Search/SearchInp.vue')['default'] - SearchSuggestions: typeof import('./src/components/Search/SearchSuggestions.vue')['default'] + SearchInpMenu: typeof import('./src/components/Menu/SearchInpMenu.vue')['default'] + SearchSuggest: typeof import('./src/components/Search/SearchSuggest.vue')['default'] + Sider: typeof import('./src/components/Layout/Sider.vue')['default'] + SongDataCard: typeof import('./src/components/Card/SongDataCard.vue')['default'] + SongInfoEditor: typeof import('./src/components/Modal/SongInfoEditor.vue')['default'] SongList: typeof import('./src/components/List/SongList.vue')['default'] - SongListDrawer: typeof import('./src/components/List/SongListDrawer.vue')['default'] - SongListDropdown: typeof import('./src/components/List/SongListDropdown.vue')['default'] - SpecialCover: typeof import('./src/components/Cover/SpecialCover.vue')['default'] - SpecialCoverCard: typeof import('./src/components/Cover/SpecialCoverCard.vue')['default'] - Spectrum: typeof import('./src/components/Player/Spectrum.vue')['default'] + SongListCard: typeof import('./src/components/Card/SongListCard.vue')['default'] + SongListMenu: typeof import('./src/components/Menu/SongListMenu.vue')['default'] SvgIcon: typeof import('./src/components/Global/SvgIcon.vue')['default'] - TitleBar: typeof import('./src/components/WinDom/TitleBar.vue')['default'] - UpCloudSong: typeof import('./src/components/Modal/UpCloudSong.vue')['default'] - UserData: typeof import('./src/components/Nav/UserData.vue')['default'] + TextContainer: typeof import('./src/components/Global/TextContainer.vue')['default'] + UpdateApp: typeof import('./src/components/Modal/UpdateApp.vue')['default'] + UpdatePlaylist: typeof import('./src/components/Modal/UpdatePlaylist.vue')['default'] + User: typeof import('./src/components/Layout/User.vue')['default'] + UserAgreement: typeof import('./src/components/Modal/UserAgreement.vue')['default'] } } diff --git a/dev-app-update.yml b/dev-app-update.yml new file mode 100644 index 0000000..aaf858f --- /dev/null +++ b/dev-app-update.yml @@ -0,0 +1,3 @@ +provider: github +owner: "imsyy" +repo: "SPlayer" diff --git a/docker-compose.yml b/docker-compose.yml index 586ef56..7c7d19b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,5 +8,5 @@ services: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro ports: - - 7899:7899 + - 25884:25884 restart: always diff --git a/electron-builder.yml b/electron-builder.yml index 41327a3..c2aaa6d 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -5,9 +5,12 @@ productName: SPlayer copyright: Copyright © imsyy 2023 # 构建资源所在的目录 directories: - buildResources: build -# 包含在最终应用程序构建中的文件列表,这里使用通配符 ! 表示排除不需要的文件 + buildResources: public +# 包含在最终应用程序构建中的文件列表 +# 使用通配符 ! 表示排除不需要的文件 files: + - "public/**" + - "out/**" - "!**/.vscode/*" - "!src/*" - "!electron.vite.config.{js,ts,mjs,cjs}" @@ -16,17 +19,20 @@ files: # 哪些文件将不会被压缩,而是解压到构建目录 asarUnpack: - public/** -# Windows 平台配置 win: # 可执行文件名 executableName: SPlayer # 应用程序的图标文件路径 - icon: public/imgs/icons/favicon-512x512.png + icon: public/icons/favicon-512x512.png # 构建类型 - target: nsis + target: + # 安装版 + - nsis + # 打包版 + - portable # NSIS 安装器配置 nsis: - # 一键式安装程序还是辅助安装程序 + # 是否一键式安装 oneClick: false # 安装程序的生成名称 artifactName: ${productName}-${version}-setup.${ext} @@ -41,23 +47,23 @@ nsis: # 是否允许用户更改安装目录 allowToChangeInstallationDirectory: true # 安装包图标 - installerIcon: public/imgs/icons/favicon.ico + installerIcon: public/icons/favicon.ico # 卸载命令图标 - uninstallerIcon: public/imgs/icons/favicon.ico + uninstallerIcon: public/icons/favicon.ico # macOS 平台配置 mac: # 可执行文件名 executableName: SPlayer # 应用程序的图标文件路径 - icon: public/imgs/icons/favicon-512x512.png + icon: public/icons/favicon-512x512.png # 权限继承的文件路径 entitlementsInherit: build/entitlements.mac.plist # 扩展信息,如权限描述 extendInfo: - NSCameraUsageDescription: Application requests access to the device's camera. - NSMicrophoneUsageDescription: Application requests access to the device's microphone. - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. + - NSCameraUsageDescription: Application requests access to the device's camera. + - NSMicrophoneUsageDescription: Application requests access to the device's microphone. + - NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder. + - NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder. # 是否启用应用程序的 Notarization(苹果的安全审核) notarize: false darkModeSupport: true @@ -74,13 +80,13 @@ mac: # macOS 平台的 DMG 配置 dmg: # DMG 文件的生成名称 - artifactName: ${productName}-${version}.${ext} + artifactName: ${name}-${version}.${ext} # Linux 平台配置 linux: # 可执行文件名 executableName: SPlayer # 应用程序的图标文件路径 - icon: public/imgs/icons/favicon-512x512.png + icon: public/icons/favicon-512x512.png # 构建类型 target: - pacman @@ -95,7 +101,7 @@ linux: # AppImage 配置 appImage: # AppImage 文件的生成名称 - artifactName: ${productName}-${version}.${ext} + artifactName: ${name}-${version}.${ext} # 是否在构建之前重新编译原生模块 npmRebuild: false # 自动更新的配置 diff --git a/electron.vite.config.mjs b/electron.vite.config.mjs deleted file mode 100644 index 83d50fd..0000000 --- a/electron.vite.config.mjs +++ /dev/null @@ -1,160 +0,0 @@ -import { resolve } from "path"; -import { defineConfig, externalizeDepsPlugin, loadEnv } from "electron-vite"; -import { NaiveUiResolver } from "unplugin-vue-components/resolvers"; -import { VitePWA } from "vite-plugin-pwa"; -import vue from "@vitejs/plugin-vue"; -import AutoImport from "unplugin-auto-import/vite"; -import Components from "unplugin-vue-components/vite"; -import viteCompression from "vite-plugin-compression"; -import checkPort from "./electron/main/utils/checkPort"; - -export default defineConfig(async ({ mode }) => { - // 读取环境变量 - const getEnv = (name) => { - return loadEnv(mode, process.cwd())[name]; - }; - // 获取端口 - const devPort = await checkPort(getEnv("MAIN_VITE_DEV_PORT")); - const serverPort = await checkPort(getEnv("MAIN_VITE_SERVER_PORT")); - // 返回配置 - return { - // 主进程 - main: { - resolve: { - alias: { - "@main": resolve(__dirname, "electron/main"), - }, - }, - plugins: [externalizeDepsPlugin()], - build: { - publicDir: resolve(__dirname, "public"), - rollupOptions: { - input: { - index: resolve(__dirname, "electron/main/index.js"), - }, - }, - }, - }, - // 预渲染 - preload: { - plugins: [externalizeDepsPlugin()], - build: { - rollupOptions: { - input: { - index: resolve(__dirname, "electron/preload/index.mjs"), - }, - }, - }, - }, - // 渲染进程 - renderer: { - resolve: { - extensions: [".js", ".vue", ".json"], - alias: { - "@": resolve(__dirname, "src"), - }, - }, - plugins: [ - vue(), - AutoImport({ - imports: [ - "vue", - { - "naive-ui": ["useDialog", "useMessage", "useNotification", "useLoadingBar"], - }, - ], - }), - Components({ - resolvers: [NaiveUiResolver()], - }), - // viteCompression - viteCompression(), - // PWA - VitePWA({ - registerType: "autoUpdate", - workbox: { - clientsClaim: true, - skipWaiting: true, - cleanupOutdatedCaches: true, - runtimeCaching: [ - { - urlPattern: /(.*?)\.(woff2|woff|ttf)/, - handler: "CacheFirst", - options: { - cacheName: "file-cache", - }, - }, - { - urlPattern: /(.*?)\.(webp|png|jpe?g|svg|gif|bmp|psd|tiff|tga|eps)/, - handler: "CacheFirst", - options: { - cacheName: "image-cache", - }, - }, - ], - }, - manifest: { - name: getEnv("RENDERER_VITE_SITE_TITLE"), - short_name: getEnv("RENDERER_VITE_SITE_TITLE"), - description: getEnv("RENDERER_VITE_SITE_DES"), - display: "standalone", - start_url: "/", - theme_color: "#fff", - background_color: "#efefef", - icons: [ - { - src: "/imgs/icons/favicon-32x32.png", - sizes: "32x32", - type: "image/png", - }, - { - src: "/imgs/icons/favicon-96x96.png", - sizes: "96x96", - type: "image/png", - }, - { - src: "/imgs/icons/favicon-256x256.png", - sizes: "256x256", - type: "image/png", - }, - { - src: "/imgs/icons/favicon-512x512.png", - sizes: "512x512", - type: "image/png", - }, - ], - }, - }), - ], - // 服务器配置 - server: { - port: devPort, - // 代理 - proxy: { - "/api": { - target: `http://${getEnv("MAIN_VITE_SERVER_HOST")}:${serverPort}`, - changeOrigin: true, - rewrite: (path) => path.replace(/^\/api/, ""), - }, - }, - }, - // 构建 - root: ".", - build: { - minify: "terser", - publicDir: resolve(__dirname, "public"), - rollupOptions: { - input: { - index: resolve(__dirname, "index.html"), - }, - }, - terserOptions: { - compress: { - pure_funcs: ["console.log"], - }, - }, - sourcemap: false, - }, - }, - }; -}); diff --git a/electron.vite.config.ts b/electron.vite.config.ts new file mode 100644 index 0000000..6448204 --- /dev/null +++ b/electron.vite.config.ts @@ -0,0 +1,113 @@ +import { resolve } from "path"; +import { MainEnv } from "./env"; +import { defineConfig, externalizeDepsPlugin, loadEnv } from "electron-vite"; +import { NaiveUiResolver } from "unplugin-vue-components/resolvers"; +import vue from "@vitejs/plugin-vue"; +import AutoImport from "unplugin-auto-import/vite"; +import Components from "unplugin-vue-components/vite"; +import viteCompression from "vite-plugin-compression"; +import wasm from "vite-plugin-wasm"; + +export default defineConfig(({ command, mode }) => { + // 读取环境变量 + const getEnv = (name: keyof MainEnv): string => { + return loadEnv(mode, process.cwd())[name]; + }; + console.log(command); + // 获取端口 + const webPort: number = Number(getEnv("VITE_WEB_PORT") || 14558); + const servePort: number = Number(getEnv("VITE_SERVER_PORT") || 25884); + // 返回配置 + return { + // 主进程 + main: { + plugins: [externalizeDepsPlugin()], + build: { + publicDir: resolve(__dirname, "public"), + rollupOptions: { + input: { + index: resolve(__dirname, "electron/main/index.ts"), + lyric: resolve(__dirname, "web/lyric.html"), + loading: resolve(__dirname, "web/loading.html"), + }, + }, + }, + }, + // 预加载 + preload: { + plugins: [externalizeDepsPlugin()], + build: { + rollupOptions: { + input: { + index: resolve(__dirname, "electron/preload/index.ts"), + }, + }, + }, + }, + // 渲染进程 + renderer: { + root: ".", + plugins: [ + vue(), + AutoImport({ + imports: [ + "vue", + "vue-router", + "@vueuse/core", + { + "naive-ui": ["useDialog", "useMessage", "useNotification", "useLoadingBar"], + }, + ], + eslintrc: { + enabled: true, + filepath: "./.eslintrc-auto-import.json", + }, + }), + Components({ + resolvers: [NaiveUiResolver()], + }), + viteCompression(), + wasm(), + ], + resolve: { + alias: { + "@": resolve(__dirname, "src/"), + }, + }, + server: { + port: webPort, + // 代理 + proxy: { + "/api": { + target: `http://127.0.0.1:${servePort}`, + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, "/api/"), + }, + }, + }, + preview: { + port: webPort, + }, + build: { + minify: "terser", + publicDir: resolve(__dirname, "public"), + rollupOptions: { + input: { + index: resolve(__dirname, "index.html"), + }, + output: { + manualChunks: { + stores: ["src/stores/data.ts", "src/stores/index.ts"], + }, + }, + }, + terserOptions: { + compress: { + pure_funcs: ["console.log"], + }, + }, + sourcemap: false, + }, + }, + }; +}); diff --git a/electron/main/index.d.ts b/electron/main/index.d.ts new file mode 100644 index 0000000..d5822de --- /dev/null +++ b/electron/main/index.d.ts @@ -0,0 +1 @@ +/// diff --git a/electron/main/index.js b/electron/main/index.js deleted file mode 100644 index 176ed8b..0000000 --- a/electron/main/index.js +++ /dev/null @@ -1,256 +0,0 @@ -import { join } from "path"; -import { app, protocol, shell, BrowserWindow, globalShortcut, nativeImage } from "electron"; -import { platform, optimizer, is } from "@electron-toolkit/utils"; -import { startNcmServer } from "@main/startNcmServer"; -import { startMainServer } from "@main/startMainServer"; -import createSystemTray from "@main/utils/createSystemTray"; -import createGlobalShortcut from "@main/utils/createGlobalShortcut"; -import mainIpcMain from "@main/mainIpcMain"; -import Store from "electron-store"; -import log from "electron-log"; - -// 屏蔽报错 -process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = "true"; - -// 配置 log -log.transports.file.resolvePathFn = () => - join(app.getPath("documents"), "/SPlayer/SPlayer-log.txt"); -// 设置日志文件的最大大小为 2 MB -log.transports.file.maxSize = 2 * 1024 * 1024; -// 绑定 console 事件 -console.error = log.error.bind(log); -console.warn = log.warn.bind(log); -console.info = log.info.bind(log); -console.debug = log.debug.bind(log); - -// 主进程 -class MainProcess { - constructor() { - // 主窗口 - this.mainWindow = null; - // 主代理 - this.mainServer = null; - // 网易云 API - this.ncmServer = null; - // Store - this.store = new Store({ - // 窗口大小 - windowSize: { - width: { type: "number", default: 1280 }, - height: { type: "number", default: 740 }, - }, - }); - // 设置应用程序名称 - if (process.platform === "win32") app.setAppUserModelId(app.getName()); - // 初始化 - this.checkApp().then(async (lockObtained) => { - if (lockObtained) { - await this.init(); - } - }); - } - - // 单例锁 - async checkApp() { - if (!app.requestSingleInstanceLock()) { - log.error("已有一个程序正在运行,本次启动阻止"); - app.quit(); - // 未获得锁 - return false; - } - // 聚焦到当前程序 - else { - app.on("second-instance", () => { - if (this.mainWindow) { - this.mainWindow.show(); - if (this.mainWindow.isMinimized()) this.mainWindow.restore(); - this.mainWindow.focus(); - } - }); - // 获得锁 - return true; - } - } - - // 初始化程序 - async init() { - log.info("主进程初始化"); - - // 启动网易云 API - try { - this.ncmServer = await startNcmServer({ - port: import.meta.env.MAIN_VITE_SERVER_PORT, - host: import.meta.env.MAIN_VITE_SERVER_HOST, - }); - } catch (error) { - console.error("启动网易云 API 失败:", error); - } - - // 非开发环境启动代理 - if (!is.dev) { - this.mainServer = await startMainServer(); - } - - // 注册应用协议 - app.setAsDefaultProtocolClient("SPlayer"); - // 应用程序准备好之前注册 - protocol.registerSchemesAsPrivileged([ - { scheme: "app", privileges: { secure: true, standard: true } }, - ]); - - // 主应用程序事件 - this.mainAppEvents(); - } - - // 创建主窗口 - createWindow() { - // 创建浏览器窗口 - this.mainWindow = new BrowserWindow({ - title: app.getName() || "SPlayer", - width: this.store.get("windowSize.width") || 1280, // 窗口宽度 - height: this.store.get("windowSize.height") || 740, // 窗口高度 - minHeight: 700, // 最小高度 - minWidth: 1200, // 最小宽度 - center: true, // 是否出现在屏幕居中的位置 - show: false, // 初始时不显示窗口 - frame: false, // 无边框 - // transparent: true, // 透明窗口 - titleBarStyle: "customButtonsOnHover", // Macos 隐藏菜单栏 - autoHideMenuBar: true, // 失去焦点后自动隐藏菜单栏 - // 图标配置 - icon: nativeImage.createFromPath(join(__dirname, "../../public/imgs/icons/favicon.png")), - // 预加载 - webPreferences: { - // devTools: is.dev, - preload: join(__dirname, "../preload/index.mjs"), - sandbox: false, - webSecurity: false, - hardwareAcceleration: true, - }, - }); - - // 窗口准备就绪时显示窗口 - this.mainWindow.once("ready-to-show", () => { - this.mainWindow.show(); - // mainWindow.maximize(); - this.store.set("windowSize", this.mainWindow.getBounds()); - }); - - // 主窗口事件 - this.mainWindowEvents(); - - // 设置窗口打开处理程序 - this.mainWindow.webContents.setWindowOpenHandler((details) => { - shell.openExternal(details.url); - return { action: "deny" }; - }); - - // 渲染路径 - // 在开发模式 - if (is.dev && process.env.ELECTRON_RENDERER_URL) { - this.mainWindow.loadURL(process.env.ELECTRON_RENDERER_URL); - } - // 生产模式 - else { - console.log("生产模式渲染端口: " + process.env.MAIN_VITE_MAIN_PORT ?? 7899); - this.mainWindow.loadURL(`http://127.0.0.1:${process.env.MAIN_VITE_MAIN_PORT ?? 7899}`); - } - - // 配置网络代理 - const proxyRules = this.store.get("proxy"); - if (proxyRules) { - this.mainWindow.webContents.session.setProxy({ proxyRules }, (result) => { - console.info("网络代理配置:", result); - }); - } - } - - // 主应用程序事件 - mainAppEvents() { - app.whenReady().then(async () => { - // 创建主窗口 - this.createWindow(); - // 引入主 Ipc - mainIpcMain(this.mainWindow, this.store); - // 系统托盘 - createSystemTray(this.mainWindow); - // 注册快捷键 - createGlobalShortcut(this.mainWindow); - }); - - // 开发环境下 F12 打开控制台 - app.on("browser-window-created", (_, window) => { - optimizer.watchWindowShortcuts(window); - }); - - // 在 macOS 上,当单击 Dock 图标且没有其他窗口时,通常会重新创建窗口 - app.on("activate", () => { - if (BrowserWindow.getAllWindows().length === 0) this.createWindow(); - }); - - // 自定义协议 - app.on("open-url", (_, url) => { - console.log("Received custom protocol URL:", url); - }); - - // 将要退出 - app.on("will-quit", () => { - // 注销全部快捷键 - globalShortcut.unregisterAll(); - }); - - // 当所有窗口都关闭时退出应用,macOS 除外 - app.on("window-all-closed", () => { - if (!platform.isMacOS) { - app.quit(); - } - }); - } - - // 主窗口事件 - mainWindowEvents() { - this.mainWindow.on("show", () => { - this.mainWindow.webContents.send("lyricsScroll"); - }); - - // this.mainWindow.on("hide", () => { - // console.info("窗口隐藏"); - // }); - - this.mainWindow.on("focus", () => { - this.mainWindow.webContents.send("lyricsScroll"); - }); - - // this.mainWindow.on("blur", () => { - // console.info("窗口失去焦点"); - // }); - - this.mainWindow.on("maximize", () => { - this.mainWindow.webContents.send("windowState", true); - }); - - this.mainWindow.on("unmaximize", () => { - this.mainWindow.webContents.send("windowState", false); - }); - - this.mainWindow.on("resize", () => { - this.store.set("windowSize", this.mainWindow.getBounds()); - }); - - this.mainWindow.on("move", () => { - this.store.set("windowSize", this.mainWindow.getBounds()); - }); - - // 窗口关闭 - this.mainWindow.on("close", (event) => { - event.preventDefault(); - if (!app.isQuiting) { - this.mainWindow.hide(); - } else { - app.exit(); - } - }); - } -} - -new MainProcess(); diff --git a/electron/main/index.ts b/electron/main/index.ts new file mode 100644 index 0000000..86d6b8c --- /dev/null +++ b/electron/main/index.ts @@ -0,0 +1,290 @@ +import { app, shell, BrowserWindow, BrowserWindowConstructorOptions } from "electron"; +import { electronApp, optimizer } from "@electron-toolkit/utils"; +import { join } from "path"; +import { release } from "os"; +import { isDev, isMac, appName } from "./utils"; +import { registerAllShortcuts, unregisterShortcuts } from "./shortcut"; +import { initTray, MainTray } from "./tray"; +import { initThumbar, Thumbar } from "./thumbar"; +import initAppServer from "../server"; +import initIpcMain from "./ipcMain"; +import log from "./logger"; +import store from "./store"; +// icon +import icon from "../../public/icons/favicon.png?asset"; + +// 屏蔽报错 +process.env.ELECTRON_DISABLE_SECURITY_WARNINGS = "true"; + +// 模拟打包 +Object.defineProperty(app, "isPackaged", { + get() { + return true; + }, +}); + +// 主进程 +class MainProcess { + // 窗口 + mainWindow: BrowserWindow | null = null; + lyricWindow: BrowserWindow | null = null; + loadingWindow: BrowserWindow | null = null; + // 托盘 + mainTray: MainTray | null = null; + // 工具栏 + thumbar: Thumbar | null = null; + // 是否退出 + isQuit: boolean = false; + constructor() { + log.info("🚀 Main process startup"); + // 禁用 Windows 7 的 GPU 加速功能 + if (release().startsWith("6.1")) app.disableHardwareAcceleration(); + // 单例锁 + if (!app.requestSingleInstanceLock()) { + log.error("❌ There is already a program running and this process is terminated"); + app.quit(); + process.exit(0); + } else this.showWindow(); + // 准备就绪 + app.whenReady().then(async () => { + log.info("🚀 Application Process Startup"); + // 设置应用程序名称 + electronApp.setAppUserModelId(app.getName()); + // 启动主服务进程 + await initAppServer(); + // 启动进程 + this.createLoadingWindow(); + this.createMainWindow(); + this.createLyricsWindow(); + this.handleAppEvents(); + this.handleWindowEvents(); + // 注册其他服务 + this.mainTray = initTray(this.mainWindow!, this.lyricWindow!); + this.thumbar = initThumbar(this.mainWindow!); + // 注册主进程事件 + initIpcMain( + this.mainWindow, + this.lyricWindow, + this.loadingWindow, + this.mainTray, + this.thumbar, + store, + ); + // 注册快捷键 + registerAllShortcuts(this.mainWindow!); + }); + } + // 创建窗口 + createWindow(options: BrowserWindowConstructorOptions = {}): BrowserWindow { + const defaultOptions: BrowserWindowConstructorOptions = { + title: appName, + width: 1280, + height: 720, + frame: false, + center: true, + // 图标 + icon, + webPreferences: { + preload: join(__dirname, "../preload/index.mjs"), + // 禁用渲染器沙盒 + sandbox: false, + // 禁用同源策略 + webSecurity: false, + // 允许 HTTP + allowRunningInsecureContent: true, + // 禁用拼写检查 + spellcheck: false, + // 启用 Node.js + nodeIntegration: true, + nodeIntegrationInWorker: true, + // 启用上下文隔离 + contextIsolation: false, + }, + }; + // 合并参数 + options = Object.assign(defaultOptions, options); + // 创建窗口 + const win = new BrowserWindow(options); + return win; + } + // 创建主窗口 + createMainWindow() { + // 窗口配置项 + const options: BrowserWindowConstructorOptions = { + width: store.get("window").width, + height: store.get("window").height, + minHeight: 800, + minWidth: 1280, + // 菜单栏 + titleBarStyle: "customButtonsOnHover", + // 立即显示窗口 + show: false, + }; + // 初始化窗口 + this.mainWindow = this.createWindow(options); + + // 渲染路径 + if (isDev && process.env["ELECTRON_RENDERER_URL"]) { + this.mainWindow.loadURL(process.env["ELECTRON_RENDERER_URL"]); + } else { + const port = Number(import.meta.env["VITE_SERVER_PORT"] || 25884); + this.mainWindow.loadURL(`http://127.0.0.1:${port}`); + } + + // 配置网络代理 + if (store.get("proxy")) { + this.mainWindow.webContents.session.setProxy({ proxyRules: store.get("proxy") }); + } + + // 窗口打开处理程序 + this.mainWindow.webContents.setWindowOpenHandler((details) => { + const { url } = details; + if (url.startsWith("https://") || url.startsWith("http://")) { + shell.openExternal(url); + } + return { action: "deny" }; + }); + } + // 创建加载窗口 + createLoadingWindow() { + // 初始化窗口 + this.loadingWindow = this.createWindow({ + width: 800, + height: 560, + maxWidth: 800, + maxHeight: 560, + resizable: false, + }); + // 渲染路径 + this.loadingWindow.loadFile(join(__dirname, "../main/web/loading.html")); + } + // 创建桌面歌词窗口 + createLyricsWindow() { + // 初始化窗口 + this.lyricWindow = this.createWindow({ + width: store.get("lyric").width || 800, + height: store.get("lyric").height || 180, + minWidth: 440, + minHeight: 120, + maxWidth: 1600, + maxHeight: 300, + // 窗口位置 + x: store.get("lyric").x, + y: store.get("lyric").y, + transparent: true, + backgroundColor: "rgba(0, 0, 0, 0)", + alwaysOnTop: true, + resizable: true, + movable: true, + // 不在任务栏显示 + skipTaskbar: true, + // 窗口不能最小化 + minimizable: false, + // 窗口不能最大化 + maximizable: false, + // 窗口不能进入全屏状态 + fullscreenable: false, + show: false, + }); + // 渲染路径 + this.lyricWindow.loadFile(join(__dirname, "../main/web/lyric.html")); + } + // 应用程序事件 + handleAppEvents() { + // 窗口被关闭时 + app.on("window-all-closed", () => { + if (!isMac) app.quit(); + this.mainWindow = null; + this.loadingWindow = null; + }); + + // 应用被激活 + app.on("activate", () => { + const allWindows = BrowserWindow.getAllWindows(); + if (allWindows.length) { + allWindows[0].focus(); + } else { + this.createMainWindow(); + } + }); + + // 新增 session + app.on("second-instance", () => { + this.showWindow(); + }); + + // 开发环境控制台 + app.on("browser-window-created", (_, window) => { + optimizer.watchWindowShortcuts(window); + }); + + // 自定义协议 + app.on("open-url", (_, url) => { + console.log("Received custom protocol URL:", url); + }); + + // 将要退出 + app.on("will-quit", () => { + // 注销全部快捷键 + unregisterShortcuts(); + }); + + // 退出前 + app.on("before-quit", () => { + this.isQuit = true; + }); + } + // 窗口事件 + handleWindowEvents() { + this.mainWindow?.on("show", () => { + // this.mainWindow?.webContents.send("lyricsScroll"); + }); + this.mainWindow?.on("focus", () => { + this.saveBounds(); + }); + // 移动或缩放 + this.mainWindow?.on("resized", () => { + // 若处于全屏则不保存 + if (this.mainWindow?.isFullScreen()) return; + this.saveBounds(); + }); + this.mainWindow?.on("moved", () => { + this.saveBounds(); + }); + + // 歌词窗口缩放 + this.lyricWindow?.on("resized", () => { + const bounds = this.lyricWindow?.getBounds(); + if (bounds) { + const { width, height } = bounds; + store.set("lyric", { ...store.get("lyric"), width, height }); + } + }); + + // 窗口关闭 + this.mainWindow?.on("close", (event) => { + event.preventDefault(); + if (this.isQuit) { + app.exit(); + } else { + this.mainWindow?.hide(); + } + }); + } + // 更新窗口大小 + saveBounds() { + if (this.mainWindow?.isFullScreen()) return; + const bounds = this.mainWindow?.getBounds(); + if (bounds) store.set("window", bounds); + } + // 显示窗口 + showWindow() { + if (this.mainWindow) { + this.mainWindow.show(); + if (this.mainWindow.isMinimized()) this.mainWindow.restore(); + this.mainWindow.focus(); + } + } +} + +export default new MainProcess(); diff --git a/electron/main/ipcMain.ts b/electron/main/ipcMain.ts new file mode 100644 index 0000000..002e045 --- /dev/null +++ b/electron/main/ipcMain.ts @@ -0,0 +1,696 @@ +import { + app, + ipcMain, + BrowserWindow, + powerSaveBlocker, + screen, + shell, + dialog, + net, + session, +} from "electron"; +import { File, Picture, Id3v2Settings } from "node-taglib-sharp"; +import { parseFile } from "music-metadata"; +import { getFonts } from "font-list"; +import { MainTray } from "./tray"; +import { Thumbar } from "./thumbar"; +import { StoreType } from "./store"; +import { isDev, getFileID, getFileMD5 } from "./utils"; +import { isShortcutRegistered, registerShortcut, unregisterShortcuts } from "./shortcut"; +import { join, basename, resolve } from "path"; +import { download } from "electron-dl"; +import { checkUpdate, startDownloadUpdate } from "./update"; +import fs from "fs/promises"; +import log from "../main/logger"; +import Store from "electron-store"; +import fg from "fast-glob"; + +// 注册 ipcMain +const initIpcMain = ( + win: BrowserWindow | null, + lyricWin: BrowserWindow | null, + loadingWin: BrowserWindow | null, + tray: MainTray | null, + thumbar: Thumbar | null, + store: Store, +) => { + initWinIpcMain(win, loadingWin, lyricWin, store); + initLyricIpcMain(lyricWin, win, store); + initTrayIpcMain(tray, win, lyricWin); + initThumbarIpcMain(thumbar); + initStoreIpcMain(store); + initOtherIpcMain(win); +}; + +// win +const initWinIpcMain = ( + win: BrowserWindow | null, + loadingWin: BrowserWindow | null, + lyricWin: BrowserWindow | null, + store: Store, +) => { + let preventId: number | null = null; + + // 当前窗口状态 + ipcMain.on("win-state", (ev) => { + ev.returnValue = win?.isMaximized(); + }); + + // 加载完成 + ipcMain.on("win-loaded", () => { + if (loadingWin && !loadingWin.isDestroyed()) loadingWin.close(); + win?.show(); + win?.focus(); + }); + + // 最小化 + ipcMain.on("win-min", (ev) => { + ev.preventDefault(); + win?.minimize(); + }); + // 最大化 + ipcMain.on("win-max", () => { + win?.maximize(); + }); + // 还原 + ipcMain.on("win-restore", () => { + win?.restore(); + }); + // 关闭 + ipcMain.on("win-close", (ev) => { + ev.preventDefault(); + win?.close(); + app.quit(); + }); + // 隐藏 + ipcMain.on("win-hide", () => { + win?.hide(); + }); + // 显示 + ipcMain.on("win-show", () => { + win?.show(); + }); + // 重启 + ipcMain.on("win-reload", () => { + app.quit(); + app.relaunch(); + }); + + // 显示进度 + ipcMain.on("set-bar", (_, val: number | "none" | "indeterminate" | "error" | "paused") => { + switch (val) { + case "none": + win?.setProgressBar(-1); + break; + case "indeterminate": + win?.setProgressBar(2, { mode: "indeterminate" }); + break; + case "error": + win?.setProgressBar(1, { mode: "error" }); + break; + case "paused": + win?.setProgressBar(1, { mode: "paused" }); + break; + default: + if (typeof val === "number") { + win?.setProgressBar(val / 100); + } else { + win?.setProgressBar(-1); + } + break; + } + }); + + // 开启控制台 + ipcMain.on("open-dev-tools", () => { + win?.webContents.openDevTools({ + title: "SPlayer DevTools", + mode: isDev ? "right" : "detach", + }); + }); + + // 获取系统全部字体 + ipcMain.handle("get-all-fonts", async () => { + try { + const fonts = await getFonts(); + return fonts; + } catch (error) { + log.error(`❌ Failed to get all system fonts: ${error}`); + return []; + } + }); + + // 切换桌面歌词 + ipcMain.on("change-desktop-lyric", (_, val: boolean) => { + val ? lyricWin?.show() : lyricWin?.hide(); + if (val) lyricWin?.setAlwaysOnTop(true, "screen-saver"); + }); + + // 是否阻止系统息屏 + ipcMain.on("prevent-sleep", (_, val: boolean) => { + if (val) { + preventId = powerSaveBlocker.start("prevent-display-sleep"); + log.info("⏾ System sleep prevention started"); + } else { + if (preventId !== null) { + powerSaveBlocker.stop(preventId); + log.info("✅ System sleep prevention stopped"); + } + } + }); + + // 默认文件夹 + ipcMain.handle( + "get-default-dir", + (_, type: "documents" | "downloads" | "pictures" | "music" | "videos"): string => { + return app.getPath(type); + }, + ); + + // 遍历音乐文件 + ipcMain.handle("get-music-files", async (_, dirPath: string) => { + try { + // 查找指定目录下的所有音乐文件 + const musicFiles = await fg("**/*.{mp3,wav,flac}", { cwd: dirPath }); + // 解析元信息 + const metadataPromises = musicFiles.map(async (file) => { + const filePath = join(dirPath, file); + // 处理元信息 + const { common, format } = await parseFile(filePath); + // 获取文件大小 + const { size } = await fs.stat(filePath); + // 判断音质等级 + let quality: string; + if ((format.sampleRate || 0) >= 96000 || (format.bitsPerSample || 0) > 16) { + quality = "Hi-Res"; + } else if ((format.sampleRate || 0) >= 44100) { + quality = "HQ"; + } else { + quality = "SQ"; + } + return { + id: getFileID(filePath), + name: common.title || basename(filePath), + artists: common.artists?.[0] || common.artist, + album: common.album || "", + alia: common.comment?.[0], + duration: (format?.duration ?? 0) * 1000, + size: (size / (1024 * 1024)).toFixed(2), + path: filePath, + quality, + }; + }); + const metadataArray = await Promise.all(metadataPromises); + return metadataArray; + } catch (error) { + log.error("❌ Error fetching music metadata:", error); + throw error; + } + }); + + // 获取音乐元信息 + ipcMain.handle("get-music-metadata", async (_, path: string) => { + try { + const { common, format } = await parseFile(path); + return { + // 文件名称 + fileName: basename(path), + // 文件大小 + fileSize: (await fs.stat(path)).size / (1024 * 1024), + // 元信息 + common, + // 音质信息 + format, + // md5 + md5: await getFileMD5(path), + }; + } catch (error) { + log.error("❌ Error fetching music metadata:", error); + throw error; + } + }); + + // 获取音乐歌词 + ipcMain.handle("get-music-lyric", async (_, path: string): Promise => { + try { + const { common, native } = await parseFile(path); + const lyric = common?.lyrics; + if (lyric && lyric.length > 0) return String(lyric[0]); + else { + // 尝试读取 UNSYNCEDLYRICS + const nativeTags = native["ID3v2.3"] || native["ID3v2.4"]; + const usltTag = nativeTags?.find((tag) => tag.id === "USLT"); + if (usltTag) return String(usltTag.value.text); + // 如果歌词数据不存在,尝试读取同名的 lrc 文件 + else { + const lrcFilePath = path.replace(/\.[^.]+$/, ".lrc"); + try { + await fs.access(lrcFilePath); + const lrcData = await fs.readFile(lrcFilePath, "utf-8"); + return lrcData || ""; + } catch { + return ""; + } + } + } + } catch (error) { + log.error("❌ Error fetching music lyric:", error); + throw error; + } + }); + + // 获取音乐封面 + ipcMain.handle( + "get-music-cover", + async (_, path: string): Promise<{ data: Buffer; format: string } | null> => { + try { + const { common } = await parseFile(path); + // 获取封面数据 + const picture = common.picture?.[0]; + if (picture) { + return { data: Buffer.from(picture.data), format: picture.format }; + } else { + const coverFilePath = path.replace(/\.[^.]+$/, ".jpg"); + try { + await fs.access(coverFilePath); + const coverData = await fs.readFile(coverFilePath); + return { data: coverData, format: "image/jpeg" }; + } catch { + return null; + } + } + } catch (error) { + console.error("❌ Error fetching music cover:", error); + throw error; + } + }, + ); + + // 删除文件 + ipcMain.handle("delete-file", async (_, path: string) => { + try { + // 规范化路径 + const resolvedPath = resolve(path); + // 检查文件是否存在 + try { + await fs.access(resolvedPath); + } catch { + throw new Error("❌ File not found"); + } + // 删除文件 + await fs.unlink(resolvedPath); + return true; + } catch (error) { + log.error("❌ File delete error", error); + return false; + } + }); + + // 打开文件夹 + ipcMain.on("open-folder", async (_, path: string) => { + try { + // 规范化路径 + const resolvedPath = resolve(path); + // 检查文件夹是否存在 + try { + await fs.access(resolvedPath); + } catch { + throw new Error("❌ Folder not found"); + } + // 打开文件夹 + shell.showItemInFolder(resolvedPath); + } catch (error) { + log.error("❌ Folder open error", error); + throw error; + } + }); + + // 图片选择窗口 + ipcMain.handle("choose-image", async () => { + try { + const { filePaths } = await dialog.showOpenDialog({ + properties: ["openFile"], + filters: [{ name: "Images", extensions: ["jpg", "jpeg", "png"] }], + }); + if (!filePaths || filePaths.length === 0) return null; + return filePaths[0]; + } catch (error) { + log.error("❌ Image choose error", error); + return null; + } + }); + + // 路径选择窗口 + ipcMain.handle("choose-path", async () => { + try { + const { filePaths } = await dialog.showOpenDialog({ + title: "选择文件夹", + defaultPath: app.getPath("downloads"), + properties: ["openDirectory", "createDirectory"], + buttonLabel: "选择文件夹", + }); + if (!filePaths || filePaths.length === 0) return null; + return filePaths[0]; + } catch (error) { + log.error("❌ Path choose error", error); + return null; + } + }); + + // 修改音乐元信息 + ipcMain.handle("set-music-metadata", async (_, path: string, metadata: any) => { + try { + const { name, artist, album, alia, lyric, cover } = metadata; + // 规范化路径 + const songPath = resolve(path); + const coverPath = cover ? resolve(cover) : null; + // 读取歌曲文件 + const songFile = File.createFromPath(songPath); + // 读取封面文件 + const songCover = coverPath ? Picture.fromPath(coverPath) : null; + // 保存元数据 + Id3v2Settings.forceDefaultVersion = true; + Id3v2Settings.defaultVersion = 3; + songFile.tag.title = name || "未知曲目"; + songFile.tag.performers = [artist || "未知艺术家"]; + songFile.tag.album = album || "未知专辑"; + songFile.tag.albumArtists = [artist || "未知艺术家"]; + songFile.tag.lyrics = lyric || ""; + songFile.tag.description = alia || ""; + songFile.tag.comment = alia || ""; + if (songCover) songFile.tag.pictures = [songCover]; + // 保存元信息 + songFile.save(); + songFile.dispose(); + return true; + } catch (error) { + log.error("❌ Error setting music metadata:", error); + throw error; + } + }); + + // 下载文件 + ipcMain.handle( + "download-file", + async ( + _, + url: string, + options: { + fileName: string; + fileType: string; + path: string; + downloadMeta?: boolean; + downloadCover?: boolean; + downloadLyric?: boolean; + saveMetaFile?: boolean; + lyric?: string; + songData?: any; + } = { + fileName: "未知文件名", + fileType: "mp3", + path: app.getPath("downloads"), + }, + ): Promise => { + try { + if (!win) return false; + // 获取配置 + const { + fileName, + fileType, + path, + lyric, + downloadMeta, + downloadCover, + downloadLyric, + saveMetaFile, + songData, + } = options; + // 规范化路径 + const downloadPath = resolve(path); + // 检查文件夹是否存在 + try { + await fs.access(downloadPath); + } catch { + throw new Error("❌ Folder not found"); + } + // 下载文件 + const songDownload = await download(win, url, { + directory: downloadPath, + filename: `${fileName}.${fileType}`, + }); + if (!downloadMeta || !songData?.cover) return true; + // 下载封面 + const coverUrl = songData?.coverSize?.l || songData.cover; + const coverDownload = await download(win, coverUrl, { + directory: downloadPath, + filename: `${fileName}.jpg`, + }); + // 读取歌曲文件 + const songFile = File.createFromPath(songDownload.getSavePath()); + // 生成图片信息 + const songCover = Picture.fromPath(coverDownload.getSavePath()); + // 保存修改后的元数据 + Id3v2Settings.forceDefaultVersion = true; + Id3v2Settings.defaultVersion = 3; + songFile.tag.title = songData?.name || "未知曲目"; + songFile.tag.album = songData?.album?.name || "未知专辑"; + songFile.tag.performers = songData?.artists?.map((ar: any) => ar.name) || ["未知艺术家"]; + songFile.tag.albumArtists = songData?.artists?.map((ar: any) => ar.name) || ["未知艺术家"]; + if (lyric && downloadLyric) songFile.tag.lyrics = lyric; + if (songCover && downloadCover) songFile.tag.pictures = [songCover]; + // 保存元信息 + songFile.save(); + songFile.dispose(); + // 创建同名歌词文件 + if (lyric && saveMetaFile && downloadLyric) { + const lrcPath = join(downloadPath, `${fileName}.lrc`); + await fs.writeFile(lrcPath, lyric, "utf-8"); + } + // 是否删除封面 + if (!saveMetaFile || !downloadCover) await fs.unlink(coverDownload.getSavePath()); + return true; + } catch (error) { + log.error("❌ Error downloading file:", error); + return false; + } + }, + ); + + // 取消代理 + ipcMain.on("remove-proxy", () => { + store.set("proxy", ""); + win?.webContents.session.setProxy({ proxyRules: "" }); + log.info("✅ Remove proxy successfully"); + }); + + // 配置网络代理 + ipcMain.on("set-proxy", (_, config) => { + const proxyRules = `${config.protocol}://${config.server}:${config.port}`; + store.set("proxy", proxyRules); + win?.webContents.session.setProxy({ proxyRules }); + log.info("✅ Set proxy successfully:", proxyRules); + }); + + // 代理测试 + ipcMain.handle("test-proxy", async (_, config) => { + const proxyRules = `${config.protocol}://${config.server}:${config.port}`; + try { + // 设置代理 + const ses = session.defaultSession; + await ses.setProxy({ proxyRules }); + // 测试请求 + const request = net.request({ url: "https://www.baidu.com" }); + return new Promise((resolve) => { + request.on("response", (response) => { + if (response.statusCode === 200) { + log.info("✅ Proxy test successful"); + resolve(true); + } else { + log.error(`❌ Proxy test failed with status code: ${response.statusCode}`); + resolve(false); + } + }); + request.on("error", (error) => { + log.error("❌ Error testing proxy:", error); + resolve(false); + }); + request.end(); + }); + } catch (error) { + log.error("❌ Error testing proxy:", error); + return false; + } + }); + + // 重置全部设置 + ipcMain.on("reset-setting", () => { + store.reset(); + log.info("✅ Reset setting successfully"); + }); + + // 检查更新 + ipcMain.on("check-update", (_, showTip) => checkUpdate(win!, showTip)); + + // 开始下载更新 + ipcMain.on("start-download-update", () => startDownloadUpdate()); +}; + +// lyric +const initLyricIpcMain = ( + lyricWin: BrowserWindow | null, + mainWin: BrowserWindow | null, + store: Store, +): void => { + // 音乐名称更改 + ipcMain.on("play-song-change", (_, title) => { + if (!title) return; + lyricWin?.webContents.send("play-song-change", title); + }); + + // 音乐歌词更改 + ipcMain.on("play-lyric-change", (_, lyricData) => { + if (!lyricData) return; + lyricWin?.webContents.send("play-lyric-change", lyricData); + }); + + // 获取窗口位置 + ipcMain.handle("get-window-bounds", () => { + return lyricWin?.getBounds(); + }); + + // 获取屏幕尺寸 + ipcMain.handle("get-screen-size", () => { + const { width, height } = screen.getPrimaryDisplay().workAreaSize; + return { width, height }; + }); + + // 移动窗口 + ipcMain.on("move-window", (_, x, y, width, height) => { + lyricWin?.setBounds({ x, y, width, height }); + // 保存配置 + store.set("lyric", { ...store.get("lyric"), x, y, width, height }); + // 保持置顶 + lyricWin?.setAlwaysOnTop(true, "screen-saver"); + }); + + // 更新高度 + ipcMain.on("update-window-height", (_, height) => { + if (!lyricWin) return; + const { width } = lyricWin.getBounds(); + // 更新窗口高度 + lyricWin.setBounds({ width, height }); + }); + + // 获取配置 + ipcMain.handle("get-desktop-lyric-option", () => { + return store.get("lyric"); + }); + + // 保存配置 + ipcMain.on("set-desktop-lyric-option", (_, option, callback: boolean = false) => { + store.set("lyric", option); + // 触发窗口更新 + if (callback && lyricWin) { + lyricWin.webContents.send("desktop-lyric-option-change", option); + } + mainWin?.webContents.send("desktop-lyric-option-change", option); + }); + + // 发送主程序事件 + ipcMain.on("send-main-event", (_, name, val) => { + mainWin?.webContents.send(name, val); + }); + + // 关闭桌面歌词 + ipcMain.on("closeDesktopLyric", () => { + lyricWin?.hide(); + mainWin?.webContents.send("closeDesktopLyric"); + }); + + // 锁定/解锁桌面歌词 + ipcMain.on("toogleDesktopLyricLock", (_, isLock: boolean) => { + if (!lyricWin) return; + // 是否穿透 + if (isLock) { + lyricWin.setIgnoreMouseEvents(true, { forward: true }); + } else { + lyricWin.setIgnoreMouseEvents(false); + } + }); +}; + +// tray +const initTrayIpcMain = ( + tray: MainTray | null, + win: BrowserWindow | null, + lyricWin: BrowserWindow | null, +): void => { + // 音乐播放状态更改 + ipcMain.on("play-status-change", (_, playStatus: boolean) => { + tray?.setPlayState(playStatus ? "play" : "pause"); + lyricWin?.webContents.send("play-status-change", playStatus); + }); + + // 音乐名称更改 + ipcMain.on("play-song-change", (_, title) => { + if (!title) return; + // 更改标题 + win?.setTitle(title); + tray?.setTitle(title); + tray?.setPlayName(title); + }); + + // 播放模式切换 + ipcMain.on("play-mode-change", (_, mode) => { + tray?.setPlayMode(mode); + }); + + // 桌面歌词开关 + ipcMain.on("change-desktop-lyric", (_, val: boolean) => { + tray?.setDesktopLyricShow(val); + }); + + // 锁定/解锁桌面歌词 + ipcMain.on("toogleDesktopLyricLock", (_, isLock: boolean) => { + tray?.setDesktopLyricLock(isLock); + }); +}; + +// thumbar +const initThumbarIpcMain = (thumbar: Thumbar | null): void => { + if (!thumbar) return; +}; + +// store +const initStoreIpcMain = (store: Store): void => { + if (!store) return; +}; + +// other +const initOtherIpcMain = (mainWin: BrowserWindow | null): void => { + // 快捷键是否被注册 + ipcMain.handle("is-shortcut-registered", (_, shortcut: string) => isShortcutRegistered(shortcut)); + + // 注册快捷键 + ipcMain.handle("register-all-shortcut", (_, allShortcuts: any): string[] | false => { + if (!mainWin || !allShortcuts) return false; + // 卸载所有快捷键 + unregisterShortcuts(); + // 注册快捷键 + const failedShortcuts: string[] = []; + for (const key in allShortcuts) { + const shortcut = allShortcuts[key].globalShortcut; + if (!shortcut) continue; + // 快捷键回调 + const callback = () => mainWin.webContents.send(key); + const isSuccess = registerShortcut(shortcut, callback); + if (!isSuccess) failedShortcuts.push(shortcut); + } + return failedShortcuts; + }); + + // 卸载所有快捷键 + ipcMain.on("unregister-all-shortcut", () => unregisterShortcuts()); +}; + +export default initIpcMain; diff --git a/electron/main/logger.ts b/electron/main/logger.ts new file mode 100644 index 0000000..6dd36d1 --- /dev/null +++ b/electron/main/logger.ts @@ -0,0 +1,31 @@ +// 日志输出 +import { join } from "path"; +import { app } from "electron"; +import { isDev } from "./utils"; +import log from "electron-log"; + +// 绑定事件 +Object.assign(console, log.functions); + +// 日志配置 +log.transports.file.level = "info"; +log.transports.file.maxSize = 2 * 1024 * 1024; +if (log.transports.ipc) log.transports.ipc.level = false; + +// 控制台输出 +log.transports.console.useStyles = true; + +// 文件输出 +log.transports.file.format = "{h}:{i}:{s}:{ms} {text}"; + +// 本地输出 +if (!isDev) { + log.transports.file.resolvePathFn = () => + join(app.getPath("documents"), "/SPlayer/SPlayer-log.txt"); +} else { + log.transports.file.level = false; +} + +log.info("📃 logger initialized"); + +export default log; diff --git a/electron/main/mainIpcMain.js b/electron/main/mainIpcMain.js deleted file mode 100644 index 23a49fd..0000000 --- a/electron/main/mainIpcMain.js +++ /dev/null @@ -1,321 +0,0 @@ -import { ipcMain, dialog, app, clipboard, shell } from "electron"; -import { File, Picture, Id3v2Settings } from "node-taglib-sharp"; -import { configureAutoUpdater } from "@main/utils/checkUpdates"; -import { readDirAsync } from "@main/utils/readDirAsync"; -import { parseFile } from "music-metadata"; -import { download } from "electron-dl"; -import { getFonts } from "font-list"; -import getNeteaseMusicUrl from "@main/utils/getNeteaseMusicUrl"; -import axios from "axios"; -import fs from "fs/promises"; - -/** - * 监听主进程的 IPC 事件 - * @param {BrowserWindow} win - 要监听 IPC 事件的程序窗口 - * @param {Store} store - 存储对象 - */ - -const mainIpcMain = (win, store) => { - // 窗口操作部分 - ipcMain.on("window-min", (ev) => { - // 阻止最小化 - ev.preventDefault(); - // 最小化 - win.minimize(); - }); - ipcMain.on("window-maxOrRestore", (ev) => { - const winSizeState = win.isMaximized(); - winSizeState ? win.restore() : win.maximize(); - ev.reply("windowState", win.isMaximized()); - }); - ipcMain.on("window-restore", () => { - win.restore(); - }); - ipcMain.on("window-hide", () => { - win.hide(); - }); - ipcMain.on("window-close", () => { - win.close(); - app.isQuiting = true; - app.quit(); - }); - ipcMain.on("window-relaunch", () => { - app.isQuiting = true; - app.relaunch(); - app.quit(); - }); - ipcMain.on("check-updates", () => { - console.info("开始检查更新"); - configureAutoUpdater(); - }); - - // 显示进度 - ipcMain.on("setProgressBar", (_, val) => { - if (val === "close") { - win.setProgressBar(-1); - return false; - } - win.setProgressBar(val / 100); - }); - - // 解灰 - ipcMain.handle("getMusicNumUrl", async (_, data) => { - // 解析传入数据 - const songData = JSON.parse(data); - const songName = `${songData?.name}-${songData?.artists?.[0].name}`; - console.log("开始解灰:", songName); - const url = await getNeteaseMusicUrl(songName); - console.log("解灰地址:", url); - return url; - }); - - // bili 链接解析 - ipcMain.handle("getBiliUrlData", async (_, url) => { - const data = await getBiliUrlBase64(url); - return data; - }); - - // 默认音乐文件夹 - ipcMain.handle("getdefaultMusicPath", async () => { - const path = app.getPath("music"); - return path; - }); - - // 选择文件夹 - ipcMain.handle("selectDir", async (_, isChooseDl = false) => { - try { - const { canceled, filePaths } = await dialog.showOpenDialog({ - title: isChooseDl ? "选择下载目录" : "选择添加目录", - defaultPath: isChooseDl ? app.getPath("downloads") : app.getPath("music"), - properties: ["openDirectory", "createDirectory"], - buttonLabel: "选择文件夹", - }); - if (!canceled) { - const selectedDirectory = filePaths[0]; - return selectedDirectory; - } - } catch (err) { - console.error("选择文件夹时发生错误:", err); - throw err; - } - }); - - // 读取文件夹内容 - ipcMain.handle("getDirContents", async (_, selectedDir) => { - try { - // 使用 readDirAsync 函数递归地读取文件夹内容 - const directoryContents = await readDirAsync(selectedDir); - return directoryContents; - } catch (err) { - console.error("读取文件夹内容时发生错误:", err); - throw err; - } - }); - - // 读取音乐歌词 - ipcMain.handle("getMusicLyric", async (_, path) => { - try { - const data = await parseFile(path); - const lyric = data.common.lyrics; - if (lyric && lyric.length > 0) { - return lyric[0]; - } - // 如果歌词数据不存在,尝试读取同名的 lrc 文件 - else { - const lrcFilePath = path.replace(/\.[^.]+$/, ".lrc"); - const lrcData = await fs.readFile(lrcFilePath, "utf-8"); - // 返回读取的 lrc 数据,如果没有则返回 null - return lrcData || null; - } - } catch (error) { - console.error("读取音乐歌词出错:", error); - return null; - } - }); - - // 读取音乐封面 - ipcMain.handle("getMusicCover", async (_, path) => { - try { - const data = await parseFile(path); - const picture = data.common.picture; - if (picture && picture.length > 0) { - const coverData = picture[0].data; - const coverFormat = picture[0].format; - return { coverData, coverFormat }; - } - // 如果封面数据不存在,尝试读取同名的封面图片文件 - else { - const coverFilePath = path.replace(/\.[^.]+$/, ".jpg"); - const coverData = await fs.readFile(coverFilePath); - // 返回读取的封面图片数据,如果没有则返回 null - return coverData ? { coverData, coverFormat: "jpg" } : null; - } - } catch (error) { - console.error("读取音乐封面出错:", error); - return null; - } - }); - - // 执行复制操作 - ipcMain.handle("copyData", async (_, data) => { - try { - clipboard.writeText(data); - return true; - } catch (error) { - console.error("复制操作出错:", error); - return false; - } - }); - - // 本地磁盘文件删除 - ipcMain.handle("deleteFile", async (_, path) => { - try { - // 检查文件是否存在 - if (fs.access(path)) { - // 尝试删除文件 - fs.unlink(path); - console.log(`文件已删除:${path}`); - return true; - } else { - console.log(`文件不存在:${path}`); - return false; - } - } catch (err) { - console.error(`文件删除操作出错:${path}`, err); - return false; - } - }); - - // 打开歌曲目录 - ipcMain.on("openSongLocal", (_, path) => { - try { - if (fs.access(path)) { - shell.showItemInFolder(path); - } else { - console.log(`文件不存在:${path}`); - } - } catch (error) { - console.error("打开歌曲目录时出错:", error); - } - }); - - // 下载文件至指定目录 - ipcMain.handle("downloadFile", async (_, songData, options) => { - try { - const { url, data, lyric, name, type } = JSON.parse(songData); - const { path, downloadMeta, downloadCover, downloadLyrics } = JSON.parse(options); - if (fs.access(path)) { - console.info("开始下载:", name, url); - // 下载歌曲 - const songDownload = await download(win, url, { - directory: path, - filename: `${name}.${type}`, - }); - // 若关闭,则不进行元信息写入 - if (!downloadMeta) return true; - // 下载封面 - const coverDownload = await download(win, data.cover, { - directory: path, - filename: `${name}.jpg`, - }); - // 读取歌曲文件 - const songFile = File.createFromPath(songDownload.getSavePath()); - // 生成图片信息 - const songCover = Picture.fromPath(coverDownload.getSavePath()); - // 保存修改后的元数据 - Id3v2Settings.forceDefaultVersion = true; - Id3v2Settings.defaultVersion = 3; - songFile.tag.title = data.name || "未知曲目"; - songFile.tag.album = data.album?.name || "未知专辑"; - songFile.tag.performers = data?.artists?.map((ar) => ar.name) || ["未知艺术家"]; - if (downloadLyrics) songFile.tag.lyrics = lyric; - if (downloadCover) songFile.tag.pictures = [songCover]; - // 保存元信息 - songFile.save(); - songFile.dispose(); - // 删除封面 - await fs.unlink(coverDownload.getSavePath()); - return true; - } else { - console.log(`目录不存在:${path}`); - return false; - } - } catch (error) { - console.error("下载文件时出错:", error); - return false; - } - }); - - // 读取系统全部字体 - ipcMain.handle("getAllFonts", async () => { - try { - const fonts = await getFonts(); - return fonts; - } catch (error) { - console.error("获取系统字体时出错:", error); - return []; - } - }); - - // 配置网络代理 - ipcMain.on("set-proxy", (_, config) => { - console.log(config); - const proxyRules = `${config.protocol}://${config.server}:${config.port}`; - store.set("proxy", proxyRules); - win.webContents.session.setProxy({ proxyRules }, () => { - console.info("网络代理配置完成"); - }); - }); - - // 取消代理 - ipcMain.on("remove-proxy", () => { - store.set("proxy", ""); - win.webContents.session.setProxy({ proxyRules: "" }, () => { - console.info("取消网络代理配置"); - }); - }); -}; - -/** - * 从 Bilibili 视频中获取文件的 Base64 数据 - * - * @param {string} url - 要获取的文件的 URL - * @returns {Promise} - 文件的 Base64 数据 - */ -const getBiliUrlBase64 = async (url) => { - try { - const response = await axios.get(url, { - headers: { - Referer: "https://www.bilibili.com/", - "User-Agent": "okhttp/3.4.1", - }, - responseType: "arraybuffer", - withCredentials: false, - }); - // 将二进制数据转换为缓冲区 - const buffer = toBuffer(response.data); - // 将缓冲区中的数据转换为 Base64 编码的字符串 - const encodedData = buffer.toString("base64"); - // 返回 Base64 编码的文件数据 - return encodedData; - } catch (error) { - console.error("获取文件数据时发生错误:" + error); - return null; - } -}; - -/** - * 将数据转换为缓冲区( Buffer ) - * - * @param {ArrayBuffer|Buffer|Uint8Array} data - 要转换的数据 - * @returns {Buffer} - 转换后的缓冲区 - */ -const toBuffer = (data) => { - if (data instanceof Buffer) { - return data; - } else { - return Buffer.from(data); - } -}; - -export default mainIpcMain; diff --git a/electron/main/shortcut.ts b/electron/main/shortcut.ts new file mode 100644 index 0000000..278f6c2 --- /dev/null +++ b/electron/main/shortcut.ts @@ -0,0 +1,43 @@ +import { BrowserWindow, globalShortcut } from "electron"; +import { isDev } from "./utils"; +import log from "../main/logger"; + +// 注册快捷键并检查 +export const registerShortcut = (shortcut: string, callback: () => void): boolean => { + try { + const success = globalShortcut.register(shortcut, callback); + if (!success) { + log.error(`❌ Failed to register shortcut: ${shortcut}`); + return false; + } else { + log.info(`✅ Shortcut registered: ${shortcut}`); + return true; + } + } catch (error) { + log.error(`ℹ️ Error registering shortcut ${shortcut}:`, error); + return false; + } +}; + +// 检查快捷键是否被注册 +export const isShortcutRegistered = (shortcut: string): boolean => { + return globalShortcut.isRegistered(shortcut); +}; + +// 卸载所有快捷键 +export const unregisterShortcuts = () => { + globalShortcut.unregisterAll(); + log.info("🚫 All shortcuts unregistered."); +}; + +// 注册所有快捷键 +export const registerAllShortcuts = (win: BrowserWindow) => { + // 开启控制台 + registerShortcut("CmdOrCtrl+Shift+I", () => { + win.webContents.openDevTools({ + title: "SPlayer DevTools", + // 客户端分离 + mode: isDev ? "right" : "detach", + }); + }); +}; diff --git a/electron/main/startMainServer.js b/electron/main/startMainServer.js deleted file mode 100644 index 1f98254..0000000 --- a/electron/main/startMainServer.js +++ /dev/null @@ -1,22 +0,0 @@ -import { join } from "path"; -import express from "express"; -import expressProxy from "express-http-proxy"; -import checkPort from "./utils/checkPort"; - -/** - * 启动主服务器 - * @returns {import('http').Server} HTTP 服务器实例 - */ -export const startMainServer = async () => { - const { MAIN_VITE_MAIN_PORT, MAIN_VITE_SERVER_HOST, MAIN_VITE_SERVER_PORT } = import.meta.env; - const port = await checkPort(MAIN_VITE_MAIN_PORT ?? 7899); - process.env.MAIN_VITE_MAIN_PORT = port; - const apiHost = `http://${MAIN_VITE_SERVER_HOST}:${MAIN_VITE_SERVER_PORT}`; - const expressApp = express(); - // 代理 - expressApp.use("/", express.static(join(__dirname, "../renderer/"))); - expressApp.use("/api", expressProxy(apiHost)); - console.log("生产模式主进程端口: ", port); - // 启动 Express 应用服务器,并监听指定端口 - return expressApp.listen(port, "127.0.0.1"); -}; diff --git a/electron/main/startNcmServer.js b/electron/main/startNcmServer.js deleted file mode 100644 index b246a37..0000000 --- a/electron/main/startNcmServer.js +++ /dev/null @@ -1,22 +0,0 @@ -import netEaseApi from "NeteaseCloudMusicApi"; -import checkPort from "@main/utils/checkPort"; - -/** - * 启动网易云音乐 API 服务器 - * - * @async - * @param {Object} options - 服务器配置 - * @param {number} [options.port=11451] - 服务器端口 - * @param {string} [options.host="127.0.0.1"] - 服务器主机地址 - * @returns {Promise} 返回一个 Promise,在 API 服务器成功启动后 resolve - */ -export const startNcmServer = async ( - options = { - port: 11451, - host: "127.0.0.1", - }, -) => { - const serverPort = await checkPort(options.port); - options.port = serverPort; - return await netEaseApi.serveNcmApi(options); -}; diff --git a/electron/main/store.ts b/electron/main/store.ts new file mode 100644 index 0000000..6a5bc9f --- /dev/null +++ b/electron/main/store.ts @@ -0,0 +1,46 @@ +import Store from "electron-store"; +import log from "./logger"; + +log.info("🌱 Store init"); + +export interface StoreType { + window: { + width: number; + height: number; + x?: number; + y?: number; + }; + lyric: { + fontSize: number; + mainColor: string; + shadowColor: string; + // 窗口位置 + x?: number; + y?: number; + width?: number; + height?: number; + }; + proxy: string; +} + +// 初始化仓库 +const store = new Store({ + defaults: { + window: { + width: 1280, + height: 800, + }, + lyric: { + fontSize: 30, + mainColor: "#fff", + shadowColor: "rgba(0, 0, 0, 0.5)", + x: 0, + y: 0, + width: 800, + height: 180, + }, + proxy: "", + }, +}); + +export default store; diff --git a/electron/main/thumbar.ts b/electron/main/thumbar.ts new file mode 100644 index 0000000..aae0b66 --- /dev/null +++ b/electron/main/thumbar.ts @@ -0,0 +1,98 @@ +import { BrowserWindow, nativeImage, nativeTheme, ThumbarButton } from "electron"; +import { join } from "path"; +import { isWin } from "./utils"; +import log from "./logger"; + +enum ThumbarKeys { + Play = "play", + Pause = "pause", + Prev = "prev", + Next = "next", +} + +type ThumbarMap = Map; + +export interface Thumbar { + clearThumbar(): void; +} + +// 工具栏图标 +const thumbarIcon = (filename: string) => { + // 是否为暗色 + const isDark = nativeTheme.shouldUseDarkColors; + // 返回图标 + return nativeImage.createFromPath( + join(__dirname, `../../public/icons/thumbar/${filename}-${isDark ? "dark" : "light"}.png`), + ); +}; + +// 缩略图工具栏 +const createThumbarButtons = (win: BrowserWindow): ThumbarMap => { + return new Map() + .set(ThumbarKeys.Prev, { + tooltip: "上一曲", + icon: thumbarIcon("prev"), + click: () => win.webContents.send("play-prev"), + }) + .set(ThumbarKeys.Next, { + tooltip: "下一曲", + icon: thumbarIcon("next"), + click: () => win.webContents.send("play-next"), + }) + .set(ThumbarKeys.Play, { + tooltip: "播放", + icon: thumbarIcon("play"), + click: () => win.webContents.send("play"), + }) + .set(ThumbarKeys.Pause, { + tooltip: "暂停", + icon: thumbarIcon("pause"), + click: () => win.webContents.send("play-pause"), + }); +}; + +// 创建缩略图工具栏 +class createThumbar implements Thumbar { + // 窗口 + private _win: BrowserWindow; + // 工具栏 + private _thumbar: ThumbarMap; + // 工具栏按钮 + private _prev: ThumbarButton; + private _next: ThumbarButton; + private _play: ThumbarButton; + private _pause: ThumbarButton; + constructor(win: BrowserWindow) { + // 初始化数据 + this._win = win; + this._thumbar = createThumbarButtons(win); + // 工具栏按钮 + this._play = this._thumbar.get(ThumbarKeys.Play)!; + this._pause = this._thumbar.get(ThumbarKeys.Pause)!; + this._prev = this._thumbar.get(ThumbarKeys.Prev)!; + this._next = this._thumbar.get(ThumbarKeys.Next)!; + // 初始化工具栏 + this.updateThumbar(); + } + // 更新工具栏 + private updateThumbar(playing: boolean = false, clean: boolean = false) { + if (clean) return this.clearThumbar(); + this._win.setThumbarButtons([this._prev, playing ? this._pause : this._play, this._next]); + } + // 清除工具栏 + clearThumbar() { + this._win.setThumbarButtons([]); + } +} + +export const initThumbar = (win: BrowserWindow) => { + try { + // 若非 Win + if (!isWin) return null; + log.info("🚀 ThumbarButtons Startup"); + return new createThumbar(win); + } catch (error) { + log.error("❌ ThumbarButtons Error", error); + throw error; + } +}; diff --git a/electron/main/tray.ts b/electron/main/tray.ts new file mode 100644 index 0000000..cc3799c --- /dev/null +++ b/electron/main/tray.ts @@ -0,0 +1,288 @@ +import { + app, + Tray, + Menu, + MenuItemConstructorOptions, + BrowserWindow, + nativeImage, + nativeTheme, +} from "electron"; +import { isWin, isLinux, isDev, appName } from "./utils"; +import { join } from "path"; +import log from "./logger"; + +// 播放模式 +type PlayMode = "repeat" | "repeat-once" | "shuffle"; +type PlayState = "play" | "pause" | "loading"; + +// 全局数据 +let playMode: PlayMode = "repeat"; +let playState: PlayState = "pause"; +let playName: string = "未播放歌曲"; +let desktopLyricShow: boolean = false; +let desktopLyricLock: boolean = false; + +export interface MainTray { + setTitle(title: string): void; + setPlayMode(mode: PlayMode): void; + setPlayState(state: PlayState): void; + setPlayName(name: string): void; + setDesktopLyricShow(show: boolean): void; + setDesktopLyricLock(lock: boolean): void; + destroyTray(): void; +} + +// 托盘图标 +const trayIcon = (filename: string) => { + // const rootPath = isDev + // ? join(__dirname, "../../public/icons/tray") + // : join(app.getAppPath(), "../../public/icons/tray"); + // return nativeImage.createFromPath(join(rootPath, filename)); + return nativeImage.createFromPath(join(__dirname, `../../public/icons/tray/${filename}`)); +}; + +// 托盘菜单 +const createTrayMenu = ( + win: BrowserWindow, + lyricWin: BrowserWindow, +): MenuItemConstructorOptions[] => { + // 区分明暗图标 + const showIcon = (iconName: string) => { + const isDark = nativeTheme.shouldUseDarkColors; + return trayIcon(`${iconName}${isDark ? "-dark" : "-light"}.png`).resize({ + width: 16, + height: 16, + }); + }; + // 菜单 + const menu: MenuItemConstructorOptions[] = [ + { + id: "name", + label: playName, + icon: showIcon("music"), + accelerator: "CmdOrCtrl+Alt+S", + click: () => { + win.show(); + win.focus(); + }, + }, + { + type: "separator", + }, + { + id: "toogleLikeSong", + label: "添加到我喜欢", + icon: showIcon("unlike"), + accelerator: "CmdOrCtrl+Alt+L", + click: () => win.webContents.send("toogleLikeSong"), + }, + { + id: "unLike", + label: "从我喜欢中移除", + icon: showIcon("like"), + visible: false, + accelerator: "CmdOrCtrl+Alt+L", + click: () => win.webContents.send("unlike-song"), + }, + { + id: "changeMode", + label: + playMode === "repeat" ? "列表循环" : playMode === "repeat-once" ? "单曲循环" : "随机播放", + icon: showIcon(playMode), + submenu: [ + { + id: "repeat", + label: "列表循环", + icon: showIcon("repeat"), + checked: playMode === "repeat", + type: "radio", + click: () => win.webContents.send("changeMode", "repeat"), + }, + { + id: "repeat-once", + label: "单曲循环", + icon: showIcon("repeat-once"), + checked: playMode === "repeat-once", + type: "radio", + click: () => win.webContents.send("changeMode", "repeat-once"), + }, + { + id: "shuffle", + label: "随机播放", + icon: showIcon("shuffle"), + checked: playMode === "shuffle", + type: "radio", + click: () => win.webContents.send("changeMode", "shuffle"), + }, + ], + }, + { + type: "separator", + }, + { + id: "playNext", + label: "上一曲", + icon: showIcon("prev"), + accelerator: "CmdOrCtrl+Left", + click: () => win.webContents.send("playPrev"), + }, + { + id: "playOrPause", + label: playState === "pause" ? "播放" : "暂停", + icon: showIcon(playState === "pause" ? "play" : "pause"), + accelerator: "CmdOrCtrl+Space", + click: () => win.webContents.send(playState === "pause" ? "play" : "pause"), + }, + { + id: "playNext", + label: "下一曲", + icon: showIcon("next"), + accelerator: "CmdOrCtrl+Right", + click: () => win.webContents.send("playNext"), + }, + { + type: "separator", + }, + { + id: "toogleDesktopLyric", + label: `${desktopLyricShow ? "关闭" : "开启"}桌面歌词`, + icon: showIcon("lyric"), + click: () => win.webContents.send("toogleDesktopLyric"), + }, + { + id: "toogleDesktopLyricLock", + label: `${desktopLyricLock ? "解锁" : "锁定"}桌面歌词`, + icon: showIcon(desktopLyricLock ? "lock" : "unlock"), + visible: desktopLyricShow, + click: () => lyricWin.webContents.send("toogleDesktopLyricLock", !desktopLyricLock), + }, + { + type: "separator", + }, + { + id: "setting", + label: "全局设置", + icon: showIcon("setting"), + click: () => { + win.show(); + win.focus(); + win.webContents.send("openSetting"); + }, + }, + { + type: "separator", + }, + { + id: "exit", + label: "退出", + icon: showIcon("power"), + accelerator: "CmdOrCtrl+Alt+Q", + click: () => { + win.close(); + // app.exit(0); + app.quit(); + }, + }, + ]; + return menu; +}; + +// 创建托盘 +class CreateTray implements MainTray { + // 窗口 + private _win: BrowserWindow; + private _lyricWin: BrowserWindow; + // 托盘 + private _tray: Tray; + // 菜单 + private _menu: MenuItemConstructorOptions[]; + private _contextMenu: Menu; + + constructor(win: BrowserWindow, lyricWin: BrowserWindow) { + // 托盘图标 + const icon = trayIcon(isWin ? "tray.ico" : "tray@32.png").resize({ + height: 32, + width: 32, + }); + // 初始化数据 + this._win = win; + this._lyricWin = lyricWin; + this._tray = new Tray(icon); + this._menu = createTrayMenu(this._win, this._lyricWin); + this._contextMenu = Menu.buildFromTemplate(this._menu); + // 初始化事件 + this.initTrayMenu(); + this.initEvents(); + this.setTitle(appName); + } + // 托盘菜单 + private initTrayMenu() { + this._menu = createTrayMenu(this._win, this._lyricWin); + this._contextMenu = Menu.buildFromTemplate(this._menu); + this._tray.setContextMenu(this._contextMenu); + } + // 托盘事件 + private initEvents() { + // 点击 + this._tray.on("click", () => this._win.show()); + // 明暗变化 + nativeTheme.on("updated", () => { + this.initTrayMenu(); + }); + } + // 设置标题 + setTitle(title: string) { + this._tray.setTitle(title); + this._tray.setToolTip(title); + } + // 设置播放名称 + setPlayName(name: string) { + // 超长处理 + if (name.length > 20) name = name.slice(0, 20) + "..."; + playName = name; + // 更新菜单 + this.initTrayMenu(); + } + // 设置播放状态 + setPlayState(state: PlayState) { + playState = state; + // 更新菜单 + this.initTrayMenu(); + } + // 设置播放模式 + setPlayMode(mode: PlayMode) { + playMode = mode; + // 更新菜单 + this.initTrayMenu(); + } + // 桌面歌词开关 + setDesktopLyricShow(show: boolean) { + desktopLyricShow = show; + // 更新菜单 + this.initTrayMenu(); + } + // 锁定桌面歌词 + setDesktopLyricLock(lock: boolean) { + desktopLyricLock = lock; + // 更新菜单 + this.initTrayMenu(); + } + // 销毁托盘 + destroyTray() { + this._tray.destroy(); + } +} + +export const initTray = (win: BrowserWindow, lyricWin: BrowserWindow) => { + try { + // 若为 MacOS + if (isWin || isLinux || isDev) { + log.info("🚀 Tray Process Startup"); + return new CreateTray(win, lyricWin); + } + return null; + } catch (error) { + log.error("❌ Tray Process Error", error); + return null; + } +}; diff --git a/electron/main/update.ts b/electron/main/update.ts new file mode 100644 index 0000000..11991be --- /dev/null +++ b/electron/main/update.ts @@ -0,0 +1,76 @@ +import { type BrowserWindow } from "electron"; +import electronUpdater from "electron-updater"; +import log from "./logger"; + +// import +const { autoUpdater } = electronUpdater; + +// 更新源 +autoUpdater.setFeedURL({ + provider: "github", + owner: "imsyy", + repo: "SPlayer", +}); + +// 禁用自动下载 +autoUpdater.autoDownload = false; + +// 是否初始化 +let isInit: boolean = false; + +// 是否提示 +let isShowTip: boolean = false; + +// 事件监听 +const initUpdaterListeners = (win: BrowserWindow) => { + if (isInit) return; + + // 当有新版本可用时 + autoUpdater.on("update-available", (info) => { + win.webContents.send("update-available", info); + log.info(`🚀 New version available: ${info.version}`); + }); + + // 更新下载进度 + autoUpdater.on("download-progress", (progress) => { + win.webContents.send("download-progress", progress); + log.info(`🚀 Downloading: ${progress.percent}%`); + }); + + // 当下载完成时 + autoUpdater.on("update-downloaded", (info) => { + win.webContents.send("update-downloaded", info); + log.info(`🚀 Update downloaded: ${info.version}`); + // 安装更新 + autoUpdater.quitAndInstall(); + }); + + // 当没有新版本时 + autoUpdater.on("update-not-available", (info) => { + if (isShowTip) win.webContents.send("update-not-available", info); + log.info(`✅ No new version available: ${info.version}`); + }); + + // 更新错误 + autoUpdater.on("error", (err) => { + win.webContents.send("update-error", err); + log.error(`❌ Update error: ${err.message}`); + }); + + isInit = true; +}; + +// 检查更新 +export const checkUpdate = (win: BrowserWindow, showTip: boolean = false) => { + // 初始化事件监听器 + initUpdaterListeners(win); + // 更改提示 + isShowTip = showTip; + // 检查更新 + autoUpdater.checkForUpdates(); +}; + +// 开始下载 +export const startDownloadUpdate = () => { + autoUpdater.downloadUpdate(); +}; diff --git a/electron/main/utils.ts b/electron/main/utils.ts new file mode 100644 index 0000000..8f54444 --- /dev/null +++ b/electron/main/utils.ts @@ -0,0 +1,32 @@ +import { app } from "electron"; +import { is } from "@electron-toolkit/utils"; +import fs from "fs/promises"; +import crypto from "crypto"; + +// 系统判断 +export const isDev = is.dev; +export const isWin = process.platform === "win32"; +export const isMac = process.platform === "darwin"; +export const isLinux = process.platform === "linux"; + +// 程序名称 +export const appName = app.getName() || "SPlayer"; + +// 生成唯一ID +export const getFileID = (filePath: string): number => { + // SHA-256 + const hash = crypto.createHash("sha256"); + hash.update(filePath); + const digest = hash.digest("hex"); + // 将哈希值的前 16 位转换为十进制数字 + const uniqueId = parseInt(digest.substring(0, 16), 16); + return Number(uniqueId.toString().padStart(16, "0")); +}; + +// 生成文件 MD5 +export const getFileMD5 = async (path: string): Promise => { + const data = await fs.readFile(path); + const hash = crypto.createHash("md5"); + hash.update(data); + return hash.digest("hex"); +}; diff --git a/electron/main/utils/checkPort.js b/electron/main/utils/checkPort.js deleted file mode 100644 index e885c20..0000000 --- a/electron/main/utils/checkPort.js +++ /dev/null @@ -1,37 +0,0 @@ -import net from "net"; - -/** - * 检查端口是否可用, 如果被占用或不可访问,则尝试下一个端口 - * @param {number} port 端口号 - * @param {number} [maxPort=65535] 端口号上限 - * @returns {Promise} 返回可用的端口号 - */ -const checkPort = (port, maxPort = 65535) => { - return new Promise((resolve, reject) => { - if (port > maxPort) { - reject(new Error(`${port} 超出端口范围,无法找到可用端口`)); - return; - } - - port = Number(port); - - const server = net.createServer(); - - server.listen(port, "0.0.0.0", () => { - server.once("close", () => { - resolve(port); - }); - server.close(); - }); - - server.on("error", (err) => { - if (err.code === "EADDRINUSE" || err.code === "EACCES") { - resolve(checkPort(port + 1, maxPort)); - } else { - reject(err); - } - }); - }); -}; - -export default checkPort; diff --git a/electron/main/utils/checkUpdates.js b/electron/main/utils/checkUpdates.js deleted file mode 100644 index e6bc217..0000000 --- a/electron/main/utils/checkUpdates.js +++ /dev/null @@ -1,65 +0,0 @@ -import { dialog } from "electron"; -import { is } from "@electron-toolkit/utils"; -import pkg from "electron-updater"; - -const { autoUpdater } = pkg; - -// 更新弹窗 -const hasNewVersion = (info) => { - dialog - .showMessageBox({ - title: "发现新版本 v" + info.version, - message: "发现新版本 v" + info.version, - detail: "是否立即下载并安装新版本?", - buttons: ["立即下载", "取消"], - type: "question", - noLink: true, - }) - .then((result) => { - if (result.response === 0) { - // 触发手动下载 - autoUpdater.downloadUpdate(); - } - }); -}; - -export const configureAutoUpdater = () => { - if (is.dev) return false; - - // 监听下载进度事件 - autoUpdater.on("download-progress", (progressObj) => { - console.log(`更新下载进度: ${progressObj.percent}%`); - }); - - // 下载完成 - autoUpdater.on("update-downloaded", () => { - // 显示安装弹窗 - dialog - .showMessageBox({ - title: "下载完成", - message: "新版本已下载完成,是否现在安装?", - buttons: ["是", "稍后"], - type: "question", - }) - .then((result) => { - if (result.response === 0) { - // 安装更新 - autoUpdater.quitAndInstall(); - } - }); - }); - - // 下载失败 - autoUpdater.on("error", (err) => { - console.error("下载更新失败:", err); - dialog.showErrorBox("下载更新失败", "请检查网络连接并稍后重试!"); - }); - - // 若有更新 - autoUpdater.on("update-available", (info) => { - hasNewVersion(info); - }); - - // 检查更新 - autoUpdater.checkForUpdatesAndNotify(); -}; diff --git a/electron/main/utils/createGlobalShortcut.js b/electron/main/utils/createGlobalShortcut.js deleted file mode 100644 index bb4c334..0000000 --- a/electron/main/utils/createGlobalShortcut.js +++ /dev/null @@ -1,24 +0,0 @@ -import { globalShortcut } from "electron"; - -/** - * 注册全局快捷键 - * @param {BrowserWindow} win - 程序窗口 - */ -const createGlobalShortcut = (win) => { - // 刷新程序 - globalShortcut.register("CmdOrCtrl+Shift+R", () => { - if (win && win.isFocused()) win?.reload(); - }); - - // 打开开发者工具 - globalShortcut.register("CmdOrCtrl+Shift+I", () => { - if (win && win.isFocused()) { - win?.webContents.openDevTools({ - mode: "right", - activate: true, - }); - } - }); -}; - -export default createGlobalShortcut; diff --git a/electron/main/utils/createSystemTray.js b/electron/main/utils/createSystemTray.js deleted file mode 100644 index 47ff5b1..0000000 --- a/electron/main/utils/createSystemTray.js +++ /dev/null @@ -1,139 +0,0 @@ -import { Tray, Menu, app, ipcMain, nativeImage, nativeTheme } from "electron"; -import { join } from "path"; - -// 当前歌曲数据 -let playSongName = "当前暂无播放歌曲"; -let playSongState = false; - -/** - * 创建系统托盘 - * @param {BrowserWindow} win - 程序窗口 - */ -const createSystemTray = (win) => { - // 系统托盘 - const mainTray = new Tray( - nativeImage - .createFromPath( - join( - __dirname, - process.platform === "win32" - ? "../../public/imgs/icons/favicon.ico" - : "../../public/imgs/icons/favicon-32x32.png", - ), - ) - .resize({ - height: 32, - width: 32, - }), - ); - // 应用内菜单 - Menu.setApplicationMenu(createTrayMenu(win)); - // 默认名称 - win.setTitle(app.getName()); - mainTray.setTitle(app.getName()); - mainTray.setToolTip(app.getName()); - // 左键事件 - mainTray.on("click", () => win.show()); - // 托盘菜单 - mainTray.setContextMenu(createTrayMenu(win)); - // 系统主题改变 - nativeTheme.on("updated", () => { - mainTray.setContextMenu(createTrayMenu(win)); - }); - // 播放歌曲改变 - ipcMain.on("songNameChange", (_, val) => { - playSongName = val; - win.setTitle(val); - mainTray.setTitle(val); - mainTray.setToolTip(val); - mainTray.setContextMenu(createTrayMenu(win)); - }); - // 播放状态改变 - ipcMain.on("songStateChange", (_, val) => { - playSongState = val; - mainTray.setContextMenu(createTrayMenu(win)); - }); -}; - -// 生成图标 -const createIcon = (name) => { - // 系统是否为暗色 - const isDarkMode = nativeTheme.shouldUseDarkColors; - // 返回图标 - return nativeImage - .createFromPath( - isDarkMode - ? join(__dirname, `../../public/imgs/icons/${name}-dark.png`) - : join(__dirname, `../../public/imgs/icons/${name}-light.png`), - ) - .resize({ width: 16, height: 16 }); -}; - -// 生成右键菜单 -const createTrayMenu = (win) => { - // 返回菜单 - return Menu.buildFromTemplate([ - { - label: playSongName, - icon: createIcon("open"), - click() { - win.show(); - win.focus(); - win.webContents.send("showPlayer"); - }, - }, - { - type: "separator", - }, - { - label: "上一曲", - icon: createIcon("prev"), - accelerator: "CmdOrCtrl+Left", - click: () => { - win.webContents.send("playNextOrPrev", "prev"); - }, - }, - { - label: playSongState ? "暂停" : "播放", - icon: createIcon(playSongState ? "pause" : "play"), - accelerator: "CmdOrCtrl+Space", - click: () => { - win.webContents.send("playOrPause"); - }, - }, - { - label: "下一曲", - icon: createIcon("next"), - accelerator: "CmdOrCtrl+Right", - click: () => { - win.webContents.send("playNextOrPrev", "next"); - }, - }, - { - type: "separator", - }, - { - label: "全局设置", - icon: createIcon("setting"), - click: () => { - win.show(); - win.focus(); - win.webContents.send("open-setting"); - }, - }, - { - type: "separator", - }, - { - label: "退出", - icon: createIcon("power"), - click: () => { - win.close(); - app.isQuiting = true; - app.quit(); - }, - }, - ]); -}; - -export default createSystemTray; diff --git a/electron/main/utils/getNeteaseMusicUrl.js b/electron/main/utils/getNeteaseMusicUrl.js deleted file mode 100644 index e2b23b5..0000000 --- a/electron/main/utils/getNeteaseMusicUrl.js +++ /dev/null @@ -1,167 +0,0 @@ -import { encryptQuery } from "@main/utils/kwDES"; -import axios from "axios"; - -/** - * 网易云音乐解灰 - */ - -// 咪咕音乐请求头 -const requestHeader = { - Origin: "http://music.migu.cn/", - Referer: "http://m.music.migu.cn/v3/", - aversionid: import.meta.env.MAIN_VITE_MIGU_COOKIE || null, - channel: "0146921", -}; - -/** - * 获取咪咕音乐歌曲 ID - * @param {string} keyword - 搜索关键字 - * @returns {Promise} - */ -const getMiguSongId = async (keyword) => { - try { - const url = - "https://m.music.migu.cn/migu/remoting/scr_search_tag?keyword=" + - keyword.toString() + - "&type=2&rows=20&pgc=1"; - const result = await axios.get(url, { - headers: requestHeader, - }); - if (result.data?.musics?.length) { - // 是否与原曲吻合 - const originalName = keyword.split("-"); - const songName = result.data.musics[0]?.songName; - if (songName && !songName?.includes(originalName[0])) { - return null; - } - return result.data.musics[0].id; - } - return null; - } catch (error) { - console.error("获取咪咕音乐歌曲 ID 失败:", error); - return null; - } -}; - -/** - * 获取咪咕音乐歌曲 URL - * @param {string} keyword - 搜索关键字 - * @returns {Promise} - */ -const getMiguSongUrl = async (keyword) => { - try { - const songId = await getMiguSongId(keyword); - if (!songId) return null; - console.info("咪咕解灰歌曲 ID:", songId); - const soundQuality = "PQ"; - const url = - "https://app.c.nf.migu.cn/MIGUM2.0/strategy/listen-url/v2.4?netType=01&resourceType=2&songId=" + - songId.toString() + - "&toneFlag=" + - soundQuality; - const result = await axios.get(url, { - headers: requestHeader, - }); - if (result.data?.data?.url) { - const songUrl = result.data.data.url; - console.info("咪咕解灰歌曲 URL:", songUrl); - return songUrl; - } - return null; - } catch (error) { - console.error("获取咪咕音乐歌曲 URL 失败:", error); - return null; - } -}; - -/** - * 获取酷我音乐歌曲 ID - * @param {string} keyword - 搜索关键字 - * @returns {Promise} - */ -const getKuwoSongId = async (keyword) => { - try { - const url = - "http://search.kuwo.cn/r.s?&correct=1&stype=comprehensive&encoding=utf8" + - "&rformat=json&mobi=1&show_copyright_off=1&searchapi=6&all=" + - keyword.toString(); - const result = await axios.get(url); - if ( - !result.data || - result.data.content.length < 2 || - !result.data.content[1].musicpage || - result.data.content[1].musicpage.abslist.length < 1 - ) { - return null; - } - // 是否与原曲吻合 - const originalName = keyword.split("-"); - const songName = result.data.content[1].musicpage.abslist[0]?.SONGNAME; - if (songName && !songName?.includes(originalName[0])) { - return null; - } - const songId = result.data.content[1].musicpage.abslist[0].MUSICRID; - return songId.slice("MUSIC_".length); - } catch (error) { - console.error("获取酷我音乐歌曲 ID 失败:", error); - return null; - } -}; - -/** - * 获取酷我音乐歌曲 URL - * @param {string} keyword - 搜索关键字 - * @returns {Promise} - */ -const getKuwoSongUrl = async (keyword) => { - try { - const songId = await getKuwoSongId(keyword); - if (!songId) return null; - console.info("酷我解灰歌曲 ID:", songId); - const url = encryptQuery - ? "http://mobi.kuwo.cn/mobi.s?f=kuwo&q=" + - encryptQuery( - "corp=kuwo&source=kwplayer_ar_5.1.0.0_B_jiakong_vh.apk&p2p=1&type=convert_url2&sig=0&format=mp3" + - "&rid=" + - songId, - ) - : "http://antiserver.kuwo.cn/anti.s?type=convert_url&format=mp3&response=url&rid=MUSIC_" + - songId; - const result = await axios.get(url, { "user-agent": "okhttp/3.10.0" }); - if (result.data) { - const urlMatch = result.data.match(/http[^\s$"]+/)[0]; - console.info("酷我解灰歌曲 URL:", urlMatch); - return urlMatch; - } - return null; - } catch (error) { - console.error("获取酷我音乐歌曲 URL 失败:", error); - return null; - } -}; - -/** - * 获取给定关键字的音乐 URL - * @param {string} keyword - 关键字 - * @returns {Promise} 音乐 URL - */ -const getNeteaseMusicUrl = async (keyword) => { - try { - const [kuwoSongUrl, miguSongUrl] = await Promise.all([ - getKuwoSongUrl(keyword), - getMiguSongUrl(keyword), - ]); - if (kuwoSongUrl) { - return kuwoSongUrl; - } - if (miguSongUrl) { - return miguSongUrl; - } - return null; - } catch (error) { - console.error("获取解灰 URL 全部失败:", error); - return null; - } -}; - -export default getNeteaseMusicUrl; diff --git a/electron/main/utils/readDirAsync.js b/electron/main/utils/readDirAsync.js deleted file mode 100644 index c4b3983..0000000 --- a/electron/main/utils/readDirAsync.js +++ /dev/null @@ -1,151 +0,0 @@ -import { parseFile } from "music-metadata"; -import fs from "fs/promises"; -import path from "path"; - -/** - * 从指定文件夹中递归读取音乐文件,并将它们以数组形式返回 - * @param {string} directoryPath - 要读取的文件夹路径 - * @param {number} fileLimit - 返回的音乐文件数量限制 - * @returns {Array} - 包含音乐文件信息的数组 - */ -export const readDirAsync = async (directoryPath, fileLimit = 5000) => { - const result = []; - // 递归读取文件夹中的项目 - const readItem = async (item) => { - const itemPath = path.join(directoryPath, item); - const stats = await fs.stat(itemPath); - // 若为音频文件 - if (stats.isFile() && isAudioFile(itemPath)) { - try { - const { common, format } = await parseFile(itemPath); - // 音乐文件信息 - const fileInfo = { - id: generateId(itemPath), - name: common.title, - path: itemPath, - size: (stats.size / (1024 * 1024)).toFixed(2), - time: stats.mtime?.getTime(), - artists: common.artists?.[0], - album: common.album, - alia: common.comment?.[0], - duration: formatDuration(format.duration), - }; - result.push(fileInfo); - } catch (error) { - console.error("解析音乐文件元数据时出错:", error); - } - } - // 若为文件夹 - if (stats.isDirectory()) { - // 读取子文件夹中的项目 - const subItems = await fs.readdir(itemPath); - for (const subItem of subItems) { - await readItem(path.join(item, subItem)); - } - } - }; - // 从根目录开始读取 - await readItem(""); - // 返回不超过上限的音乐文件列表 - return result.slice(0, fileLimit); -}; - -/** - * 递归地读取文件夹内容,包括文件和子文件夹的信息 - * @param {string} directoryPath - 要读取的文件夹路径 - * @param {number} depth - 递归深度(默认为 -1,无限递归) - * @param {number} fileLimit - 文件总数 - * @returns {Promise} 包含文件和子文件夹信息的树形数组 - */ -export const readDirTreeAsync = async (directoryPath, depth = -1, fileLimit = 5000) => { - const result = []; - - const readItem = async (item) => { - const itemPath = path.join(directoryPath, item); - const stats = await fs.stat(itemPath); - - const fileInfo = { - id: generateId(item), - name: item, - path: itemPath, - type: stats.isFile() ? "song" : "dir", - size: (stats.size / (1024 * 1024)).toFixed(2), // 文件大小 - modified: stats.mtime, // 修改日期 - }; - - if (stats.isFile() && isAudioFile(itemPath)) { - try { - const { common, format } = await parseFile(itemPath); - fileInfo.metadata = { - name: common.title, - artists: common.artists, - album: common.album, - date: common.date, - alia: common.comment?.[0], - year: common.year, - duration: formatDuration(format.duration), - }; - } catch (error) { - console.error("解析音乐文件元数据时出错:", error); - } - } - - if (stats.isDirectory() && (depth === -1 || depth > 0)) { - // 如果是文件夹且未达到递归深度限制,且文件数量未达到上限,则递归读取文件夹内容 - if (fileInfo.type === "dir" && result.length < fileLimit) { - fileInfo.children = await readDirAsync( - itemPath, - depth === -1 ? -1 : depth - 1, - fileLimit - result.length, - ); - } - } - - result.push(fileInfo); - }; - - const items = await fs.readdir(directoryPath); - await Promise.all(items.map(readItem)); - - return result.slice(0, fileLimit); // 返回不超过上限的文件列表 -}; - -/** - * 歌曲时长时间戳转换 - * @param {number} mss 毫秒数 - * @returns {string} 格式为 "mm:ss" 的字符串 - */ -const formatDuration = (seconds) => { - const minutes = Math.floor(seconds / 60); - const remainingSeconds = Math.round(seconds % 60); - const formattedMinutes = minutes < 10 ? `0${minutes}` : `${minutes}`; - const formattedSeconds = remainingSeconds < 10 ? `0${remainingSeconds}` : `${remainingSeconds}`; - return `${formattedMinutes}:${formattedSeconds}`; -}; - -/** - * 判断文件是否为音频文件 - * @param {string} filePath - 文件路径 - * @returns {boolean} - 是否为音频文件 - */ -const isAudioFile = (filePath) => { - const audioExtensions = [".flac", ".mp3"]; - const extension = path.extname(filePath).toLowerCase(); - return audioExtensions.includes(extension); -}; - -/** - * 从文件名生成数字 ID - * @param {string} fileName - 文件名 - * @returns {number} - 生成的数字ID - */ -const generateId = (fileName) => { - // 将文件名转换为哈希值 - let hash = 0; - for (let i = 0; i < fileName.length; i++) { - hash = (hash << 5) - hash + fileName.charCodeAt(i); - } - // 将哈希值转换为正整数 - const numericId = Math.abs(hash % 10000000000); - return numericId; -}; diff --git a/electron/preload/index.d.ts b/electron/preload/index.d.ts new file mode 100644 index 0000000..ab1657a --- /dev/null +++ b/electron/preload/index.d.ts @@ -0,0 +1,8 @@ +import { ElectronAPI } from "@electron-toolkit/preload"; + +declare global { + interface Window { + electron: ElectronAPI; + api: unknown; + } +} diff --git a/electron/preload/index.mjs b/electron/preload/index.ts similarity index 53% rename from electron/preload/index.mjs rename to electron/preload/index.ts index 7320004..5e4ca2a 100644 --- a/electron/preload/index.mjs +++ b/electron/preload/index.ts @@ -1,15 +1,16 @@ import { contextBridge } from "electron"; import { electronAPI } from "@electron-toolkit/preload"; -// 如果启用了上下文隔离,使用 `contextBridge` 将 Electron API 暴露给渲染进程 +// Use `contextBridge` APIs to expose Electron APIs to +// renderer only if context isolation is enabled, otherwise +// just add to the DOM global. if (process.contextIsolated) { try { - // 使用 contextBridge 暴露 electronAPI 到渲染进程的全局对象中 contextBridge.exposeInMainWorld("electron", electronAPI); } catch (error) { console.error(error); } } else { - // 如果上下文隔离未启用,将 electronAPI 添加到 DOM 全局对象 + // @ts-expect-error (define in dts) window.electron = electronAPI; } diff --git a/electron/server/index.ts b/electron/server/index.ts new file mode 100644 index 0000000..8dd77dc --- /dev/null +++ b/electron/server/index.ts @@ -0,0 +1,59 @@ +import { join } from "path"; +import { isDev } from "../main/utils"; +import initNcmAPI from "./netease"; +import initUnblockAPI from "./unblock"; +import fastifyCookie from "@fastify/cookie"; +import fastifyMultipart from "@fastify/multipart"; +import fastifyStatic from "@fastify/static"; +import fastify from "fastify"; +import log from "../main/logger"; + +const initAppServer = async () => { + try { + const server = fastify({ + // 忽略尾随斜杠 + ignoreTrailingSlash: true, + }); + // 注册插件 + server.register(fastifyCookie); + server.register(fastifyMultipart); + // 生产环境启用静态文件 + if (!isDev) { + log.info("📂 Serving static files from /renderer"); + server.register(fastifyStatic, { + root: join(__dirname, "../renderer"), + }); + } + // 声明 + server.get("/api", (_, reply) => { + reply.send({ + name: "SPlayer API", + description: "SPlayer API service", + author: "@imsyy", + list: [ + { + name: "NeteaseCloudMusicApi", + url: "/api/netease", + }, + { + name: "UnblockAPI", + url: "/api/unblock", + }, + ], + }); + }); + // 注册接口 + server.register(initNcmAPI, { prefix: "/api" }); + server.register(initUnblockAPI, { prefix: "/api" }); + // 启动端口 + const port = Number(import.meta.env["VITE_SERVER_PORT"] || 25884); + await server.listen({ port }); + log.info(`🌐 Starting AppServer on port ${port}`); + return server; + } catch (error) { + log.error("🚫 AppServer failed to start"); + throw error; + } +}; + +export default initAppServer; diff --git a/electron/server/netease/index.ts b/electron/server/netease/index.ts new file mode 100644 index 0000000..8f79f75 --- /dev/null +++ b/electron/server/netease/index.ts @@ -0,0 +1,66 @@ +import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify"; +import { pathCase } from "change-case"; +import NeteaseCloudMusicApi from "NeteaseCloudMusicApi"; +import log from "../../main/logger"; + +// 获取数据 +const getHandler = (name: string, neteaseApi: (params: any) => any) => { + return async ( + req: FastifyRequest<{ Querystring: { [key: string]: string } }>, + reply: FastifyReply, + ) => { + log.info("🌐 Request NcmAPI:", name); + // 获取 NcmAPI 数据 + try { + const result = await neteaseApi({ + ...req.query, + ...(req.body as Record), + cookie: req.cookies, + }); + return reply.send(result.body); + } catch (error: any) { + log.error("❌ NcmAPI Error:", error); + if ([400, 301].includes(error.status)) { + return reply.status(error.status).send(error.body); + } + return reply.status(500); + } + }; +}; + +// 初始化 NcmAPI +const initNcmAPI = async (fastify: FastifyInstance) => { + // 主信息 + fastify.get("/netease", (_, reply) => { + reply.send({ + name: "NeteaseCloudMusicApi", + version: "4.20.0", + description: "网易云音乐 Node.js API service", + author: "@binaryify", + license: "MIT", + url: "https://gitlab.com/Binaryify/neteasecloudmusicapi", + }); + }); + + // 注册 NeteaseCloudMusicApi 所有接口 + Object.entries(NeteaseCloudMusicApi).forEach(([routerName, neteaseApi]: [string, any]) => { + // 例外 + if (["serveNcmApi", "getModulesDefinitions"].includes(routerName)) return; + // 路由名称 + const pathName = pathCase(routerName); + // 获取数据 + const handler = getHandler(pathName, neteaseApi); + // 注册路由 + fastify.get(`/netease/${pathName}`, handler); + fastify.post(`/netease/${pathName}`, handler); + // 兼容路由 - 中间具有 _ 的路由 + if (routerName.includes("_")) { + fastify.get(`/netease/${routerName}`, handler); + fastify.post(`/netease/${routerName}`, handler); + } + }); + + log.info("🌐 Register NcmAPI successfully"); +}; + +export default initNcmAPI; diff --git a/electron/server/unblock/index.ts b/electron/server/unblock/index.ts new file mode 100644 index 0000000..e1bce02 --- /dev/null +++ b/electron/server/unblock/index.ts @@ -0,0 +1,68 @@ +import { FastifyInstance, FastifyRequest, FastifyReply } from "fastify"; +import { SongUrlResult } from "./unblock"; +import getKuwoSongUrl from "./kuwo"; +import log from "../../main/logger"; +import axios from "axios"; + +/** + * 直接获取 网易云云盘 链接 + * Thank @939163156 + * Power by GD音乐台(music.gdstudio.xyz) + */ +const getNeteaseSongUrl = async (id: number | string): Promise => { + try { + if (!id) return { code: 404, url: null }; + const baseUrl = "https://music-api.gdstudio.xyz/api.php"; + const result = await axios.get(baseUrl, { + params: { types: "url", id }, + }); + const songUrl = result.data.url; + log.info("🔗 NeteaseSongUrl URL:", songUrl); + return { code: 200, url: songUrl }; + } catch (error) { + log.error("❌ Get NeteaseSongUrl Error:", error); + return { code: 404, url: null }; + } +}; + +// 初始化 UnblockAPI +const UnblockAPI = async (fastify: FastifyInstance) => { + // 主信息 + fastify.get("/unblock", (_, reply) => { + reply.send({ + name: "UnblockAPI", + description: "SPlayer UnblockAPI service", + author: "@imsyy", + content: + "部分接口采用 @939163156 by GD音乐台(music.gdstudio.xyz),仅供本人学习使用,不可传播下载内容,不可用于商业用途。", + }); + }); + // netease + fastify.get( + "/unblock/netease", + async ( + req: FastifyRequest<{ Querystring: { [key: string]: string } }>, + reply: FastifyReply, + ) => { + const { id } = req.query; + const result = await getNeteaseSongUrl(id); + return reply.send(result); + }, + ); + // kuwo + fastify.get( + "/unblock/kuwo", + async ( + req: FastifyRequest<{ Querystring: { [key: string]: string } }>, + reply: FastifyReply, + ) => { + const { keyword } = req.query; + const result = await getKuwoSongUrl(keyword); + return reply.send(result); + }, + ); + + log.info("🌐 Register UnblockAPI successfully"); +}; + +export default UnblockAPI; diff --git a/electron/server/unblock/kuwo.ts b/electron/server/unblock/kuwo.ts new file mode 100644 index 0000000..0caee66 --- /dev/null +++ b/electron/server/unblock/kuwo.ts @@ -0,0 +1,66 @@ +import { encryptQuery } from "./kwDES"; +import { SongUrlResult } from "./unblock"; +import log from "../../main/logger"; +import axios from "axios"; + +// 获取酷我音乐歌曲 ID +const getKuwoSongId = async (keyword: string): Promise => { + try { + const url = + "http://search.kuwo.cn/r.s?&correct=1&stype=comprehensive&encoding=utf8&rformat=json&mobi=1&show_copyright_off=1&searchapi=6&all=" + + keyword; + const result = await axios.get(url); + if ( + !result.data || + result.data.content.length < 2 || + !result.data.content[1].musicpage || + result.data.content[1].musicpage.abslist.length < 1 + ) { + return null; + } + // 获取歌曲信息 + const songId = result.data.content[1].musicpage.abslist[0].MUSICRID; + const songName = result.data.content[1].musicpage.abslist[0]?.SONGNAME; + // 是否与原曲吻合 + const originalName = keyword?.split("-") ?? keyword; + if (songName && !songName?.includes(originalName[0])) return null; + return songId.slice("MUSIC_".length); + } catch (error) { + log.error("❌ Get KuwoSongId Error:", error); + return null; + } +}; + +// 获取酷我音乐歌曲 URL +const getKuwoSongUrl = async (keyword: string): Promise => { + try { + if (!keyword) return { code: 404, url: null }; + const songId = await getKuwoSongId(keyword); + if (!songId) return { code: 404, url: null }; + // 请求地址 + const PackageName = "kwplayer_ar_5.1.0.0_B_jiakong_vh.apk"; + const url = + "http://mobi.kuwo.cn/mobi.s?f=kuwo&q=" + + encryptQuery( + `corp=kuwo&source=${PackageName}&p2p=1&type=convert_url2&sig=0&format=mp3` + + "&rid=" + + songId, + ); + const result = await axios.get(url, { + headers: { + "User-Agent": "okhttp/3.10.0", + }, + }); + if (result.data) { + const urlMatch = result.data.match(/http[^\s$"]+/)[0]; + log.info("🔗 KuwoSong URL:", urlMatch); + return { code: 200, url: urlMatch }; + } + return { code: 404, url: null }; + } catch (error) { + log.error("❌ Get KuwoSong URL Error:", error); + return { code: 404, url: null }; + } +}; + +export default getKuwoSongUrl; diff --git a/electron/main/utils/kwDES.js b/electron/server/unblock/kwDES.js similarity index 99% rename from electron/main/utils/kwDES.js rename to electron/server/unblock/kwDES.js index 83190a5..db47194 100644 --- a/electron/main/utils/kwDES.js +++ b/electron/server/unblock/kwDES.js @@ -1,4 +1,3 @@ -/* eslint-disable no-undef */ /* Thanks to https://github.com/XuShaohua/kwplayer/blob/master/kuwo/DES.py diff --git a/electron/server/unblock/unblock.d.ts b/electron/server/unblock/unblock.d.ts new file mode 100644 index 0000000..f39c377 --- /dev/null +++ b/electron/server/unblock/unblock.d.ts @@ -0,0 +1,4 @@ +export type SongUrlResult = { + code: number; + url: string | null; +}; diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..30c0529 --- /dev/null +++ b/env.d.ts @@ -0,0 +1,5 @@ +export interface MainEnv { + readonly VITE_WEB_PORT: string; + readonly VITE_SERVER_PORT: string; + readonly VITE_API_URL: string; +} diff --git a/index.html b/index.html index afb7a2b..663a88b 100644 --- a/index.html +++ b/index.html @@ -1,23 +1,21 @@ - - - - - - - %RENDERER_VITE_SITE_TITLE% - - - - - - - - - -
- - + + + + + + + + SPlayer + + + + + +
+ + + diff --git a/nginx.conf b/nginx.conf index 0cf056f..33811a3 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,8 +1,9 @@ server { gzip on; - listen 7899; - listen [::]:7899; + listen 25884; + listen [::]:25884; server_name localhost; + client_max_body_size 100M; location / { root /usr/share/nginx/html; @@ -14,10 +15,10 @@ server { rewrite ^(.*)$ /index.html last; } - location /api/ { - proxy_buffers 16 32k; + location /api/netease/ { + proxy_buffers 16 64k; proxy_buffer_size 128k; - proxy_busy_buffers_size 128k; + proxy_busy_buffers_size 256k; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $remote_addr; diff --git a/package.json b/package.json index 8425c15..1eeae1f 100644 --- a/package.json +++ b/package.json @@ -1,77 +1,113 @@ { "name": "splayer", - "version": "2.1.0", + "productName": "SPlayer", + "version": "3.0.0-alpha.1", "description": "A minimalist music player", "main": "./out/main/index.js", "author": "imsyy", "home": "https://imsyy.top", "github": "https://github.com/imsyy/SPlayer", + "blog": "https://blog.imsyy.top", "repository": "github:imsyy/SPlayer", "license": "AGPL-3.0", "license-file": "LICENSE", "engines": { - "node": ">=18.16.0", - "npm": ">=9.6.7", - "pnpm": ">=8.14.0" + "node": ">=20", + "npm": ">=10" }, "type": "module", "scripts": { "format": "prettier --write .", - "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts,.vue --fix", + "lint": "npx eslint . --fix", + "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false", + "typecheck:web": "vue-tsc --noEmit -p tsconfig.web.json --composite false", + "typecheck": "npm run typecheck:node && npm run typecheck:web", "start": "electron-vite preview", - "dev": "electron-vite dev --watch", - "build": "electron-vite build", + "dev": "electron-vite dev", + "build": "npm run typecheck && electron-vite build", "postinstall": "electron-builder install-app-deps", - "build:win": "npm run build && electron-builder --win --config", - "build:mac": "npm run build && electron-builder --mac --config", - "build:linux": "npm run build && electron-builder --linux --config" + "build:web": "npm run build", + "build:unpack": "npm run build && electron-builder --dir", + "build:win": "npm run build && electron-builder --win", + "build:mac": "npm run build && electron-builder --mac", + "build:linux": "npm run build && electron-builder --linux" }, "dependencies": { + "@applemusic-like-lyrics/core": "^0.1.3", + "@applemusic-like-lyrics/lyric": "^0.2.2", + "@applemusic-like-lyrics/vue": "^0.1.5", "@electron-toolkit/preload": "^3.0.1", "@electron-toolkit/utils": "^3.0.0", - "@material/material-color-utilities": "^0.2.7", - "NeteaseCloudMusicApi": "^4.19.9", - "axios": "^1.7.2", - "colorthief": "^2.4.0", + "@imsyy/color-utils": "^1.0.2", + "@material/material-color-utilities": "^0.3.0", + "@pixi/app": "^7.4.2", + "@pixi/core": "^7.4.2", + "@pixi/display": "^7.4.2", + "@pixi/filter-blur": "^7.4.2", + "@pixi/filter-bulge-pinch": "^5.1.1", + "@pixi/filter-color-matrix": "^7.4.2", + "@pixi/sprite": "^7.4.2", + "@vueuse/core": "^10.11.1", + "NeteaseCloudMusicApi": "^4.22.0", + "axios": "^1.7.7", + "change-case": "^5.4.4", + "dayjs": "^1.11.13", "electron-dl": "^3.5.2", "electron-store": "^8.2.0", - "electron-updater": "^6.2.1", - "express": "^4.19.2", - "express-http-proxy": "^2.0.0", + "electron-updater": "^6.3.4", + "file-saver": "^2.0.5", "font-list": "^1.5.1", "howler": "^2.2.4", "js-cookie": "^3.0.5", + "jss": "^10.10.0", + "jss-preset-default": "^10.10.0", "localforage": "^1.10.0", + "lodash-es": "^4.17.21", + "marked": "^14.1.2", "music-metadata": "7.14.0", - "node-taglib-sharp": "^5.2.3", - "pinia": "^2.1.7", - "pinia-plugin-persistedstate": "^3.2.1", + "pinia": "^2.2.2", + "pinia-plugin-persistedstate": "^3.2.3", "plyr": "^3.7.8", - "screenfull": "^6.0.2", - "vue-router": "^4.3.3", - "vue-slider-component": "4.1.0-beta.7" + "vue-virtual-scroller": "2.0.0-beta.8" }, "devDependencies": { - "@electron-toolkit/eslint-config": "^1.0.2", - "@rushstack/eslint-patch": "^1.10.3", - "@vitejs/plugin-vue": "^5.0.5", - "@vue/eslint-config-prettier": "^9.0.0", - "ajv": "^8.16.0", + "@electron-toolkit/preload": "^3.0.1", + "@electron-toolkit/tsconfig": "^1.0.1", + "@electron-toolkit/utils": "^3.0.0", + "@fastify/cookie": "^9.4.0", + "@fastify/http-proxy": "^9.5.0", + "@fastify/multipart": "^8.3.0", + "@fastify/static": "^7.0.4", + "@types/file-saver": "^2.0.7", + "@types/howler": "^2.2.11", + "@types/js-cookie": "^3.0.6", + "@types/node": "^22.5.4", + "@typescript-eslint/eslint-plugin": "^7.18.0", + "@typescript-eslint/parser": "^7.18.0", + "@vitejs/plugin-vue": "^5.1.3", + "ajv": "^8.17.1", + "crypto-js": "^4.2.0", "electron": "^28.3.3", "electron-builder": "^24.13.3", - "electron-log": "^5.1.5", - "electron-vite": "^2.2.0", + "electron-log": "^5.2.0", + "electron-vite": "^2.3.0", "eslint": "^8.57.0", - "eslint-plugin-vue": "^9.26.0", - "naive-ui": "^2.38.2", - "prettier": "^3.3.1", - "sass": "^1.77.4", - "terser": "^5.31.1", - "unplugin-auto-import": "^0.17.6", - "unplugin-vue-components": "^0.26.0", - "vite": "^5.2.13", + "eslint-plugin-vue": "^9.28.0", + "fast-glob": "^3.3.2", + "fastify": "^4.28.1", + "naive-ui": "^2.39.0", + "node-taglib-sharp": "^5.2.3", + "prettier": "^3.3.3", + "sass": "^1.78.0", + "terser": "^5.33.0", + "typescript": "^5.5.4", + "unplugin-auto-import": "^0.18.2", + "unplugin-vue-components": "^0.27.4", + "vite": "^5.4.3", "vite-plugin-compression": "^0.5.1", - "vite-plugin-pwa": "^0.17.5", - "vue": "3.4.8" + "vite-plugin-wasm": "^3.3.0", + "vue": "3.4.38", + "vue-router": "^4.4.3", + "vue-tsc": "^2.1.6" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 33d9478..d76d25e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,1470 +1,4021 @@ -lockfileVersion: '6.0' +lockfileVersion: '9.0' settings: autoInstallPeers: true excludeLinksFromLockfile: false -dependencies: - '@electron-toolkit/preload': - specifier: ^3.0.1 - version: 3.0.1(electron@28.3.3) - '@electron-toolkit/utils': - specifier: ^3.0.0 - version: 3.0.0(electron@28.3.3) - '@material/material-color-utilities': - specifier: ^0.2.7 - version: 0.2.7 - NeteaseCloudMusicApi: - specifier: ^4.19.9 - version: 4.20.0 - axios: - specifier: ^1.7.2 - version: 1.7.2 - colorthief: - specifier: ^2.4.0 - version: 2.4.0 - electron-dl: - specifier: ^3.5.2 - version: 3.5.2 - electron-store: - specifier: ^8.2.0 - version: 8.2.0 - electron-updater: - specifier: ^6.2.1 - version: 6.2.1 - express: - specifier: ^4.19.2 - version: 4.19.2 - express-http-proxy: - specifier: ^2.0.0 - version: 2.0.0 - font-list: - specifier: ^1.5.1 - version: 1.5.1 - howler: - specifier: ^2.2.4 - version: 2.2.4 - js-cookie: - specifier: ^3.0.5 - version: 3.0.5 - localforage: - specifier: ^1.10.0 - version: 1.10.0 - music-metadata: - specifier: 7.14.0 - version: 7.14.0 - node-taglib-sharp: - specifier: ^5.2.3 - version: 5.2.3 - pinia: - specifier: ^2.1.7 - version: 2.1.7(vue@3.4.8) - pinia-plugin-persistedstate: - specifier: ^3.2.1 - version: 3.2.1(pinia@2.1.7) - plyr: - specifier: ^3.7.8 - version: 3.7.8 - screenfull: - specifier: ^6.0.2 - version: 6.0.2 - vue-router: - specifier: ^4.3.3 - version: 4.3.3(vue@3.4.8) - vue-slider-component: - specifier: 4.1.0-beta.7 - version: 4.1.0-beta.7 +importers: -devDependencies: - '@electron-toolkit/eslint-config': - specifier: ^1.0.2 - version: 1.0.2(eslint@8.57.0) - '@rushstack/eslint-patch': - specifier: ^1.10.3 - version: 1.10.3 - '@vitejs/plugin-vue': - specifier: ^5.0.5 - version: 5.0.5(vite@5.3.1)(vue@3.4.8) - '@vue/eslint-config-prettier': - specifier: ^9.0.0 - version: 9.0.0(eslint@8.57.0)(prettier@3.3.2) - ajv: - specifier: ^8.16.0 - version: 8.16.0 - electron: - specifier: ^28.3.3 - version: 28.3.3 - electron-builder: - specifier: ^24.13.3 - version: 24.13.3(electron-builder-squirrel-windows@24.13.3) - electron-log: - specifier: ^5.1.5 - version: 5.1.5 - electron-vite: - specifier: ^2.2.0 - version: 2.2.0(vite@5.3.1) - eslint: - specifier: ^8.57.0 - version: 8.57.0 - eslint-plugin-vue: - specifier: ^9.26.0 - version: 9.26.0(eslint@8.57.0) - naive-ui: - specifier: ^2.38.2 - version: 2.38.2(vue@3.4.8) - prettier: - specifier: ^3.3.1 - version: 3.3.2 - sass: - specifier: ^1.77.4 - version: 1.77.6 - terser: - specifier: ^5.31.1 - version: 5.31.1 - unplugin-auto-import: - specifier: ^0.17.6 - version: 0.17.6(rollup@2.79.1) - unplugin-vue-components: - specifier: ^0.26.0 - version: 0.26.0(rollup@2.79.1)(vue@3.4.8) - vite: - specifier: ^5.2.13 - version: 5.3.1(sass@1.77.6)(terser@5.31.1) - vite-plugin-compression: - specifier: ^0.5.1 - version: 0.5.1(vite@5.3.1) - vite-plugin-pwa: - specifier: ^0.17.5 - version: 0.17.5(vite@5.3.1)(workbox-build@7.1.1)(workbox-window@7.1.0) - vue: - specifier: 3.4.8 - version: 3.4.8 + .: + dependencies: + '@applemusic-like-lyrics/core': + specifier: ^0.1.3 + version: 0.1.3(@pixi/app@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2))(@pixi/filter-blur@7.4.2(@pixi/core@7.4.2))(@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.2))(@pixi/filter-color-matrix@7.4.2(@pixi/core@7.4.2))(@pixi/sprite@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(jss-preset-default@10.10.0)(jss@10.10.0) + '@applemusic-like-lyrics/lyric': + specifier: ^0.2.2 + version: 0.2.2 + '@applemusic-like-lyrics/vue': + specifier: ^0.1.5 + version: 0.1.5(@pixi/app@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2))(@pixi/filter-blur@7.4.2(@pixi/core@7.4.2))(@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.2))(@pixi/filter-color-matrix@7.4.2(@pixi/core@7.4.2))(@pixi/sprite@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(jss-preset-default@10.10.0)(jss@10.10.0)(vue@3.4.38(typescript@5.5.4)) + '@electron-toolkit/preload': + specifier: ^3.0.1 + version: 3.0.1(electron@28.3.3) + '@electron-toolkit/utils': + specifier: ^3.0.0 + version: 3.0.0(electron@28.3.3) + '@imsyy/color-utils': + specifier: ^1.0.2 + version: 1.0.2 + '@material/material-color-utilities': + specifier: ^0.3.0 + version: 0.3.0 + '@pixi/app': + specifier: ^7.4.2 + version: 7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)) + '@pixi/core': + specifier: ^7.4.2 + version: 7.4.2 + '@pixi/display': + specifier: ^7.4.2 + version: 7.4.2(@pixi/core@7.4.2) + '@pixi/filter-blur': + specifier: ^7.4.2 + version: 7.4.2(@pixi/core@7.4.2) + '@pixi/filter-bulge-pinch': + specifier: ^5.1.1 + version: 5.1.1(@pixi/core@7.4.2) + '@pixi/filter-color-matrix': + specifier: ^7.4.2 + version: 7.4.2(@pixi/core@7.4.2) + '@pixi/sprite': + specifier: ^7.4.2 + version: 7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)) + '@vueuse/core': + specifier: ^10.11.1 + version: 10.11.1(vue@3.4.38(typescript@5.5.4)) + NeteaseCloudMusicApi: + specifier: ^4.22.0 + version: 4.22.0 + axios: + specifier: ^1.7.7 + version: 1.7.7 + change-case: + specifier: ^5.4.4 + version: 5.4.4 + dayjs: + specifier: ^1.11.13 + version: 1.11.13 + electron-dl: + specifier: ^3.5.2 + version: 3.5.2 + electron-store: + specifier: ^8.2.0 + version: 8.2.0 + electron-updater: + specifier: ^6.3.4 + version: 6.3.4 + file-saver: + specifier: ^2.0.5 + version: 2.0.5 + font-list: + specifier: ^1.5.1 + version: 1.5.1 + howler: + specifier: ^2.2.4 + version: 2.2.4 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + jss: + specifier: ^10.10.0 + version: 10.10.0 + jss-preset-default: + specifier: ^10.10.0 + version: 10.10.0 + localforage: + specifier: ^1.10.0 + version: 1.10.0 + lodash-es: + specifier: ^4.17.21 + version: 4.17.21 + marked: + specifier: ^14.1.2 + version: 14.1.2 + music-metadata: + specifier: 7.14.0 + version: 7.14.0 + pinia: + specifier: ^2.2.2 + version: 2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)) + pinia-plugin-persistedstate: + specifier: ^3.2.3 + version: 3.2.3(pinia@2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4))) + plyr: + specifier: ^3.7.8 + version: 3.7.8 + vue-virtual-scroller: + specifier: 2.0.0-beta.8 + version: 2.0.0-beta.8(vue@3.4.38(typescript@5.5.4)) + devDependencies: + '@electron-toolkit/tsconfig': + specifier: ^1.0.1 + version: 1.0.1(@types/node@22.5.4) + '@fastify/cookie': + specifier: ^9.4.0 + version: 9.4.0 + '@fastify/http-proxy': + specifier: ^9.5.0 + version: 9.5.0 + '@fastify/multipart': + specifier: ^8.3.0 + version: 8.3.0 + '@fastify/static': + specifier: ^7.0.4 + version: 7.0.4 + '@types/file-saver': + specifier: ^2.0.7 + version: 2.0.7 + '@types/howler': + specifier: ^2.2.11 + version: 2.2.11 + '@types/js-cookie': + specifier: ^3.0.6 + version: 3.0.6 + '@types/node': + specifier: ^22.5.4 + version: 22.5.4 + '@typescript-eslint/eslint-plugin': + specifier: ^7.18.0 + version: 7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/parser': + specifier: ^7.18.0 + version: 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@vitejs/plugin-vue': + specifier: ^5.1.3 + version: 5.1.3(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0))(vue@3.4.38(typescript@5.5.4)) + ajv: + specifier: ^8.17.1 + version: 8.17.1 + crypto-js: + specifier: ^4.2.0 + version: 4.2.0 + electron: + specifier: ^28.3.3 + version: 28.3.3 + electron-builder: + specifier: ^24.13.3 + version: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) + electron-log: + specifier: ^5.2.0 + version: 5.2.0 + electron-vite: + specifier: ^2.3.0 + version: 2.3.0(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0)) + eslint: + specifier: ^8.57.0 + version: 8.57.0 + eslint-plugin-vue: + specifier: ^9.28.0 + version: 9.28.0(eslint@8.57.0) + fast-glob: + specifier: ^3.3.2 + version: 3.3.2 + fastify: + specifier: ^4.28.1 + version: 4.28.1 + naive-ui: + specifier: ^2.39.0 + version: 2.39.0(vue@3.4.38(typescript@5.5.4)) + node-taglib-sharp: + specifier: ^5.2.3 + version: 5.2.3 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + sass: + specifier: ^1.78.0 + version: 1.78.0 + terser: + specifier: ^5.33.0 + version: 5.33.0 + typescript: + specifier: ^5.5.4 + version: 5.5.4 + unplugin-auto-import: + specifier: ^0.18.2 + version: 0.18.2(@vueuse/core@10.11.1(vue@3.4.38(typescript@5.5.4)))(rollup@4.21.2)(webpack-sources@3.2.3) + unplugin-vue-components: + specifier: ^0.27.4 + version: 0.27.4(@babel/parser@7.25.6)(rollup@4.21.2)(vue@3.4.38(typescript@5.5.4))(webpack-sources@3.2.3) + vite: + specifier: ^5.4.3 + version: 5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0) + vite-plugin-compression: + specifier: ^0.5.1 + version: 0.5.1(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0)) + vite-plugin-wasm: + specifier: ^3.3.0 + version: 3.3.0(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0)) + vue: + specifier: 3.4.38 + version: 3.4.38(typescript@5.5.4) + vue-router: + specifier: ^4.4.3 + version: 4.4.3(vue@3.4.38(typescript@5.5.4)) + vue-tsc: + specifier: ^2.1.6 + version: 2.1.6(typescript@5.5.4) packages: - /7zip-bin@5.2.0: + 7zip-bin@5.2.0: resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==} - dev: true - /@ampproject/remapping@2.3.0: + '@ampproject/remapping@2.3.0': resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@applemusic-like-lyrics/core@0.1.3': + resolution: {integrity: sha512-QCT280bl7zr0Dw7uXH22d7NGNRKfP0MisCL8U639BpFep9WpKbd1CwTnX8smE7D3KliIN8QC+6hYZrpRUyPy0Q==} + peerDependencies: + '@pixi/app': '*' + '@pixi/core': '*' + '@pixi/display': '*' + '@pixi/filter-blur': '*' + '@pixi/filter-bulge-pinch': '*' + '@pixi/filter-color-matrix': '*' + '@pixi/sprite': '*' + jss: '*' + jss-preset-default: '*' + + '@applemusic-like-lyrics/lyric@0.2.2': + resolution: {integrity: sha512-MqKjFOHqkeuma40tgPKdPZYG5IRF/d/tbY4BCiS3ykr74s8tjZWsfRQ9ykdkjKsn1+bYsztfZocrwzUrXq6npQ==} + + '@applemusic-like-lyrics/vue@0.1.5': + resolution: {integrity: sha512-FE8XtfoScmSwg61XFdNjdYBBQ8RvT10V01hFv38sMsOPUxLQn7rVUafx3NCwUDwGbAYPrC4Azn5wUpeZPdKFOg==} + peerDependencies: + vue: '*' + + '@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.25.4': + resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.2': + resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.6': + resolution: {integrity: sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.2': + resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==} + 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.25.2': + resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.24.8': + resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==} + engines: {node: '>=6.9.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-string-parser@7.24.8': + resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==} + 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.8': + resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.6': + resolution: {integrity: sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.24.7': + resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.6': + resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-arrow-functions@7.24.7': + resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.25.6': + resolution: {integrity: sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.0': + resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.6': + resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.6': + resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==} + engines: {node: '>=6.9.0'} + + '@css-render/plugin-bem@0.15.14': + resolution: {integrity: sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==} + peerDependencies: + css-render: ~0.15.14 + + '@css-render/vue3-ssr@0.15.14': + resolution: {integrity: sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==} + peerDependencies: + vue: ^3.0.11 + + '@develar/schema-utils@2.6.5': + resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} + engines: {node: '>= 8.9.0'} + + '@electron-toolkit/preload@3.0.1': + resolution: {integrity: sha512-EzoQmpK8jqqU8YnM5jRe0GJjGVJPke2KtANqz8QtN2JPT96ViOvProBdK5C6riCm0j1T8jjAGVQCZLQy9OVoIA==} + peerDependencies: + electron: '>=13.0.0' + + '@electron-toolkit/tsconfig@1.0.1': + resolution: {integrity: sha512-M0Mol3odspvtCuheyujLNAW7bXq7KFNYVMRtpjFa4ZfES4MuklXBC7Nli/omvc+PRKlrklgAGx3l4VakjNo8jg==} + peerDependencies: + '@types/node': '*' + + '@electron-toolkit/utils@3.0.0': + resolution: {integrity: sha512-GaXHDhiT7KCvMJjXdp/QqpYinq69T/Pdl49Z1XLf8mKGf63dnsODMWyrmIjEQ0z/vG7dO8qF3fvmI6Eb2lUNZA==} + peerDependencies: + electron: '>=13.0.0' + + '@electron/asar@3.2.10': + resolution: {integrity: sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw==} + engines: {node: '>=10.12.0'} + hasBin: true + + '@electron/get@2.0.3': + resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} + engines: {node: '>=12'} + + '@electron/notarize@2.2.1': + resolution: {integrity: sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg==} + engines: {node: '>= 10.0.0'} + + '@electron/osx-sign@1.0.5': + resolution: {integrity: sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==} + engines: {node: '>=12.0.0'} + hasBin: true + + '@electron/universal@1.5.1': + resolution: {integrity: sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==} + engines: {node: '>=8.6'} + + '@emotion/hash@0.8.0': + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + 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.11.0': + resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.0': + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@fastify/accept-negotiator@1.1.0': + resolution: {integrity: sha512-OIHZrb2ImZ7XG85HXOONLcJWGosv7sIvM2ifAPQVhg9Lv7qdmMBNVaai4QTdyuaqbKM5eO6sLSQOYI7wEQeCJQ==} + engines: {node: '>=14'} + + '@fastify/ajv-compiler@3.6.0': + resolution: {integrity: sha512-LwdXQJjmMD+GwLOkP7TVC68qa+pSSogeWWmznRJ/coyTcfe9qA05AHFSe1eZFwK6q+xVRpChnvFUkf1iYaSZsQ==} + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@fastify/cookie@9.4.0': + resolution: {integrity: sha512-Th+pt3kEkh4MQD/Q2q1bMuJIB5NX/D5SwSpOKu3G/tjoGbwfpurIMJsWSPS0SJJ4eyjtmQ8OipDQspf8RbUOlg==} + + '@fastify/deepmerge@1.3.0': + resolution: {integrity: sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A==} + + '@fastify/error@3.4.1': + resolution: {integrity: sha512-wWSvph+29GR783IhmvdwWnN4bUxTD01Vm5Xad4i7i1VuAOItLvbPAb69sb0IQ2N57yprvhNIwAP5B6xfKTmjmQ==} + + '@fastify/fast-json-stringify-compiler@4.3.0': + resolution: {integrity: sha512-aZAXGYo6m22Fk1zZzEUKBvut/CIIQe/BapEORnxiD5Qr0kPHqqI69NtEMCme74h+at72sPhbkb4ZrLd1W3KRLA==} + + '@fastify/http-proxy@9.5.0': + resolution: {integrity: sha512-1iqIdV10d5k9YtfHq9ylX5zt1NiM50fG+rIX40qt00R694sqWso3ukyTFZVk33SDoSiBW8roB7n11RUVUoN+Ag==} + + '@fastify/merge-json-schemas@0.1.1': + resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==} + + '@fastify/multipart@8.3.0': + resolution: {integrity: sha512-A8h80TTyqUzaMVH0Cr9Qcm6RxSkVqmhK/MVBYHYeRRSUbUYv08WecjWKSlG2aSnD4aGI841pVxAjC+G1GafUeQ==} + + '@fastify/reply-from@9.8.0': + resolution: {integrity: sha512-bPNVaFhEeNI0Lyl6404YZaPFokudCplidE3QoOcr78yOy6H9sYw97p5KPYvY/NJNUHfFtvxOaSAHnK+YSiv/Mg==} + + '@fastify/send@2.1.0': + resolution: {integrity: sha512-yNYiY6sDkexoJR0D8IDy3aRP3+L4wdqCpvx5WP+VtEU58sn7USmKynBzDQex5X42Zzvw2gNzzYgP90UfWShLFA==} + + '@fastify/static@7.0.4': + resolution: {integrity: sha512-p2uKtaf8BMOZWLs6wu+Ihg7bWNBdjNgCwDza4MJtTqg+5ovKmcbgbR9Xs5/smZ1YISfzKOCNYmZV8LaCj+eJ1Q==} + + '@humanwhocodes/config-array@0.11.14': + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@imsyy/color-utils@1.0.2': + resolution: {integrity: sha512-sLXkCpdd5L8s0mVNWLaTBNXK4RYLNbEnlZIMT/wml8GCDFYsLLJbpkRraQUlMwpw8SgdmJCCi8T5GCUcfySwRw==} + engines: {node: '>=20'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@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/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@juggle/resize-observer@3.4.0': + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + + '@lokesh.dhakar/quantize@1.3.0': + resolution: {integrity: sha512-4KBSyaMj65d8A+2vnzLxtHFu4OmBU4IKO0yLxZ171Itdf9jGV4w+WbG7VsKts2jUdRkFSzsZqpZOz6hTB3qGAw==} + + '@lukeed/ms@2.0.2': + resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==} + engines: {node: '>=8'} + + '@malept/cross-spawn-promise@1.1.1': + resolution: {integrity: sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==} + engines: {node: '>= 10'} + + '@malept/flatpak-bundler@0.4.0': + resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} + engines: {node: '>= 10.0.0'} + + '@material/material-color-utilities@0.2.7': + resolution: {integrity: sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==} + + '@material/material-color-utilities@0.3.0': + resolution: {integrity: sha512-ztmtTd6xwnuh2/xu+Vb01btgV8SQWYCaK56CkRK8gEkWe5TuDyBcYJ0wgkMRn+2VcE9KUmhvkz+N9GHrqw/C0g==} + + '@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'} + + '@pixi/app@7.4.2': + resolution: {integrity: sha512-ugkH3kOgjT8P1mTMY29yCOgEh+KuVMAn8uBxeY0aMqaUgIMysfpnFv+Aepp2CtvI9ygr22NC+OiKl+u+eEaQHw==} + peerDependencies: + '@pixi/core': 7.4.2 + '@pixi/display': 7.4.2 + + '@pixi/color@7.4.2': + resolution: {integrity: sha512-av1LOvhHsiaW8+T4n/FgnOKHby55/w7VcA1HzPIHRBtEcsmxvSCDanT1HU2LslNhrxLPzyVx18nlmalOyt5OBg==} + + '@pixi/colord@2.9.6': + resolution: {integrity: sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==} + + '@pixi/constants@7.4.2': + resolution: {integrity: sha512-N9vn6Wpz5WIQg7ugUg2+SdqD2u2+NM0QthE8YzLJ4tLH2Iz+/TrnPKUJzeyIqbg3sxJG5ZpGGPiacqIBpy1KyA==} + + '@pixi/core@7.4.2': + resolution: {integrity: sha512-UbMtgSEnyCOFPzbE6ThB9qopXxbZ5GCof2ArB4FXOC5Xi/83MOIIYg5kf5M8689C5HJMhg2SrJu3xLKppF+CMg==} + + '@pixi/display@7.4.2': + resolution: {integrity: sha512-DaD0J7gIlNlzO0Fdlby/0OH+tB5LtCY6rgFeCBKVDnzmn8wKW3zYZRenWBSFJ0Psx6vLqXYkSIM/rcokaKviIw==} + peerDependencies: + '@pixi/core': 7.4.2 + + '@pixi/extensions@7.4.2': + resolution: {integrity: sha512-Hmx2+O0yZ8XIvgomHM9GZEGcy9S9Dd8flmtOK5Aa3fXs/8v7xD08+ANQpN9ZqWU2Xs+C6UBlpqlt2BWALvKKKA==} + + '@pixi/filter-blur@7.4.2': + resolution: {integrity: sha512-gOXBbIUx6CRZP1fmsis2wLzzSsofrqmIHhbf1gIkZMIQaLsc9T7brj+PaLTTiOiyJgnvGN5j20RZnkERWWKV0Q==} + peerDependencies: + '@pixi/core': 7.4.2 + + '@pixi/filter-bulge-pinch@5.1.1': + resolution: {integrity: sha512-80I3g813td7Fnzi7IJSiR3z8gZlKblk6WN+5z6WnscQROcNEpck6lgWS/Lf/IdeHB/FtUKJCbx7RzxkUhiRTvA==} + peerDependencies: + '@pixi/core': ^7.0.0-X + + '@pixi/filter-color-matrix@7.4.2': + resolution: {integrity: sha512-ykZiR59Gvj80UKs9qm7jeUTKvn+wWk6HBVJOmJbK9jFK5juakDWp7BbH26U78Q61EWj97kI1FdfcbMkuQ7rqkA==} + peerDependencies: + '@pixi/core': 7.4.2 + + '@pixi/math@7.4.2': + resolution: {integrity: sha512-7jHmCQoYk6e0rfSKjdNFOPl0wCcdgoraxgteXJTTHv3r0bMNx2pHD9FJ0VvocEUG7XHfj55O3+u7yItOAx0JaQ==} + + '@pixi/runner@7.4.2': + resolution: {integrity: sha512-LPBpwym4vdyyDY5ucF4INQccaGyxztERyLTY1YN6aqJyyMmnc7iqXlIKt+a0euMBtNoLoxy6MWMvIuZj0JfFPA==} + + '@pixi/settings@7.4.2': + resolution: {integrity: sha512-pMN+L6aWgvUbwhFIL/BTHKe2ShYGPZ8h9wlVBnFHMtUcJcFLMF1B3lzuvCayZRepOphs6RY0TqvnDvVb585JhQ==} + + '@pixi/sprite@7.4.2': + resolution: {integrity: sha512-Ccf/OVQsB+HQV0Fyf5lwD+jk1jeU7uSIqEjbxenNNssmEdB7S5qlkTBV2EJTHT83+T6Z9OMOHsreJZerydpjeg==} + peerDependencies: + '@pixi/core': 7.4.2 + '@pixi/display': 7.4.2 + + '@pixi/ticker@7.4.2': + resolution: {integrity: sha512-cAvxCh/KI6IW4m3tp2b+GQIf+DoSj9NNmPJmsOeEJ7LzvruG8Ps7SKI6CdjQob5WbceL1apBTDbqZ/f77hFDiQ==} + + '@pixi/utils@7.4.2': + resolution: {integrity: sha512-aU/itcyMC4TxFbmdngmak6ey4kC5c16Y5ntIYob9QnjNAfD/7GTsYIBnP6FqEAyO1eq0MjkAALxdONuay1BG3g==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@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.21.2': + resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.21.2': + resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.21.2': + resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.21.2': + resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-linux-arm-gnueabihf@4.21.2': + resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.21.2': + resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.21.2': + resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.21.2': + resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': + resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-gnu@4.21.2': + resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-s390x-gnu@4.21.2': + resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.21.2': + resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.21.2': + resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-win32-arm64-msvc@4.21.2': + resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.21.2': + resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.21.2': + resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==} + cpu: [x64] + os: [win32] + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@tootallnate/once@2.0.0': + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + + '@types/css-font-loading-module@0.0.12': + resolution: {integrity: sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/earcut@2.1.4': + resolution: {integrity: sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==} + + '@types/estree@1.0.5': + resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + + '@types/file-saver@2.0.7': + resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==} + + '@types/fs-extra@9.0.13': + resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} + + '@types/howler@2.2.11': + resolution: {integrity: sha512-7aBoUL6RbSIrqKnpEgfa1wSNUBK06mn08siP2QI0zYk7MXfEJAaORc4tohamQYqCqVESoDyRWSdQn2BOKWj2Qw==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/js-cookie@3.0.6': + resolution: {integrity: sha512-wkw9yd1kEXOPnvEeEV1Go1MmxtBJL0RR79aOTAApecWFVu7w0NNXNqhcWgvw2YgZDYadliXkl14pa3WXw5jlCQ==} + + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.7': + resolution: {integrity: sha512-8wTvZawATi/lsmNu10/j2hk1KEP0IvjubqPE3cu1Xz7xfXXt5oCq3SNUz4fMIP4XGF9Ky+Ue2tBA3hcS7LSBlA==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/node@18.19.50': + resolution: {integrity: sha512-xonK+NRrMBRtkL1hVCc3G+uXtjh1Al4opBLjqVmipe5ZAaBYWW6cNAiBVZ1BvmkBhep698rP3UM3aRAdSALuhg==} + + '@types/node@22.5.4': + resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==} + + '@types/plist@3.0.5': + resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} + + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + '@types/verror@1.10.10': + resolution: {integrity: sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + + '@typescript-eslint/eslint-plugin@7.18.0': + resolution: {integrity: sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==} + 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.18.0': + resolution: {integrity: sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@7.18.0': + resolution: {integrity: sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/type-utils@7.18.0': + resolution: {integrity: sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@7.18.0': + resolution: {integrity: sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@typescript-eslint/typescript-estree@7.18.0': + resolution: {integrity: sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@7.18.0': + resolution: {integrity: sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==} + engines: {node: ^18.18.0 || >=20.0.0} + peerDependencies: + eslint: ^8.56.0 + + '@typescript-eslint/visitor-keys@7.18.0': + resolution: {integrity: sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==} + engines: {node: ^18.18.0 || >=20.0.0} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vitejs/plugin-vue@5.1.3': + resolution: {integrity: sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + vue: ^3.2.25 + + '@volar/language-core@2.4.2': + resolution: {integrity: sha512-sONt5RLvLL1SlBdhyUSthZzuKePbJ7DwFFB9zT0eyWpDl+v7GXGh/RkPxxWaR22bIhYtTzp4Ka1MWatl/53Riw==} + + '@volar/source-map@2.4.2': + resolution: {integrity: sha512-qiGfGgeZ5DEarPX3S+HcFktFCjfDrFPCXKeXNbrlB7v8cvtPRm8YVwoXOdGG1NhaL5rMlv5BZPVQyu4EdWWIvA==} + + '@volar/typescript@2.4.2': + resolution: {integrity: sha512-m2uZduhaHO1SZuagi30OsjI/X1gwkaEAC+9wT/nCNAtJ5FqXEkKvUncHmffG7ESDZPlFFUBK4vJ0D9Hfr+f2EA==} + + '@vue/compiler-core@3.4.38': + resolution: {integrity: sha512-8IQOTCWnLFqfHzOGm9+P8OPSEDukgg3Huc92qSG49if/xI2SAwLHQO2qaPQbjCWPBcQoO1WYfXfTACUrWV3c5A==} + + '@vue/compiler-core@3.5.3': + resolution: {integrity: sha512-adAfy9boPkP233NTyvLbGEqVuIfK/R0ZsBsIOW4BZNfb4BRpRW41Do1u+ozJpsb+mdoy80O20IzAsHaihRb5qA==} + + '@vue/compiler-dom@3.4.38': + resolution: {integrity: sha512-Osc/c7ABsHXTsETLgykcOwIxFktHfGSUDkb05V61rocEfsFDcjDLH/IHJSNJP+/Sv9KeN2Lx1V6McZzlSb9EhQ==} + + '@vue/compiler-dom@3.5.3': + resolution: {integrity: sha512-wnzFArg9zpvk/811CDOZOadJRugf1Bgl/TQ3RfV4nKfSPok4hi0w10ziYUQR6LnnBAUlEXYLUfZ71Oj9ds/+QA==} + + '@vue/compiler-sfc@3.4.38': + resolution: {integrity: sha512-s5QfZ+9PzPh3T5H4hsQDJtI8x7zdJaew/dCGgqZ2630XdzaZ3AD8xGZfBqpT8oaD/p2eedd+pL8tD5vvt5ZYJQ==} + + '@vue/compiler-ssr@3.4.38': + resolution: {integrity: sha512-YXznKFQ8dxYpAz9zLuVvfcXhc31FSPFDcqr0kyujbOwNhlmaNvL2QfIy+RZeJgSn5Fk54CWoEUeW+NVBAogGaw==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/devtools-api@6.6.3': + resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==} + + '@vue/language-core@2.1.6': + resolution: {integrity: sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.4.38': + resolution: {integrity: sha512-4vl4wMMVniLsSYYeldAKzbk72+D3hUnkw9z8lDeJacTxAkXeDAP1uE9xr2+aKIN0ipOL8EG2GPouVTH6yF7Gnw==} + + '@vue/runtime-core@3.4.38': + resolution: {integrity: sha512-21z3wA99EABtuf+O3IhdxP0iHgkBs1vuoCAsCKLVJPEjpVqvblwBnTj42vzHRlWDCyxu9ptDm7sI2ZMcWrQqlA==} + + '@vue/runtime-dom@3.4.38': + resolution: {integrity: sha512-afZzmUreU7vKwKsV17H1NDThEEmdYI+GCAK/KY1U957Ig2NATPVjCROv61R19fjZNzMmiU03n79OMnXyJVN0UA==} + + '@vue/server-renderer@3.4.38': + resolution: {integrity: sha512-NggOTr82FbPEkkUvBm4fTGcwUY8UuTsnWC/L2YZBmvaQ4C4Jl/Ao4HHTB+l7WnFCt5M/dN3l0XLuyjzswGYVCA==} + peerDependencies: + vue: 3.4.38 + + '@vue/shared@3.4.38': + resolution: {integrity: sha512-q0xCiLkuWWQLzVrecPb0RMsNWyxICOjPrcrwxTUEHb1fsnvni4dcuyG7RT/Ie7VPTvnjzIaWzRMUBsrqNj/hhw==} + + '@vue/shared@3.5.3': + resolution: {integrity: sha512-Jp2v8nylKBT+PlOUjun2Wp/f++TfJVFjshLzNtJDdmFJabJa7noGMncqXRM1vXGX+Yo2V7WykQFNxusSim8SCA==} + + '@vueuse/core@10.11.1': + resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==} + + '@vueuse/metadata@10.11.1': + resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==} + + '@vueuse/shared@10.11.1': + resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==} + + '@xmldom/xmldom@0.8.10': + resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} + engines: {node: '>=10.0.0'} + + NeteaseCloudMusicApi@4.22.0: + resolution: {integrity: sha512-xbEA+Bs8TRCRBNVBzuJMvymEOXRXSmhi9/qVtGKkPES14WRz8Kqjkt9+A9K1eU2QEvLrcOBM98aqWVZQh25HZQ==} + engines: {node: '>=12'} + hasBin: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + abstract-logging@2.0.1: + resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.12.1: + resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.1: + resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} + engines: {node: '>= 14'} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + 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@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@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + app-builder-bin@4.0.0: + resolution: {integrity: sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==} + + app-builder-lib@24.13.3: + resolution: {integrity: sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig==} + engines: {node: '>=14.0.0'} + peerDependencies: + dmg-builder: 24.13.3 + electron-builder-squirrel-windows: 24.13.3 + + archiver-utils@2.1.0: + resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} + engines: {node: '>= 6'} + + archiver-utils@3.0.4: + resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} + engines: {node: '>= 10'} + + archiver@5.3.2: + resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} + engines: {node: '>= 10'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-exit-hook@2.0.1: + resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} + engines: {node: '>=0.12.0'} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + atomically@1.7.0: + resolution: {integrity: sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==} + engines: {node: '>=10.12.0'} + + avvio@8.4.0: + resolution: {integrity: sha512-CDSwaxINFy59iNwhYnkvALBwZiTydGkOecZyPkqBpABYR1KqGEsET0VOOYDwtleZSUIdeY36DC2bSZ24CO1igA==} + + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + basic-ftp@5.0.5: + resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} + engines: {node: '>=10.0.0'} + + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + bezier-easing@2.1.0: + resolution: {integrity: sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird-lst@1.0.9: + resolution: {integrity: sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.23.3: + resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal@1.0.1: + resolution: {integrity: sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==} + engines: {node: '>=0.4'} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + builder-util-runtime@9.2.4: + resolution: {integrity: sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==} + engines: {node: '>=12.0.0'} + + builder-util-runtime@9.2.5: + resolution: {integrity: sha512-HjIDfhvqx/8B3TDN4GbABQcgpewTU4LMRTQPkVpKYV3lsuxEJoIfvg09GyWTNmfVNSUAYf+fbTN//JX4TH20pg==} + engines: {node: '>=12.0.0'} + + builder-util@24.13.1: + resolution: {integrity: sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001657: + resolution: {integrity: sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + 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'} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + 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'} + + chromium-pickle-js@0.2.0: + resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + 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==} + + colorthief@2.4.0: + resolution: {integrity: sha512-0U48RGNRo5fVO+yusBwgp+d3augWSorXabnqXUu9SabEhCpCgZJEUjUTTI41OOBBYuMMxawa3177POT6qLfLeQ==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + + compare-version@0.1.2: + resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} + engines: {node: '>=0.10.0'} + + compress-commons@4.1.2: + resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} + engines: {node: '>= 10'} + + computeds@0.0.1: + resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + conf@10.2.0: + resolution: {integrity: sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==} + engines: {node: '>=12'} + + confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + + config-file-ts@0.2.6: + resolution: {integrity: sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie-signature@1.2.1: + resolution: {integrity: sha512-78KWk9T26NhzXtuL26cIJ8/qNHANyJ/ZYrmEXFzUmhZdjpBv+DlWlOANRTGBt48YcyslsLrj0bMLFTmXvLRCOw==} + engines: {node: '>=6.6.0'} + + cookie@0.6.0: + resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} + engines: {node: '>= 0.6'} + + core-js@3.38.1: + resolution: {integrity: sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw==} + + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + crc32-stream@4.0.3: + resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} + engines: {node: '>= 10'} + + crc@3.8.0: + resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} + + cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + css-render@0.15.14: + resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==} + + css-vendor@2.0.8: + resolution: {integrity: sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + csstype@3.0.11: + resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + custom-event-polyfill@1.0.7: + resolution: {integrity: sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==} + + cwise-compiler@1.1.3: + resolution: {integrity: sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==} + + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + + data-uri-to-buffer@0.0.3: + resolution: {integrity: sha512-Cp+jOa8QJef5nXS5hU7M1DWzXPEIoVR3kbV0dQuVGwROZg8bGf1DcCnkmajBTnvghTtSNMUdRrPjgaT6ZQucbw==} + + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + + date-fns-tz@2.0.1: + resolution: {integrity: sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==} + peerDependencies: + date-fns: 2.x + + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + + dateformat@3.0.3: + resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debounce-fn@4.0.0: + resolution: {integrity: sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==} + engines: {node: '>=10'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + 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'} + + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + + dir-compare@3.3.0: + resolution: {integrity: sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dmg-builder@24.13.3: + resolution: {integrity: sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==} + + dmg-license@1.0.11: + resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} + engines: {node: '>=8'} + os: [darwin] + hasBin: true + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dot-prop@6.0.1: + resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} + engines: {node: '>=10'} + + dotenv-expand@5.1.0: + resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} + + dotenv@9.0.2: + resolution: {integrity: sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==} + engines: {node: '>=10'} + + earcut@2.2.4: + resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-builder-squirrel-windows@24.13.3: + resolution: {integrity: sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg==} + + electron-builder@24.13.3: + resolution: {integrity: sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg==} + engines: {node: '>=14.0.0'} + hasBin: true + + electron-dl@3.5.2: + resolution: {integrity: sha512-i104cl+u8yJ0lhpRAtUWfeGuWuL1PL6TBiw2gLf0MMIBjfgE485Ags2mcySx4uWU9P9uj/vsD3jd7X+w1lzZxw==} + engines: {node: '>=12'} + + electron-log@5.2.0: + resolution: {integrity: sha512-VjLkvaLmbP3AOGOh5Fob9M8bFU0mmeSAb5G2EoTBx+kQLf2XA/0byzjsVGBTHhikbT+m1AB27NEQUv9wX9nM8w==} + engines: {node: '>= 14'} + + electron-publish@24.13.1: + resolution: {integrity: sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==} + + electron-store@8.2.0: + resolution: {integrity: sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==} + + electron-to-chromium@1.5.16: + resolution: {integrity: sha512-2gQpi2WYobXmz2q23FrOBYTLcI1O/P4heW3eqX+ldmPVDQELRqhiebV380EhlGG12NtnX1qbK/FHpN0ba+7bLA==} + + electron-updater@6.3.4: + resolution: {integrity: sha512-uZUo7p1Y53G4tl6Cgw07X1yF8Jlz6zhaL7CQJDZ1fVVkOaBfE2cWtx80avwDVi8jHp+I/FWawrMgTAeCCNIfAg==} + + electron-vite@2.3.0: + resolution: {integrity: sha512-lsN2FymgJlp4k6MrcsphGqZQ9fKRdJKasoaiwIrAewN1tapYI/KINLdfEL7n10LuF0pPSNf/IqjzZbB5VINctg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@swc/core': ^1.0.0 + vite: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + '@swc/core': + optional: true + + electron@28.3.3: + resolution: {integrity: sha512-ObKMLSPNhomtCOBAxFS8P2DW/4umkh72ouZUlUKzXGtYuPzgr1SYhskhFWgzAsPtUzhL2CzyV2sfbHcEW4CXqw==} + engines: {node: '>= 12.20.55'} + hasBin: true + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + 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==} + + 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'} + + es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-goat@2.1.1: + resolution: {integrity: sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==} + engines: {node: '>=8'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + 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'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-plugin-vue@9.28.0: + resolution: {integrity: sha512-ShrihdjIhOTxs+MfWun6oJWuk+g/LAhN+CiuOl/jjkG3l0F2AuK5NMTaWqyvBgkFtpYmyks6P4603mLmhNJW8g==} + 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-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@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + + 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.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + 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'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + evtd@0.2.4: + resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} + + execa@1.0.0: + resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} + engines: {node: '>=6'} + + express-fileupload@1.5.1: + resolution: {integrity: sha512-LsYG1ALXEB7vlmjuSw8ABeOctMp8a31aUC5ZF55zuz7O2jLFnmJYrCv10py357ky48aEoBQ/9bVXgFynjvaPmA==} + engines: {node: '>=12.0.0'} + + express@4.19.2: + resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} + engines: {node: '>= 0.10.0'} + + ext-list@2.2.2: + resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} + engines: {node: '>=0.10.0'} + + ext-name@5.0.0: + resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} + engines: {node: '>=4'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + extsprintf@1.4.1: + resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} + engines: {'0': node >=0.6.0} + + fast-content-type-parse@1.1.0: + resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} + + fast-decode-uri-component@1.0.1: + resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + 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-json-stringify@5.16.1: + resolution: {integrity: sha512-KAdnLvy1yu/XrRtP+LJnxbBGrhN+xXu+gt3EUvZhYGKCr3lFHq/7UFJHHFgmJKoqlh6B40bZLEv7w46B0mqn1g==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-querystring@1.1.2: + resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-uri@2.4.0: + resolution: {integrity: sha512-ypuAmmMKInk5q7XcepxlnUWDLWv4GFtaJqAzWKqn62IpQ3pejtr5dTVbt3vwqVaMKmkNR55sTT+CqUKIaT21BA==} + + fast-uri@3.0.1: + resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==} + + fastify-plugin@4.5.1: + resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} + + fastify@4.28.1: + resolution: {integrity: sha512-kFWUtpNr4i7t5vY2EJPCN2KgMVpuqfU4NjnJNCgiNB900oiDeYqaNDRcAfeBbOF5hGixixxcKnOU4KN9z6QncQ==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-saver@2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + + file-type@16.5.4: + resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} + engines: {node: '>=10'} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + + find-my-way@8.2.0: + resolution: {integrity: sha512-HdWXgFYc6b1BJcOBDBwjqWuHJj1WYiqrxSh25qtU4DabpMFdj/gSunNBQb83t+8Zt67D7CXEzJWTkxaShMTMOA==} + engines: {node: '>=14'} + + find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + + 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@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.8: + resolution: {integrity: sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==} + engines: {node: '>=4.0'} + deprecated: Browser detection issues fixed in v1.15.9 + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + font-list@1.5.1: + resolution: {integrity: sha512-Hr5V0dsSv91wH3FgirXd7qh1PydqA/vMQyWjFFWn+lUPJtC+3i2tzgVqbLRcvQh87TGdbTGbAR3mEo4VlwC1jw==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + + form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + 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==} + + 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-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-pixels@3.3.3: + resolution: {integrity: sha512-5kyGBn90i9tSMUVHTqkgCHsoWoR+/lGbl4yC83Gefyr0HLIhgSWEx/2F/3YgsZ7UpYNuM6pDhDK7zebrUJ5nXg==} + + get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-uri@6.0.3: + resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} + engines: {node: '>= 14'} + + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + + 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.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + global-agent@3.0.0: + resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} + engines: {node: '>=10.0'} + + 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'} + + 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'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + + 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==} + + har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + + har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + + 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'} + + 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 + + highlight.js@11.10.0: + resolution: {integrity: sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==} + engines: {node: '>=12.0.0'} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + howler@2.2.4: + resolution: {integrity: sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} + engines: {node: '>= 14'} + + hyphenate-style-name@1.1.0: + resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} + + iconv-corefoundation@1.1.7: + resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} + engines: {node: ^8.11.2 || >=10} + os: [darwin] + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immutable@4.3.7: + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + 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==} + + invert-kv@3.0.1: + resolution: {integrity: sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==} + engines: {node: '>=8'} + + iota-array@1.0.0: + resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} + + ip-address@9.0.5: + resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + 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-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-in-browser@1.1.3: + resolution: {integrity: sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==} + + 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-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isbinaryfile@4.0.10: + resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} + engines: {node: '>= 8.0.0'} + + isbinaryfile@5.0.2: + resolution: {integrity: sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==} + engines: {node: '>= 18.0.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + ismobilejs@1.1.1: + resolution: {integrity: sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==} + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + itiriri@2.0.1: + resolution: {integrity: sha512-XutdsL9Nm9ejgRlFwOBdWW78Txvs9ehhMFeGCp3GjGIWSeQNgOzOfo+PjuQSmaFgE1ol6Pr2g5Jg7W4BYIploQ==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + + jpeg-js@0.4.4: + resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + 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@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + + jsbn@1.1.0: + resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-ref-resolver@1.0.1: + resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@7.0.3: + resolution: {integrity: sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + + jss-plugin-camel-case@10.10.0: + resolution: {integrity: sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==} + + jss-plugin-compose@10.10.0: + resolution: {integrity: sha512-F5kgtWpI2XfZ3Z8eP78tZEYFdgTIbpA/TMuX3a8vwrNolYtN1N4qJR/Ob0LAsqIwCMLojtxN7c7Oo/+Vz6THow==} + + jss-plugin-default-unit@10.10.0: + resolution: {integrity: sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==} + + jss-plugin-expand@10.10.0: + resolution: {integrity: sha512-ymT62W2OyDxBxr7A6JR87vVX9vTq2ep5jZLIdUSusfBIEENLdkkc0lL/Xaq8W9s3opUq7R0sZQpzRWELrfVYzA==} + + jss-plugin-extend@10.10.0: + resolution: {integrity: sha512-sKYrcMfr4xxigmIwqTjxNcHwXJIfvhvjTNxF+Tbc1NmNdyspGW47Ey6sGH8BcQ4FFQhLXctpWCQSpDwdNmXSwg==} + + jss-plugin-global@10.10.0: + resolution: {integrity: sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==} + + jss-plugin-nested@10.10.0: + resolution: {integrity: sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==} + + jss-plugin-props-sort@10.10.0: + resolution: {integrity: sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==} + + jss-plugin-rule-value-function@10.10.0: + resolution: {integrity: sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==} + + jss-plugin-rule-value-observable@10.10.0: + resolution: {integrity: sha512-ZLMaYrR3QE+vD7nl3oNXuj79VZl9Kp8/u6A1IbTPDcuOu8b56cFdWRZNZ0vNr8jHewooEeq2doy8Oxtymr2ZPA==} + + jss-plugin-template@10.10.0: + resolution: {integrity: sha512-ocXZBIOJOA+jISPdsgkTs8wwpK6UbsvtZK5JI7VUggTD6LWKbtoxUzadd2TpfF+lEtlhUmMsCkTRNkITdPKa6w==} + + jss-plugin-vendor-prefixer@10.10.0: + resolution: {integrity: sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==} + + jss-preset-default@10.10.0: + resolution: {integrity: sha512-GL175Wt2FGhjE+f+Y3aWh+JioL06/QWFgZp53CbNNq6ZkVU0TDplD8Bxm9KnkotAYn3FlplNqoW5CjyLXcoJ7Q==} + + jss@10.10.0: + resolution: {integrity: sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + lazy-val@1.0.5: + resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} + + lazystream@1.0.1: + resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} + engines: {node: '>= 0.6.3'} + + lcid@3.1.1: + resolution: {integrity: sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==} + engines: {node: '>=8'} + + 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==} + + light-my-request@5.13.0: + resolution: {integrity: sha512-9IjUN9ZyCS9pTG+KqTDEQo68Sui2lHsYBrfMyVUTTZ3XhH8PMZq7xO94Kr+eP9dhi/kcKsx4N41p2IXEBil1pQ==} + + loadjs@4.3.0: + resolution: {integrity: sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ==} + + 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@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + + 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.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + + lodash.difference@4.5.0: + resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} + + lodash.escaperegexp@4.1.2: + resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} + + lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + + lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.union@4.6.0: + resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + magic-string@0.30.11: + resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==} + + map-age-cleaner@0.1.3: + resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} + engines: {node: '>=6'} + + marked@14.1.2: + resolution: {integrity: sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==} + engines: {node: '>= 18'} + hasBin: true + + matcher@3.0.0: + resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} + engines: {node: '>=10'} + + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + mem@5.1.1: + resolution: {integrity: sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==} + engines: {node: '>=8'} + + merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + 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'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@3.1.0: + resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} + engines: {node: '>=8'} + + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + 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.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + 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'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mitt@2.1.0: + resolution: {integrity: sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.1: + resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + + modify-filename@1.1.0: + resolution: {integrity: sha512-EickqnKq3kVVaZisYuCxhtKbZjInCuwgwZWyAmRIp1NTMhri7r3380/uqwrUHfaDiPzLVTuoNy4whX66bxPVog==} + engines: {node: '>=0.10.0'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + music-metadata@7.14.0: + resolution: {integrity: sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA==} + engines: {node: '>=10'} + + naive-ui@2.39.0: + resolution: {integrity: sha512-5oUJzRG+rtLSH8eRU+fJvVYiQids2BxF9jp+fwGoAqHOptEINrBlgBu9uy+95RHE5FLJ7Q/z41o+qkoGnUrKxQ==} + peerDependencies: + vue: ^3.0.0 + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + ndarray-pack@1.2.1: + resolution: {integrity: sha512-51cECUJMT0rUZNQa09EoKsnFeDL4x2dHRT0VR5U2H5ZgEcm95ZDWcMA5JShroXjHOejmAD/fg8+H+OvUnVXz2g==} + + ndarray@1.0.19: + resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + + node-addon-api@1.7.2: + resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + + node-bitmap@0.0.1: + resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==} + engines: {node: '>=v0.6.5'} + + node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + node-taglib-sharp@5.2.3: + resolution: {integrity: sha512-cqomQ+pD/4HPYpVS5UpDkyN3YQwX67YHSXFk9udSI0VgFKdHSG9/PJFKLehsuwWUr5HKVqRVgSJjBIeOvyLajA==} + engines: {node: '>=12.16.1'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + + npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + omggif@1.0.10: + resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + 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'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + os-locale@4.0.0: + resolution: {integrity: sha512-HsSR1+2l6as4Wp2SGZxqLnuFHxVvh1Ir9pvZxyujsC13egZVe7P0YeBLN0ijQzM/twrO5To3ia3jzBXAvpMTEA==} + engines: {node: '>=8'} + + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + + p-defer@1.0.0: + resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} + engines: {node: '>=4'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-is-promise@2.1.0: + resolution: {integrity: sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==} + engines: {node: '>=6'} + + 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-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + + 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-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + pac-proxy-agent@7.0.2: + resolution: {integrity: sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==} + engines: {node: '>= 14'} + + pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + + package-json-from-dist@1.0.0: + resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-data-uri@0.2.0: + resolution: {integrity: sha512-uOtts8NqDcaCt1rIsO3VFDRsAfgE4c6osG4d9z3l4dCBlxYFzni6Di/oNU270SDrjkfZuUvLZx1rxMyqh46Y9w==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + 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@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + peek-readable@4.1.0: + resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} + engines: {node: '>=8'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pinia-plugin-persistedstate@3.2.3: + resolution: {integrity: sha512-Cm819WBj/s5K5DGw55EwbXDtx+EZzM0YR5AZbq9XE3u0xvXwvX2JnWoFpWIcdzISBHqy9H1UiSIUmXyXqWsQRQ==} + peerDependencies: + pinia: ^2.0.0 + + pinia@2.2.2: + resolution: {integrity: sha512-ja2XqFWZC36mupU4z1ZzxeTApV7DOw44cV4dhQ9sGwun+N89v/XP7+j7q6TanS1u1tdbK4r+1BUx7heMaIdagA==} + 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 + + pino-abstract-transport@1.2.0: + resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} + + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + + pino@9.4.0: + resolution: {integrity: sha512-nbkQb5+9YPhQRz/BeQmrWpEknAaqjpAqRK8NwJpmrX/JHu7JuZC5G1CeAwJDJfGes4h+YihC6in3Q2nGb+Y09w==} + hasBin: true + + pkg-types@1.2.0: + resolution: {integrity: sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==} + + pkg-up@3.1.0: + resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} + engines: {node: '>=8'} + + plist@3.1.0: + resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} + engines: {node: '>=10.4.0'} + + plyr@3.7.8: + resolution: {integrity: sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==} + + pngjs@3.4.0: + resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} + engines: {node: '>=4.0.0'} + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss@8.4.45: + resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@3.0.0: + resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} + + process-warning@4.0.0: + resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pupa@2.1.1: + resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==} + engines: {node: '>=8'} + + qrcode@1.5.4: + resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==} + engines: {node: '>=10.13.0'} + hasBin: true + + qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + rangetouch@2.0.1: + resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + read-config-file@6.3.2: + resolution: {integrity: sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==} + engines: {node: '>=12.0.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readable-stream@4.5.2: + resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readable-web-to-node-stream@3.0.2: + resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} + engines: {node: '>=8'} + + readdir-glob@1.1.3: + resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + + 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'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + 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'} + + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + + ret@0.4.3: + resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} + engines: {node: '>=10'} + + 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.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + roarr@2.15.4: + resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} + engines: {node: '>=8.0'} + + rollup@4.21.2: + resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-decode-uri-component@1.2.1: + resolution: {integrity: sha512-j0PKk0v8qPOD0goqRAvoI7GKy+HwLHXEpXaQlA1IqJ65jjiILRK1InlfNdIKUUUYuLtERADaJumgYKNfyQBO+w==} + + safe-regex2@3.1.0: + resolution: {integrity: sha512-RAAZAGbap2kBfbVhvmnTFv73NWLMvDGOITFYTZBAaY8eR+Ir4ef7Up/e7amo+y1+AH+3PtLkrt9mvcTsG9LXug==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sanitize-filename@1.6.3: + resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} + + sass@1.78.0: + resolution: {integrity: sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + sax@1.4.1: + resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + + scule@1.3.0: + resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} + + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + + seemly@0.3.8: + resolution: {integrity: sha512-MW8Qs6vbzo0pHmDpFSYPna+lwpZ6Zk1ancbajw/7E8TKtHdV+1DfZZD+kKJEhG/cAoB/i+LiT+5msZOqj0DwRA==} + + semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + + 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.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + + serialize-error@7.0.1: + resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} + engines: {node: '>=10'} + + serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-cookie-parser@2.7.0: + resolution: {integrity: sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + 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'} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.4: + resolution: {integrity: sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==} + engines: {node: '>= 14'} + + socks@2.8.3: + resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sonic-boom@4.1.0: + resolution: {integrity: sha512-NGipjjRicyJJ03rPiZCJYjwlsuP2d1/5QUviozRXC7S3WdVWNK5e3Ojieb9CCyfhq2UC+3+SRd9nG3I2lPRvUw==} + + sort-keys-length@1.0.1: + resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} + engines: {node: '>=0.10.0'} + + sort-keys@1.1.2: + resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} + engines: {node: '>=0.10.0'} + + source-map-js@1.2.0: + resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.1.3: + resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} + + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + stat-mode@1.0.0: + resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} + engines: {node: '>= 6'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + stream-wormhole@1.1.0: + resolution: {integrity: sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==} + engines: {node: '>=4.0.0'} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + 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_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + 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-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strip-literal@2.1.0: + resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + + strtok3@6.3.0: + resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} + engines: {node: '>=10'} + + sumchecker@3.0.1: + resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} + engines: {node: '>= 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'} + + symbol-observable@1.2.0: + resolution: {integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==} + engines: {node: '>=0.10.0'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + temp-file@3.4.0: + resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} + + terser@5.33.0: + resolution: {integrity: sha512-JuPVaB7s1gdFKPKTelwUyRq5Sid2A3Gko2S0PncwdBq7kN9Ti9HPWDQ06MPsEDGsZeVESjKEnyGy68quBk1w6g==} + engines: {node: '>=10'} + hasBin: true + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tiny-typed-emitter@2.1.0: + resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tmp-promise@3.0.3: + resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + + tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toad-cache@3.7.0: + resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==} + engines: {node: '>=12'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + token-types@4.2.1: + resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==} + engines: {node: '>=10'} + + tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + + treemate@0.3.11: + resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} + + truncate-utf8-bytes@1.0.2: + resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tunnel@0.0.6: + resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.13.1: + resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} + engines: {node: '>=10'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typescript@5.5.4: + resolution: {integrity: sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + unimport@3.11.1: + resolution: {integrity: sha512-DuB1Uoq01LrrXTScxnwOoMSlTXxyKcULguFxbLrMDFcE/CO0ZWHpEiyhovN0mycPt7K6luAHe8laqvwvuoeUPg==} + + uniq@1.0.1: + resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unplugin-auto-import@0.18.2: + resolution: {integrity: sha512-Dwb3rAic75harVBrVjwiq6H24PT+nBq2dpxV5BH8NNI6sDFaTytvP+iyo4xy7prQbR3r5K6nMs4f5Wp9PE4g8A==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': ^3.2.2 + '@vueuse/core': '*' + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@vueuse/core': + optional: true + + unplugin-vue-components@0.27.4: + resolution: {integrity: sha512-1XVl5iXG7P1UrOMnaj2ogYa5YTq8aoh5jwDPQhemwO/OrXW+lPQKDXd1hMz15qxQPxgb/XXlbgo3HQ2rLEbmXQ==} + 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.13.1: + resolution: {integrity: sha512-6Kq1iSSwg7KyjcThRUks9LuqDAKvtnioxbL9iEtB9ctTyBA5OmrB8gZd/d225VJu1w3UpUsKV7eGrvf59J7+VA==} + engines: {node: '>=14.0.0'} + peerDependencies: + webpack-sources: ^3 + peerDependenciesMeta: + webpack-sources: + optional: true + + unused-filename@2.1.0: + resolution: {integrity: sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==} + engines: {node: '>=8'} + + update-browserslist-db@1.1.0: + resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-polyfill@1.1.12: + resolution: {integrity: sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==} + + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + utf8-byte-length@1.0.5: + resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vdirs@0.1.8: + resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} + peerDependencies: + vue: ^3.0.11 + + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + + verror@1.10.1: + resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} + engines: {node: '>=0.6.0'} + + vite-plugin-compression@0.5.1: + resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==} + peerDependencies: + vite: '>=2.0.0' + + vite-plugin-wasm@3.3.0: + resolution: {integrity: sha512-tVhz6w+W9MVsOCHzxo6SSMSswCeIw4HTrXEi6qL3IRzATl83jl09JVO1djBqPSwfjgnpVHNLYcaMbaDX5WB/pg==} + peerDependencies: + vite: ^2 || ^3 || ^4 || ^5 + + vite@5.4.3: + resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==} + 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: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vooks@0.2.12: + resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==} + peerDependencies: + vue: ^3.0.0 + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + 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-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + vue-observe-visibility@2.0.0-alpha.1: + resolution: {integrity: sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g==} + peerDependencies: + vue: ^3.0.0 + + vue-resize@2.0.0-alpha.1: + resolution: {integrity: sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==} + peerDependencies: + vue: ^3.0.0 + + vue-router@4.4.3: + resolution: {integrity: sha512-sv6wmNKx2j3aqJQDMxLFzs/u/mjA9Z5LCgy6BE0f7yFWMjrPLnS/sPNn8ARY/FXw6byV18EFutn5lTO6+UsV5A==} + peerDependencies: + vue: ^3.2.0 + + vue-tsc@2.1.6: + resolution: {integrity: sha512-f98dyZp5FOukcYmbFpuSCJ4Z0vHSOSmxGttZJCsFeX0M4w/Rsq0s4uKXjcSRsZqsRgQa6z7SfuO+y0HVICE57Q==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue-virtual-scroller@2.0.0-beta.8: + resolution: {integrity: sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==} + peerDependencies: + vue: ^3.2.0 + + vue@3.4.38: + resolution: {integrity: sha512-f0ZgN+mZ5KFgVv9wz0f4OgVKukoXtS3nwET4c2vLBGQR50aI8G0cqbFtLlX9Yiyg3LFGBitruPHt2PxwTduJEw==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vueuc@0.4.58: + resolution: {integrity: sha512-Wnj/N8WbPRSxSt+9ji1jtDHPzda5h2OH/0sFBhvdxDRuyCZbjGg3/cKMaKqEoe+dErTexG2R+i6Q8S/Toq1MYg==} + peerDependencies: + vue: ^3.0.11 + + 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-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + 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'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xmlbuilder@15.1.1: + resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} + engines: {node: '>=8.0'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + 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==} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zip-stream@4.1.1: + resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} + engines: {node: '>= 10'} + +snapshots: + + 7zip-bin@5.2.0: {} + + '@ampproject/remapping@2.3.0': dependencies: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - dev: true - /@antfu/utils@0.7.8: - resolution: {integrity: sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==} - dev: true + '@antfu/utils@0.7.10': {} - /@apideck/better-ajv-errors@0.3.6(ajv@8.16.0): - resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} - engines: {node: '>=10'} - peerDependencies: - ajv: '>=8' + '@applemusic-like-lyrics/core@0.1.3(@pixi/app@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2))(@pixi/filter-blur@7.4.2(@pixi/core@7.4.2))(@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.2))(@pixi/filter-color-matrix@7.4.2(@pixi/core@7.4.2))(@pixi/sprite@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(jss-preset-default@10.10.0)(jss@10.10.0)': dependencies: - ajv: 8.16.0 - json-schema: 0.4.0 - jsonpointer: 5.0.1 - leven: 3.1.0 - dev: true + '@pixi/app': 7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)) + '@pixi/core': 7.4.2 + '@pixi/display': 7.4.2(@pixi/core@7.4.2) + '@pixi/filter-blur': 7.4.2(@pixi/core@7.4.2) + '@pixi/filter-bulge-pinch': 5.1.1(@pixi/core@7.4.2) + '@pixi/filter-color-matrix': 7.4.2(@pixi/core@7.4.2) + '@pixi/sprite': 7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)) + bezier-easing: 2.1.0 + jss: 10.10.0 + jss-preset-default: 10.10.0 - /@babel/code-frame@7.24.7: - resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==} - engines: {node: '>=6.9.0'} + '@applemusic-like-lyrics/lyric@0.2.2': {} + + '@applemusic-like-lyrics/vue@0.1.5(@pixi/app@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2))(@pixi/filter-blur@7.4.2(@pixi/core@7.4.2))(@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.2))(@pixi/filter-color-matrix@7.4.2(@pixi/core@7.4.2))(@pixi/sprite@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(jss-preset-default@10.10.0)(jss@10.10.0)(vue@3.4.38(typescript@5.5.4))': + dependencies: + '@applemusic-like-lyrics/core': 0.1.3(@pixi/app@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2))(@pixi/filter-blur@7.4.2(@pixi/core@7.4.2))(@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.2))(@pixi/filter-color-matrix@7.4.2(@pixi/core@7.4.2))(@pixi/sprite@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2)))(jss-preset-default@10.10.0)(jss@10.10.0) + vue: 3.4.38(typescript@5.5.4) + transitivePeerDependencies: + - '@pixi/app' + - '@pixi/core' + - '@pixi/display' + - '@pixi/filter-blur' + - '@pixi/filter-bulge-pinch' + - '@pixi/filter-color-matrix' + - '@pixi/sprite' + - jss + - jss-preset-default + + '@babel/code-frame@7.24.7': dependencies: '@babel/highlight': 7.24.7 - picocolors: 1.0.1 - dev: true + picocolors: 1.1.0 - /@babel/compat-data@7.24.7: - resolution: {integrity: sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==} - engines: {node: '>=6.9.0'} - dev: true + '@babel/compat-data@7.25.4': {} - /@babel/core@7.24.7: - resolution: {integrity: sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==} - engines: {node: '>=6.9.0'} + '@babel/core@7.25.2': 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 + '@babel/generator': 7.25.6 + '@babel/helper-compilation-targets': 7.25.2 + '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2) + '@babel/helpers': 7.25.6 + '@babel/parser': 7.25.6 + '@babel/template': 7.25.0 + '@babel/traverse': 7.25.6 + '@babel/types': 7.25.6 convert-source-map: 2.0.0 - debug: 4.3.5 + debug: 4.3.7 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - dev: true - /@babel/generator@7.24.7: - resolution: {integrity: sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==} - engines: {node: '>=6.9.0'} + '@babel/generator@7.25.6': dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.25.6 '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 - dev: true - /@babel/helper-annotate-as-pure@7.24.7: - resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==} - engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@7.25.2': dependencies: - '@babel/types': 7.24.7 - dev: true - - /@babel/helper-builder-binary-assignment-operator-visitor@7.24.7: - resolution: {integrity: sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-compilation-targets@7.24.7: - resolution: {integrity: sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.24.7 - '@babel/helper-validator-option': 7.24.7 - browserslist: 4.23.1 + '@babel/compat-data': 7.25.4 + '@babel/helper-validator-option': 7.24.8 + browserslist: 4.23.3 lru-cache: 5.1.1 semver: 6.3.1 - dev: true - /@babel/helper-create-class-features-plugin@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-kTkaDl7c9vO80zeX1rJxnuRpEsD5tA81yh11X1gQo+PhSti3JS+7qeZo9U4RHobKRiFPKaGK3svUAeb8D0Q7eg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/helper-module-imports@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 + '@babel/traverse': 7.25.6 + '@babel/types': 7.25.6 transitivePeerDependencies: - supports-color - dev: true - /@babel/helper-create-regexp-features-plugin@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-03TCmXy2FtXJEZfbXDTSqq1fRJArk7lX9DOFC/47VthYcxyIOx+eXQmdo6DOQvrbpIix+KfXwvuXdFDZHxt+rA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.7 - '@babel/helper-annotate-as-pure': 7.24.7 - regexpu-core: 5.3.2 - semver: 6.3.1 - dev: true - - /@babel/helper-define-polyfill-provider@0.6.2(@babel/core@7.24.7): - resolution: {integrity: sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - debug: 4.3.5 - lodash.debounce: 4.0.8 - resolve: 1.22.8 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-environment-visitor@7.24.7: - resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.7 - dev: true - - /@babel/helper-function-name@7.24.7: - resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.24.7 - '@babel/types': 7.24.7 - dev: true - - /@babel/helper-hoist-variables@7.24.7: - resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.7 - dev: true - - /@babel/helper-member-expression-to-functions@7.24.7: - resolution: {integrity: sha512-LGeMaf5JN4hAT471eJdBs/GK1DoYIJ5GCtZN/EsL6KUiiDZOvO/eKE11AMZJa2zP4zk4qe9V2O/hxAmkRc8p6w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-module-imports@7.24.7: - resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-module-transforms@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-environment-visitor': 7.24.7 + '@babel/core': 7.25.2 '@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 + '@babel/traverse': 7.25.6 transitivePeerDependencies: - supports-color - dev: true - /@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.8': {} + + '@babel/helper-simple-access@7.24.7': dependencies: - '@babel/types': 7.24.7 - dev: true - - /@babel/helper-plugin-utils@7.24.7: - resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-remap-async-to-generator@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-9pKLcTlZ92hNZMQfGCHImUpDOlAgkkpqalWEeftW5FBya75k8Li2ilerxkM/uBEj01iBZXcCIB/bwvDYgWyibA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-wrap-function': 7.24.7 + '@babel/traverse': 7.25.6 + '@babel/types': 7.25.6 transitivePeerDependencies: - supports-color - dev: true - /@babel/helper-replace-supers@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-qTAxxBM81VEyoAY0TtLrx1oAEJc09ZK67Q9ljQToqCnA+55eNwCORaxlKyu+rNfX86o8OXRUSNUnrtsAZXM9sg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/helper-string-parser@7.24.8': {} + + '@babel/helper-validator-identifier@7.24.7': {} + + '@babel/helper-validator-option@7.24.8': {} + + '@babel/helpers@7.25.6': 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 - dev: true + '@babel/template': 7.25.0 + '@babel/types': 7.25.6 - /@babel/helper-simple-access@7.24.7: - resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-skip-transparent-expression-wrappers@7.24.7: - resolution: {integrity: sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-split-export-declaration@7.24.7: - resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.24.7 - dev: true - - /@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'} - dev: true - - /@babel/helper-wrap-function@7.24.7: - resolution: {integrity: sha512-N9JIYk3TD+1vq/wn77YnJOqMtfWhNewNE+DJV4puD2X7Ew9J4JvrzrFDfTfyv5EgEXVy9/Wt8QiOErzEmv5Ifw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-function-name': 7.24.7 - '@babel/template': 7.24.7 - '@babel/traverse': 7.24.7 - '@babel/types': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helpers@7.24.7: - resolution: {integrity: sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.24.7 - '@babel/types': 7.24.7 - dev: true - - /@babel/highlight@7.24.7: - resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==} - engines: {node: '>=6.9.0'} + '@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 - dev: true + picocolors: 1.1.0 - /@babel/parser@7.24.7: - resolution: {integrity: sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==} - engines: {node: '>=6.0.0'} - hasBin: true + '@babel/parser@7.25.6': dependencies: - '@babel/types': 7.24.7 + '@babel/types': 7.25.6 - /@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-TiT1ss81W80eQsN+722OaeQMY/G4yTb4G9JrqeiDADs3N8lbPMGldWi9x8tyqCW5NLx1Jh2AvkE6r6QvEltMMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 + '@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.25.2)': dependencies: - '@babel/core': 7.24.7 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true + '@babel/core': 7.25.2 + '@babel/helper-plugin-utils': 7.24.8 - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-unaQgZ/iRu/By6tsjMZzpeBZjChYfLYry6HrEXPoz3KmfF0sVBQ1l8zKMQ4xRGLWVsjuvB8nQfjNP/DcfEOCsg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.13.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-utA4HuR6F4Vvcr+o4DnjL8fCOlgRFGbeeBEGNg3ZTrLFw6VWG5XmUrvcQ0FjIYMU2ST4XcR2Wsp7t9qOAPnxMg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7): - resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - dev: true - - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.7): - resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.7): - resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.7): - resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.7): - resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.7): - resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-import-assertions@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-import-attributes@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.7): - resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.7): - resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.7): - resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.7): - resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.7): - resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.7): - resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.7): - resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.7): - resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.7): - resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.7): - resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.7): - resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-arrow-functions@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-async-generator-functions@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-o+iF77e3u7ZS4AoAuJvapz9Fm001PuD2V3Lp6OSE4FYQke+cSewYtnek+THqGRWyQloRCyvWL1OkyfNEl9vr/g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-async-to-generator@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-imports': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-remap-async-to-generator': 7.24.7(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-block-scoped-functions@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-block-scoping@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-Nd5CvgMbWc+oWzBsuaMcbwjJWAcp5qzrbg69SZdHSP7AMY0AbWFqFO0WTFCA1jxhMCwodRwvRec8k0QUbZk7RQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-class-properties@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-vKbfawVYayKcSeSR5YYzzyXvsDFWU2mD8U5TFeXtbCPLFUqe7GyCgvO6XDHzje862ODrOwy6WCPmKeWHbCFJ4w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-class-static-block@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.12.0 - dependencies: - '@babel/core': 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-class-static-block': 7.14.5(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-classes@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-CFbbBigp8ln4FU6Bpy6g7sE8B/WmCmzvivzUC6xDAdWVsjYTXijpuuGJmYkAaoWAzcItGKT3IOAbxRItZ5HTjw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-annotate-as-pure': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-environment-visitor': 7.24.7 - '@babel/helper-function-name': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) - '@babel/helper-split-export-declaration': 7.24.7 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-computed-properties@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/template': 7.24.7 - dev: true - - /@babel/plugin-transform-destructuring@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-19eJO/8kdCQ9zISOf+SEUJM/bAUIsvY3YDnXZTupUCQ8LgrWnsG/gFB9dvXqdXnRXMAM8fvt7b0CBKQHNGy1mw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-dotall-regex@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-duplicate-keys@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-dynamic-import@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-exponentiation-operator@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-builder-binary-assignment-operator-visitor': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-export-namespace-from@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-for-of@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-function-name@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-U9FcnA821YoILngSmYkW6FjyQe2TyZD5pHt4EVIhmcTkrJw/3KqcrRSxuOo5tFZJi7TE19iDyI1u+weTI7bn2w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-function-name': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-json-strings@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-literals@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-vcwCbb4HDH+hWi8Pqenwnjy+UiklO4Kt1vfspcQYFhJdpthSnW8XvWGyDZWKNVrVbVViI/S7K9PDJZiUmP2fYQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-logical-assignment-operators@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-member-expression-literals@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-modules-amd@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-commonjs@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-iFI8GDxtevHJ/Z22J5xQpVqFLlMNstcLXh994xifFwxxGslr2ZXXLWgtBeLctOD63UFDArdvN6Tg8RFw+aEmjQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-simple-access': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-systemjs@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-GYQE0tW7YoaN13qFh3O1NCY4MPkUiAH3fiF7UcV/I3ajmDKEdG3l+UOcbAm4zUE3gnvUU+Eni7XrVKo9eO9auw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-hoist-variables': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-validator-identifier': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-modules-umd@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-transforms': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-named-capturing-groups-regex@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-new-target@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-nullish-coalescing-operator@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-numeric-separator@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-object-rest-spread@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-object-super@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-replace-supers': 7.24.7(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-optional-catch-binding@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) - dev: true - - /@babel/plugin-transform-optional-chaining@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-tK+0N9yd4j+x/4hxF3F0e0fu/VdcxU18y5SevtyM/PCFlQvXbR0Zmlo2eBrKtVipGNFzpq56o8WsIIKcJFUCRQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-parameters@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-private-methods@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-COTCOkG2hn4JKGEKBADkA8WNb35TGkkRbI5iT845dB+NyqgO8Hn+ajPbSnIQznneJTa3d30scb6iz/DhH8GsJQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-private-property-in-object@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - 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-private-property-in-object': 7.14.5(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-property-literals@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-regenerator@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - regenerator-transform: 0.15.2 - dev: true - - /@babel/plugin-transform-reserved-words@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-shorthand-properties@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-spread@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-skip-transparent-expression-wrappers': 7.24.7 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/plugin-transform-sticky-regex@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-template-literals@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-typeof-symbol@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-VtR8hDy7YLB7+Pet9IarXjg/zgCMSF+1mNS/EQEiEaUPoFXCVsHG64SIxcaaI2zJgRiv+YmgaQESUfWAdbjzgg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-unicode-escapes@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-unicode-property-regex@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-unicode-regex@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/plugin-transform-unicode-sets-regex@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-2G8aAvF4wy1w/AGZkemprdGMRg5o6zPNhbHVImRz3lss55TYCBd6xStN19rt8XJHq20sqV0JbyWjOWwQRwV/wg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-create-regexp-features-plugin': 7.24.7(@babel/core@7.24.7) - '@babel/helper-plugin-utils': 7.24.7 - dev: true - - /@babel/preset-env@7.24.7(@babel/core@7.24.7): - resolution: {integrity: sha512-1YZNsc+y6cTvWlDHidMBsQZrZfEFjRIo/BZCT906PMdzOyXtSLTgqGdrpcuTDCXyd11Am5uQULtDIcCfnTc8fQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/compat-data': 7.24.7 - '@babel/core': 7.24.7 - '@babel/helper-compilation-targets': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/helper-validator-option': 7.24.7 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.24.7) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.7) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.7) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.7) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-import-assertions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-syntax-import-attributes': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.7) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.7) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.7) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.7) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.24.7) - '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-async-generator-functions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-async-to-generator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-block-scoped-functions': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-block-scoping': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-class-properties': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-class-static-block': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-classes': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-computed-properties': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-destructuring': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-dotall-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-duplicate-keys': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-dynamic-import': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-exponentiation-operator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-export-namespace-from': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-for-of': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-function-name': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-json-strings': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-logical-assignment-operators': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-member-expression-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-amd': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-commonjs': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-systemjs': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-modules-umd': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-named-capturing-groups-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-new-target': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-nullish-coalescing-operator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-numeric-separator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-object-rest-spread': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-object-super': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-optional-catch-binding': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-optional-chaining': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-parameters': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-private-methods': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-private-property-in-object': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-property-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-regenerator': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-reserved-words': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-shorthand-properties': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-spread': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-sticky-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-template-literals': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-typeof-symbol': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-escapes': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-property-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-regex': 7.24.7(@babel/core@7.24.7) - '@babel/plugin-transform-unicode-sets-regex': 7.24.7(@babel/core@7.24.7) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.24.7) - babel-plugin-polyfill-corejs2: 0.4.11(@babel/core@7.24.7) - babel-plugin-polyfill-corejs3: 0.10.4(@babel/core@7.24.7) - babel-plugin-polyfill-regenerator: 0.6.2(@babel/core@7.24.7) - core-js-compat: 3.37.1 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.24.7): - resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} - peerDependencies: - '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-plugin-utils': 7.24.7 - '@babel/types': 7.24.7 - esutils: 2.0.3 - dev: true - - /@babel/regjsgen@0.8.0: - resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} - dev: true - - /@babel/runtime@7.24.7: - resolution: {integrity: sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==} - engines: {node: '>=6.9.0'} + '@babel/runtime@7.25.6': dependencies: regenerator-runtime: 0.14.1 - dev: true - /@babel/template@7.24.7: - resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==} - engines: {node: '>=6.9.0'} + '@babel/template@7.25.0': dependencies: '@babel/code-frame': 7.24.7 - '@babel/parser': 7.24.7 - '@babel/types': 7.24.7 - dev: true + '@babel/parser': 7.25.6 + '@babel/types': 7.25.6 - /@babel/traverse@7.24.7: - resolution: {integrity: sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==} - engines: {node: '>=6.9.0'} + '@babel/traverse@7.25.6': 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 + '@babel/generator': 7.25.6 + '@babel/parser': 7.25.6 + '@babel/template': 7.25.0 + '@babel/types': 7.25.6 + debug: 4.3.7 globals: 11.12.0 transitivePeerDependencies: - supports-color - dev: true - /@babel/types@7.24.7: - resolution: {integrity: sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==} - engines: {node: '>=6.9.0'} + '@babel/types@7.25.6': dependencies: - '@babel/helper-string-parser': 7.24.7 + '@babel/helper-string-parser': 7.24.8 '@babel/helper-validator-identifier': 7.24.7 to-fast-properties: 2.0.0 - /@css-render/plugin-bem@0.15.14(css-render@0.15.14): - resolution: {integrity: sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==} - peerDependencies: - css-render: ~0.15.14 + '@css-render/plugin-bem@0.15.14(css-render@0.15.14)': dependencies: css-render: 0.15.14 - dev: true - /@css-render/vue3-ssr@0.15.14(vue@3.4.8): - resolution: {integrity: sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==} - peerDependencies: - vue: ^3.0.11 + '@css-render/vue3-ssr@0.15.14(vue@3.4.38(typescript@5.5.4))': dependencies: - vue: 3.4.8 - dev: true + vue: 3.4.38(typescript@5.5.4) - /@develar/schema-utils@2.6.5: - resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==} - engines: {node: '>= 8.9.0'} + '@develar/schema-utils@2.6.5': dependencies: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - dev: true - /@electron-toolkit/eslint-config@1.0.2(eslint@8.57.0): - resolution: {integrity: sha512-GJVuMsxBHfVARfmUoSTCHT0e/QfWlVbXcGk3tgoku0ad6tLjydbv2LpvKi02+Sy2WiEz9L9SkGSw090ukT/F0A==} - peerDependencies: - eslint: '>= 8.0.0' - dependencies: - eslint: 8.57.0 - dev: true - - /@electron-toolkit/preload@3.0.1(electron@28.3.3): - resolution: {integrity: sha512-EzoQmpK8jqqU8YnM5jRe0GJjGVJPke2KtANqz8QtN2JPT96ViOvProBdK5C6riCm0j1T8jjAGVQCZLQy9OVoIA==} - peerDependencies: - electron: '>=13.0.0' + '@electron-toolkit/preload@3.0.1(electron@28.3.3)': dependencies: electron: 28.3.3 - dev: false - /@electron-toolkit/utils@3.0.0(electron@28.3.3): - resolution: {integrity: sha512-GaXHDhiT7KCvMJjXdp/QqpYinq69T/Pdl49Z1XLf8mKGf63dnsODMWyrmIjEQ0z/vG7dO8qF3fvmI6Eb2lUNZA==} - peerDependencies: - electron: '>=13.0.0' + '@electron-toolkit/tsconfig@1.0.1(@types/node@22.5.4)': + dependencies: + '@types/node': 22.5.4 + + '@electron-toolkit/utils@3.0.0(electron@28.3.3)': dependencies: electron: 28.3.3 - dev: false - /@electron/asar@3.2.10: - resolution: {integrity: sha512-mvBSwIBUeiRscrCeJE1LwctAriBj65eUDm0Pc11iE5gRwzkmsdbS7FnZ1XUWjpSeQWL1L5g12Fc/SchPM9DUOw==} - engines: {node: '>=10.12.0'} - hasBin: true + '@electron/asar@3.2.10': dependencies: commander: 5.1.0 glob: 7.2.3 minimatch: 3.1.2 - dev: true - /@electron/get@2.0.3: - resolution: {integrity: sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==} - engines: {node: '>=12'} + '@electron/get@2.0.3': dependencies: - debug: 4.3.5 + debug: 4.3.7 env-paths: 2.2.1 fs-extra: 8.1.0 got: 11.8.6 @@ -1476,1114 +4027,723 @@ packages: transitivePeerDependencies: - supports-color - /@electron/notarize@2.2.1: - resolution: {integrity: sha512-aL+bFMIkpR0cmmj5Zgy0LMKEpgy43/hw5zadEArgmAMWWlKc5buwFvFT9G/o/YJkvXAJm5q3iuTuLaiaXW39sg==} - engines: {node: '>= 10.0.0'} + '@electron/notarize@2.2.1': dependencies: - debug: 4.3.5 + debug: 4.3.7 fs-extra: 9.1.0 promise-retry: 2.0.1 transitivePeerDependencies: - supports-color - dev: true - /@electron/osx-sign@1.0.5: - resolution: {integrity: sha512-k9ZzUQtamSoweGQDV2jILiRIHUu7lYlJ3c6IEmjv1hC17rclE+eb9U+f6UFlOOETo0JzY1HNlXy4YOlCvl+Lww==} - engines: {node: '>=12.0.0'} - hasBin: true + '@electron/osx-sign@1.0.5': dependencies: compare-version: 0.1.2 - debug: 4.3.5 + debug: 4.3.7 fs-extra: 10.1.0 isbinaryfile: 4.0.10 minimist: 1.2.8 plist: 3.1.0 transitivePeerDependencies: - supports-color - dev: true - /@electron/universal@1.5.1: - resolution: {integrity: sha512-kbgXxyEauPJiQQUNG2VgUeyfQNFk6hBF11ISN2PNI6agUgPl55pv4eQmaqHzTAzchBvqZ2tQuRVaPStGf0mxGw==} - engines: {node: '>=8.6'} + '@electron/universal@1.5.1': dependencies: '@electron/asar': 3.2.10 '@malept/cross-spawn-promise': 1.1.1 - debug: 4.3.5 + debug: 4.3.7 dir-compare: 3.3.0 fs-extra: 9.1.0 minimatch: 3.1.2 plist: 3.1.0 transitivePeerDependencies: - supports-color - dev: true - /@emotion/hash@0.8.0: - resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} - dev: true + '@emotion/hash@0.8.0': {} - /@esbuild/aix-ppc64@0.19.12: - resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - dev: true + '@esbuild/aix-ppc64@0.21.5': optional: true - /@esbuild/aix-ppc64@0.21.5: - resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [aix] - requiresBuild: true - dev: true + '@esbuild/android-arm64@0.21.5': optional: true - /@esbuild/android-arm64@0.19.12: - resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + '@esbuild/android-arm@0.21.5': optional: true - /@esbuild/android-arm64@0.21.5: - resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + '@esbuild/android-x64@0.21.5': optional: true - /@esbuild/android-arm@0.19.12: - resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true + '@esbuild/darwin-arm64@0.21.5': optional: true - /@esbuild/android-arm@0.21.5: - resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} - engines: {node: '>=12'} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true + '@esbuild/darwin-x64@0.21.5': optional: true - /@esbuild/android-x64@0.19.12: - resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true + '@esbuild/freebsd-arm64@0.21.5': optional: true - /@esbuild/android-x64@0.21.5: - resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} - engines: {node: '>=12'} - cpu: [x64] - os: [android] - requiresBuild: true - dev: true + '@esbuild/freebsd-x64@0.21.5': optional: true - /@esbuild/darwin-arm64@0.19.12: - resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@esbuild/linux-arm64@0.21.5': optional: true - /@esbuild/darwin-arm64@0.21.5: - resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} - engines: {node: '>=12'} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@esbuild/linux-arm@0.21.5': optional: true - /@esbuild/darwin-x64@0.19.12: - resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@esbuild/linux-ia32@0.21.5': optional: true - /@esbuild/darwin-x64@0.21.5: - resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} - engines: {node: '>=12'} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@esbuild/linux-loong64@0.21.5': optional: true - /@esbuild/freebsd-arm64@0.19.12: - resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true + '@esbuild/linux-mips64el@0.21.5': optional: true - /@esbuild/freebsd-arm64@0.21.5: - resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} - engines: {node: '>=12'} - cpu: [arm64] - os: [freebsd] - requiresBuild: true - dev: true + '@esbuild/linux-ppc64@0.21.5': optional: true - /@esbuild/freebsd-x64@0.19.12: - resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true + '@esbuild/linux-riscv64@0.21.5': optional: true - /@esbuild/freebsd-x64@0.21.5: - resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [freebsd] - requiresBuild: true - dev: true + '@esbuild/linux-s390x@0.21.5': optional: true - /@esbuild/linux-arm64@0.19.12: - resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/linux-x64@0.21.5': optional: true - /@esbuild/linux-arm64@0.21.5: - resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} - engines: {node: '>=12'} - cpu: [arm64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/netbsd-x64@0.21.5': optional: true - /@esbuild/linux-arm@0.19.12: - resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/openbsd-x64@0.21.5': optional: true - /@esbuild/linux-arm@0.21.5: - resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} - engines: {node: '>=12'} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/sunos-x64@0.21.5': optional: true - /@esbuild/linux-ia32@0.19.12: - resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/win32-arm64@0.21.5': optional: true - /@esbuild/linux-ia32@0.21.5: - resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} - engines: {node: '>=12'} - cpu: [ia32] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/win32-ia32@0.21.5': optional: true - /@esbuild/linux-loong64@0.19.12: - resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true + '@esbuild/win32-x64@0.21.5': optional: true - /@esbuild/linux-loong64@0.21.5: - resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} - engines: {node: '>=12'} - cpu: [loong64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.19.12: - resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-mips64el@0.21.5: - resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} - engines: {node: '>=12'} - cpu: [mips64el] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.19.12: - resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-ppc64@0.21.5: - resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} - engines: {node: '>=12'} - cpu: [ppc64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-riscv64@0.19.12: - resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-riscv64@0.21.5: - resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} - engines: {node: '>=12'} - cpu: [riscv64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.19.12: - resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-s390x@0.21.5: - resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} - engines: {node: '>=12'} - cpu: [s390x] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-x64@0.19.12: - resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/linux-x64@0.21.5: - resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} - engines: {node: '>=12'} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.19.12: - resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/netbsd-x64@0.21.5: - resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} - engines: {node: '>=12'} - cpu: [x64] - os: [netbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64@0.19.12: - resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/openbsd-x64@0.21.5: - resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} - engines: {node: '>=12'} - cpu: [x64] - os: [openbsd] - requiresBuild: true - dev: true - optional: true - - /@esbuild/sunos-x64@0.19.12: - resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/sunos-x64@0.21.5: - resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} - engines: {node: '>=12'} - cpu: [x64] - os: [sunos] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.19.12: - resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-arm64@0.21.5: - resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} - engines: {node: '>=12'} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32@0.19.12: - resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-ia32@0.21.5: - resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} - engines: {node: '>=12'} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64@0.19.12: - resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@esbuild/win32-x64@0.21.5: - resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} - engines: {node: '>=12'} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@eslint-community/eslint-utils@4.4.0(eslint@8.57.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/eslint-utils@4.4.0(eslint@8.57.0)': dependencies: eslint: 8.57.0 eslint-visitor-keys: 3.4.3 - dev: true - /@eslint-community/regexpp@4.10.1: - resolution: {integrity: sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==} - engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - dev: true + '@eslint-community/regexpp@4.11.0': {} - /@eslint/eslintrc@2.1.4: - resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.5 + debug: 4.3.7 espree: 9.6.1 globals: 13.24.0 - ignore: 5.3.1 + ignore: 5.3.2 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - dev: true - /@eslint/js@8.57.0: - resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true + '@eslint/js@8.57.0': {} - /@humanwhocodes/config-array@0.11.14: - resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} - engines: {node: '>=10.10.0'} - deprecated: Use @eslint/config-array instead + '@fastify/accept-negotiator@1.1.0': {} + + '@fastify/ajv-compiler@3.6.0': + dependencies: + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + fast-uri: 2.4.0 + + '@fastify/busboy@2.1.1': {} + + '@fastify/cookie@9.4.0': + dependencies: + cookie-signature: 1.2.1 + fastify-plugin: 4.5.1 + + '@fastify/deepmerge@1.3.0': {} + + '@fastify/error@3.4.1': {} + + '@fastify/fast-json-stringify-compiler@4.3.0': + dependencies: + fast-json-stringify: 5.16.1 + + '@fastify/http-proxy@9.5.0': + dependencies: + '@fastify/reply-from': 9.8.0 + fast-querystring: 1.1.2 + fastify-plugin: 4.5.1 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@fastify/merge-json-schemas@0.1.1': + dependencies: + fast-deep-equal: 3.1.3 + + '@fastify/multipart@8.3.0': + dependencies: + '@fastify/busboy': 2.1.1 + '@fastify/deepmerge': 1.3.0 + '@fastify/error': 3.4.1 + fastify-plugin: 4.5.1 + secure-json-parse: 2.7.0 + stream-wormhole: 1.1.0 + + '@fastify/reply-from@9.8.0': + dependencies: + '@fastify/error': 3.4.1 + end-of-stream: 1.4.4 + fast-content-type-parse: 1.1.0 + fast-querystring: 1.1.2 + fastify-plugin: 4.5.1 + toad-cache: 3.7.0 + undici: 5.28.4 + + '@fastify/send@2.1.0': + dependencies: + '@lukeed/ms': 2.0.2 + escape-html: 1.0.3 + fast-decode-uri-component: 1.0.1 + http-errors: 2.0.0 + mime: 3.0.0 + + '@fastify/static@7.0.4': + dependencies: + '@fastify/accept-negotiator': 1.1.0 + '@fastify/send': 2.1.0 + content-disposition: 0.5.4 + fastify-plugin: 4.5.1 + fastq: 1.17.1 + glob: 10.4.5 + + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.5 + debug: 4.3.7 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - dev: true - /@humanwhocodes/module-importer@1.0.1: - resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} - engines: {node: '>=12.22'} - dev: true + '@humanwhocodes/module-importer@1.0.1': {} - /@humanwhocodes/object-schema@2.0.3: - resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} - deprecated: Use @eslint/object-schema instead - dev: true + '@humanwhocodes/object-schema@2.0.3': {} - /@isaacs/cliui@8.0.2: - resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} - engines: {node: '>=12'} + '@imsyy/color-utils@1.0.2': + dependencies: + '@material/material-color-utilities': 0.2.7 + colorthief: 2.4.0 + + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 - string-width-cjs: /string-width@4.2.3 + string-width-cjs: string-width@4.2.3 strip-ansi: 7.1.0 - strip-ansi-cjs: /strip-ansi@6.0.1 + strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 - wrap-ansi-cjs: /wrap-ansi@7.0.0 - dev: true + wrap-ansi-cjs: wrap-ansi@7.0.0 - /@jridgewell/gen-mapping@0.3.5: - resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.5': dependencies: '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/sourcemap-codec': 1.5.0 '@jridgewell/trace-mapping': 0.3.25 - dev: true - /@jridgewell/resolve-uri@3.1.2: - resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} - engines: {node: '>=6.0.0'} - dev: true + '@jridgewell/resolve-uri@3.1.2': {} - /@jridgewell/set-array@1.2.1: - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - dev: true + '@jridgewell/set-array@1.2.1': {} - /@jridgewell/source-map@0.3.6: - resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + '@jridgewell/source-map@0.3.6': dependencies: '@jridgewell/gen-mapping': 0.3.5 '@jridgewell/trace-mapping': 0.3.25 - dev: true - /@jridgewell/sourcemap-codec@1.4.15: - resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + '@jridgewell/sourcemap-codec@1.5.0': {} - /@jridgewell/trace-mapping@0.3.25: - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.4.15 - dev: true + '@jridgewell/sourcemap-codec': 1.5.0 - /@juggle/resize-observer@3.4.0: - resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} - dev: true + '@juggle/resize-observer@3.4.0': {} - /@lokesh.dhakar/quantize@1.3.0: - resolution: {integrity: sha512-4KBSyaMj65d8A+2vnzLxtHFu4OmBU4IKO0yLxZ171Itdf9jGV4w+WbG7VsKts2jUdRkFSzsZqpZOz6hTB3qGAw==} - dev: false + '@lokesh.dhakar/quantize@1.3.0': {} - /@malept/cross-spawn-promise@1.1.1: - resolution: {integrity: sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==} - engines: {node: '>= 10'} + '@lukeed/ms@2.0.2': {} + + '@malept/cross-spawn-promise@1.1.1': dependencies: cross-spawn: 7.0.3 - dev: true - /@malept/flatpak-bundler@0.4.0: - resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} - engines: {node: '>= 10.0.0'} + '@malept/flatpak-bundler@0.4.0': dependencies: - debug: 4.3.5 + debug: 4.3.7 fs-extra: 9.1.0 lodash: 4.17.21 tmp-promise: 3.0.3 transitivePeerDependencies: - supports-color - dev: true - /@material/material-color-utilities@0.2.7: - resolution: {integrity: sha512-0FCeqG6WvK4/Cc06F/xXMd/pv4FeisI0c1tUpBbfhA2n9Y8eZEv4Karjbmf2ZqQCPUWMrGp8A571tCjizxoTiQ==} - dev: false + '@material/material-color-utilities@0.2.7': {} - /@nodelib/fs.scandir@2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} + '@material/material-color-utilities@0.3.0': {} + + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 run-parallel: 1.2.0 - dev: true - /@nodelib/fs.stat@2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true + '@nodelib/fs.stat@2.0.5': {} - /@nodelib/fs.walk@1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 fastq: 1.17.1 - dev: true - /@pkgjs/parseargs@0.11.0: - resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} - engines: {node: '>=14'} - requiresBuild: true - dev: true + '@pixi/app@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2))': + dependencies: + '@pixi/core': 7.4.2 + '@pixi/display': 7.4.2(@pixi/core@7.4.2) + + '@pixi/color@7.4.2': + dependencies: + '@pixi/colord': 2.9.6 + + '@pixi/colord@2.9.6': {} + + '@pixi/constants@7.4.2': {} + + '@pixi/core@7.4.2': + dependencies: + '@pixi/color': 7.4.2 + '@pixi/constants': 7.4.2 + '@pixi/extensions': 7.4.2 + '@pixi/math': 7.4.2 + '@pixi/runner': 7.4.2 + '@pixi/settings': 7.4.2 + '@pixi/ticker': 7.4.2 + '@pixi/utils': 7.4.2 + + '@pixi/display@7.4.2(@pixi/core@7.4.2)': + dependencies: + '@pixi/core': 7.4.2 + + '@pixi/extensions@7.4.2': {} + + '@pixi/filter-blur@7.4.2(@pixi/core@7.4.2)': + dependencies: + '@pixi/core': 7.4.2 + + '@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.2)': + dependencies: + '@pixi/core': 7.4.2 + + '@pixi/filter-color-matrix@7.4.2(@pixi/core@7.4.2)': + dependencies: + '@pixi/core': 7.4.2 + + '@pixi/math@7.4.2': {} + + '@pixi/runner@7.4.2': {} + + '@pixi/settings@7.4.2': + dependencies: + '@pixi/constants': 7.4.2 + '@types/css-font-loading-module': 0.0.12 + ismobilejs: 1.1.1 + + '@pixi/sprite@7.4.2(@pixi/core@7.4.2)(@pixi/display@7.4.2(@pixi/core@7.4.2))': + dependencies: + '@pixi/core': 7.4.2 + '@pixi/display': 7.4.2(@pixi/core@7.4.2) + + '@pixi/ticker@7.4.2': + dependencies: + '@pixi/extensions': 7.4.2 + '@pixi/settings': 7.4.2 + '@pixi/utils': 7.4.2 + + '@pixi/utils@7.4.2': + dependencies: + '@pixi/color': 7.4.2 + '@pixi/constants': 7.4.2 + '@pixi/settings': 7.4.2 + '@types/earcut': 2.1.4 + earcut: 2.2.4 + eventemitter3: 4.0.7 + url: 0.11.4 + + '@pkgjs/parseargs@0.11.0': optional: true - /@pkgr/core@0.1.1: - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} - engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - dev: true - - /@rollup/plugin-babel@5.3.1(@babel/core@7.24.7)(rollup@2.79.1): - resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} - engines: {node: '>= 10.0.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@types/babel__core': ^7.1.9 - rollup: ^1.20.0||^2.0.0 - peerDependenciesMeta: - '@types/babel__core': - optional: true - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-module-imports': 7.24.7 - '@rollup/pluginutils': 3.1.0(rollup@2.79.1) - rollup: 2.79.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@rollup/plugin-node-resolve@15.2.3(rollup@2.79.1): - resolution: {integrity: sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.78.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) - '@types/resolve': 1.20.2 - deepmerge: 4.3.1 - is-builtin-module: 3.2.1 - is-module: 1.0.0 - resolve: 1.22.8 - rollup: 2.79.1 - dev: true - - /@rollup/plugin-replace@2.4.2(rollup@2.79.1): - resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} - peerDependencies: - rollup: ^1.20.0 || ^2.0.0 - dependencies: - '@rollup/pluginutils': 3.1.0(rollup@2.79.1) - magic-string: 0.25.9 - rollup: 2.79.1 - dev: true - - /@rollup/plugin-terser@0.4.4(rollup@2.79.1): - resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - rollup: 2.79.1 - serialize-javascript: 6.0.2 - smob: 1.5.0 - terser: 5.31.1 - dev: true - - /@rollup/pluginutils@3.1.0(rollup@2.79.1): - resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} - engines: {node: '>= 8.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0 - dependencies: - '@types/estree': 0.0.39 - estree-walker: 1.0.1 - picomatch: 2.3.1 - rollup: 2.79.1 - dev: true - - /@rollup/pluginutils@5.1.0(rollup@2.79.1): - 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/pluginutils@5.1.0(rollup@4.21.2)': dependencies: '@types/estree': 1.0.5 estree-walker: 2.0.2 picomatch: 2.3.1 - rollup: 2.79.1 - dev: true + optionalDependencies: + rollup: 4.21.2 - /@rollup/rollup-android-arm-eabi@4.18.0: - resolution: {integrity: sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true + '@rollup/rollup-android-arm-eabi@4.21.2': optional: true - /@rollup/rollup-android-arm64@4.18.0: - resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==} - cpu: [arm64] - os: [android] - requiresBuild: true - dev: true + '@rollup/rollup-android-arm64@4.21.2': optional: true - /@rollup/rollup-darwin-arm64@4.18.0: - resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true + '@rollup/rollup-darwin-arm64@4.21.2': optional: true - /@rollup/rollup-darwin-x64@4.18.0: - resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true + '@rollup/rollup-darwin-x64@4.21.2': optional: true - /@rollup/rollup-linux-arm-gnueabihf@4.18.0: - resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==} - cpu: [arm] - os: [linux] - libc: [glibc] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm-gnueabihf@4.21.2': optional: true - /@rollup/rollup-linux-arm-musleabihf@4.18.0: - resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==} - cpu: [arm] - os: [linux] - libc: [musl] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm-musleabihf@4.21.2': optional: true - /@rollup/rollup-linux-arm64-gnu@4.18.0: - resolution: {integrity: sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==} - cpu: [arm64] - os: [linux] - libc: [glibc] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm64-gnu@4.21.2': optional: true - /@rollup/rollup-linux-arm64-musl@4.18.0: - resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==} - cpu: [arm64] - os: [linux] - libc: [musl] - requiresBuild: true - dev: true + '@rollup/rollup-linux-arm64-musl@4.21.2': optional: true - /@rollup/rollup-linux-powerpc64le-gnu@4.18.0: - resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - requiresBuild: true - dev: true + '@rollup/rollup-linux-powerpc64le-gnu@4.21.2': optional: true - /@rollup/rollup-linux-riscv64-gnu@4.18.0: - resolution: {integrity: sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - requiresBuild: true - dev: true + '@rollup/rollup-linux-riscv64-gnu@4.21.2': optional: true - /@rollup/rollup-linux-s390x-gnu@4.18.0: - resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==} - cpu: [s390x] - os: [linux] - libc: [glibc] - requiresBuild: true - dev: true + '@rollup/rollup-linux-s390x-gnu@4.21.2': optional: true - /@rollup/rollup-linux-x64-gnu@4.18.0: - resolution: {integrity: sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==} - cpu: [x64] - os: [linux] - libc: [glibc] - requiresBuild: true - dev: true + '@rollup/rollup-linux-x64-gnu@4.21.2': optional: true - /@rollup/rollup-linux-x64-musl@4.18.0: - resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==} - cpu: [x64] - os: [linux] - libc: [musl] - requiresBuild: true - dev: true + '@rollup/rollup-linux-x64-musl@4.21.2': optional: true - /@rollup/rollup-win32-arm64-msvc@4.18.0: - resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-arm64-msvc@4.21.2': optional: true - /@rollup/rollup-win32-ia32-msvc@4.18.0: - resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==} - cpu: [ia32] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-ia32-msvc@4.21.2': optional: true - /@rollup/rollup-win32-x64-msvc@4.18.0: - resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true + '@rollup/rollup-win32-x64-msvc@4.21.2': optional: true - /@rushstack/eslint-patch@1.10.3: - resolution: {integrity: sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==} - dev: true + '@sindresorhus/is@4.6.0': {} - /@sindresorhus/is@4.6.0: - resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} - engines: {node: '>=10'} - - /@surma/rollup-plugin-off-main-thread@2.2.3: - resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} - dependencies: - ejs: 3.1.10 - json5: 2.2.3 - magic-string: 0.25.9 - string.prototype.matchall: 4.0.11 - dev: true - - /@szmarczak/http-timer@4.0.6: - resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} - engines: {node: '>=10'} + '@szmarczak/http-timer@4.0.6': dependencies: defer-to-connect: 2.0.1 - /@tokenizer/token@0.3.0: - resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} - dev: false + '@tokenizer/token@0.3.0': {} - /@tootallnate/once@2.0.0: - resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} - engines: {node: '>= 10'} - dev: true + '@tootallnate/once@2.0.0': {} - /@tootallnate/quickjs-emscripten@0.23.0: - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - dev: false + '@tootallnate/quickjs-emscripten@0.23.0': {} - /@types/cacheable-request@6.0.3: - resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 18.19.37 + '@types/node': 22.5.4 '@types/responselike': 1.0.3 - /@types/debug@4.1.12: - resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/css-font-loading-module@0.0.12': {} + + '@types/debug@4.1.12': dependencies: '@types/ms': 0.7.34 - dev: true - /@types/estree@0.0.39: - resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} - dev: true + '@types/earcut@2.1.4': {} - /@types/estree@1.0.5: - resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: true + '@types/estree@1.0.5': {} - /@types/fs-extra@9.0.13: - resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} + '@types/file-saver@2.0.7': {} + + '@types/fs-extra@9.0.13': dependencies: - '@types/node': 20.14.6 - dev: true + '@types/node': 22.5.4 - /@types/http-cache-semantics@4.0.4: - resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + '@types/howler@2.2.11': {} - /@types/katex@0.16.7: - resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} - dev: true + '@types/http-cache-semantics@4.0.4': {} - /@types/keyv@3.1.4: - resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + '@types/js-cookie@3.0.6': {} + + '@types/katex@0.16.7': {} + + '@types/keyv@3.1.4': dependencies: - '@types/node': 18.19.37 + '@types/node': 22.5.4 - /@types/lodash-es@4.17.12: - resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + '@types/lodash-es@4.17.12': dependencies: - '@types/lodash': 4.17.5 - dev: true + '@types/lodash': 4.17.7 - /@types/lodash@4.17.5: - resolution: {integrity: sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw==} - dev: true + '@types/lodash@4.17.7': {} - /@types/ms@0.7.34: - resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - dev: true + '@types/ms@0.7.34': {} - /@types/node@18.19.37: - resolution: {integrity: sha512-Pi53fdVMk7Ig5IfAMltQQMgtY7xLzHaEous8IQasYsdQbYK3v90FkxI3XYQCe/Qme58pqp14lXJIsFmGP8VoZQ==} + '@types/node@18.19.50': dependencies: undici-types: 5.26.5 - /@types/node@20.14.6: - resolution: {integrity: sha512-JbA0XIJPL1IiNnU7PFxDXyfAwcwVVrOoqyzzyQTyMeVhBzkJVMSkC1LlVsRQ2lpqiY4n6Bb9oCS6lzDKVQxbZw==} + '@types/node@22.5.4': dependencies: - undici-types: 5.26.5 - dev: true + undici-types: 6.19.8 - /@types/plist@3.0.5: - resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==} - requiresBuild: true + '@types/plist@3.0.5': dependencies: - '@types/node': 20.14.6 + '@types/node': 22.5.4 xmlbuilder: 15.1.1 - dev: true optional: true - /@types/resolve@1.20.2: - resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} - dev: true - - /@types/responselike@1.0.3: - resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + '@types/responselike@1.0.3': dependencies: - '@types/node': 18.19.37 + '@types/node': 22.5.4 - /@types/trusted-types@2.0.7: - resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} - dev: true - - /@types/verror@1.10.10: - resolution: {integrity: sha512-l4MM0Jppn18hb9xmM6wwD1uTdShpf9Pn80aXTStnK1C94gtPvJcV2FrDmbOQUAQfJ1cKZHktkQUDwEqaAKXMMg==} - requiresBuild: true - dev: true + '@types/verror@1.10.10': optional: true - /@types/yauzl@2.10.3: - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - requiresBuild: true + '@types/web-bluetooth@0.0.20': {} + + '@types/yauzl@2.10.3': dependencies: - '@types/node': 18.19.37 + '@types/node': 22.5.4 optional: true - /@ungap/structured-clone@1.2.0: - resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} - dev: true - - /@vitejs/plugin-vue@5.0.5(vite@5.3.1)(vue@3.4.8): - resolution: {integrity: sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==} - engines: {node: ^18.0.0 || >=20.0.0} - peerDependencies: - vite: ^5.0.0 - vue: ^3.2.25 + '@typescript-eslint/eslint-plugin@7.18.0(@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4))(eslint@8.57.0)(typescript@5.5.4)': dependencies: - vite: 5.3.1(sass@1.77.6)(terser@5.31.1) - vue: 3.4.8 - dev: true + '@eslint-community/regexpp': 4.11.0 + '@typescript-eslint/parser': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/type-utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.18.0 + eslint: 8.57.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color - /@vue/compiler-core@3.4.8: - resolution: {integrity: sha512-GjAwOydZV6UyVBi1lYW5v4jjfU6wOeyi3vBATKJOwV7muYF0/nZi4kfdJc0pwdT5lXwbbx57lyA2Y356rFpw1A==} + '@typescript-eslint/parser@7.18.0(eslint@8.57.0)(typescript@5.5.4)': dependencies: - '@babel/parser': 7.24.7 - '@vue/shared': 3.4.8 + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.7 + eslint: 8.57.0 + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + + '@typescript-eslint/type-utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + '@typescript-eslint/utils': 7.18.0(eslint@8.57.0)(typescript@5.5.4) + debug: 4.3.7 + eslint: 8.57.0 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@7.18.0': {} + + '@typescript-eslint/typescript-estree@7.18.0(typescript@5.5.4)': + dependencies: + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/visitor-keys': 7.18.0 + debug: 4.3.7 + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.5.4) + optionalDependencies: + typescript: 5.5.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@7.18.0(eslint@8.57.0)(typescript@5.5.4)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@typescript-eslint/scope-manager': 7.18.0 + '@typescript-eslint/types': 7.18.0 + '@typescript-eslint/typescript-estree': 7.18.0(typescript@5.5.4) + eslint: 8.57.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@7.18.0': + dependencies: + '@typescript-eslint/types': 7.18.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.2.0': {} + + '@vitejs/plugin-vue@5.1.3(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0))(vue@3.4.38(typescript@5.5.4))': + dependencies: + vite: 5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0) + vue: 3.4.38(typescript@5.5.4) + + '@volar/language-core@2.4.2': + dependencies: + '@volar/source-map': 2.4.2 + + '@volar/source-map@2.4.2': {} + + '@volar/typescript@2.4.2': + dependencies: + '@volar/language-core': 2.4.2 + path-browserify: 1.0.1 + vscode-uri: 3.0.8 + + '@vue/compiler-core@3.4.38': + dependencies: + '@babel/parser': 7.25.6 + '@vue/shared': 3.4.38 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.0 - /@vue/compiler-dom@3.4.8: - resolution: {integrity: sha512-GsPyji42zmkSJlaDFKXvwB97ukTlHzlFH/iVzPFYz/APnSzuhu/CMFQbsYmrtsnc2yscF39eC4rKzvKR27aBug==} + '@vue/compiler-core@3.5.3': dependencies: - '@vue/compiler-core': 3.4.8 - '@vue/shared': 3.4.8 - - /@vue/compiler-sfc@3.4.8: - resolution: {integrity: sha512-3ZcurOa6bQdZ6VZLtMqYSUZqpsMqfX0MC3oCxQG0VIJFCqouZAgRYJN1c8QvGs7HW5wW8aXVvUOQU0ILVlYHKA==} - dependencies: - '@babel/parser': 7.24.7 - '@vue/compiler-core': 3.4.8 - '@vue/compiler-dom': 3.4.8 - '@vue/compiler-ssr': 3.4.8 - '@vue/shared': 3.4.8 + '@babel/parser': 7.25.6 + '@vue/shared': 3.5.3 + entities: 4.5.0 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.8: - resolution: {integrity: sha512-nxN79LHeAemhBpIa2PQ6rz57cW7W4C/XIJCOMSn2g49u6q2ekirmJI0osAOTErQPApOR0KwP2QyeTexX4zQCrw==} + '@vue/compiler-dom@3.4.38': dependencies: - '@vue/compiler-dom': 3.4.8 - '@vue/shared': 3.4.8 + '@vue/compiler-core': 3.4.38 + '@vue/shared': 3.4.38 - /@vue/devtools-api@6.6.3: - resolution: {integrity: sha512-0MiMsFma/HqA6g3KLKn+AGpL1kgKhFWszC9U29NfpWK5LE7bjeXxySWJrOJ77hBz+TBrBQ7o4QJqbPbqbs8rJw==} - dev: false - - /@vue/eslint-config-prettier@9.0.0(eslint@8.57.0)(prettier@3.3.2): - resolution: {integrity: sha512-z1ZIAAUS9pKzo/ANEfd2sO+v2IUalz7cM/cTLOZ7vRFOPk5/xuRKQteOu1DErFLAh/lYGXMVZ0IfYKlyInuDVg==} - peerDependencies: - eslint: '>= 8.0.0' - prettier: '>= 3.0.0' + '@vue/compiler-dom@3.5.3': dependencies: - eslint: 8.57.0 - eslint-config-prettier: 9.1.0(eslint@8.57.0) - eslint-plugin-prettier: 5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.3.2) - prettier: 3.3.2 - transitivePeerDependencies: - - '@types/eslint' - dev: true + '@vue/compiler-core': 3.5.3 + '@vue/shared': 3.5.3 - /@vue/reactivity@3.4.8: - resolution: {integrity: sha512-UJYMQ3S2rqIGw9IvKomD4Xw2uS5VlcKEEmwcfboGOdrI79oqebxnCgTvXWLMClvg3M5SF0Cyn+9eDQoyGMLu9Q==} + '@vue/compiler-sfc@3.4.38': dependencies: - '@vue/shared': 3.4.8 + '@babel/parser': 7.25.6 + '@vue/compiler-core': 3.4.38 + '@vue/compiler-dom': 3.4.38 + '@vue/compiler-ssr': 3.4.38 + '@vue/shared': 3.4.38 + estree-walker: 2.0.2 + magic-string: 0.30.11 + postcss: 8.4.45 + source-map-js: 1.2.0 - /@vue/runtime-core@3.4.8: - resolution: {integrity: sha512-sMRXOy89KnwY6fWG5epgPOsCWzpo/64FrA0QkjIeNeGnoA2YyZ6bBUxpFUyqhJ8VbrDhXEFH+6LHMOYrpzX/ZQ==} + '@vue/compiler-ssr@3.4.38': dependencies: - '@vue/reactivity': 3.4.8 - '@vue/shared': 3.4.8 + '@vue/compiler-dom': 3.4.38 + '@vue/shared': 3.4.38 - /@vue/runtime-dom@3.4.8: - resolution: {integrity: sha512-L4gZcYo8f3d7rQqQIHkPvyczkjjQ55cJqz2G0v6Ptmqa1mO2zkqN9F8lBT6aGPYy3hd0RDiINbs4jxhSvvy10Q==} + '@vue/compiler-vue2@2.7.16': dependencies: - '@vue/runtime-core': 3.4.8 - '@vue/shared': 3.4.8 + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-api@6.6.3': {} + + '@vue/language-core@2.1.6(typescript@5.5.4)': + dependencies: + '@volar/language-core': 2.4.2 + '@vue/compiler-dom': 3.5.3 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.3 + computeds: 0.0.1 + minimatch: 9.0.5 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.5.4 + + '@vue/reactivity@3.4.38': + dependencies: + '@vue/shared': 3.4.38 + + '@vue/runtime-core@3.4.38': + dependencies: + '@vue/reactivity': 3.4.38 + '@vue/shared': 3.4.38 + + '@vue/runtime-dom@3.4.38': + dependencies: + '@vue/reactivity': 3.4.38 + '@vue/runtime-core': 3.4.38 + '@vue/shared': 3.4.38 csstype: 3.1.3 - /@vue/server-renderer@3.4.8(vue@3.4.8): - resolution: {integrity: sha512-pBeHM59Owevr3P0Fl1XOjBmq4DTy5JDcjMG4NuzJEVDlZYzY8fHybx0wdjkY5lK5mCtUyBtw6Mz4d87aosc1Sw==} - peerDependencies: - vue: 3.4.8 + '@vue/server-renderer@3.4.38(vue@3.4.38(typescript@5.5.4))': dependencies: - '@vue/compiler-ssr': 3.4.8 - '@vue/shared': 3.4.8 - vue: 3.4.8 + '@vue/compiler-ssr': 3.4.38 + '@vue/shared': 3.4.38 + vue: 3.4.38(typescript@5.5.4) - /@vue/shared@3.4.8: - resolution: {integrity: sha512-ChLCWzXiJboQ009oVkemhEoUdrxHme7v3ip+Kh+/kDDeF1WtHWGt0knRLGm1Y4YqCRTSs9QxsZIY8paJj5Szrw==} + '@vue/shared@3.4.38': {} - /@xmldom/xmldom@0.8.10: - resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} - engines: {node: '>=10.0.0'} - dev: true + '@vue/shared@3.5.3': {} - /NeteaseCloudMusicApi@4.20.0: - resolution: {integrity: sha512-RTGevWc9UnOGaLCIVxOPQpOBQ0ymFxfZleIqf1SOLQot3m9WO05uS/0VbEzmElDsbtRH3paJKO/Nzmxau6VV6A==} - engines: {node: '>=12'} - hasBin: true + '@vueuse/core@10.11.1(vue@3.4.38(typescript@5.5.4))': dependencies: - axios: 1.7.2 + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 10.11.1 + '@vueuse/shared': 10.11.1(vue@3.4.38(typescript@5.5.4)) + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@10.11.1': {} + + '@vueuse/shared@10.11.1(vue@3.4.38(typescript@5.5.4))': + dependencies: + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@xmldom/xmldom@0.8.10': {} + + NeteaseCloudMusicApi@4.22.0: + dependencies: + axios: 1.7.7 crypto-js: 4.2.0 express: 4.19.2 - express-fileupload: 1.5.0 + express-fileupload: 1.5.1 md5: 2.3.0 music-metadata: 7.14.0 node-forge: 1.3.1 - pac-proxy-agent: 7.0.1 - qrcode: 1.5.3 + pac-proxy-agent: 7.0.2 + qrcode: 1.5.4 safe-decode-uri-component: 1.2.1 tunnel: 0.0.6 xml2js: 0.6.2 @@ -2591,128 +4751,84 @@ packages: transitivePeerDependencies: - debug - supports-color - dev: false - /accepts@1.3.8: - resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} - engines: {node: '>= 0.6'} + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + abstract-logging@2.0.1: {} + + accepts@1.3.8: dependencies: mime-types: 2.1.35 negotiator: 0.6.3 - dev: false - /acorn-jsx@5.3.2(acorn@8.12.0): - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn-jsx@5.3.2(acorn@8.12.1): dependencies: - acorn: 8.12.0 - dev: true + acorn: 8.12.1 - /acorn@8.12.0: - resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true + acorn@8.12.1: {} - /agent-base@6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} + agent-base@6.0.2: dependencies: - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color - dev: true - /agent-base@7.1.1: - resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} - engines: {node: '>= 14'} + agent-base@7.1.1: dependencies: - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color - dev: false - /ajv-formats@2.1.1(ajv@8.16.0): - resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - dependencies: - ajv: 8.16.0 - dev: false + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 - /ajv-keywords@3.5.2(ajv@6.12.6): - resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} - peerDependencies: - ajv: ^6.9.1 + ajv-formats@3.0.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@3.5.2(ajv@6.12.6): dependencies: ajv: 6.12.6 - dev: true - /ajv@6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + 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 - /ajv@8.16.0: - resolution: {integrity: sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==} + ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 + fast-uri: 3.0.1 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - uri-js: 4.4.1 - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + ansi-regex@5.0.1: {} - /ansi-regex@6.0.1: - resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} - engines: {node: '>=12'} - dev: true + ansi-regex@6.0.1: {} - /ansi-styles@3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 - dev: true - /ansi-styles@4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 - /ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} - engines: {node: '>=12'} - dev: true + ansi-styles@6.2.1: {} - /anymatch@3.1.3: - resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} - engines: {node: '>= 8'} + anymatch@3.1.3: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true - /app-builder-bin@4.0.0: - resolution: {integrity: sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==} - dev: true + app-builder-bin@4.0.0: {} - /app-builder-lib@24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3): - resolution: {integrity: sha512-FAzX6IBit2POXYGnTCT8YHFO/lr5AapAII6zzhQO3Rw4cEDOgK+t1xhLc5tNcKlicTHlo9zxIwnYCX9X2DLkig==} - engines: {node: '>=14.0.0'} - peerDependencies: - dmg-builder: 24.13.3 - electron-builder-squirrel-windows: 24.13.3 + app-builder-lib@24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)): dependencies: '@develar/schema-utils': 2.6.5 '@electron/notarize': 2.2.1 @@ -2725,7 +4841,7 @@ packages: builder-util: 24.13.1 builder-util-runtime: 9.2.4 chromium-pickle-js: 0.2.0 - debug: 4.3.5 + debug: 4.3.7 dmg-builder: 24.13.3(electron-builder-squirrel-windows@24.13.3) ejs: 3.1.10 electron-builder-squirrel-windows: 24.13.3(dmg-builder@24.13.3) @@ -2740,16 +4856,13 @@ packages: minimatch: 5.1.6 read-config-file: 6.3.2 sanitize-filename: 1.6.3 - semver: 7.6.2 + semver: 7.6.3 tar: 6.2.1 temp-file: 3.4.0 transitivePeerDependencies: - supports-color - dev: true - /archiver-utils@2.1.0: - resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} - engines: {node: '>= 6'} + archiver-utils@2.1.0: dependencies: glob: 7.2.3 graceful-fs: 4.2.11 @@ -2761,11 +4874,8 @@ packages: lodash.union: 4.6.0 normalize-path: 3.0.0 readable-stream: 2.3.8 - dev: true - /archiver-utils@3.0.4: - resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} - engines: {node: '>= 10'} + archiver-utils@3.0.4: dependencies: glob: 7.2.3 graceful-fs: 4.2.11 @@ -2777,206 +4887,94 @@ packages: lodash.union: 4.6.0 normalize-path: 3.0.0 readable-stream: 3.6.2 - dev: true - /archiver@5.3.2: - resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} - engines: {node: '>= 10'} + archiver@5.3.2: dependencies: archiver-utils: 2.1.0 - async: 3.2.5 + async: 3.2.6 buffer-crc32: 0.2.13 readable-stream: 3.6.2 readdir-glob: 1.1.3 tar-stream: 2.2.0 zip-stream: 4.1.1 - dev: true - /argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + argparse@2.0.1: {} - /array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - is-array-buffer: 3.0.4 - dev: true + array-flatten@1.1.1: {} - /array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - dev: false + array-union@2.1.0: {} - /arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} - engines: {node: '>= 0.4'} - 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 - dev: true - - /asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + asn1@0.2.6: dependencies: safer-buffer: 2.1.2 - dev: false - /assert-plus@1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} + assert-plus@1.0.0: {} - /ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} + ast-types@0.13.4: dependencies: - tslib: 2.6.3 - dev: false + tslib: 2.7.0 - /astral-regex@2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - requiresBuild: true - dev: true + astral-regex@2.0.0: optional: true - /async-exit-hook@2.0.1: - resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} - engines: {node: '>=0.12.0'} - dev: true + async-exit-hook@2.0.1: {} - /async-validator@4.2.5: - resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} - dev: true + async-validator@4.2.5: {} - /async@3.2.5: - resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} - dev: true + async@3.2.6: {} - /asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + asynckit@0.4.0: {} - /at-least-node@1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - dev: true + at-least-node@1.0.0: {} - /atomically@1.7.0: - resolution: {integrity: sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==} - engines: {node: '>=10.12.0'} - dev: false + atomic-sleep@1.0.0: {} - /available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + atomically@1.7.0: {} + + avvio@8.4.0: dependencies: - possible-typed-array-names: 1.0.0 - dev: true + '@fastify/error': 3.4.1 + fastq: 1.17.1 - /aws-sign2@0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - dev: false + aws-sign2@0.7.0: {} - /aws4@1.13.0: - resolution: {integrity: sha512-3AungXC4I8kKsS9PuS4JH2nc+0bVY/mjgrephHTIi8fpEeGsTHBUJeosp0Wc1myYMElmD0B3Oc4XL/HVJ4PV2g==} - dev: false + aws4@1.13.2: {} - /axios@1.7.2: - resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==} + axios@1.7.7: dependencies: - follow-redirects: 1.15.6 + follow-redirects: 1.15.8 form-data: 4.0.0 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug - dev: false - /babel-plugin-polyfill-corejs2@0.4.11(@babel/core@7.24.7): - resolution: {integrity: sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/compat-data': 7.24.7 - '@babel/core': 7.24.7 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - dev: true + balanced-match@1.0.2: {} - /babel-plugin-polyfill-corejs3@0.10.4(@babel/core@7.24.7): - resolution: {integrity: sha512-25J6I8NGfa5YkCDogHRID3fVCadIR8/pGl1/spvCkzb6lVn6SR3ojpx9nOn9iEBcUsjY24AmdKm5khcfKdylcg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) - core-js-compat: 3.37.1 - transitivePeerDependencies: - - supports-color - dev: true + base64-js@1.5.1: {} - /babel-plugin-polyfill-regenerator@0.6.2(@babel/core@7.24.7): - resolution: {integrity: sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - dependencies: - '@babel/core': 7.24.7 - '@babel/helper-define-polyfill-provider': 0.6.2(@babel/core@7.24.7) - transitivePeerDependencies: - - supports-color - dev: true + basic-ftp@5.0.5: {} - /balanced-match@1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /base64-js@1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true - - /basic-ftp@5.0.5: - resolution: {integrity: sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==} - engines: {node: '>=10.0.0'} - dev: false - - /bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + bcrypt-pbkdf@1.0.2: dependencies: tweetnacl: 0.14.5 - dev: false - /binary-extensions@2.3.0: - resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} - engines: {node: '>=8'} - dev: true + bezier-easing@2.1.0: {} - /bl@4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + binary-extensions@2.3.0: {} + + bl@4.1.0: dependencies: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 - dev: true - /bluebird-lst@1.0.9: - resolution: {integrity: sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==} + bluebird-lst@1.0.9: dependencies: bluebird: 3.7.2 - dev: true - /bluebird@3.7.2: - resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} - dev: true + bluebird@3.7.2: {} - /body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + body-parser@1.20.2: dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -2992,78 +4990,63 @@ packages: unpipe: 1.0.0 transitivePeerDependencies: - supports-color - dev: false - /boolbase@1.0.0: - resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - dev: true + boolbase@1.0.0: {} - /boolean@3.2.0: - resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} - requiresBuild: true + boolean@3.2.0: optional: true - /brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - dev: true - /brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.1: dependencies: balanced-match: 1.0.2 - dev: true - /braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + braces@3.0.3: dependencies: fill-range: 7.1.1 - dev: true - /browserslist@4.23.1: - resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true + browserslist@4.23.3: dependencies: - caniuse-lite: 1.0.30001636 - electron-to-chromium: 1.4.807 - node-releases: 2.0.14 - update-browserslist-db: 1.0.16(browserslist@4.23.1) - dev: true + caniuse-lite: 1.0.30001657 + electron-to-chromium: 1.5.16 + node-releases: 2.0.18 + update-browserslist-db: 1.1.0(browserslist@4.23.3) - /buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + buffer-crc32@0.2.13: {} - /buffer-equal@1.0.1: - resolution: {integrity: sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==} - engines: {node: '>=0.4'} - dev: true + buffer-equal@1.0.1: {} - /buffer-from@1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true + buffer-from@1.1.2: {} - /buffer@5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + buffer@5.7.1: dependencies: base64-js: 1.5.1 ieee754: 1.2.1 - dev: true - /builder-util-runtime@9.2.4: - resolution: {integrity: sha512-upp+biKpN/XZMLim7aguUyW8s0FUpDvOtK6sbanMFDAMBzpHDqdhgVYm6zc9HJ6nWo7u2Lxk60i2M6Jd3aiNrA==} - engines: {node: '>=12.0.0'} + buffer@6.0.3: dependencies: - debug: 4.3.5 + base64-js: 1.5.1 + ieee754: 1.2.1 + + builder-util-runtime@9.2.4: + dependencies: + debug: 4.3.7 sax: 1.4.1 transitivePeerDependencies: - supports-color - /builder-util@24.13.1: - resolution: {integrity: sha512-NhbCSIntruNDTOVI9fdXz0dihaqX2YuE1D6zZMrwiErzH4ELZHE6mdiB40wEgZNprDia+FghRFgKoAqMZRRjSA==} + builder-util-runtime@9.2.5: + dependencies: + debug: 4.3.7 + sax: 1.4.1 + transitivePeerDependencies: + - supports-color + + builder-util@24.13.1: dependencies: 7zip-bin: 5.2.0 '@types/debug': 4.1.12 @@ -3072,7 +5055,7 @@ packages: builder-util-runtime: 9.2.4 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.5 + debug: 4.3.7 fs-extra: 10.1.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 @@ -3083,37 +5066,18 @@ packages: temp-file: 3.4.0 transitivePeerDependencies: - supports-color - dev: true - /builtin-modules@3.3.0: - resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} - engines: {node: '>=6'} - dev: true - - /busboy@1.6.0: - resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} - engines: {node: '>=10.16.0'} + busboy@1.6.0: dependencies: streamsearch: 1.1.0 - dev: false - /bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - dev: false + bytes@3.1.2: {} - /cac@6.7.14: - resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} - engines: {node: '>=8'} - dev: true + cac@6.7.14: {} - /cacheable-lookup@5.0.4: - resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} - engines: {node: '>=10.6.0'} + cacheable-lookup@5.0.4: {} - /cacheable-request@7.0.4: - resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} - engines: {node: '>=8'} + cacheable-request@7.0.4: dependencies: clone-response: 1.0.3 get-stream: 5.2.0 @@ -3123,9 +5087,7 @@ packages: normalize-url: 6.1.0 responselike: 2.0.1 - /call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} - engines: {node: '>= 0.4'} + call-bind@1.0.7: dependencies: es-define-property: 1.0.0 es-errors: 1.3.0 @@ -3133,48 +5095,30 @@ packages: get-intrinsic: 1.2.4 set-function-length: 1.2.2 - /callsites@3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true + callsites@3.1.0: {} - /camelcase@5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: false + camelcase@5.3.1: {} - /caniuse-lite@1.0.30001636: - resolution: {integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==} - dev: true + caniuse-lite@1.0.30001657: {} - /caseless@0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: false + caseless@0.12.0: {} - /chalk@2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 - dev: true - /chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 - dev: true - /charenc@0.0.2: - resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} - dev: false + change-case@5.4.4: {} - /chokidar@3.6.0: - resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} - engines: {node: '>= 8.10.0'} + charenc@0.0.2: {} + + chokidar@3.6.0: dependencies: anymatch: 3.1.3 braces: 3.0.3 @@ -3185,124 +5129,77 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.3 - dev: true - /chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - dev: true + chownr@2.0.0: {} - /chromium-pickle-js@0.2.0: - resolution: {integrity: sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==} - dev: true + chromium-pickle-js@0.2.0: {} - /ci-info@3.9.0: - resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} - engines: {node: '>=8'} - dev: true + ci-info@3.9.0: {} - /cli-truncate@2.1.0: - resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} - engines: {node: '>=8'} - requiresBuild: true + cli-truncate@2.1.0: dependencies: slice-ansi: 3.0.0 string-width: 4.2.3 - dev: true optional: true - /cliui@6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + cliui@6.0.0: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 6.2.0 - dev: false - /cliui@8.0.1: - resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} - engines: {node: '>=12'} + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - /clone-response@1.0.3: - resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + clone-response@1.0.3: dependencies: mimic-response: 1.0.1 - /color-convert@1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + color-convert@1.9.3: dependencies: color-name: 1.1.3 - dev: true - /color-convert@2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} + color-convert@2.0.1: dependencies: color-name: 1.1.4 - /color-name@1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true + color-name@1.1.3: {} - /color-name@1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + color-name@1.1.4: {} - /colorthief@2.4.0: - resolution: {integrity: sha512-0U48RGNRo5fVO+yusBwgp+d3augWSorXabnqXUu9SabEhCpCgZJEUjUTTI41OOBBYuMMxawa3177POT6qLfLeQ==} + colorthief@2.4.0: dependencies: '@lokesh.dhakar/quantize': 1.3.0 get-pixels: 3.3.3 - dev: false - /combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 - /commander@2.20.3: - resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - dev: true + commander@2.20.3: {} - /commander@5.1.0: - resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} - engines: {node: '>= 6'} - dev: true + commander@5.1.0: {} - /common-tags@1.8.2: - resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} - engines: {node: '>=4.0.0'} - dev: true + compare-version@0.1.2: {} - /compare-version@0.1.2: - resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==} - engines: {node: '>=0.10.0'} - dev: true - - /compress-commons@4.1.2: - resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} - engines: {node: '>= 10'} + compress-commons@4.1.2: dependencies: buffer-crc32: 0.2.13 crc32-stream: 4.0.3 normalize-path: 3.0.0 readable-stream: 3.6.2 - dev: true - /concat-map@0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true + computeds@0.0.1: {} - /conf@10.2.0: - resolution: {integrity: sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==} - engines: {node: '>=12'} + concat-map@0.0.1: {} + + conf@10.2.0: dependencies: - ajv: 8.16.0 - ajv-formats: 2.1.1(ajv@8.16.0) + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) atomically: 1.7.0 debounce-fn: 4.0.0 dot-prop: 6.0.1 @@ -3310,333 +5207,173 @@ packages: json-schema-typed: 7.0.3 onetime: 5.1.2 pkg-up: 3.1.0 - semver: 7.6.2 - dev: false + semver: 7.6.3 - /confbox@0.1.7: - resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} - dev: true + confbox@0.1.7: {} - /config-file-ts@0.2.6: - resolution: {integrity: sha512-6boGVaglwblBgJqGyxm4+xCmEGcWgnWHSWHY5jad58awQhB6gftq0G8HbzU39YqCIYHMLAiL1yjwiZ36m/CL8w==} + config-file-ts@0.2.6: dependencies: - glob: 10.4.2 - typescript: 5.4.5 - dev: true + glob: 10.4.5 + typescript: 5.5.4 - /content-disposition@0.5.4: - resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} - engines: {node: '>= 0.6'} + content-disposition@0.5.4: dependencies: safe-buffer: 5.2.1 - dev: false - /content-type@1.0.5: - resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} - engines: {node: '>= 0.6'} - dev: false + content-type@1.0.5: {} - /convert-source-map@2.0.0: - resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - dev: true + convert-source-map@2.0.0: {} - /cookie-signature@1.0.6: - resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} - dev: false + cookie-signature@1.0.6: {} - /cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} - engines: {node: '>= 0.6'} - dev: false + cookie-signature@1.2.1: {} - /core-js-compat@3.37.1: - resolution: {integrity: sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==} - dependencies: - browserslist: 4.23.1 - dev: true + cookie@0.6.0: {} - /core-js@3.37.1: - resolution: {integrity: sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==} - requiresBuild: true - dev: false + core-js@3.38.1: {} - /core-util-is@1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + core-util-is@1.0.2: {} - /core-util-is@1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true + core-util-is@1.0.3: {} - /crc-32@1.2.2: - resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} - engines: {node: '>=0.8'} - hasBin: true - dev: true + crc-32@1.2.2: {} - /crc32-stream@4.0.3: - resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} - engines: {node: '>= 10'} + crc32-stream@4.0.3: dependencies: crc-32: 1.2.2 readable-stream: 3.6.2 - dev: true - /crc@3.8.0: - resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} - requiresBuild: true + crc@3.8.0: dependencies: buffer: 5.7.1 - dev: true optional: true - /cross-spawn@6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} + cross-spawn@6.0.5: dependencies: nice-try: 1.0.5 path-key: 2.0.1 semver: 5.7.2 shebang-command: 1.2.0 which: 1.3.1 - dev: false - /cross-spawn@7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - dev: true - /crypt@0.0.2: - resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} - dev: false + crypt@0.0.2: {} - /crypto-js@4.2.0: - resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} - dev: false + crypto-js@4.2.0: {} - /crypto-random-string@2.0.0: - resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} - engines: {node: '>=8'} - dev: true - - /css-render@0.15.14: - resolution: {integrity: sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==} + css-render@0.15.14: dependencies: '@emotion/hash': 0.8.0 csstype: 3.0.11 - dev: true - /cssesc@3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - dev: true + css-vendor@2.0.8: + dependencies: + '@babel/runtime': 7.25.6 + is-in-browser: 1.1.3 - /csstype@3.0.11: - resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} - dev: true + cssesc@3.0.0: {} - /csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + csstype@3.0.11: {} - /custom-event-polyfill@1.0.7: - resolution: {integrity: sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==} - dev: false + csstype@3.1.3: {} - /cwise-compiler@1.1.3: - resolution: {integrity: sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==} + custom-event-polyfill@1.0.7: {} + + cwise-compiler@1.1.3: dependencies: uniq: 1.0.1 - dev: false - /dashdash@1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} + dashdash@1.14.1: dependencies: assert-plus: 1.0.0 - dev: false - /data-uri-to-buffer@0.0.3: - resolution: {integrity: sha512-Cp+jOa8QJef5nXS5hU7M1DWzXPEIoVR3kbV0dQuVGwROZg8bGf1DcCnkmajBTnvghTtSNMUdRrPjgaT6ZQucbw==} - dev: false + data-uri-to-buffer@0.0.3: {} - /data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - dev: false + data-uri-to-buffer@6.0.2: {} - /data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 - dev: true - - /data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 - dev: true - - /data-view-byte-offset@1.0.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-data-view: 1.0.1 - dev: true - - /date-fns-tz@2.0.1(date-fns@2.30.0): - resolution: {integrity: sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==} - peerDependencies: - date-fns: 2.x + date-fns-tz@2.0.1(date-fns@2.30.0): dependencies: date-fns: 2.30.0 - dev: true - /date-fns@2.30.0: - resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} - engines: {node: '>=0.11'} + date-fns@2.30.0: dependencies: - '@babel/runtime': 7.24.7 - dev: true + '@babel/runtime': 7.25.6 - /dateformat@3.0.3: - resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} - dev: false + dateformat@3.0.3: {} - /debounce-fn@4.0.0: - resolution: {integrity: sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==} - engines: {node: '>=10'} + dayjs@1.11.13: {} + + de-indent@1.0.2: {} + + debounce-fn@4.0.0: dependencies: mimic-fn: 3.1.0 - dev: false - /debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@2.6.9: dependencies: ms: 2.0.0 - dev: false - /debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + debug@4.3.7: dependencies: ms: 2.1.3 - dev: false - /debug@4.3.5: - resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 + decamelize@1.2.0: {} - /decamelize@1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - dev: false - - /decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} + decompress-response@6.0.0: dependencies: mimic-response: 3.1.0 - /deep-is@0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true + deep-is@0.1.4: {} - /deepmerge@4.3.1: - resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} - engines: {node: '>=0.10.0'} - dev: true + defer-to-connect@2.0.1: {} - /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-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: - resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} - engines: {node: '>= 0.4'} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 has-property-descriptors: 1.0.2 object-keys: 1.1.1 + optional: true - /degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} + degenerator@5.0.1: dependencies: ast-types: 0.13.4 escodegen: 2.1.0 esprima: 4.0.1 - dev: false - /delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} + delayed-stream@1.0.0: {} - /depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - dev: false + depd@2.0.0: {} - /destroy@1.2.0: - resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - dev: false + destroy@1.2.0: {} - /detect-node@2.1.0: - resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - requiresBuild: true + detect-node@2.1.0: optional: true - /dijkstrajs@1.0.3: - resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} - dev: false + dijkstrajs@1.0.3: {} - /dir-compare@3.3.0: - resolution: {integrity: sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==} + dir-compare@3.3.0: dependencies: buffer-equal: 1.0.1 minimatch: 3.1.2 - dev: true - /dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3): - resolution: {integrity: sha512-rcJUkMfnJpfCboZoOOPf4L29TRtEieHNOeAbYPWPxlaBw/Z1RKrRA86dOI9rwaI4tQSc/RD82zTNHprfUHXsoQ==} + dir-glob@3.0.1: dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3) + path-type: 4.0.0 + + dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3): + dependencies: + app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) builder-util: 24.13.1 builder-util-runtime: 9.2.4 fs-extra: 10.1.0 @@ -3647,14 +5384,8 @@ packages: transitivePeerDependencies: - electron-builder-squirrel-windows - supports-color - dev: true - /dmg-license@1.0.11: - resolution: {integrity: sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==} - engines: {node: '>=8'} - os: [darwin] - hasBin: true - requiresBuild: true + dmg-license@1.0.11: dependencies: '@types/plist': 3.0.5 '@types/verror': 1.10.10 @@ -3664,73 +5395,48 @@ packages: plist: 3.1.0 smart-buffer: 4.2.0 verror: 1.10.1 - dev: true optional: true - /doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} + doctrine@3.0.0: dependencies: esutils: 2.0.3 - dev: true - /dot-prop@6.0.1: - resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} - engines: {node: '>=10'} + dot-prop@6.0.1: dependencies: is-obj: 2.0.0 - dev: false - /dotenv-expand@5.1.0: - resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} - dev: true + dotenv-expand@5.1.0: {} - /dotenv@9.0.2: - resolution: {integrity: sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==} - engines: {node: '>=10'} - dev: true + dotenv@9.0.2: {} - /eastasianwidth@0.2.0: - resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - dev: true + earcut@2.2.4: {} - /ecc-jsbn@0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + eastasianwidth@0.2.0: {} + + ecc-jsbn@0.1.2: dependencies: jsbn: 0.1.1 safer-buffer: 2.1.2 - dev: false - /ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - dev: false + ee-first@1.1.1: {} - /ejs@3.1.10: - resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} - engines: {node: '>=0.10.0'} - hasBin: true + ejs@3.1.10: dependencies: - jake: 10.9.1 - dev: true + jake: 10.9.2 - /electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3): - resolution: {integrity: sha512-oHkV0iogWfyK+ah9ZIvMDpei1m9ZRpdXcvde1wTpra2U8AFDNNpqJdnin5z+PM1GbQ5BoaKCWas2HSjtR0HwMg==} + electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3) + app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) archiver: 5.3.2 builder-util: 24.13.1 fs-extra: 10.1.0 transitivePeerDependencies: - dmg-builder - supports-color - dev: true - /electron-builder@24.13.3(electron-builder-squirrel-windows@24.13.3): - resolution: {integrity: sha512-yZSgVHft5dNVlo31qmJAe4BVKQfFdwpRw7sFp1iQglDRCDD6r22zfRJuZlhtB5gp9FHUxCMEoWGq10SkCnMAIg==} - engines: {node: '>=14.0.0'} - hasBin: true + electron-builder@24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)): dependencies: - app-builder-lib: 24.13.3(dmg-builder@24.13.3)(electron-builder-squirrel-windows@24.13.3) + app-builder-lib: 24.13.3(dmg-builder@24.13.3(electron-builder-squirrel-windows@24.13.3))(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3)) builder-util: 24.13.1 builder-util-runtime: 9.2.4 chalk: 4.1.2 @@ -3744,24 +5450,16 @@ packages: transitivePeerDependencies: - electron-builder-squirrel-windows - supports-color - dev: true - /electron-dl@3.5.2: - resolution: {integrity: sha512-i104cl+u8yJ0lhpRAtUWfeGuWuL1PL6TBiw2gLf0MMIBjfgE485Ags2mcySx4uWU9P9uj/vsD3jd7X+w1lzZxw==} - engines: {node: '>=12'} + electron-dl@3.5.2: dependencies: ext-name: 5.0.0 pupa: 2.1.1 unused-filename: 2.1.0 - dev: false - /electron-log@5.1.5: - resolution: {integrity: sha512-vuq10faUAxRbILgQx7yHoMObKZDEfj7hMSZrJPsVrDNeCpV/HN11dU7QuY4UDUe055pzBxhSCB3m0+6D3Aktjw==} - engines: {node: '>= 14'} - dev: true + electron-log@5.2.0: {} - /electron-publish@24.13.1: - resolution: {integrity: sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==} + electron-publish@24.13.1: dependencies: '@types/fs-extra': 9.0.13 builder-util: 24.13.1 @@ -3772,233 +5470,73 @@ packages: mime: 2.6.0 transitivePeerDependencies: - supports-color - dev: true - /electron-store@8.2.0: - resolution: {integrity: sha512-ukLL5Bevdil6oieAOXz3CMy+OgaItMiVBg701MNlG6W5RaC0AHN7rvlqTCmeb6O7jP0Qa1KKYTE0xV0xbhF4Hw==} + electron-store@8.2.0: dependencies: conf: 10.2.0 type-fest: 2.19.0 - dev: false - /electron-to-chromium@1.4.807: - resolution: {integrity: sha512-kSmJl2ZwhNf/bcIuCH/imtNOKlpkLDn2jqT5FJ+/0CXjhnFaOa9cOe9gHKKy71eM49izwuQjZhKk+lWQ1JxB7A==} - dev: true + electron-to-chromium@1.5.16: {} - /electron-updater@6.2.1: - resolution: {integrity: sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==} + electron-updater@6.3.4: dependencies: - builder-util-runtime: 9.2.4 + builder-util-runtime: 9.2.5 fs-extra: 10.1.0 js-yaml: 4.1.0 lazy-val: 1.0.5 lodash.escaperegexp: 4.1.2 lodash.isequal: 4.5.0 - semver: 7.6.2 + semver: 7.6.3 tiny-typed-emitter: 2.1.0 transitivePeerDependencies: - supports-color - dev: false - /electron-vite@2.2.0(vite@5.3.1): - resolution: {integrity: sha512-WvE8KlZTiay9uWqBRvnYuxg2JqIicaNqaz9qFvsZkIae2/FmqZC5jctziyduCuuwVxqJG0Sjh8RlTwSn8xcCoQ==} - engines: {node: ^18.0.0 || >=20.0.0} - hasBin: true - peerDependencies: - '@swc/core': ^1.0.0 - vite: ^4.0.0 || ^5.0.0 - peerDependenciesMeta: - '@swc/core': - optional: true + electron-vite@2.3.0(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0)): dependencies: - '@babel/core': 7.24.7 - '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.24.7) + '@babel/core': 7.25.2 + '@babel/plugin-transform-arrow-functions': 7.24.7(@babel/core@7.25.2) cac: 6.7.14 - esbuild: 0.19.12 - magic-string: 0.30.10 - picocolors: 1.0.1 - vite: 5.3.1(sass@1.77.6)(terser@5.31.1) + esbuild: 0.21.5 + magic-string: 0.30.11 + picocolors: 1.1.0 + vite: 5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0) transitivePeerDependencies: - supports-color - dev: true - /electron@28.3.3: - resolution: {integrity: sha512-ObKMLSPNhomtCOBAxFS8P2DW/4umkh72ouZUlUKzXGtYuPzgr1SYhskhFWgzAsPtUzhL2CzyV2sfbHcEW4CXqw==} - engines: {node: '>= 12.20.55'} - hasBin: true - requiresBuild: true + electron@28.3.3: dependencies: '@electron/get': 2.0.3 - '@types/node': 18.19.37 + '@types/node': 18.19.50 extract-zip: 2.0.1 transitivePeerDependencies: - supports-color - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + emoji-regex@8.0.0: {} - /emoji-regex@9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true + emoji-regex@9.2.2: {} - /encode-utf8@1.0.3: - resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} - dev: false + encodeurl@1.0.2: {} - /encodeurl@1.0.2: - resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} - engines: {node: '>= 0.8'} - dev: false - - /end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + end-of-stream@1.4.4: dependencies: once: 1.4.0 - /entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} + entities@4.5.0: {} - /env-paths@2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} + env-paths@2.2.1: {} - /err-code@2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - dev: true + err-code@2.0.3: {} - /es-abstract@1.23.3: - resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} - engines: {node: '>= 0.4'} - 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 - dev: true - - /es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} + es-define-property@1.0.0: dependencies: get-intrinsic: 1.2.4 - /es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + es-errors@1.3.0: {} - /es-object-atoms@1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - dev: true - - /es-set-tostringtag@2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.4 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - dev: true - - /es-to-primitive@1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 - dev: true - - /es6-error@4.1.1: - resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} - requiresBuild: true + es6-error@4.1.1: optional: true - /es6-promise@4.2.8: - resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} - dev: false - - /esbuild@0.19.12: - resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - optionalDependencies: - '@esbuild/aix-ppc64': 0.19.12 - '@esbuild/android-arm': 0.19.12 - '@esbuild/android-arm64': 0.19.12 - '@esbuild/android-x64': 0.19.12 - '@esbuild/darwin-arm64': 0.19.12 - '@esbuild/darwin-x64': 0.19.12 - '@esbuild/freebsd-arm64': 0.19.12 - '@esbuild/freebsd-x64': 0.19.12 - '@esbuild/linux-arm': 0.19.12 - '@esbuild/linux-arm64': 0.19.12 - '@esbuild/linux-ia32': 0.19.12 - '@esbuild/linux-loong64': 0.19.12 - '@esbuild/linux-mips64el': 0.19.12 - '@esbuild/linux-ppc64': 0.19.12 - '@esbuild/linux-riscv64': 0.19.12 - '@esbuild/linux-s390x': 0.19.12 - '@esbuild/linux-x64': 0.19.12 - '@esbuild/netbsd-x64': 0.19.12 - '@esbuild/openbsd-x64': 0.19.12 - '@esbuild/sunos-x64': 0.19.12 - '@esbuild/win32-arm64': 0.19.12 - '@esbuild/win32-ia32': 0.19.12 - '@esbuild/win32-x64': 0.19.12 - dev: true - - /esbuild@0.21.5: - resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 '@esbuild/android-arm': 0.21.5 @@ -4023,116 +5561,52 @@ packages: '@esbuild/win32-arm64': 0.21.5 '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 - dev: true - /escalade@3.1.2: - resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} - engines: {node: '>=6'} + escalade@3.2.0: {} - /escape-goat@2.1.1: - resolution: {integrity: sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==} - engines: {node: '>=8'} - dev: false + escape-goat@2.1.1: {} - /escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - dev: false + escape-html@1.0.3: {} - /escape-string-regexp@1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true + escape-string-regexp@1.0.5: {} - /escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} + escape-string-regexp@4.0.0: {} - /escape-string-regexp@5.0.0: - resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} - engines: {node: '>=12'} - dev: true + escape-string-regexp@5.0.0: {} - /escodegen@2.1.0: - resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} - engines: {node: '>=6.0'} - hasBin: true + escodegen@2.1.0: dependencies: esprima: 4.0.1 estraverse: 5.3.0 esutils: 2.0.3 optionalDependencies: source-map: 0.6.1 - dev: false - /eslint-config-prettier@9.1.0(eslint@8.57.0): - resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 8.57.0 - dev: true - - /eslint-plugin-prettier@5.1.3(eslint-config-prettier@9.1.0)(eslint@8.57.0)(prettier@3.3.2): - 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 - dependencies: - eslint: 8.57.0 - eslint-config-prettier: 9.1.0(eslint@8.57.0) - prettier: 3.3.2 - prettier-linter-helpers: 1.0.0 - synckit: 0.8.8 - dev: true - - /eslint-plugin-vue@9.26.0(eslint@8.57.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-plugin-vue@9.28.0(eslint@8.57.0): dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) eslint: 8.57.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 + postcss-selector-parser: 6.1.2 + semver: 7.6.3 vue-eslint-parser: 9.4.3(eslint@8.57.0) xml-name-validator: 4.0.0 transitivePeerDependencies: - supports-color - dev: true - /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@7.2.2: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 - dev: true - /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} - dev: true + eslint-visitor-keys@3.4.3: {} - /eslint@8.57.0: - resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true + eslint@8.57.0: dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.10.1 + '@eslint-community/regexpp': 4.11.0 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 @@ -4142,13 +5616,13 @@ packages: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.5 + debug: 4.3.7 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.5.0 + esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 file-entry-cache: 6.0.1 @@ -4156,7 +5630,7 @@ packages: glob-parent: 6.0.2 globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.3.1 + ignore: 5.3.2 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -4171,70 +5645,44 @@ packages: text-table: 0.2.0 transitivePeerDependencies: - supports-color - dev: true - /espree@9.6.1: - resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + espree@9.6.1: dependencies: - acorn: 8.12.0 - acorn-jsx: 5.3.2(acorn@8.12.0) + acorn: 8.12.1 + acorn-jsx: 5.3.2(acorn@8.12.1) eslint-visitor-keys: 3.4.3 - dev: true - /esprima@4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: false + esprima@4.0.1: {} - /esquery@1.5.0: - resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} - engines: {node: '>=0.10'} + esquery@1.6.0: dependencies: estraverse: 5.3.0 - dev: true - /esrecurse@4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} + esrecurse@4.3.0: dependencies: estraverse: 5.3.0 - dev: true - /estraverse@5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} + estraverse@5.3.0: {} - /estree-walker@1.0.1: - resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} - dev: true + estree-walker@2.0.2: {} - /estree-walker@2.0.2: - resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} - - /estree-walker@3.0.3: - resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.5 - dev: true - /esutils@2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} + esutils@2.0.3: {} - /etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - dev: false + etag@1.8.1: {} - /evtd@0.2.4: - resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} - dev: true + event-target-shim@5.0.1: {} - /execa@1.0.0: - resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} - engines: {node: '>=6'} + eventemitter3@4.0.7: {} + + events@3.3.0: {} + + evtd@0.2.4: {} + + execa@1.0.0: dependencies: cross-spawn: 6.0.5 get-stream: 4.1.0 @@ -4243,29 +5691,12 @@ packages: p-finally: 1.0.0 signal-exit: 3.0.7 strip-eof: 1.0.0 - dev: false - /express-fileupload@1.5.0: - resolution: {integrity: sha512-jSW3w9evqM37VWkEPkL2Ck5wUo2a8qa03MH+Ou/0ZSTpNlQFBvSLjU12k2nYcHhaMPv4JVvv6+Ac1OuLgUZb7w==} - engines: {node: '>=12.0.0'} + express-fileupload@1.5.1: dependencies: busboy: 1.6.0 - dev: false - /express-http-proxy@2.0.0: - resolution: {integrity: sha512-TXxcPFTWVUMSEmyM6iX2sT/JtmqhqngTq29P+eXTVFdtxZrTmM8THUYK59rUXiln0FfPGvxEpGRnVrgvHksXDw==} - engines: {node: '>=6.0.0'} - dependencies: - debug: 3.2.7 - es6-promise: 4.2.8 - raw-body: 2.5.2 - transitivePeerDependencies: - - supports-color - dev: false - - /express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} - engines: {node: '>= 0.10.0'} + express@4.19.2: dependencies: accepts: 1.3.8 array-flatten: 1.1.1 @@ -4300,33 +5731,21 @@ packages: vary: 1.1.2 transitivePeerDependencies: - supports-color - dev: false - /ext-list@2.2.2: - resolution: {integrity: sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==} - engines: {node: '>=0.10.0'} + ext-list@2.2.2: dependencies: mime-db: 1.52.0 - dev: false - /ext-name@5.0.0: - resolution: {integrity: sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==} - engines: {node: '>=4'} + ext-name@5.0.0: dependencies: ext-list: 2.2.2 sort-keys-length: 1.0.1 - dev: false - /extend@3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: false + extend@3.0.2: {} - /extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true + extract-zip@2.0.1: dependencies: - debug: 4.3.5 + debug: 4.3.7 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -4334,86 +5753,98 @@ packages: transitivePeerDependencies: - supports-color - /extsprintf@1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - dev: false + extsprintf@1.3.0: {} - /extsprintf@1.4.1: - resolution: {integrity: sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==} - engines: {'0': node >=0.6.0} - requiresBuild: true - dev: true - optional: true + extsprintf@1.4.1: {} - /fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-content-type-parse@1.1.0: {} - /fast-diff@1.3.0: - resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} - dev: true + fast-decode-uri-component@1.0.1: {} - /fast-glob@3.3.2: - resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} - engines: {node: '>=8.6.0'} + fast-deep-equal@3.1.3: {} + + 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 - dev: true + micromatch: 4.0.8 - /fast-json-stable-stringify@2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-json-stable-stringify@2.1.0: {} - /fast-levenshtein@2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true + fast-json-stringify@5.16.1: + dependencies: + '@fastify/merge-json-schemas': 0.1.1 + ajv: 8.17.1 + ajv-formats: 3.0.1(ajv@8.17.1) + fast-deep-equal: 3.1.3 + fast-uri: 2.4.0 + json-schema-ref-resolver: 1.0.1 + rfdc: 1.4.1 - /fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fast-levenshtein@2.0.6: {} + + fast-querystring@1.1.2: + dependencies: + fast-decode-uri-component: 1.0.1 + + fast-redact@3.5.0: {} + + fast-uri@2.4.0: {} + + fast-uri@3.0.1: {} + + fastify-plugin@4.5.1: {} + + fastify@4.28.1: + dependencies: + '@fastify/ajv-compiler': 3.6.0 + '@fastify/error': 3.4.1 + '@fastify/fast-json-stringify-compiler': 4.3.0 + abstract-logging: 2.0.1 + avvio: 8.4.0 + fast-content-type-parse: 1.1.0 + fast-json-stringify: 5.16.1 + find-my-way: 8.2.0 + light-my-request: 5.13.0 + pino: 9.4.0 + process-warning: 3.0.0 + proxy-addr: 2.0.7 + rfdc: 1.4.1 + secure-json-parse: 2.7.0 + semver: 7.6.3 + toad-cache: 3.7.0 + + fastq@1.17.1: dependencies: reusify: 1.0.4 - dev: true - /fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + fd-slicer@1.1.0: dependencies: pend: 1.2.0 - /file-entry-cache@6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} + file-entry-cache@6.0.1: dependencies: flat-cache: 3.2.0 - dev: true - /file-type@16.5.4: - resolution: {integrity: sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw==} - engines: {node: '>=10'} + file-saver@2.0.5: {} + + file-type@16.5.4: dependencies: readable-web-to-node-stream: 3.0.2 strtok3: 6.3.0 token-types: 4.2.1 - dev: false - /filelist@1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filelist@1.0.4: dependencies: minimatch: 5.1.6 - dev: true - /fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - dev: true - /finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} + finalhandler@1.2.0: dependencies: debug: 2.6.9 encodeurl: 1.0.2 @@ -4424,190 +5855,105 @@ packages: unpipe: 1.0.0 transitivePeerDependencies: - supports-color - dev: false - /find-up@3.0.0: - resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} - engines: {node: '>=6'} + find-my-way@8.2.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-querystring: 1.1.2 + safe-regex2: 3.1.0 + + find-up@3.0.0: dependencies: locate-path: 3.0.0 - dev: false - /find-up@4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} + find-up@4.1.0: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - dev: false - /find-up@5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} + find-up@5.0.0: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true - /flat-cache@3.2.0: - resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} - engines: {node: ^10.12.0 || >=12.0.0} + flat-cache@3.2.0: dependencies: flatted: 3.3.1 keyv: 4.5.4 rimraf: 3.0.2 - dev: true - /flatted@3.3.1: - resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} - dev: true + flatted@3.3.1: {} - /follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false + follow-redirects@1.15.8: {} - /font-list@1.5.1: - resolution: {integrity: sha512-Hr5V0dsSv91wH3FgirXd7qh1PydqA/vMQyWjFFWn+lUPJtC+3i2tzgVqbLRcvQh87TGdbTGbAR3mEo4VlwC1jw==} - dev: false + font-list@1.5.1: {} - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 - dev: true - - /foreground-child@3.2.1: - resolution: {integrity: sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==} - engines: {node: '>=14'} + foreground-child@3.3.0: dependencies: cross-spawn: 7.0.3 signal-exit: 4.1.0 - dev: true - /forever-agent@0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - dev: false + forever-agent@0.6.1: {} - /form-data@2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: false - - /form-data@4.0.0: - resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} - engines: {node: '>= 6'} + form-data@2.3.3: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 mime-types: 2.1.35 - /forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - dev: false + form-data@4.0.0: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 - /fresh@0.5.2: - resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} - engines: {node: '>= 0.6'} - dev: false + forwarded@0.2.0: {} - /fs-constants@1.0.0: - resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: true + fresh@0.5.2: {} - /fs-extra@10.1.0: - resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} - engines: {node: '>=12'} + fs-constants@1.0.0: {} + + fs-extra@10.1.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.1 - /fs-extra@11.2.0: - resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} - engines: {node: '>=14.14'} + fs-extra@11.2.0: dependencies: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.1 - dev: false - /fs-extra@8.1.0: - resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} - engines: {node: '>=6 <7 || >=8'} + fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 jsonfile: 4.0.0 universalify: 0.1.2 - /fs-extra@9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} + fs-extra@9.1.0: dependencies: at-least-node: 1.0.0 graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.1 - dev: true - /fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} + fs-minipass@2.1.0: dependencies: minipass: 3.3.6 - dev: true - /fs.realpath@1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true + fs.realpath@1.0.0: {} - /fsevents@2.3.3: - resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - requiresBuild: true - dev: true + fsevents@2.3.3: optional: true - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function-bind@1.1.2: {} - /function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - functions-have-names: 1.2.3 - dev: true + gensync@1.0.0-beta.2: {} - /functions-have-names@1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true + get-caller-file@2.0.5: {} - /gensync@1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - - /get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 @@ -4615,12 +5961,7 @@ packages: has-symbols: 1.0.3 hasown: 2.0.2 - /get-own-enumerable-property-symbols@3.0.2: - resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} - dev: true - - /get-pixels@3.3.3: - resolution: {integrity: sha512-5kyGBn90i9tSMUVHTqkgCHsoWoR+/lGbl4yC83Gefyr0HLIhgSWEx/2F/3YgsZ7UpYNuM6pDhDK7zebrUJ5nXg==} + get-pixels@3.3.3: dependencies: data-uri-to-buffer: 0.0.3 jpeg-js: 0.4.4 @@ -4633,78 +5974,46 @@ packages: pngjs: 3.4.0 request: 2.88.2 through: 2.3.8 - dev: false - /get-stream@4.1.0: - resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} - engines: {node: '>=6'} - dependencies: - pump: 3.0.0 - dev: false - - /get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} + get-stream@4.1.0: dependencies: pump: 3.0.0 - /get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} - engines: {node: '>= 0.4'} + get-stream@5.2.0: dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - get-intrinsic: 1.2.4 - dev: true + pump: 3.0.0 - /get-uri@6.0.3: - resolution: {integrity: sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==} - engines: {node: '>= 14'} + get-uri@6.0.3: dependencies: basic-ftp: 5.0.5 data-uri-to-buffer: 6.0.2 - debug: 4.3.5 + debug: 4.3.7 fs-extra: 11.2.0 transitivePeerDependencies: - supports-color - dev: false - /getpass@0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + getpass@0.1.7: dependencies: assert-plus: 1.0.0 - dev: false - /glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 - dev: true - /glob-parent@6.0.2: - resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} - engines: {node: '>=10.13.0'} + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 - dev: true - /glob@10.4.2: - resolution: {integrity: sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==} - engines: {node: '>=16 || 14 >=14.18'} - hasBin: true + glob@10.4.5: dependencies: - foreground-child: 3.2.1 - jackspeak: 3.4.0 - minimatch: 9.0.4 + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 minipass: 7.1.2 package-json-from-dist: 1.0.0 path-scurry: 1.11.1 - dev: true - /glob@7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + glob@7.2.3: dependencies: fs.realpath: 1.0.0 inflight: 1.0.6 @@ -4712,48 +6021,43 @@ packages: minimatch: 3.1.2 once: 1.4.0 path-is-absolute: 1.0.1 - dev: true - /global-agent@3.0.0: - resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} - engines: {node: '>=10.0'} - requiresBuild: true + global-agent@3.0.0: dependencies: boolean: 3.2.0 es6-error: 4.1.1 matcher: 3.0.0 roarr: 2.15.4 - semver: 7.6.2 + semver: 7.6.3 serialize-error: 7.0.1 optional: true - /globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true + globals@11.12.0: {} - /globals@13.24.0: - resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} - engines: {node: '>=8'} + globals@13.24.0: dependencies: type-fest: 0.20.2 - dev: true - /globalthis@1.0.4: - resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} - engines: {node: '>= 0.4'} + globalthis@1.0.4: dependencies: define-properties: 1.2.1 gopd: 1.0.1 + optional: true - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: dependencies: get-intrinsic: 1.2.4 - /got@11.8.6: - resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} - engines: {node: '>=10.19.0'} + got@11.8.6: dependencies: '@sindresorhus/is': 4.6.0 '@szmarczak/http-timer': 4.0.6 @@ -4767,965 +6071,559 @@ packages: p-cancelable: 2.1.1 responselike: 2.0.1 - /graceful-fs@4.2.11: - resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + graceful-fs@4.2.11: {} - /graphemer@1.4.0: - resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - dev: true + graphemer@1.4.0: {} - /har-schema@2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - dev: false + har-schema@2.0.0: {} - /har-validator@5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported + har-validator@5.1.5: dependencies: ajv: 6.12.6 har-schema: 2.0.0 - dev: false - /has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true + has-flag@3.0.0: {} - /has-flag@3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true + has-flag@4.0.0: {} - /has-flag@4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.0 - /has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} + has-proto@1.0.3: {} - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} + has-symbols@1.0.3: {} - /has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} + hasown@2.0.2: dependencies: function-bind: 1.1.2 - /highlight.js@11.9.0: - resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==} - engines: {node: '>=12.0.0'} - dev: true + he@1.2.0: {} - /hosted-git-info@4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} + highlight.js@11.10.0: {} + + hosted-git-info@4.1.0: dependencies: lru-cache: 6.0.0 - dev: true - /howler@2.2.4: - resolution: {integrity: sha512-iARIBPgcQrwtEr+tALF+rapJ8qSc+Set2GJQl7xT1MQzWaVkFebdJhR3alVlSiUf5U7nAANKuj3aWpwerocD5w==} - dev: false + howler@2.2.4: {} - /http-cache-semantics@4.1.1: - resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + http-cache-semantics@4.1.1: {} - /http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} + http-errors@2.0.0: dependencies: depd: 2.0.0 inherits: 2.0.4 setprototypeof: 1.2.0 statuses: 2.0.1 toidentifier: 1.0.1 - dev: false - /http-proxy-agent@5.0.0: - resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} - engines: {node: '>= 6'} + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color - dev: true - /http-proxy-agent@7.0.2: - resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} - engines: {node: '>= 14'} + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.1 - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color - dev: false - /http-signature@1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} + http-signature@1.2.0: dependencies: assert-plus: 1.0.0 jsprim: 1.4.2 sshpk: 1.18.0 - dev: false - /http2-wrapper@1.0.3: - resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} - engines: {node: '>=10.19.0'} + http2-wrapper@1.0.3: dependencies: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - /https-proxy-agent@5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} + https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color - dev: true - /https-proxy-agent@7.0.4: - resolution: {integrity: sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==} - engines: {node: '>= 14'} + https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.1 - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color - dev: false - /iconv-corefoundation@1.1.7: - resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==} - engines: {node: ^8.11.2 || >=10} - os: [darwin] - requiresBuild: true + hyphenate-style-name@1.1.0: {} + + iconv-corefoundation@1.1.7: dependencies: cli-truncate: 2.1.0 node-addon-api: 1.7.2 - dev: true optional: true - /iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: false - - /iconv-lite@0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 - /idb@7.1.1: - resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} - dev: true + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 - /ieee754@1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + ieee754@1.2.1: {} - /ignore@5.3.1: - resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} - engines: {node: '>= 4'} - dev: true + ignore@5.3.2: {} - /immediate@3.0.6: - resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} - dev: false + immediate@3.0.6: {} - /immutable@4.3.6: - resolution: {integrity: sha512-Ju0+lEMyzMVZarkTn/gqRpdqd5dOPaz1mCZ0SH3JV6iFw81PldE/PEB1hWVEA288HPt4WXW8O7AWxB10M+03QQ==} - dev: true + immutable@4.3.7: {} - /import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} + import-fresh@3.3.0: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 - dev: true - /imurmurhash@0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true + imurmurhash@0.1.4: {} - /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. + inflight@1.0.6: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: true - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + inherits@2.0.4: {} - /internal-slot@1.0.7: - resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} - engines: {node: '>= 0.4'} - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.0.6 - dev: true + invert-kv@3.0.1: {} - /invert-kv@3.0.1: - resolution: {integrity: sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==} - engines: {node: '>=8'} - dev: false + iota-array@1.0.0: {} - /iota-array@1.0.0: - resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==} - dev: false - - /ip-address@9.0.5: - resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} - engines: {node: '>= 12'} + ip-address@9.0.5: dependencies: jsbn: 1.1.0 sprintf-js: 1.1.3 - dev: false - /ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - dev: false + ipaddr.js@1.9.1: {} - /is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - dev: true - - /is-bigint@1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - dependencies: - has-bigints: 1.0.2 - dev: true - - /is-binary-path@2.1.0: - resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} - engines: {node: '>=8'} + is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 - dev: true - /is-boolean-object@1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - dev: true + is-buffer@1.1.6: {} - /is-buffer@1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: false - - /is-builtin-module@3.2.1: - resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} - engines: {node: '>=6'} - dependencies: - builtin-modules: 3.3.0 - dev: true - - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true - - /is-ci@3.0.1: - resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} - hasBin: true + is-ci@3.0.1: dependencies: ci-info: 3.9.0 - dev: true - /is-core-module@2.13.1: - resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} - dependencies: - hasown: 2.0.2 - dev: true + is-extglob@2.1.1: {} - /is-data-view@1.0.1: - resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} - engines: {node: '>= 0.4'} - dependencies: - is-typed-array: 1.1.13 - dev: true + is-fullwidth-code-point@3.0.0: {} - /is-date-object@1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: true - - /is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - - /is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 - dev: true - /is-module@1.0.0: - resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} - dev: true + is-in-browser@1.1.3: {} - /is-negative-zero@2.0.3: - resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} - engines: {node: '>= 0.4'} - dev: true + is-number@7.0.0: {} - /is-number-object@1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: true + is-obj@2.0.0: {} - /is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true + is-path-inside@3.0.3: {} - /is-obj@1.0.1: - resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} - engines: {node: '>=0.10.0'} - dev: true + is-plain-obj@1.1.0: {} - /is-obj@2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - dev: false + is-stream@1.1.0: {} - /is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true + is-typedarray@1.0.0: {} - /is-plain-obj@1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - dev: false + isarray@1.0.0: {} - /is-regex@1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 - dev: true + isbinaryfile@4.0.10: {} - /is-regexp@1.0.0: - resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} - engines: {node: '>=0.10.0'} - dev: true + isbinaryfile@5.0.2: {} - /is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - dev: true + isexe@2.0.0: {} - /is-stream@1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - dev: false + ismobilejs@1.1.1: {} - /is-stream@2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true + isstream@0.1.2: {} - /is-string@1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.2 - dev: true + itiriri@2.0.1: {} - /is-symbol@1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} - dependencies: - which-typed-array: 1.1.15 - dev: true - - /is-typedarray@1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: false - - /is-weakref@1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - dependencies: - call-bind: 1.0.7 - dev: true - - /isarray@1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true - - /isarray@2.0.5: - resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true - - /isbinaryfile@4.0.10: - resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} - engines: {node: '>= 8.0.0'} - dev: true - - /isbinaryfile@5.0.2: - resolution: {integrity: sha512-GvcjojwonMjWbTkfMpnVHVqXW/wKMYDfEpY94/8zy8HFMOqb/VL6oeONq9v87q4ttVlaTLnGXnJD4B5B1OTGIg==} - engines: {node: '>= 18.0.0'} - dev: true - - /isexe@2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - - /isstream@0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - dev: false - - /itiriri@2.0.1: - resolution: {integrity: sha512-XutdsL9Nm9ejgRlFwOBdWW78Txvs9ehhMFeGCp3GjGIWSeQNgOzOfo+PjuQSmaFgE1ol6Pr2g5Jg7W4BYIploQ==} - dev: false - - /jackspeak@3.4.0: - resolution: {integrity: sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==} - engines: {node: '>=14'} + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 optionalDependencies: '@pkgjs/parseargs': 0.11.0 - dev: true - /jake@10.9.1: - resolution: {integrity: sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==} - engines: {node: '>=10'} - hasBin: true + jake@10.9.2: dependencies: - async: 3.2.5 + async: 3.2.6 chalk: 4.1.2 filelist: 1.0.4 minimatch: 3.1.2 - dev: true - /jpeg-js@0.4.4: - resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==} - dev: false + jpeg-js@0.4.4: {} - /js-cookie@3.0.5: - resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} - engines: {node: '>=14'} - dev: false + js-cookie@3.0.5: {} - /js-tokens@4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true + js-tokens@4.0.0: {} - /js-tokens@9.0.0: - resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==} - dev: true + js-tokens@9.0.0: {} - /js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true + js-yaml@4.1.0: dependencies: argparse: 2.0.1 - /jsbn@0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - dev: false + jsbn@0.1.1: {} - /jsbn@1.1.0: - resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} - dev: false + jsbn@1.1.0: {} - /jsesc@0.5.0: - resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} - hasBin: true - dev: true + jsesc@2.5.2: {} - /jsesc@2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true + json-buffer@3.0.1: {} - /json-buffer@3.0.1: - resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + json-schema-ref-resolver@1.0.1: + dependencies: + fast-deep-equal: 3.1.3 - /json-schema-traverse@0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + json-schema-traverse@0.4.1: {} - /json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + json-schema-traverse@1.0.0: {} - /json-schema-typed@7.0.3: - resolution: {integrity: sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==} - dev: false + json-schema-typed@7.0.3: {} - /json-schema@0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + json-schema@0.4.0: {} - /json-stable-stringify-without-jsonify@1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true + json-stable-stringify-without-jsonify@1.0.1: {} - /json-stringify-safe@5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + json-stringify-safe@5.0.1: {} - /json5@2.2.3: - resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} - engines: {node: '>=6'} - hasBin: true - dev: true + json5@2.2.3: {} - /jsonfile@4.0.0: - resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@4.0.0: optionalDependencies: graceful-fs: 4.2.11 - /jsonfile@6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + jsonfile@6.1.0: dependencies: universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 - /jsonpointer@5.0.1: - resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} - engines: {node: '>=0.10.0'} - dev: true - - /jsprim@1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} + jsprim@1.4.2: dependencies: assert-plus: 1.0.0 extsprintf: 1.3.0 json-schema: 0.4.0 verror: 1.10.0 - dev: false - /keyv@4.5.4: - resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + jss-plugin-camel-case@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + hyphenate-style-name: 1.1.0 + jss: 10.10.0 + + jss-plugin-compose@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + tiny-warning: 1.0.3 + + jss-plugin-default-unit@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + + jss-plugin-expand@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + + jss-plugin-extend@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + tiny-warning: 1.0.3 + + jss-plugin-global@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + + jss-plugin-nested@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + tiny-warning: 1.0.3 + + jss-plugin-props-sort@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + + jss-plugin-rule-value-function@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + tiny-warning: 1.0.3 + + jss-plugin-rule-value-observable@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + symbol-observable: 1.2.0 + + jss-plugin-template@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + tiny-warning: 1.0.3 + + jss-plugin-vendor-prefixer@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + css-vendor: 2.0.8 + jss: 10.10.0 + + jss-preset-default@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + jss: 10.10.0 + jss-plugin-camel-case: 10.10.0 + jss-plugin-compose: 10.10.0 + jss-plugin-default-unit: 10.10.0 + jss-plugin-expand: 10.10.0 + jss-plugin-extend: 10.10.0 + jss-plugin-global: 10.10.0 + jss-plugin-nested: 10.10.0 + jss-plugin-props-sort: 10.10.0 + jss-plugin-rule-value-function: 10.10.0 + jss-plugin-rule-value-observable: 10.10.0 + jss-plugin-template: 10.10.0 + jss-plugin-vendor-prefixer: 10.10.0 + + jss@10.10.0: + dependencies: + '@babel/runtime': 7.25.6 + csstype: 3.1.3 + is-in-browser: 1.1.3 + tiny-warning: 1.0.3 + + keyv@4.5.4: dependencies: json-buffer: 3.0.1 - /lazy-val@1.0.5: - resolution: {integrity: sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==} + lazy-val@1.0.5: {} - /lazystream@1.0.1: - resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} - engines: {node: '>= 0.6.3'} + lazystream@1.0.1: dependencies: readable-stream: 2.3.8 - dev: true - /lcid@3.1.1: - resolution: {integrity: sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==} - engines: {node: '>=8'} + lcid@3.1.1: dependencies: invert-kv: 3.0.1 - dev: false - /leven@3.1.0: - resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} - engines: {node: '>=6'} - dev: true - - /levn@0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - dev: true - /lie@3.1.1: - resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + lie@3.1.1: dependencies: immediate: 3.0.6 - dev: false - /loadjs@4.3.0: - resolution: {integrity: sha512-vNX4ZZLJBeDEOBvdr2v/F+0aN5oMuPu7JTqrMwp+DtgK+AryOlpy6Xtm2/HpNr+azEa828oQjOtWsB6iDtSfSQ==} - dev: false + light-my-request@5.13.0: + dependencies: + cookie: 0.6.0 + process-warning: 3.0.0 + set-cookie-parser: 2.7.0 - /local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} - engines: {node: '>=14'} - dev: true + loadjs@4.3.0: {} - /local-pkg@0.5.0: - resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} - engines: {node: '>=14'} + local-pkg@0.5.0: dependencies: mlly: 1.7.1 - pkg-types: 1.1.1 - dev: true + pkg-types: 1.2.0 - /localforage@1.10.0: - resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + localforage@1.10.0: dependencies: lie: 3.1.1 - dev: false - /locate-path@3.0.0: - resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} - engines: {node: '>=6'} + locate-path@3.0.0: dependencies: p-locate: 3.0.0 path-exists: 3.0.0 - dev: false - /locate-path@5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} + locate-path@5.0.0: dependencies: p-locate: 4.1.0 - dev: false - /locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 - dev: true - /lodash-es@4.17.21: - resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} - dev: true + lodash-es@4.17.21: {} - /lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - dev: true + lodash.defaults@4.2.0: {} - /lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - dev: true + lodash.difference@4.5.0: {} - /lodash.difference@4.5.0: - resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} - dev: true + lodash.escaperegexp@4.1.2: {} - /lodash.escaperegexp@4.1.2: - resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==} - dev: false + lodash.flatten@4.4.0: {} - /lodash.flatten@4.4.0: - resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} - dev: true + lodash.isequal@4.5.0: {} - /lodash.isequal@4.5.0: - resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} - dev: false + lodash.isplainobject@4.0.6: {} - /lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} - dev: true + lodash.merge@4.6.2: {} - /lodash.merge@4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true + lodash.union@4.6.0: {} - /lodash.sortby@4.7.0: - resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} - dev: true + lodash@4.17.21: {} - /lodash.union@4.6.0: - resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} - dev: true + lowercase-keys@2.0.0: {} - /lodash@4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true + lru-cache@10.4.3: {} - /lowercase-keys@2.0.0: - resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} - engines: {node: '>=8'} - - /lru-cache@10.2.2: - resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==} - engines: {node: 14 || >=16.14} - dev: true - - /lru-cache@5.1.1: - resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lru-cache@5.1.1: dependencies: yallist: 3.1.1 - dev: true - /lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} + lru-cache@6.0.0: dependencies: yallist: 4.0.0 - dev: true - /magic-string@0.25.9: - resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + magic-string@0.30.11: dependencies: - sourcemap-codec: 1.4.8 - dev: true + '@jridgewell/sourcemap-codec': 1.5.0 - /magic-string@0.30.10: - resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==} - dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 - - /map-age-cleaner@0.1.3: - resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} - engines: {node: '>=6'} + map-age-cleaner@0.1.3: dependencies: p-defer: 1.0.0 - dev: false - /matcher@3.0.0: - resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==} - engines: {node: '>=10'} - requiresBuild: true + marked@14.1.2: {} + + matcher@3.0.0: dependencies: escape-string-regexp: 4.0.0 optional: true - /md5@2.3.0: - resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + md5@2.3.0: dependencies: charenc: 0.0.2 crypt: 0.0.2 is-buffer: 1.1.6 - dev: false - /media-typer@0.3.0: - resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} - engines: {node: '>= 0.6'} - dev: false + media-typer@0.3.0: {} - /media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - dev: false + media-typer@1.1.0: {} - /mem@5.1.1: - resolution: {integrity: sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==} - engines: {node: '>=8'} + mem@5.1.1: dependencies: map-age-cleaner: 0.1.3 mimic-fn: 2.1.0 p-is-promise: 2.1.0 - dev: false - /merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - dev: false + merge-descriptors@1.0.1: {} - /merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true + merge2@1.4.1: {} - /methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - dev: false + methods@1.1.2: {} - /micromatch@4.0.7: - resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==} - engines: {node: '>=8.6'} + micromatch@4.0.8: dependencies: braces: 3.0.3 picomatch: 2.3.1 - dev: true - /mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} + mime-db@1.52.0: {} - /mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 - /mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - dev: false + mime@1.6.0: {} - /mime@2.6.0: - resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} - engines: {node: '>=4.0.0'} - hasBin: true - dev: true + mime@2.6.0: {} - /mimic-fn@2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: false + mime@3.0.0: {} - /mimic-fn@3.1.0: - resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} - engines: {node: '>=8'} - dev: false + mimic-fn@2.1.0: {} - /mimic-response@1.0.1: - resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} - engines: {node: '>=4'} + mimic-fn@3.1.0: {} - /mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} + mimic-response@1.0.1: {} - /minimatch@3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + mimic-response@3.1.0: {} + + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 - dev: true - /minimatch@5.1.6: - resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} - engines: {node: '>=10'} + minimatch@5.1.6: dependencies: brace-expansion: 2.0.1 - dev: true - /minimatch@9.0.4: - resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} - engines: {node: '>=16 || 14 >=14.17'} + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 - dev: true - /minimist@1.2.8: - resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - dev: true + minimist@1.2.8: {} - /minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} + minipass@3.3.6: dependencies: yallist: 4.0.0 - dev: true - /minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - dev: true + minipass@5.0.0: {} - /minipass@7.1.2: - resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} - engines: {node: '>=16 || 14 >=14.17'} - dev: true + minipass@7.1.2: {} - /minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} + minizlib@2.1.2: dependencies: minipass: 3.3.6 yallist: 4.0.0 - dev: true - /mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true + mitt@2.1.0: {} - /mlly@1.7.1: - resolution: {integrity: sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==} + mkdirp@1.0.4: {} + + mlly@1.7.1: dependencies: - acorn: 8.12.0 + acorn: 8.12.1 pathe: 1.1.2 - pkg-types: 1.1.1 - ufo: 1.5.3 - dev: true + pkg-types: 1.2.0 + ufo: 1.5.4 - /modify-filename@1.1.0: - resolution: {integrity: sha512-EickqnKq3kVVaZisYuCxhtKbZjInCuwgwZWyAmRIp1NTMhri7r3380/uqwrUHfaDiPzLVTuoNy4whX66bxPVog==} - engines: {node: '>=0.10.0'} - dev: false + modify-filename@1.1.0: {} - /ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: false + ms@2.0.0: {} - /ms@2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: {} - /ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: false + muggle-string@0.4.1: {} - /music-metadata@7.14.0: - resolution: {integrity: sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA==} - engines: {node: '>=10'} + music-metadata@7.14.0: dependencies: '@tokenizer/token': 0.3.0 content-type: 1.0.5 - debug: 4.3.5 + debug: 4.3.7 file-type: 16.5.4 media-typer: 1.1.0 strtok3: 6.3.0 token-types: 4.2.1 transitivePeerDependencies: - supports-color - dev: false - /naive-ui@2.38.2(vue@3.4.8): - resolution: {integrity: sha512-WhZ+6DW61aYSmFyfH7evcSGFmd2xR68Yq1mNRrVdJwBhZsnNdAUsMN9IeNCVEPMCND/jzYZghkStoNoR5Xa09g==} - peerDependencies: - vue: ^3.0.0 + naive-ui@2.39.0(vue@3.4.38(typescript@5.5.4)): dependencies: '@css-render/plugin-bem': 0.15.14(css-render@0.15.14) - '@css-render/vue3-ssr': 0.15.14(vue@3.4.8) + '@css-render/vue3-ssr': 0.15.14(vue@3.4.38(typescript@5.5.4)) '@types/katex': 0.16.7 - '@types/lodash': 4.17.5 + '@types/lodash': 4.17.7 '@types/lodash-es': 4.17.12 async-validator: 4.2.5 css-render: 0.15.14 @@ -5733,154 +6631,89 @@ packages: date-fns: 2.30.0 date-fns-tz: 2.0.1(date-fns@2.30.0) evtd: 0.2.4 - highlight.js: 11.9.0 + highlight.js: 11.10.0 lodash: 4.17.21 lodash-es: 4.17.21 seemly: 0.3.8 treemate: 0.3.11 - vdirs: 0.1.8(vue@3.4.8) - vooks: 0.2.12(vue@3.4.8) - vue: 3.4.8 - vueuc: 0.4.58(vue@3.4.8) - dev: true + vdirs: 0.1.8(vue@3.4.38(typescript@5.5.4)) + vooks: 0.2.12(vue@3.4.38(typescript@5.5.4)) + vue: 3.4.38(typescript@5.5.4) + vueuc: 0.4.58(vue@3.4.38(typescript@5.5.4)) - /nanoid@3.3.7: - resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true + nanoid@3.3.7: {} - /natural-compare@1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true + natural-compare@1.4.0: {} - /ndarray-pack@1.2.1: - resolution: {integrity: sha512-51cECUJMT0rUZNQa09EoKsnFeDL4x2dHRT0VR5U2H5ZgEcm95ZDWcMA5JShroXjHOejmAD/fg8+H+OvUnVXz2g==} + ndarray-pack@1.2.1: dependencies: cwise-compiler: 1.1.3 ndarray: 1.0.19 - dev: false - /ndarray@1.0.19: - resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==} + ndarray@1.0.19: dependencies: iota-array: 1.0.0 is-buffer: 1.1.6 - dev: false - /negotiator@0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: false + negotiator@0.6.3: {} - /netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - dev: false + netmask@2.0.2: {} - /nice-try@1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: false + nice-try@1.0.5: {} - /node-addon-api@1.7.2: - resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} - requiresBuild: true - dev: true + node-addon-api@1.7.2: optional: true - /node-bitmap@0.0.1: - resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==} - engines: {node: '>=v0.6.5'} - dev: false + node-bitmap@0.0.1: {} - /node-forge@1.3.1: - resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} - engines: {node: '>= 6.13.0'} - dev: false + node-forge@1.3.1: {} - /node-releases@2.0.14: - resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} - dev: true + node-releases@2.0.18: {} - /node-taglib-sharp@5.2.3: - resolution: {integrity: sha512-cqomQ+pD/4HPYpVS5UpDkyN3YQwX67YHSXFk9udSI0VgFKdHSG9/PJFKLehsuwWUr5HKVqRVgSJjBIeOvyLajA==} - engines: {node: '>=12.16.1'} + node-taglib-sharp@5.2.3: dependencies: dateformat: 3.0.3 iconv-lite: 0.6.3 itiriri: 2.0.1 os-locale: 4.0.0 uuid: 8.3.2 - dev: false - /normalize-path@3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true + normalize-path@3.0.0: {} - /normalize-url@6.1.0: - resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} - engines: {node: '>=10'} + normalize-url@6.1.0: {} - /npm-run-path@2.0.2: - resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} - engines: {node: '>=4'} + npm-run-path@2.0.2: dependencies: path-key: 2.0.1 - dev: false - /nth-check@2.1.1: - resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nth-check@2.1.1: dependencies: boolbase: 1.0.0 - dev: true - /oauth-sign@0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - dev: false + oauth-sign@0.9.0: {} - /object-inspect@1.13.1: - resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} + object-inspect@1.13.2: {} - /object-keys@1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} + object-keys@1.1.1: + optional: true - /object.assign@4.1.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true + omggif@1.0.10: {} - /omggif@1.0.10: - resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} - dev: false + on-exit-leak-free@2.1.2: {} - /on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} + on-finished@2.4.1: dependencies: ee-first: 1.1.1 - dev: false - /once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + once@1.4.0: dependencies: wrappy: 1.0.2 - /onetime@5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} + onetime@5.1.2: dependencies: mimic-fn: 2.1.0 - dev: false - /optionator@0.9.4: - resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} - engines: {node: '>= 0.8.0'} + optionator@0.9.4: dependencies: deep-is: 0.1.4 fast-levenshtein: 2.0.6 @@ -5888,412 +6721,253 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 word-wrap: 1.2.5 - dev: true - /os-locale@4.0.0: - resolution: {integrity: sha512-HsSR1+2l6as4Wp2SGZxqLnuFHxVvh1Ir9pvZxyujsC13egZVe7P0YeBLN0ijQzM/twrO5To3ia3jzBXAvpMTEA==} - engines: {node: '>=8'} + os-locale@4.0.0: dependencies: execa: 1.0.0 lcid: 3.1.1 mem: 5.1.1 - dev: false - /p-cancelable@2.1.1: - resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} - engines: {node: '>=8'} + p-cancelable@2.1.1: {} - /p-defer@1.0.0: - resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} - engines: {node: '>=4'} - dev: false + p-defer@1.0.0: {} - /p-finally@1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} - dev: false + p-finally@1.0.0: {} - /p-is-promise@2.1.0: - resolution: {integrity: sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==} - engines: {node: '>=6'} - dev: false + p-is-promise@2.1.0: {} - /p-limit@2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} + p-limit@2.3.0: dependencies: p-try: 2.2.0 - dev: false - /p-limit@3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 - dev: true - /p-locate@3.0.0: - resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} - engines: {node: '>=6'} + p-locate@3.0.0: dependencies: p-limit: 2.3.0 - dev: false - /p-locate@4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} + p-locate@4.1.0: dependencies: p-limit: 2.3.0 - dev: false - /p-locate@5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} + p-locate@5.0.0: dependencies: p-limit: 3.1.0 - dev: true - /p-try@2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: false + p-try@2.2.0: {} - /pac-proxy-agent@7.0.1: - resolution: {integrity: sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==} - engines: {node: '>= 14'} + pac-proxy-agent@7.0.2: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.1 - debug: 4.3.5 + debug: 4.3.7 get-uri: 6.0.3 http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.4 + https-proxy-agent: 7.0.5 pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.3 + socks-proxy-agent: 8.0.4 transitivePeerDependencies: - supports-color - dev: false - /pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} + pac-resolver@7.0.1: dependencies: degenerator: 5.0.1 netmask: 2.0.2 - dev: false - /package-json-from-dist@1.0.0: - resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==} - dev: true + package-json-from-dist@1.0.0: {} - /parent-module@1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} + parent-module@1.0.1: dependencies: callsites: 3.1.0 - dev: true - /parse-data-uri@0.2.0: - resolution: {integrity: sha512-uOtts8NqDcaCt1rIsO3VFDRsAfgE4c6osG4d9z3l4dCBlxYFzni6Di/oNU270SDrjkfZuUvLZx1rxMyqh46Y9w==} + parse-data-uri@0.2.0: dependencies: data-uri-to-buffer: 0.0.3 - dev: false - /parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - dev: false + parseurl@1.3.3: {} - /path-exists@3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} - dev: false + path-browserify@1.0.1: {} - /path-exists@4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} + path-exists@3.0.0: {} - /path-is-absolute@1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true + path-exists@4.0.0: {} - /path-key@2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: false + path-is-absolute@1.0.1: {} - /path-key@3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true + path-key@2.0.1: {} - /path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true + path-key@3.1.1: {} - /path-scurry@1.11.1: - resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} - engines: {node: '>=16 || 14 >=14.18'} + path-scurry@1.11.1: dependencies: - lru-cache: 10.2.2 + lru-cache: 10.4.3 minipass: 7.1.2 - dev: true - /path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - dev: false + path-to-regexp@0.1.7: {} - /pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - dev: true + path-type@4.0.0: {} - /peek-readable@4.1.0: - resolution: {integrity: sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg==} - engines: {node: '>=8'} - dev: false + pathe@1.1.2: {} - /pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + peek-readable@4.1.0: {} - /performance-now@2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - dev: false + pend@1.2.0: {} - /picocolors@1.0.1: - resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} + performance-now@2.1.0: {} - /picomatch@2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true + picocolors@1.1.0: {} - /pinia-plugin-persistedstate@3.2.1(pinia@2.1.7): - resolution: {integrity: sha512-MK++8LRUsGF7r45PjBFES82ISnPzyO6IZx3CH5vyPseFLZCk1g2kgx6l/nW8pEBKxxd4do0P6bJw+mUSZIEZUQ==} - peerDependencies: - pinia: ^2.0.0 + picomatch@2.3.1: {} + + pinia-plugin-persistedstate@3.2.3(pinia@2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4))): dependencies: - pinia: 2.1.7(vue@3.4.8) - dev: false + pinia: 2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)) - /pinia@2.1.7(vue@3.4.8): - 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 + pinia@2.2.2(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4)): dependencies: '@vue/devtools-api': 6.6.3 - vue: 3.4.8 - vue-demi: 0.14.8(vue@3.4.8) - dev: false + vue: 3.4.38(typescript@5.5.4) + vue-demi: 0.14.10(vue@3.4.38(typescript@5.5.4)) + optionalDependencies: + typescript: 5.5.4 - /pkg-types@1.1.1: - resolution: {integrity: sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==} + pino-abstract-transport@1.2.0: + dependencies: + readable-stream: 4.5.2 + split2: 4.2.0 + + pino-std-serializers@7.0.0: {} + + pino@9.4.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 1.2.0 + pino-std-serializers: 7.0.0 + process-warning: 4.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.1.0 + thread-stream: 3.1.0 + + pkg-types@1.2.0: dependencies: confbox: 0.1.7 mlly: 1.7.1 pathe: 1.1.2 - dev: true - /pkg-up@3.1.0: - resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} - engines: {node: '>=8'} + pkg-up@3.1.0: dependencies: find-up: 3.0.0 - dev: false - /plist@3.1.0: - resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==} - engines: {node: '>=10.4.0'} + plist@3.1.0: dependencies: '@xmldom/xmldom': 0.8.10 base64-js: 1.5.1 xmlbuilder: 15.1.1 - dev: true - /plyr@3.7.8: - resolution: {integrity: sha512-yG/EHDobwbB/uP+4Bm6eUpJ93f8xxHjjk2dYcD1Oqpe1EcuQl5tzzw9Oq+uVAzd2lkM11qZfydSiyIpiB8pgdA==} + plyr@3.7.8: dependencies: - core-js: 3.37.1 + core-js: 3.38.1 custom-event-polyfill: 1.0.7 loadjs: 4.3.0 rangetouch: 2.0.1 url-polyfill: 1.1.12 - dev: false - /pngjs@3.4.0: - resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} - engines: {node: '>=4.0.0'} - dev: false + pngjs@3.4.0: {} - /pngjs@5.0.0: - resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} - engines: {node: '>=10.13.0'} - dev: false + pngjs@5.0.0: {} - /possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} - dev: true - - /postcss-selector-parser@6.1.0: - resolution: {integrity: sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==} - engines: {node: '>=4'} + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 - dev: true - /postcss@8.4.38: - resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==} - engines: {node: ^10 || ^12 || >=14} + postcss@8.4.45: dependencies: nanoid: 3.3.7 - picocolors: 1.0.1 + picocolors: 1.1.0 source-map-js: 1.2.0 - /prelude-ls@1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true + prelude-ls@1.2.1: {} - /prettier-linter-helpers@1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - dependencies: - fast-diff: 1.3.0 - dev: true + prettier@3.3.3: {} - /prettier@3.3.2: - resolution: {integrity: sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==} - engines: {node: '>=14'} - hasBin: true - dev: true + process-nextick-args@2.0.1: {} - /pretty-bytes@5.6.0: - resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} - engines: {node: '>=6'} - dev: true + process-warning@3.0.0: {} - /pretty-bytes@6.1.1: - resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} - engines: {node: ^14.13.1 || >=16.0.0} - dev: true + process-warning@4.0.0: {} - /process-nextick-args@2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true + process@0.11.10: {} - /progress@2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} + progress@2.0.3: {} - /promise-retry@2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} + promise-retry@2.0.1: dependencies: err-code: 2.0.3 retry: 0.12.0 - dev: true - /proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 - dev: false - /proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false + proxy-from-env@1.1.0: {} - /psl@1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: false + psl@1.9.0: {} - /pump@3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + pump@3.0.0: dependencies: end-of-stream: 1.4.4 once: 1.4.0 - /punycode@2.3.1: - resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} - engines: {node: '>=6'} + punycode@1.4.1: {} - /pupa@2.1.1: - resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==} - engines: {node: '>=8'} + punycode@2.3.1: {} + + pupa@2.1.1: dependencies: escape-goat: 2.1.1 - dev: false - /qrcode@1.5.3: - resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} - engines: {node: '>=10.13.0'} - hasBin: true + qrcode@1.5.4: dependencies: dijkstrajs: 1.0.3 - encode-utf8: 1.0.3 pngjs: 5.0.0 yargs: 15.4.1 - dev: false - /qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} + qs@6.11.0: dependencies: side-channel: 1.0.6 - dev: false - /qs@6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - dev: false - - /queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - /quick-lru@5.1.1: - resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} - engines: {node: '>=10'} - - /randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + qs@6.13.0: dependencies: - safe-buffer: 5.2.1 - dev: true + side-channel: 1.0.6 - /range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - dev: false + qs@6.5.3: {} - /rangetouch@2.0.1: - resolution: {integrity: sha512-sln+pNSc8NGaHoLzwNBssFSf/rSYkqeBXzX1AtJlkJiUaVSJSbRAWJk+4omsXkN+EJalzkZhWQ3th1m0FpR5xA==} - dev: false + queue-microtask@1.2.3: {} - /raw-body@2.5.2: - resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} - engines: {node: '>= 0.8'} + quick-format-unescaped@4.0.4: {} + + quick-lru@5.1.1: {} + + range-parser@1.2.1: {} + + rangetouch@2.0.1: {} + + raw-body@2.5.2: dependencies: bytes: 3.1.2 http-errors: 2.0.0 iconv-lite: 0.4.24 unpipe: 1.0.0 - dev: false - /read-config-file@6.3.2: - resolution: {integrity: sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==} - engines: {node: '>=12.0.0'} + read-config-file@6.3.2: dependencies: config-file-ts: 0.2.6 dotenv: 9.0.2 @@ -6301,10 +6975,8 @@ packages: js-yaml: 4.1.0 json5: 2.2.3 lazy-val: 1.0.5 - dev: true - /readable-stream@2.3.8: - resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 inherits: 2.0.4 @@ -6313,93 +6985,41 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 - dev: true - /readable-stream@3.6.2: - resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} - engines: {node: '>= 6'} + readable-stream@3.6.2: dependencies: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 - /readable-web-to-node-stream@3.0.2: - resolution: {integrity: sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==} - engines: {node: '>=8'} + readable-stream@4.5.2: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readable-web-to-node-stream@3.0.2: dependencies: readable-stream: 3.6.2 - dev: false - /readdir-glob@1.1.3: - resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} + readdir-glob@1.1.3: dependencies: minimatch: 5.1.6 - dev: true - /readdirp@3.6.0: - resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} - engines: {node: '>=8.10.0'} + readdirp@3.6.0: dependencies: picomatch: 2.3.1 - dev: true - /regenerate-unicode-properties@10.1.1: - resolution: {integrity: sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q==} - engines: {node: '>=4'} - dependencies: - regenerate: 1.4.2 - dev: true + real-require@0.2.0: {} - /regenerate@1.4.2: - resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} - dev: true + regenerator-runtime@0.14.1: {} - /regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - dev: true - - /regenerator-transform@0.15.2: - resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} - dependencies: - '@babel/runtime': 7.24.7 - dev: true - - /regexp.prototype.flags@1.5.2: - resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-errors: 1.3.0 - set-function-name: 2.0.2 - dev: true - - /regexpu-core@5.3.2: - resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} - engines: {node: '>=4'} - dependencies: - '@babel/regjsgen': 0.8.0 - regenerate: 1.4.2 - regenerate-unicode-properties: 10.1.1 - regjsparser: 0.9.1 - unicode-match-property-ecmascript: 2.0.0 - unicode-match-property-value-ecmascript: 2.1.0 - dev: true - - /regjsparser@0.9.1: - resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} - hasBin: true - dependencies: - jsesc: 0.5.0 - dev: true - - /request@2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + request@2.88.2: dependencies: aws-sign2: 0.7.0 - aws4: 1.13.0 + aws4: 1.13.2 caseless: 0.12.0 combined-stream: 1.0.8 extend: 3.0.2 @@ -6418,64 +7038,34 @@ packages: tough-cookie: 2.5.0 tunnel-agent: 0.6.0 uuid: 3.4.0 - dev: false - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} + require-directory@2.1.1: {} - /require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} + require-from-string@2.0.2: {} - /require-main-filename@2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - dev: false + require-main-filename@2.0.0: {} - /resolve-alpn@1.2.1: - resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + resolve-alpn@1.2.1: {} - /resolve-from@4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true + resolve-from@4.0.0: {} - /resolve@1.22.8: - resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} - hasBin: true - dependencies: - is-core-module: 2.13.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /responselike@2.0.1: - resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + responselike@2.0.1: dependencies: lowercase-keys: 2.0.0 - /retry@0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - dev: true + ret@0.4.3: {} - /reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true + retry@0.12.0: {} - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true + reusify@1.0.4: {} + + rfdc@1.4.1: {} + + rimraf@3.0.2: dependencies: glob: 7.2.3 - dev: true - /roarr@2.15.4: - resolution: {integrity: sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==} - engines: {node: '>=8.0'} - requiresBuild: true + roarr@2.15.4: dependencies: boolean: 3.2.0 detect-node: 2.1.0 @@ -6485,133 +7075,74 @@ packages: sprintf-js: 1.1.3 optional: true - /rollup@2.79.1: - resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} - engines: {node: '>=10.0.0'} - hasBin: true - optionalDependencies: - fsevents: 2.3.3 - dev: true - - /rollup@4.18.0: - resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true + rollup@4.21.2: 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 + '@rollup/rollup-android-arm-eabi': 4.21.2 + '@rollup/rollup-android-arm64': 4.21.2 + '@rollup/rollup-darwin-arm64': 4.21.2 + '@rollup/rollup-darwin-x64': 4.21.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.21.2 + '@rollup/rollup-linux-arm-musleabihf': 4.21.2 + '@rollup/rollup-linux-arm64-gnu': 4.21.2 + '@rollup/rollup-linux-arm64-musl': 4.21.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.21.2 + '@rollup/rollup-linux-riscv64-gnu': 4.21.2 + '@rollup/rollup-linux-s390x-gnu': 4.21.2 + '@rollup/rollup-linux-x64-gnu': 4.21.2 + '@rollup/rollup-linux-x64-musl': 4.21.2 + '@rollup/rollup-win32-arm64-msvc': 4.21.2 + '@rollup/rollup-win32-ia32-msvc': 4.21.2 + '@rollup/rollup-win32-x64-msvc': 4.21.2 fsevents: 2.3.3 - dev: true - /run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 - dev: true - /safe-array-concat@1.1.2: - resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} - engines: {node: '>=0.4'} + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-decode-uri-component@1.2.1: {} + + safe-regex2@3.1.0: dependencies: - call-bind: 1.0.7 - get-intrinsic: 1.2.4 - has-symbols: 1.0.3 - isarray: 2.0.5 - dev: true + ret: 0.4.3 - /safe-buffer@5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true + safe-stable-stringify@2.5.0: {} - /safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: {} - /safe-decode-uri-component@1.2.1: - resolution: {integrity: sha512-j0PKk0v8qPOD0goqRAvoI7GKy+HwLHXEpXaQlA1IqJ65jjiILRK1InlfNdIKUUUYuLtERADaJumgYKNfyQBO+w==} - dev: false - - /safe-regex-test@1.0.3: - resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-regex: 1.1.4 - dev: true - - /safer-buffer@2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - - /sanitize-filename@1.6.3: - resolution: {integrity: sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==} + sanitize-filename@1.6.3: dependencies: truncate-utf8-bytes: 1.0.2 - dev: true - /sass@1.77.6: - resolution: {integrity: sha512-ByXE1oLD79GVq9Ht1PeHWCPMPB8XHpBuz1r85oByKHjZY6qV6rWnQovQzXJXuQ/XyE1Oj3iPk3lo28uzaRA2/Q==} - engines: {node: '>=14.0.0'} - hasBin: true + sass@1.78.0: dependencies: chokidar: 3.6.0 - immutable: 4.3.6 + immutable: 4.3.7 source-map-js: 1.2.0 - dev: true - /sax@1.4.1: - resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} + sax@1.4.1: {} - /screenfull@6.0.2: - resolution: {integrity: sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==} - engines: {node: ^14.13.1 || >=16.0.0} - dev: false + scule@1.3.0: {} - /scule@1.3.0: - resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==} - dev: true + secure-json-parse@2.7.0: {} - /seemly@0.3.8: - resolution: {integrity: sha512-MW8Qs6vbzo0pHmDpFSYPna+lwpZ6Zk1ancbajw/7E8TKtHdV+1DfZZD+kKJEhG/cAoB/i+LiT+5msZOqj0DwRA==} - dev: true + seemly@0.3.8: {} - /semver-compare@1.0.0: - resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} - requiresBuild: true + semver-compare@1.0.0: optional: true - /semver@5.7.2: - resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} - hasBin: true - dev: false + semver@5.7.2: {} - /semver@6.3.1: - resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} - hasBin: true + semver@6.3.1: {} - /semver@7.6.2: - resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} - engines: {node: '>=10'} - hasBin: true + semver@7.6.3: {} - /send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} + send@0.18.0: dependencies: debug: 2.6.9 depd: 2.0.0 @@ -6628,25 +7159,13 @@ packages: statuses: 2.0.1 transitivePeerDependencies: - supports-color - dev: false - /serialize-error@7.0.1: - resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} - engines: {node: '>=10'} - requiresBuild: true + serialize-error@7.0.1: dependencies: type-fest: 0.13.1 optional: true - /serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - dependencies: - randombytes: 2.1.0 - dev: true - - /serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} + serve-static@1.15.0: dependencies: encodeurl: 1.0.2 escape-html: 1.0.3 @@ -6654,15 +7173,12 @@ packages: send: 0.18.0 transitivePeerDependencies: - supports-color - dev: false - /set-blocking@2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: false + set-blocking@2.0.0: {} - /set-function-length@1.2.2: - resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} - engines: {node: '>= 0.4'} + set-cookie-parser@2.7.0: {} + + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 @@ -6671,155 +7187,85 @@ packages: gopd: 1.0.1 has-property-descriptors: 1.0.2 - /set-function-name@2.0.2: - resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} - engines: {node: '>= 0.4'} - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - dev: true + setprototypeof@1.2.0: {} - /setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - dev: false - - /shebang-command@1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} + shebang-command@1.2.0: dependencies: shebang-regex: 1.0.0 - dev: false - /shebang-command@2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 - dev: true - /shebang-regex@1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: false + shebang-regex@1.0.0: {} - /shebang-regex@3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true + shebang-regex@3.0.0: {} - /side-channel@1.0.6: - resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} - engines: {node: '>= 0.4'} + 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 + object-inspect: 1.13.2 - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: false + signal-exit@3.0.7: {} - /signal-exit@4.1.0: - resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} - engines: {node: '>=14'} - dev: true + signal-exit@4.1.0: {} - /simple-update-notifier@2.0.0: - resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} - engines: {node: '>=10'} + simple-update-notifier@2.0.0: dependencies: - semver: 7.6.2 - dev: true + semver: 7.6.3 - /slice-ansi@3.0.0: - resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} - engines: {node: '>=8'} - requiresBuild: true + slash@3.0.0: {} + + slice-ansi@3.0.0: dependencies: ansi-styles: 4.3.0 astral-regex: 2.0.0 is-fullwidth-code-point: 3.0.0 - dev: true optional: true - /smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + smart-buffer@4.2.0: {} - /smob@1.5.0: - resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} - dev: true - - /socks-proxy-agent@8.0.3: - resolution: {integrity: sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==} - engines: {node: '>= 14'} + socks-proxy-agent@8.0.4: dependencies: agent-base: 7.1.1 - debug: 4.3.5 + debug: 4.3.7 socks: 2.8.3 transitivePeerDependencies: - supports-color - dev: false - /socks@2.8.3: - resolution: {integrity: sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + socks@2.8.3: dependencies: ip-address: 9.0.5 smart-buffer: 4.2.0 - dev: false - /sort-keys-length@1.0.1: - resolution: {integrity: sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==} - engines: {node: '>=0.10.0'} + sonic-boom@4.1.0: + dependencies: + atomic-sleep: 1.0.0 + + sort-keys-length@1.0.1: dependencies: sort-keys: 1.1.2 - dev: false - /sort-keys@1.1.2: - resolution: {integrity: sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==} - engines: {node: '>=0.10.0'} + sort-keys@1.1.2: dependencies: is-plain-obj: 1.1.0 - dev: false - /source-map-js@1.2.0: - resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==} - engines: {node: '>=0.10.0'} + source-map-js@1.2.0: {} - /source-map-support@0.5.21: - resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 source-map: 0.6.1 - dev: true - /source-map@0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} + source-map@0.6.1: {} - /source-map@0.8.0-beta.0: - resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} - engines: {node: '>= 8'} - dependencies: - whatwg-url: 7.1.0 - dev: true + split2@4.2.0: {} - /sourcemap-codec@1.4.8: - resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - deprecated: Please use @jridgewell/sourcemap-codec instead - dev: true + sprintf-js@1.1.3: {} - /sprintf-js@1.1.3: - resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} - - /sshpk@1.18.0: - resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} - engines: {node: '>=0.10.0'} - hasBin: true + sshpk@1.18.0: dependencies: asn1: 0.2.6 assert-plus: 1.0.0 @@ -6830,196 +7276,81 @@ packages: jsbn: 0.1.1 safer-buffer: 2.1.2 tweetnacl: 0.14.5 - dev: false - /stat-mode@1.0.0: - resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} - engines: {node: '>= 6'} - dev: true + stat-mode@1.0.0: {} - /statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - dev: false + statuses@2.0.1: {} - /streamsearch@1.1.0: - resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} - engines: {node: '>=10.0.0'} - dev: false + stream-wormhole@1.1.0: {} - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} + streamsearch@1.1.0: {} + + 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: - resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} - engines: {node: '>=12'} + string-width@5.1.2: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 strip-ansi: 7.1.0 - dev: true - /string.prototype.matchall@4.0.11: - resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} - engines: {node: '>= 0.4'} - 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 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-symbols: 1.0.3 - internal-slot: 1.0.7 - regexp.prototype.flags: 1.5.2 - set-function-name: 2.0.2 - side-channel: 1.0.6 - dev: true - - /string.prototype.trim@1.2.9: - resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-abstract: 1.23.3 - es-object-atoms: 1.0.0 - dev: true - - /string.prototype.trimend@1.0.8: - resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - dev: true - - /string.prototype.trimstart@1.0.8: - resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.7 - define-properties: 1.2.1 - es-object-atoms: 1.0.0 - dev: true - - /string_decoder@1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.1.1: dependencies: safe-buffer: 5.1.2 - dev: true - /string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 - /stringify-object@3.3.0: - resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} - engines: {node: '>=4'} - dependencies: - get-own-enumerable-property-symbols: 3.0.2 - is-obj: 1.0.1 - is-regexp: 1.0.0 - dev: true - - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 - /strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} - engines: {node: '>=12'} + strip-ansi@7.1.0: dependencies: ansi-regex: 6.0.1 - dev: true - /strip-comments@2.0.1: - resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} - engines: {node: '>=10'} - dev: true + strip-eof@1.0.0: {} - /strip-eof@1.0.0: - resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} - engines: {node: '>=0.10.0'} - dev: false + strip-json-comments@3.1.1: {} - /strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true - - /strip-literal@2.1.0: - resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==} + strip-literal@2.1.0: dependencies: js-tokens: 9.0.0 - dev: true - /strtok3@6.3.0: - resolution: {integrity: sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw==} - engines: {node: '>=10'} + strtok3@6.3.0: dependencies: '@tokenizer/token': 0.3.0 peek-readable: 4.1.0 - dev: false - /sumchecker@3.0.1: - resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==} - engines: {node: '>= 8.0'} + sumchecker@3.0.1: dependencies: - debug: 4.3.5 + debug: 4.3.7 transitivePeerDependencies: - supports-color - /supports-color@5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 - dev: true - /supports-color@7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - dev: true - /supports-preserve-symlinks-flag@1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true + symbol-observable@1.2.0: {} - /synckit@0.8.8: - resolution: {integrity: sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==} - engines: {node: ^14.18.0 || >=16.0.0} - dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.6.3 - dev: true - - /tar-stream@2.2.0: - resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} - engines: {node: '>=6'} + tar-stream@2.2.0: dependencies: bl: 4.1.0 end-of-stream: 1.4.4 fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 - dev: true - /tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} + tar@6.2.1: dependencies: chownr: 2.0.0 fs-minipass: 2.1.0 @@ -7027,899 +7358,389 @@ packages: minizlib: 2.1.2 mkdirp: 1.0.4 yallist: 4.0.0 - dev: true - /temp-dir@2.0.0: - resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} - engines: {node: '>=8'} - dev: true - - /temp-file@3.4.0: - resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==} + temp-file@3.4.0: dependencies: async-exit-hook: 2.0.1 fs-extra: 10.1.0 - dev: true - /tempy@0.6.0: - resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} - engines: {node: '>=10'} - dependencies: - is-stream: 2.0.1 - temp-dir: 2.0.0 - type-fest: 0.16.0 - unique-string: 2.0.0 - dev: true - - /terser@5.31.1: - resolution: {integrity: sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==} - engines: {node: '>=10'} - hasBin: true + terser@5.33.0: dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.12.0 + acorn: 8.12.1 commander: 2.20.3 source-map-support: 0.5.21 - dev: true - /text-table@0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true + text-table@0.2.0: {} - /through@2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: false + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 - /tiny-typed-emitter@2.1.0: - resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==} - dev: false + through@2.3.8: {} - /tmp-promise@3.0.3: - resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + tiny-typed-emitter@2.1.0: {} + + tiny-warning@1.0.3: {} + + tmp-promise@3.0.3: dependencies: tmp: 0.2.3 - dev: true - /tmp@0.2.3: - resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} - engines: {node: '>=14.14'} - dev: true + tmp@0.2.3: {} - /to-fast-properties@2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} + to-fast-properties@2.0.0: {} - /to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - dev: true - /toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - dev: false + toad-cache@3.7.0: {} - /token-types@4.2.1: - resolution: {integrity: sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ==} - engines: {node: '>=10'} + toidentifier@1.0.1: {} + + token-types@4.2.1: dependencies: '@tokenizer/token': 0.3.0 ieee754: 1.2.1 - dev: false - /tough-cookie@2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} + tough-cookie@2.5.0: dependencies: psl: 1.9.0 punycode: 2.3.1 - dev: false - /tr46@1.0.1: - resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} - dependencies: - punycode: 2.3.1 - dev: true + treemate@0.3.11: {} - /treemate@0.3.11: - resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} - dev: true - - /truncate-utf8-bytes@1.0.2: - resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==} + truncate-utf8-bytes@1.0.2: dependencies: utf8-byte-length: 1.0.5 - dev: true - /tslib@2.6.3: - resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + ts-api-utils@1.3.0(typescript@5.5.4): + dependencies: + typescript: 5.5.4 - /tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + tslib@2.7.0: {} + + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 - dev: false - /tunnel@0.0.6: - resolution: {integrity: sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==} - engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} - dev: false + tunnel@0.0.6: {} - /tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - dev: false + tweetnacl@0.14.5: {} - /type-check@0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} + type-check@0.4.0: dependencies: prelude-ls: 1.2.1 - dev: true - /type-fest@0.13.1: - resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} - engines: {node: '>=10'} - requiresBuild: true + type-fest@0.13.1: optional: true - /type-fest@0.16.0: - resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} - engines: {node: '>=10'} - dev: true + type-fest@0.20.2: {} - /type-fest@0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true + type-fest@2.19.0: {} - /type-fest@2.19.0: - resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} - engines: {node: '>=12.20'} - dev: false - - /type-is@1.6.18: - resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} - engines: {node: '>= 0.6'} + type-is@1.6.18: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 - dev: false - /typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} - engines: {node: '>= 0.4'} + typescript@5.5.4: {} + + ufo@1.5.4: {} + + undici-types@5.26.5: {} + + undici-types@6.19.8: {} + + undici@5.28.4: dependencies: - call-bind: 1.0.7 - es-errors: 1.3.0 - is-typed-array: 1.1.13 - dev: true + '@fastify/busboy': 2.1.1 - /typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} - engines: {node: '>= 0.4'} + unimport@3.11.1(rollup@4.21.2)(webpack-sources@3.2.3): 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 - dev: true - - /typed-array-byte-offset@1.0.2: - resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} - engines: {node: '>= 0.4'} - 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 - dev: true - - /typed-array-length@1.0.6: - resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} - engines: {node: '>= 0.4'} - 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 - dev: true - - /typescript@5.4.5: - resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} - engines: {node: '>=14.17'} - hasBin: true - dev: true - - /ufo@1.5.3: - resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} - dev: true - - /unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - dependencies: - call-bind: 1.0.7 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - dev: true - - /undici-types@5.26.5: - resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - - /unicode-canonical-property-names-ecmascript@2.0.0: - resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} - engines: {node: '>=4'} - dev: true - - /unicode-match-property-ecmascript@2.0.0: - resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} - engines: {node: '>=4'} - dependencies: - unicode-canonical-property-names-ecmascript: 2.0.0 - unicode-property-aliases-ecmascript: 2.1.0 - dev: true - - /unicode-match-property-value-ecmascript@2.1.0: - resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} - engines: {node: '>=4'} - dev: true - - /unicode-property-aliases-ecmascript@2.1.0: - resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} - engines: {node: '>=4'} - dev: true - - /unimport@3.7.2(rollup@2.79.1): - resolution: {integrity: sha512-91mxcZTadgXyj3lFWmrGT8GyoRHWuE5fqPOjg5RVtF6vj+OfM5G6WCzXjuYtSgELE5ggB34RY4oiCSEP8I3AHw==} - dependencies: - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) - acorn: 8.12.0 + '@rollup/pluginutils': 5.1.0(rollup@4.21.2) + acorn: 8.12.1 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 + magic-string: 0.30.11 mlly: 1.7.1 pathe: 1.1.2 - pkg-types: 1.1.1 + pkg-types: 1.2.0 scule: 1.3.0 strip-literal: 2.1.0 - unplugin: 1.10.1 + unplugin: 1.13.1(webpack-sources@3.2.3) transitivePeerDependencies: - rollup - dev: true + - webpack-sources - /uniq@1.0.1: - resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==} - dev: false + uniq@1.0.1: {} - /unique-string@2.0.0: - resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} - engines: {node: '>=8'} + universalify@0.1.2: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + unplugin-auto-import@0.18.2(@vueuse/core@10.11.1(vue@3.4.38(typescript@5.5.4)))(rollup@4.21.2)(webpack-sources@3.2.3): dependencies: - crypto-random-string: 2.0.0 - dev: true - - /universalify@0.1.2: - resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} - engines: {node: '>= 4.0.0'} - - /universalify@2.0.1: - resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} - engines: {node: '>= 10.0.0'} - - /unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - dev: false - - /unplugin-auto-import@0.17.6(rollup@2.79.1): - 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 - dependencies: - '@antfu/utils': 0.7.8 - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.1.0(rollup@4.21.2) fast-glob: 3.3.2 local-pkg: 0.5.0 - magic-string: 0.30.10 - minimatch: 9.0.4 - unimport: 3.7.2(rollup@2.79.1) - unplugin: 1.10.1 + magic-string: 0.30.11 + minimatch: 9.0.5 + unimport: 3.11.1(rollup@4.21.2)(webpack-sources@3.2.3) + unplugin: 1.13.1(webpack-sources@3.2.3) + optionalDependencies: + '@vueuse/core': 10.11.1(vue@3.4.38(typescript@5.5.4)) transitivePeerDependencies: - rollup - dev: true + - webpack-sources - /unplugin-vue-components@0.26.0(rollup@2.79.1)(vue@3.4.8): - resolution: {integrity: sha512-s7IdPDlnOvPamjunVxw8kNgKNK8A5KM1YpK5j/p97jEKTjlPNrA0nZBiSfAKKlK1gWZuyWXlKL5dk3EDw874LQ==} - 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-vue-components@0.27.4(@babel/parser@7.25.6)(rollup@4.21.2)(vue@3.4.38(typescript@5.5.4))(webpack-sources@3.2.3): dependencies: - '@antfu/utils': 0.7.8 - '@rollup/pluginutils': 5.1.0(rollup@2.79.1) + '@antfu/utils': 0.7.10 + '@rollup/pluginutils': 5.1.0(rollup@4.21.2) chokidar: 3.6.0 - debug: 4.3.5 + debug: 4.3.7 fast-glob: 3.3.2 - local-pkg: 0.4.3 - magic-string: 0.30.10 - minimatch: 9.0.4 - resolve: 1.22.8 - unplugin: 1.10.1 - vue: 3.4.8 + local-pkg: 0.5.0 + magic-string: 0.30.11 + minimatch: 9.0.5 + mlly: 1.7.1 + unplugin: 1.13.1(webpack-sources@3.2.3) + vue: 3.4.38(typescript@5.5.4) + optionalDependencies: + '@babel/parser': 7.25.6 transitivePeerDependencies: - rollup - supports-color - dev: true + - webpack-sources - /unplugin@1.10.1: - resolution: {integrity: sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==} - engines: {node: '>=14.0.0'} + unplugin@1.13.1(webpack-sources@3.2.3): dependencies: - acorn: 8.12.0 - chokidar: 3.6.0 - webpack-sources: 3.2.3 + acorn: 8.12.1 webpack-virtual-modules: 0.6.2 - dev: true + optionalDependencies: + webpack-sources: 3.2.3 - /unused-filename@2.1.0: - resolution: {integrity: sha512-BMiNwJbuWmqCpAM1FqxCTD7lXF97AvfQC8Kr/DIeA6VtvhJaMDupZ82+inbjl5yVP44PcxOuCSxye1QMS0wZyg==} - engines: {node: '>=8'} + unused-filename@2.1.0: dependencies: modify-filename: 1.1.0 path-exists: 4.0.0 - dev: false - /upath@1.2.0: - resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} - engines: {node: '>=4'} - dev: true - - /update-browserslist-db@1.0.16(browserslist@4.23.1): - resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + update-browserslist-db@1.1.0(browserslist@4.23.3): dependencies: - browserslist: 4.23.1 - escalade: 3.1.2 - picocolors: 1.0.1 - dev: true + browserslist: 4.23.3 + escalade: 3.2.0 + picocolors: 1.1.0 - /uri-js@4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + uri-js@4.4.1: dependencies: punycode: 2.3.1 - /url-polyfill@1.1.12: - resolution: {integrity: sha512-mYFmBHCapZjtcNHW0MDq9967t+z4Dmg5CJ0KqysK3+ZbyoNOWQHksGCTWwDhxGXllkWlOc10Xfko6v4a3ucM6A==} - dev: false + url-polyfill@1.1.12: {} - /utf8-byte-length@1.0.5: - resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} - dev: true + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.13.0 - /util-deprecate@1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + utf8-byte-length@1.0.5: {} - /utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - dev: false + util-deprecate@1.0.2: {} - /uuid@3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: false + utils-merge@1.0.1: {} - /uuid@8.3.2: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} - hasBin: true - dev: false + uuid@3.4.0: {} - /vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - dev: false + uuid@8.3.2: {} - /vdirs@0.1.8(vue@3.4.8): - resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} - peerDependencies: - vue: ^3.0.11 + vary@1.1.2: {} + + vdirs@0.1.8(vue@3.4.38(typescript@5.5.4)): dependencies: evtd: 0.2.4 - vue: 3.4.8 - dev: true + vue: 3.4.38(typescript@5.5.4) - /verror@1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: false - - /verror@1.10.1: - resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} - engines: {node: '>=0.6.0'} - requiresBuild: true + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.4.1 + + verror@1.10.1: dependencies: assert-plus: 1.0.0 core-util-is: 1.0.2 extsprintf: 1.4.1 - dev: true optional: true - /vite-plugin-compression@0.5.1(vite@5.3.1): - resolution: {integrity: sha512-5QJKBDc+gNYVqL/skgFAP81Yuzo9R+EAf19d+EtsMF/i8kFUpNi3J/H01QD3Oo8zBQn+NzoCIFkpPLynoOzaJg==} - peerDependencies: - vite: '>=2.0.0' + vite-plugin-compression@0.5.1(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0)): dependencies: chalk: 4.1.2 - debug: 4.3.5 + debug: 4.3.7 fs-extra: 10.1.0 - vite: 5.3.1(sass@1.77.6)(terser@5.31.1) + vite: 5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0) transitivePeerDependencies: - supports-color - dev: true - /vite-plugin-pwa@0.17.5(vite@5.3.1)(workbox-build@7.1.1)(workbox-window@7.1.0): - resolution: {integrity: sha512-UxRNPiJBzh4tqU/vc8G2TxmrUTzT6BqvSzhszLk62uKsf+npXdvLxGDz9C675f4BJi6MbD2tPnJhi5txlMzxbQ==} - engines: {node: '>=16.0.0'} - peerDependencies: - vite: ^3.1.0 || ^4.0.0 || ^5.0.0 - workbox-build: ^7.0.0 - workbox-window: ^7.0.0 + vite-plugin-wasm@3.3.0(vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0)): dependencies: - debug: 4.3.5 - fast-glob: 3.3.2 - pretty-bytes: 6.1.1 - vite: 5.3.1(sass@1.77.6)(terser@5.31.1) - workbox-build: 7.1.1 - workbox-window: 7.1.0 - transitivePeerDependencies: - - supports-color - dev: true + vite: 5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0) - /vite@5.3.1(sass@1.77.6)(terser@5.31.1): - resolution: {integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==} - 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 + vite@5.4.3(@types/node@22.5.4)(sass@1.78.0)(terser@5.33.0): dependencies: esbuild: 0.21.5 - postcss: 8.4.38 - rollup: 4.18.0 - sass: 1.77.6 - terser: 5.31.1 + postcss: 8.4.45 + rollup: 4.21.2 optionalDependencies: + '@types/node': 22.5.4 fsevents: 2.3.3 - dev: true + sass: 1.78.0 + terser: 5.33.0 - /vooks@0.2.12(vue@3.4.8): - resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==} - peerDependencies: - vue: ^3.0.0 + vooks@0.2.12(vue@3.4.38(typescript@5.5.4)): dependencies: evtd: 0.2.4 - vue: 3.4.8 - dev: true + vue: 3.4.38(typescript@5.5.4) - /vue-demi@0.14.8(vue@3.4.8): - resolution: {integrity: sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==} - engines: {node: '>=12'} - hasBin: true - requiresBuild: true - peerDependencies: - '@vue/composition-api': ^1.0.0-rc.1 - vue: ^3.0.0-0 || ^2.6.0 - peerDependenciesMeta: - '@vue/composition-api': - optional: true - dependencies: - vue: 3.4.8 - dev: false + vscode-uri@3.0.8: {} - /vue-eslint-parser@9.4.3(eslint@8.57.0): - resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} - engines: {node: ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '>=6.0.0' + vue-demi@0.14.10(vue@3.4.38(typescript@5.5.4)): dependencies: - debug: 4.3.5 + vue: 3.4.38(typescript@5.5.4) + + vue-eslint-parser@9.4.3(eslint@8.57.0): + dependencies: + debug: 4.3.7 eslint: 8.57.0 eslint-scope: 7.2.2 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - esquery: 1.5.0 + esquery: 1.6.0 lodash: 4.17.21 - semver: 7.6.2 + semver: 7.6.3 transitivePeerDependencies: - supports-color - dev: true - /vue-router@4.3.3(vue@3.4.8): - resolution: {integrity: sha512-8Q+u+WP4N2SXY38FDcF2H1dUEbYVHVPtPCPZj/GTZx8RCbiB8AtJP9+YIxn4Vs0svMTNQcLIzka4GH7Utkx9xQ==} - peerDependencies: - vue: ^3.2.0 + vue-observe-visibility@2.0.0-alpha.1(vue@3.4.38(typescript@5.5.4)): + dependencies: + vue: 3.4.38(typescript@5.5.4) + + vue-resize@2.0.0-alpha.1(vue@3.4.38(typescript@5.5.4)): + dependencies: + vue: 3.4.38(typescript@5.5.4) + + vue-router@4.4.3(vue@3.4.38(typescript@5.5.4)): dependencies: '@vue/devtools-api': 6.6.3 - vue: 3.4.8 - dev: false + vue: 3.4.38(typescript@5.5.4) - /vue-slider-component@4.1.0-beta.7: - resolution: {integrity: sha512-Qb7K920ZG7PoQswoF6Ias+i3W2rd3k4fpk04JUl82kEUcN86Yg6et7bVSKWt/7VpQe8a5IT3BqCKSCOZ7AJgCA==} - dev: false - - /vue@3.4.8: - resolution: {integrity: sha512-vJffFOe6DqWsAI10v3tDhb1nJrj7CF3CbdQwOznywAsFNoyvrQ1AWQdcIWJpmRpRnw7NFzstzh6fh4w7n1PNdg==} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true + vue-tsc@2.1.6(typescript@5.5.4): dependencies: - '@vue/compiler-dom': 3.4.8 - '@vue/compiler-sfc': 3.4.8 - '@vue/runtime-dom': 3.4.8 - '@vue/server-renderer': 3.4.8(vue@3.4.8) - '@vue/shared': 3.4.8 + '@volar/typescript': 2.4.2 + '@vue/language-core': 2.1.6(typescript@5.5.4) + semver: 7.6.3 + typescript: 5.5.4 - /vueuc@0.4.58(vue@3.4.8): - resolution: {integrity: sha512-Wnj/N8WbPRSxSt+9ji1jtDHPzda5h2OH/0sFBhvdxDRuyCZbjGg3/cKMaKqEoe+dErTexG2R+i6Q8S/Toq1MYg==} - peerDependencies: - vue: ^3.0.11 + vue-virtual-scroller@2.0.0-beta.8(vue@3.4.38(typescript@5.5.4)): dependencies: - '@css-render/vue3-ssr': 0.15.14(vue@3.4.8) + mitt: 2.1.0 + vue: 3.4.38(typescript@5.5.4) + vue-observe-visibility: 2.0.0-alpha.1(vue@3.4.38(typescript@5.5.4)) + vue-resize: 2.0.0-alpha.1(vue@3.4.38(typescript@5.5.4)) + + vue@3.4.38(typescript@5.5.4): + dependencies: + '@vue/compiler-dom': 3.4.38 + '@vue/compiler-sfc': 3.4.38 + '@vue/runtime-dom': 3.4.38 + '@vue/server-renderer': 3.4.38(vue@3.4.38(typescript@5.5.4)) + '@vue/shared': 3.4.38 + optionalDependencies: + typescript: 5.5.4 + + vueuc@0.4.58(vue@3.4.38(typescript@5.5.4)): + dependencies: + '@css-render/vue3-ssr': 0.15.14(vue@3.4.38(typescript@5.5.4)) '@juggle/resize-observer': 3.4.0 css-render: 0.15.14 evtd: 0.2.4 seemly: 0.3.8 - vdirs: 0.1.8(vue@3.4.8) - vooks: 0.2.12(vue@3.4.8) - vue: 3.4.8 - dev: true + vdirs: 0.1.8(vue@3.4.38(typescript@5.5.4)) + vooks: 0.2.12(vue@3.4.38(typescript@5.5.4)) + vue: 3.4.38(typescript@5.5.4) - /webidl-conversions@4.0.2: - resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} - dev: true + webpack-sources@3.2.3: + optional: true - /webpack-sources@3.2.3: - resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} - engines: {node: '>=10.13.0'} - dev: true + webpack-virtual-modules@0.6.2: {} - /webpack-virtual-modules@0.6.2: - resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==} - dev: true + which-module@2.0.1: {} - /whatwg-url@7.1.0: - resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} - dependencies: - lodash.sortby: 4.7.0 - tr46: 1.0.1 - webidl-conversions: 4.0.2 - dev: true - - /which-boxed-primitive@1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - 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 - dev: true - - /which-module@2.0.1: - resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} - dev: false - - /which-typed-array@1.1.15: - resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} - engines: {node: '>= 0.4'} - 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 - dev: true - - /which@1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true + which@1.3.1: dependencies: isexe: 2.0.0 - dev: false - /which@2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true + which@2.0.2: dependencies: isexe: 2.0.0 - dev: true - /word-wrap@1.2.5: - resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} - engines: {node: '>=0.10.0'} - dev: true + word-wrap@1.2.5: {} - /workbox-background-sync@7.1.0: - resolution: {integrity: sha512-rMbgrzueVWDFcEq1610YyDW71z0oAXLfdRHRQcKw4SGihkfOK0JUEvqWHFwA6rJ+6TClnMIn7KQI5PNN1XQXwQ==} - dependencies: - idb: 7.1.1 - workbox-core: 7.1.0 - dev: true - - /workbox-broadcast-update@7.1.0: - resolution: {integrity: sha512-O36hIfhjej/c5ar95pO67k1GQw0/bw5tKP7CERNgK+JdxBANQhDmIuOXZTNvwb2IHBx9hj2kxvcDyRIh5nzOgQ==} - dependencies: - workbox-core: 7.1.0 - dev: true - - /workbox-build@7.1.1: - resolution: {integrity: sha512-WdkVdC70VMpf5NBCtNbiwdSZeKVuhTEd5PV3mAwpTQCGAB5XbOny1P9egEgNdetv4srAMmMKjvBk4RD58LpooA==} - engines: {node: '>=16.0.0'} - dependencies: - '@apideck/better-ajv-errors': 0.3.6(ajv@8.16.0) - '@babel/core': 7.24.7 - '@babel/preset-env': 7.24.7(@babel/core@7.24.7) - '@babel/runtime': 7.24.7 - '@rollup/plugin-babel': 5.3.1(@babel/core@7.24.7)(rollup@2.79.1) - '@rollup/plugin-node-resolve': 15.2.3(rollup@2.79.1) - '@rollup/plugin-replace': 2.4.2(rollup@2.79.1) - '@rollup/plugin-terser': 0.4.4(rollup@2.79.1) - '@surma/rollup-plugin-off-main-thread': 2.2.3 - ajv: 8.16.0 - common-tags: 1.8.2 - fast-json-stable-stringify: 2.1.0 - fs-extra: 9.1.0 - glob: 7.2.3 - lodash: 4.17.21 - pretty-bytes: 5.6.0 - rollup: 2.79.1 - source-map: 0.8.0-beta.0 - stringify-object: 3.3.0 - strip-comments: 2.0.1 - tempy: 0.6.0 - upath: 1.2.0 - workbox-background-sync: 7.1.0 - workbox-broadcast-update: 7.1.0 - workbox-cacheable-response: 7.1.0 - workbox-core: 7.1.0 - workbox-expiration: 7.1.0 - workbox-google-analytics: 7.1.0 - workbox-navigation-preload: 7.1.0 - workbox-precaching: 7.1.0 - workbox-range-requests: 7.1.0 - workbox-recipes: 7.1.0 - workbox-routing: 7.1.0 - workbox-strategies: 7.1.0 - workbox-streams: 7.1.0 - workbox-sw: 7.1.0 - workbox-window: 7.1.0 - transitivePeerDependencies: - - '@types/babel__core' - - supports-color - dev: true - - /workbox-cacheable-response@7.1.0: - resolution: {integrity: sha512-iwsLBll8Hvua3xCuBB9h92+/e0wdsmSVgR2ZlvcfjepZWwhd3osumQB3x9o7flj+FehtWM2VHbZn8UJeBXXo6Q==} - dependencies: - workbox-core: 7.1.0 - dev: true - - /workbox-core@7.1.0: - resolution: {integrity: sha512-5KB4KOY8rtL31nEF7BfvU7FMzKT4B5TkbYa2tzkS+Peqj0gayMT9SytSFtNzlrvMaWgv6y/yvP9C0IbpFjV30Q==} - dev: true - - /workbox-expiration@7.1.0: - resolution: {integrity: sha512-m5DcMY+A63rJlPTbbBNtpJ20i3enkyOtSgYfv/l8h+D6YbbNiA0zKEkCUaMsdDlxggla1oOfRkyqTvl5Ni5KQQ==} - dependencies: - idb: 7.1.1 - workbox-core: 7.1.0 - dev: true - - /workbox-google-analytics@7.1.0: - resolution: {integrity: sha512-FvE53kBQHfVTcZyczeBVRexhh7JTkyQ8HAvbVY6mXd2n2A7Oyz/9fIwnY406ZcDhvE4NFfKGjW56N4gBiqkrew==} - dependencies: - workbox-background-sync: 7.1.0 - workbox-core: 7.1.0 - workbox-routing: 7.1.0 - workbox-strategies: 7.1.0 - dev: true - - /workbox-navigation-preload@7.1.0: - resolution: {integrity: sha512-4wyAbo0vNI/X0uWNJhCMKxnPanNyhybsReMGN9QUpaePLTiDpKxPqFxl4oUmBNddPwIXug01eTSLVIFXimRG/A==} - dependencies: - workbox-core: 7.1.0 - dev: true - - /workbox-precaching@7.1.0: - resolution: {integrity: sha512-LyxzQts+UEpgtmfnolo0hHdNjoB7EoRWcF7EDslt+lQGd0lW4iTvvSe3v5JiIckQSB5KTW5xiCqjFviRKPj1zA==} - dependencies: - workbox-core: 7.1.0 - workbox-routing: 7.1.0 - workbox-strategies: 7.1.0 - dev: true - - /workbox-range-requests@7.1.0: - resolution: {integrity: sha512-m7+O4EHolNs5yb/79CrnwPR/g/PRzMFYEdo01LqwixVnc/sbzNSvKz0d04OE3aMRel1CwAAZQheRsqGDwATgPQ==} - dependencies: - workbox-core: 7.1.0 - dev: true - - /workbox-recipes@7.1.0: - resolution: {integrity: sha512-NRrk4ycFN9BHXJB6WrKiRX3W3w75YNrNrzSX9cEZgFB5ubeGoO8s/SDmOYVrFYp9HMw6sh1Pm3eAY/1gVS8YLg==} - dependencies: - workbox-cacheable-response: 7.1.0 - workbox-core: 7.1.0 - workbox-expiration: 7.1.0 - workbox-precaching: 7.1.0 - workbox-routing: 7.1.0 - workbox-strategies: 7.1.0 - dev: true - - /workbox-routing@7.1.0: - resolution: {integrity: sha512-oOYk+kLriUY2QyHkIilxUlVcFqwduLJB7oRZIENbqPGeBP/3TWHYNNdmGNhz1dvKuw7aqvJ7CQxn27/jprlTdg==} - dependencies: - workbox-core: 7.1.0 - dev: true - - /workbox-strategies@7.1.0: - resolution: {integrity: sha512-/UracPiGhUNehGjRm/tLUQ+9PtWmCbRufWtV0tNrALuf+HZ4F7cmObSEK+E4/Bx1p8Syx2tM+pkIrvtyetdlew==} - dependencies: - workbox-core: 7.1.0 - dev: true - - /workbox-streams@7.1.0: - resolution: {integrity: sha512-WyHAVxRXBMfysM8ORwiZnI98wvGWTVAq/lOyBjf00pXFvG0mNaVz4Ji+u+fKa/mf1i2SnTfikoYKto4ihHeS6w==} - dependencies: - workbox-core: 7.1.0 - workbox-routing: 7.1.0 - dev: true - - /workbox-sw@7.1.0: - resolution: {integrity: sha512-Hml/9+/njUXBglv3dtZ9WBKHI235AQJyLBV1G7EFmh4/mUdSQuXui80RtjDeVRrXnm/6QWgRUEHG3/YBVbxtsA==} - dev: true - - /workbox-window@7.1.0: - resolution: {integrity: sha512-ZHeROyqR+AS5UPzholQRDttLFqGMwP0Np8MKWAdyxsDETxq3qOAyXvqessc3GniohG6e0mAqSQyKOHmT8zPF7g==} - dependencies: - '@types/trusted-types': 2.0.7 - workbox-core: 7.1.0 - dev: true - - /wrap-ansi@6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: false - - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 - /wrap-ansi@8.1.0: - resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} - engines: {node: '>=12'} + 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 - dev: true - /wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + wrappy@1.0.2: {} - /xml-name-validator@4.0.0: - resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} - engines: {node: '>=12'} - dev: true + ws@8.18.0: {} - /xml2js@0.6.2: - resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} - engines: {node: '>=4.0.0'} + xml-name-validator@4.0.0: {} + + xml2js@0.6.2: dependencies: sax: 1.4.1 xmlbuilder: 11.0.1 - dev: false - /xmlbuilder@11.0.1: - resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} - engines: {node: '>=4.0'} - dev: false + xmlbuilder@11.0.1: {} - /xmlbuilder@15.1.1: - resolution: {integrity: sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==} - engines: {node: '>=8.0'} - dev: true + xmlbuilder@15.1.1: {} - /y18n@4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - dev: false + y18n@4.0.3: {} - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} + y18n@5.0.8: {} - /yallist@3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true + yallist@3.1.1: {} - /yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true + yallist@4.0.0: {} - /yargs-parser@18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} + yargs-parser@18.1.3: dependencies: camelcase: 5.3.1 decamelize: 1.2.0 - dev: false - /yargs-parser@21.1.1: - resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} - engines: {node: '>=12'} + yargs-parser@21.1.1: {} - /yargs@15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} + yargs@15.4.1: dependencies: cliui: 6.0.0 decamelize: 1.2.0 @@ -7932,36 +7753,26 @@ packages: which-module: 2.0.1 y18n: 4.0.3 yargs-parser: 18.1.3 - dev: false - /yargs@17.7.2: - resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} - engines: {node: '>=12'} + yargs@17.7.2: dependencies: cliui: 8.0.1 - escalade: 3.1.2 + escalade: 3.2.0 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 - /yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + yauzl@2.10.0: dependencies: buffer-crc32: 0.2.13 fd-slicer: 1.1.0 - /yocto-queue@0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true + yocto-queue@0.1.0: {} - /zip-stream@4.1.1: - resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} - engines: {node: '>= 10'} + zip-stream@4.1.1: dependencies: archiver-utils: 3.0.4 compress-commons: 4.1.2 readable-stream: 3.6.2 - dev: true diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 1d8e59d..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/favicon.png b/public/favicon.png deleted file mode 100644 index 297d702..0000000 Binary files a/public/favicon.png and /dev/null differ diff --git a/public/font/HarmonyOS_Sans_SC.woff2 b/public/font/HarmonyOS_Sans_SC.woff2 deleted file mode 100644 index bc7a7c5..0000000 Binary files a/public/font/HarmonyOS_Sans_SC.woff2 and /dev/null differ diff --git a/public/font/HarmonyOS_Sans_SC_Bold.woff2 b/public/font/HarmonyOS_Sans_SC_Bold.woff2 deleted file mode 100644 index 972e3d1..0000000 Binary files a/public/font/HarmonyOS_Sans_SC_Bold.woff2 and /dev/null differ diff --git a/public/font/font.css b/public/font/font.css deleted file mode 100644 index a06949c..0000000 --- a/public/font/font.css +++ /dev/null @@ -1,13 +0,0 @@ -@font-face { - font-family: "HarmonyOS Sans"; - src: url("./HarmonyOS_Sans_SC.woff2") format("woff2"); - font-weight: normal; - font-style: normal; -} - -@font-face { - font-family: "HarmonyOS Sans"; - src: url("./HarmonyOS_Sans_SC_Bold.woff2") format("woff2"); - font-weight: bold; - font-style: normal; -} diff --git a/public/fonts/font.css b/public/fonts/font.css new file mode 100644 index 0000000..9e8a70a --- /dev/null +++ b/public/fonts/font.css @@ -0,0 +1,6 @@ +@font-face { + font-family: "logo"; + src: url("./logo.woff2") format("woff2"); + font-weight: normal; + font-style: normal; +} diff --git a/public/fonts/logo.woff2 b/public/fonts/logo.woff2 new file mode 100644 index 0000000..10568d9 Binary files /dev/null and b/public/fonts/logo.woff2 differ diff --git a/public/imgs/icons/favicon-16x16.png b/public/icons/favicon-16x16.png similarity index 100% rename from public/imgs/icons/favicon-16x16.png rename to public/icons/favicon-16x16.png diff --git a/public/imgs/icons/favicon-192x192.png b/public/icons/favicon-192x192.png similarity index 100% rename from public/imgs/icons/favicon-192x192.png rename to public/icons/favicon-192x192.png diff --git a/public/imgs/icons/favicon-256x256.png b/public/icons/favicon-256x256.png similarity index 100% rename from public/imgs/icons/favicon-256x256.png rename to public/icons/favicon-256x256.png diff --git a/public/imgs/icons/favicon-32x32.png b/public/icons/favicon-32x32.png similarity index 100% rename from public/imgs/icons/favicon-32x32.png rename to public/icons/favicon-32x32.png diff --git a/public/imgs/icons/favicon-512x512.png b/public/icons/favicon-512x512.png similarity index 100% rename from public/imgs/icons/favicon-512x512.png rename to public/icons/favicon-512x512.png diff --git a/public/imgs/icons/favicon-96x96.png b/public/icons/favicon-96x96.png similarity index 100% rename from public/imgs/icons/favicon-96x96.png rename to public/icons/favicon-96x96.png diff --git a/public/imgs/icons/favicon.ico b/public/icons/favicon.ico similarity index 100% rename from public/imgs/icons/favicon.ico rename to public/icons/favicon.ico diff --git a/public/imgs/icons/favicon.png b/public/icons/favicon.png similarity index 100% rename from public/imgs/icons/favicon.png rename to public/icons/favicon.png diff --git a/public/icons/icon.icns b/public/icons/icon.icns new file mode 100644 index 0000000..45523b6 Binary files /dev/null and b/public/icons/icon.icns differ diff --git a/public/imgs/icons/favicon.svg b/public/icons/logo.svg similarity index 100% rename from public/imgs/icons/favicon.svg rename to public/icons/logo.svg diff --git a/public/icons/thumbar/next-dark.png b/public/icons/thumbar/next-dark.png new file mode 100644 index 0000000..c169f51 Binary files /dev/null and b/public/icons/thumbar/next-dark.png differ diff --git a/public/icons/thumbar/next-light.png b/public/icons/thumbar/next-light.png new file mode 100644 index 0000000..3533021 Binary files /dev/null and b/public/icons/thumbar/next-light.png differ diff --git a/public/icons/thumbar/pause-dark.png b/public/icons/thumbar/pause-dark.png new file mode 100644 index 0000000..b6ba009 Binary files /dev/null and b/public/icons/thumbar/pause-dark.png differ diff --git a/public/icons/thumbar/pause-light.png b/public/icons/thumbar/pause-light.png new file mode 100644 index 0000000..1dd1105 Binary files /dev/null and b/public/icons/thumbar/pause-light.png differ diff --git a/public/icons/thumbar/play-dark.png b/public/icons/thumbar/play-dark.png new file mode 100644 index 0000000..85307a4 Binary files /dev/null and b/public/icons/thumbar/play-dark.png differ diff --git a/public/icons/thumbar/play-light.png b/public/icons/thumbar/play-light.png new file mode 100644 index 0000000..6d03554 Binary files /dev/null and b/public/icons/thumbar/play-light.png differ diff --git a/public/icons/thumbar/prev-dark.png b/public/icons/thumbar/prev-dark.png new file mode 100644 index 0000000..7ff7176 Binary files /dev/null and b/public/icons/thumbar/prev-dark.png differ diff --git a/public/icons/thumbar/prev-light.png b/public/icons/thumbar/prev-light.png new file mode 100644 index 0000000..e8ac0a8 Binary files /dev/null and b/public/icons/thumbar/prev-light.png differ diff --git a/public/icons/tray/like-dark.png b/public/icons/tray/like-dark.png new file mode 100644 index 0000000..10b2903 Binary files /dev/null and b/public/icons/tray/like-dark.png differ diff --git a/public/icons/tray/like-light.png b/public/icons/tray/like-light.png new file mode 100644 index 0000000..0c8fdff Binary files /dev/null and b/public/icons/tray/like-light.png differ diff --git a/public/icons/tray/lock-dark.png b/public/icons/tray/lock-dark.png new file mode 100644 index 0000000..48a29cb Binary files /dev/null and b/public/icons/tray/lock-dark.png differ diff --git a/public/icons/tray/lock-light.png b/public/icons/tray/lock-light.png new file mode 100644 index 0000000..1c7ec9d Binary files /dev/null and b/public/icons/tray/lock-light.png differ diff --git a/public/icons/tray/lyric-dark.png b/public/icons/tray/lyric-dark.png new file mode 100644 index 0000000..a6fde17 Binary files /dev/null and b/public/icons/tray/lyric-dark.png differ diff --git a/public/icons/tray/lyric-light.png b/public/icons/tray/lyric-light.png new file mode 100644 index 0000000..def0853 Binary files /dev/null and b/public/icons/tray/lyric-light.png differ diff --git a/public/icons/tray/music-dark.png b/public/icons/tray/music-dark.png new file mode 100644 index 0000000..d6147fd Binary files /dev/null and b/public/icons/tray/music-dark.png differ diff --git a/public/icons/tray/music-light.png b/public/icons/tray/music-light.png new file mode 100644 index 0000000..f5b02af Binary files /dev/null and b/public/icons/tray/music-light.png differ diff --git a/public/icons/tray/next-dark.png b/public/icons/tray/next-dark.png new file mode 100644 index 0000000..c169f51 Binary files /dev/null and b/public/icons/tray/next-dark.png differ diff --git a/public/icons/tray/next-light.png b/public/icons/tray/next-light.png new file mode 100644 index 0000000..3533021 Binary files /dev/null and b/public/icons/tray/next-light.png differ diff --git a/public/icons/tray/pause-dark.png b/public/icons/tray/pause-dark.png new file mode 100644 index 0000000..b6ba009 Binary files /dev/null and b/public/icons/tray/pause-dark.png differ diff --git a/public/icons/tray/pause-light.png b/public/icons/tray/pause-light.png new file mode 100644 index 0000000..1dd1105 Binary files /dev/null and b/public/icons/tray/pause-light.png differ diff --git a/public/icons/tray/play-dark.png b/public/icons/tray/play-dark.png new file mode 100644 index 0000000..85307a4 Binary files /dev/null and b/public/icons/tray/play-dark.png differ diff --git a/public/icons/tray/play-light.png b/public/icons/tray/play-light.png new file mode 100644 index 0000000..6d03554 Binary files /dev/null and b/public/icons/tray/play-light.png differ diff --git a/public/icons/tray/power-dark.png b/public/icons/tray/power-dark.png new file mode 100644 index 0000000..f149a9c Binary files /dev/null and b/public/icons/tray/power-dark.png differ diff --git a/public/icons/tray/power-light.png b/public/icons/tray/power-light.png new file mode 100644 index 0000000..12ab718 Binary files /dev/null and b/public/icons/tray/power-light.png differ diff --git a/public/icons/tray/prev-dark.png b/public/icons/tray/prev-dark.png new file mode 100644 index 0000000..7ff7176 Binary files /dev/null and b/public/icons/tray/prev-dark.png differ diff --git a/public/icons/tray/prev-light.png b/public/icons/tray/prev-light.png new file mode 100644 index 0000000..e8ac0a8 Binary files /dev/null and b/public/icons/tray/prev-light.png differ diff --git a/public/icons/tray/repeat-dark.png b/public/icons/tray/repeat-dark.png new file mode 100644 index 0000000..fb6fc25 Binary files /dev/null and b/public/icons/tray/repeat-dark.png differ diff --git a/public/icons/tray/repeat-light.png b/public/icons/tray/repeat-light.png new file mode 100644 index 0000000..38332ca Binary files /dev/null and b/public/icons/tray/repeat-light.png differ diff --git a/public/icons/tray/repeat-once-dark.png b/public/icons/tray/repeat-once-dark.png new file mode 100644 index 0000000..8a10aa4 Binary files /dev/null and b/public/icons/tray/repeat-once-dark.png differ diff --git a/public/icons/tray/repeat-once-light.png b/public/icons/tray/repeat-once-light.png new file mode 100644 index 0000000..76d8212 Binary files /dev/null and b/public/icons/tray/repeat-once-light.png differ diff --git a/public/icons/tray/setting-dark.png b/public/icons/tray/setting-dark.png new file mode 100644 index 0000000..1a1ac1f Binary files /dev/null and b/public/icons/tray/setting-dark.png differ diff --git a/public/icons/tray/setting-light.png b/public/icons/tray/setting-light.png new file mode 100644 index 0000000..dabf0ac Binary files /dev/null and b/public/icons/tray/setting-light.png differ diff --git a/public/icons/tray/shuffle-dark.png b/public/icons/tray/shuffle-dark.png new file mode 100644 index 0000000..755a33a Binary files /dev/null and b/public/icons/tray/shuffle-dark.png differ diff --git a/public/icons/tray/shuffle-light.png b/public/icons/tray/shuffle-light.png new file mode 100644 index 0000000..d200958 Binary files /dev/null and b/public/icons/tray/shuffle-light.png differ diff --git a/public/icons/tray/tray.ico b/public/icons/tray/tray.ico new file mode 100644 index 0000000..9d36dc5 Binary files /dev/null and b/public/icons/tray/tray.ico differ diff --git a/public/icons/tray/tray@32.png b/public/icons/tray/tray@32.png new file mode 100644 index 0000000..5a7aea4 Binary files /dev/null and b/public/icons/tray/tray@32.png differ diff --git a/public/icons/tray/unlike-dark.png b/public/icons/tray/unlike-dark.png new file mode 100644 index 0000000..75d67e4 Binary files /dev/null and b/public/icons/tray/unlike-dark.png differ diff --git a/public/icons/tray/unlike-light.png b/public/icons/tray/unlike-light.png new file mode 100644 index 0000000..f70ab80 Binary files /dev/null and b/public/icons/tray/unlike-light.png differ diff --git a/public/icons/tray/unlock-dark.png b/public/icons/tray/unlock-dark.png new file mode 100644 index 0000000..34ed30c Binary files /dev/null and b/public/icons/tray/unlock-dark.png differ diff --git a/public/icons/tray/unlock-light.png b/public/icons/tray/unlock-light.png new file mode 100644 index 0000000..0802975 Binary files /dev/null and b/public/icons/tray/unlock-light.png differ diff --git a/public/imgs/pic/album.jpg b/public/images/album.jpg similarity index 100% rename from public/imgs/pic/album.jpg rename to public/images/album.jpg diff --git a/public/images/annual.png b/public/images/annual.png new file mode 100644 index 0000000..3ec3e11 Binary files /dev/null and b/public/images/annual.png differ diff --git a/public/imgs/pic/artist.jpg b/public/images/artist.jpg similarity index 100% rename from public/imgs/pic/artist.jpg rename to public/images/artist.jpg diff --git a/public/images/avatar.jpg b/public/images/avatar.jpg new file mode 100644 index 0000000..831b4e4 Binary files /dev/null and b/public/images/avatar.jpg differ diff --git a/public/imgs/pic/pointer.png b/public/images/pointer.png similarity index 100% rename from public/imgs/pic/pointer.png rename to public/images/pointer.png diff --git a/public/imgs/pic/record.png b/public/images/record.png similarity index 100% rename from public/imgs/pic/record.png rename to public/images/record.png diff --git a/public/imgs/pic/song.jpg b/public/images/song.jpg similarity index 100% rename from public/imgs/pic/song.jpg rename to public/images/song.jpg diff --git a/public/imgs/pic/video.jpg b/public/images/video.jpg similarity index 100% rename from public/imgs/pic/video.jpg rename to public/images/video.jpg diff --git a/public/imgs/pic/vip.png b/public/images/vip.png similarity index 100% rename from public/imgs/pic/vip.png rename to public/images/vip.png diff --git a/public/imgs/icons/android-chrome-192x192.png b/public/imgs/icons/android-chrome-192x192.png deleted file mode 100644 index e055c00..0000000 Binary files a/public/imgs/icons/android-chrome-192x192.png and /dev/null differ diff --git a/public/imgs/icons/android-chrome-512x512.png b/public/imgs/icons/android-chrome-512x512.png deleted file mode 100644 index 82e8cb3..0000000 Binary files a/public/imgs/icons/android-chrome-512x512.png and /dev/null differ diff --git a/public/imgs/icons/apple-touch-icon.png b/public/imgs/icons/apple-touch-icon.png deleted file mode 100644 index a63ddb9..0000000 Binary files a/public/imgs/icons/apple-touch-icon.png and /dev/null differ diff --git a/public/imgs/icons/mstile-150x150.png b/public/imgs/icons/mstile-150x150.png deleted file mode 100644 index d3083e6..0000000 Binary files a/public/imgs/icons/mstile-150x150.png and /dev/null differ diff --git a/public/imgs/icons/next-dark.png b/public/imgs/icons/next-dark.png deleted file mode 100644 index c3b44f4..0000000 Binary files a/public/imgs/icons/next-dark.png and /dev/null differ diff --git a/public/imgs/icons/next-light.png b/public/imgs/icons/next-light.png deleted file mode 100644 index 1703a46..0000000 Binary files a/public/imgs/icons/next-light.png and /dev/null differ diff --git a/public/imgs/icons/open-dark.png b/public/imgs/icons/open-dark.png deleted file mode 100644 index 75176e9..0000000 Binary files a/public/imgs/icons/open-dark.png and /dev/null differ diff --git a/public/imgs/icons/open-light.png b/public/imgs/icons/open-light.png deleted file mode 100644 index 2c6e210..0000000 Binary files a/public/imgs/icons/open-light.png and /dev/null differ diff --git a/public/imgs/icons/pause-dark.png b/public/imgs/icons/pause-dark.png deleted file mode 100644 index c7371d3..0000000 Binary files a/public/imgs/icons/pause-dark.png and /dev/null differ diff --git a/public/imgs/icons/pause-light.png b/public/imgs/icons/pause-light.png deleted file mode 100644 index e7e09fc..0000000 Binary files a/public/imgs/icons/pause-light.png and /dev/null differ diff --git a/public/imgs/icons/play-dark.png b/public/imgs/icons/play-dark.png deleted file mode 100644 index 4ca5f85..0000000 Binary files a/public/imgs/icons/play-dark.png and /dev/null differ diff --git a/public/imgs/icons/play-light.png b/public/imgs/icons/play-light.png deleted file mode 100644 index 5bac4cc..0000000 Binary files a/public/imgs/icons/play-light.png and /dev/null differ diff --git a/public/imgs/icons/power-dark.png b/public/imgs/icons/power-dark.png deleted file mode 100644 index aaa0a7a..0000000 Binary files a/public/imgs/icons/power-dark.png and /dev/null differ diff --git a/public/imgs/icons/power-light.png b/public/imgs/icons/power-light.png deleted file mode 100644 index efd9be1..0000000 Binary files a/public/imgs/icons/power-light.png and /dev/null differ diff --git a/public/imgs/icons/prev-dark.png b/public/imgs/icons/prev-dark.png deleted file mode 100644 index 22c3b50..0000000 Binary files a/public/imgs/icons/prev-dark.png and /dev/null differ diff --git a/public/imgs/icons/prev-light.png b/public/imgs/icons/prev-light.png deleted file mode 100644 index 40f373f..0000000 Binary files a/public/imgs/icons/prev-light.png and /dev/null differ diff --git a/public/imgs/icons/safari-pinned-tab.svg b/public/imgs/icons/safari-pinned-tab.svg deleted file mode 100644 index 0b27da9..0000000 --- a/public/imgs/icons/safari-pinned-tab.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - -Created by potrace 1.14, written by Peter Selinger 2001-2017 - - - - - diff --git a/public/imgs/icons/setting-dark.png b/public/imgs/icons/setting-dark.png deleted file mode 100644 index 6471ad7..0000000 Binary files a/public/imgs/icons/setting-dark.png and /dev/null differ diff --git a/public/imgs/icons/setting-light.png b/public/imgs/icons/setting-light.png deleted file mode 100644 index 75b2ab8..0000000 Binary files a/public/imgs/icons/setting-light.png and /dev/null differ diff --git a/public/imgs/pic/avatar.png b/public/imgs/pic/avatar.png deleted file mode 100644 index b0aa697..0000000 Binary files a/public/imgs/pic/avatar.png and /dev/null differ diff --git a/public/imgs/pic/cover-2.jpg b/public/imgs/pic/cover-2.jpg deleted file mode 100644 index 1e194c0..0000000 Binary files a/public/imgs/pic/cover-2.jpg and /dev/null differ diff --git a/public/imgs/pic/cover.jpg b/public/imgs/pic/cover.jpg deleted file mode 100644 index dabd0e1..0000000 Binary files a/public/imgs/pic/cover.jpg and /dev/null differ diff --git a/public/imgs/pic/default.jpg b/public/imgs/pic/default.jpg deleted file mode 100644 index 8b9188f..0000000 Binary files a/public/imgs/pic/default.jpg and /dev/null differ diff --git a/public/imgs/pic/like.jpg b/public/imgs/pic/like.jpg deleted file mode 100644 index 1c5556d..0000000 Binary files a/public/imgs/pic/like.jpg and /dev/null differ diff --git a/public/imgs/pic/pl-1.jpg b/public/imgs/pic/pl-1.jpg deleted file mode 100644 index 009f799..0000000 Binary files a/public/imgs/pic/pl-1.jpg and /dev/null differ diff --git a/public/imgs/pic/pl-2.jpg b/public/imgs/pic/pl-2.jpg deleted file mode 100644 index 344c474..0000000 Binary files a/public/imgs/pic/pl-2.jpg and /dev/null differ diff --git a/public/imgs/pic/pl-3.jpg b/public/imgs/pic/pl-3.jpg deleted file mode 100644 index dbc69d0..0000000 Binary files a/public/imgs/pic/pl-3.jpg and /dev/null differ diff --git a/public/imgs/pic/pl-4.jpg b/public/imgs/pic/pl-4.jpg deleted file mode 100644 index a568bed..0000000 Binary files a/public/imgs/pic/pl-4.jpg and /dev/null differ diff --git a/public/imgs/pic/radar-private.jpg b/public/imgs/pic/radar-private.jpg deleted file mode 100644 index a7e8c36..0000000 Binary files a/public/imgs/pic/radar-private.jpg and /dev/null differ diff --git a/public/imgs/pic/radar-treasure.jpg b/public/imgs/pic/radar-treasure.jpg deleted file mode 100644 index dc12e16..0000000 Binary files a/public/imgs/pic/radar-treasure.jpg and /dev/null differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..1f53798 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/src/App.vue b/src/App.vue index 52f607d..1e68e44 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,247 +1,146 @@ - diff --git a/src/api/album.js b/src/api/album.js deleted file mode 100644 index b8fb167..0000000 --- a/src/api/album.js +++ /dev/null @@ -1,37 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 专辑部分 - */ - -/** - * 获取专辑内容 - * @param {number} id - 专辑id - */ -export const getAlbumDetail = (id) => { - return axios({ - method: "GET", - url: "/album", - params: { - id, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 收藏/取消收藏专辑 - * @param {number} t - 操作类型,1为收藏,2为取消收藏 - * @param {number} id - 专辑id - */ -export const likeAlbum = (t, id) => { - return axios({ - method: "GET", - url: "/album/sub", - params: { - t, - id, - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/album.ts b/src/api/album.ts new file mode 100644 index 0000000..cc149c7 --- /dev/null +++ b/src/api/album.ts @@ -0,0 +1,18 @@ +import request from "@/utils/request"; + +// 获取专辑详情 +export const albumDetail = (id: number) => { + return request({ url: "/album", params: { id } }); +}; + +// 收藏/取消收藏专辑 +export const likeAlbum = (id: number, t: number = 1 | 2) => { + return request({ + url: "/album/sub", + params: { + id, + t, + timestamp: new Date().getTime(), + }, + }); +}; diff --git a/src/api/artist.js b/src/api/artist.ts similarity index 53% rename from src/api/artist.js rename to src/api/artist.ts index 6203ef6..8310500 100644 --- a/src/api/artist.js +++ b/src/api/artist.ts @@ -1,26 +1,27 @@ -import axios from "@/utils/request"; - -/** - * 歌手部分 - */ +import request from "@/utils/request"; /** * 歌手分类列表 * @param {number} type - 歌手类型(-1:全部 1:男歌手 2:女歌手 3:乐队) * @param {number} area - 歌手区域(-1:全部 7:华语 96:欧美 8:日本 16:韩国 0:其他) - * @param {number} [limit=50] - 返回数量,默认 50 + * @param {number|string} initial - 首字母索引查找参数 * @param {number} [offset=0] - 偏移数量,默认 0 - * @param {number} initial - 首字母索引查找参数 + * @param {number} [limit=50] - 返回数量,默认 50 */ -export const getArtistList = (type = -1, area = -1, offset = 0, initial = -1, limit = 50) => { - return axios({ - method: "GET", +export const artistTypeList = ( + type: number = -1, + area: number = -1, + initial: number | string = -1, + offset: number = 0, + limit: number = 50, +) => { + return request({ url: "/artist/list", params: { type, area, - offset, initial, + offset, limit, }, }); @@ -30,13 +31,10 @@ export const getArtistList = (type = -1, area = -1, offset = 0, initial = -1, li * 获取歌手详情 * @param {number} id - 歌手id */ -export const getArtistDetail = (id) => { - return axios({ - method: "GET", +export const artistDetail = (id: number) => { + return request({ url: "/artist/detail", - params: { - id, - }, + params: { id }, }); }; @@ -44,14 +42,10 @@ export const getArtistDetail = (id) => { * 获取歌手部分信息和热门歌曲 * @param {number} id - 歌手id */ -export const getArtistSongs = (id) => { - return axios({ - method: "GET", +export const artistHotSongs = (id: number) => { + return request({ url: "/artists", - params: { - id, - timestamp: new Date().getTime(), - }, + params: { id }, }); }; @@ -62,17 +56,15 @@ export const getArtistSongs = (id) => { * @param {number} [offset=0] - 偏移数量,默认0 * @param {string} order - hot: 热门, time: 时间 */ -export const getArtistAllSongs = (id, limit = 50, offset = 0, order = "hot") => { - return axios({ - method: "GET", +export const artistAllSongs = ( + id: number, + limit: number = 50, + offset: number = 0, + order: "hot" | "time" = "hot", +) => { + return request({ url: "/artist/songs", - params: { - id, - limit, - offset, - order, - timestamp: new Date().getTime(), - }, + params: { id, limit, offset, order }, }); }; @@ -82,15 +74,10 @@ export const getArtistAllSongs = (id, limit = 50, offset = 0, order = "hot") => * @param {number} [limit=50] - 返回数量,默认50 * @param {number} [offset=0] - 偏移数量,默认0 */ -export const getArtistAblums = (id, limit = 50, offset = 0) => { - return axios({ - method: "GET", +export const artistAblums = (id: number, limit: number = 50, offset: number = 0) => { + return request({ url: "/artist/album", - params: { - id, - limit, - offset, - }, + params: { id, limit, offset }, }); }; @@ -100,15 +87,10 @@ export const getArtistAblums = (id, limit = 50, offset = 0) => { * @param {number} [limit=50] - 返回数量,默认50 * @param {number} [offset=0] - 偏移数量,默认0 */ -export const getArtistVideos = (id, limit = 50, offset = 0) => { - return axios({ - method: "GET", +export const artistVideos = (id: number, limit: number = 50, offset: number = 0) => { + return request({ url: "/artist/mv", - params: { - id, - limit, - offset, - }, + params: { id, limit, offset }, }); }; @@ -117,14 +99,21 @@ export const getArtistVideos = (id, limit = 50, offset = 0) => { * @param {number} t - 操作类型,1 为收藏,其他为取消收藏 * @param {number} id - 歌手id */ -export const likeArtist = (t, id) => { - return axios({ - method: "GET", +export const likeArtist = (id: number, t: number = 1 | 2) => { + return request({ url: "/artist/sub", - params: { - t, - id, - timestamp: new Date().getTime(), - }, + params: { id, t, timestamp: new Date().getTime() }, + }); +}; + +/** + * 搜索歌手 + * @param {string} keyword - 关键词 + * @param {number} [limit=10] - 返回数量 + */ +export const searchArtist = (keyword: string, limit: number = 10) => { + return request({ + url: "/ugc/artist/search", + params: { keyword, limit }, }); }; diff --git a/src/api/cloud.js b/src/api/cloud.js deleted file mode 100644 index add9dd1..0000000 --- a/src/api/cloud.js +++ /dev/null @@ -1,79 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 云盘部分 - */ - -/** - * 获取云盘数据 - * @param {number} [limit=50] - 返回数量,默认 50 - * @param {number} [offset=0] - 偏移数量,默认 0 - */ -export const getUserCloud = (limit = 50, offset = 0) => { - return axios({ - method: "GET", - url: "/user/cloud", - params: { - limit, - offset, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 用户云盘歌曲删除 - * @param {string} id - 歌曲的id - */ -export const setCloudDel = (id) => { - return axios({ - method: "GET", - url: "/user/cloud/del", - params: { - id, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 云盘歌曲信息匹配纠正 - * @param {string} uid - 用户 id - * @param {string} sid - 原歌曲 id - * @param {string} asid - 要匹配的歌曲 id - */ -export const setCloudMatch = (uid, sid, asid) => { - return axios({ - method: "GET", - url: "/cloud/match", - params: { - uid, - sid, - asid, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 用户云盘上传 - * @param {File} file - 要上传的文件 - */ -export const upCloudSong = (file, onUploadProgress) => { - const formData = new FormData(); - formData.append("songFile", file); - return axios({ - url: "/cloud", - method: "POST", - hiddenBar: true, - params: { - timestamp: new Date().getTime(), - }, - data: formData, - headers: { - "Content-Type": "multipart/form-data", - }, - timeout: 200000, - onUploadProgress, - }); -}; diff --git a/src/api/cloud.ts b/src/api/cloud.ts new file mode 100644 index 0000000..360dbf7 --- /dev/null +++ b/src/api/cloud.ts @@ -0,0 +1,59 @@ +import request from "@/utils/request"; + +// 获取云盘数据 +export const userCloud = (limit: number = 50, offset: number = 0) => { + return request({ + url: "/user/cloud", + params: { + limit, + offset, + timestamp: Date.now(), + }, + }); +}; + +// 云盘歌曲删除 +export const deleteCloudSong = (id: number) => { + return request({ + url: "/user/cloud/del", + params: { + id, + timestamp: Date.now(), + }, + }); +}; + +/** + * 云盘歌曲信息匹配纠正 + * @param {string} uid - 用户 id + * @param {string} sid - 原歌曲 id + * @param {string} asid - 要匹配的歌曲 id + */ +export const matchCloudSong = (uid: number, sid: number, asid: number) => { + return request({ + url: "/cloud/match", + params: { + uid, + sid, + asid, + timestamp: Date.now(), + }, + }); +}; + +// 上传歌曲到云盘 +export const uploadCloudSong = (file: File) => { + const formData = new FormData(); + formData.append("songFile", file); + return request({ + url: "/cloud", + method: "post", + headers: { + "Content-Type": "multipart/form-data", + }, + data: formData, + params: { + timestamp: Date.now(), + }, + }); +}; diff --git a/src/api/comment.js b/src/api/comment.js deleted file mode 100644 index 5d0c9aa..0000000 --- a/src/api/comment.js +++ /dev/null @@ -1,118 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 评论部分 - */ - -/** - * 获取评论 - * @param {number} id - 对应资源的 id - * @param {string} type - 对应资源的类型,0: 歌曲, 1: mv, 2: 歌单, 3: 专辑, 4: 电台节目, 5: 视频, 6: 动态, 7: 电台 - * @param {number} pageNo - 分页参数,第 N 页, 默认 1 - * @param {number} pageSize - 分页参数,每页多少条数据, 默认 20 - * @param {number} sortType - 排序方式, 1:按推荐排序, 2:按热度排序, 3:按时间排序 - * @param {number} cursor - 当 sortType 为 3 时且页数不是第一页时需传入, 值为上一条数据的 time - */ -export const getComment = (id, type = 0, pageNo = 1, sortType = 3, pageSize = 20, cursor) => { - return axios({ - method: "GET", - url: "/comment/new", - params: { - id, - type, - pageNo, - pageSize, - sortType, - cursor, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取热门评论 - * @param {number} id - 对应资源的 id - * @param {string} type - 对应资源的类型,0: 歌曲, 1: mv, 2: 歌单, 3: 专辑, 4: 电台节目, 5: 视频, 6: 动态, 7: 电台 - * @param {number} limit - 取出评论数量 , 默认为 20 - * @param {number} offset - 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*20, 其中 20 为 limit 的值 - * @param {string} before - 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过 5000 条评论的时候需要用到) - */ -export const getHotComment = (id, type = 0, limit = 20, offset = 0, before) => { - return axios({ - method: "GET", - url: "/comment/hot", - params: { - id, - type, - limit, - offset, - before, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 发送 / 删除评论 - * @param {number} id - 对应资源的id - * @param {number} commentId - 回复的评论 id(回复评论时必填) - * @param {string} content - 要发送的内容 - * @param {number} t - 是否点赞,0为删除,1为发送,2为回复 - * @param {number} [type=0] - 对应资源的类型,默认为0(歌曲) - */ -export const sendComment = (id, commentId = null, content, t, type = 0) => { - return axios({ - method: "GET", - url: "/comment", - params: { - id, - commentId, - content, - t, - type, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 评论点赞 - * @param {number} id - 对应资源的 id - * @param {number} cid - 评论的 id - * @param {number} t - 操作, 1 为点赞, 其他为取消点赞 - * @param {number} type - 资源类型 / 0: 歌曲 / 1: mv / 2: 歌单 / 3: 专辑 / 4: 电台节目 / 5: 视频 / 6: 动态 / 7: 电台 - */ -export const likeComment = (id, cid, t, type = 0) => { - return axios({ - method: "GET", - url: "/comment/like", - params: { - id, - cid, - t, - type, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 电台节目评论 - * @param {number} id - 电台节目的 id - * @param {number} limit - 取出评论数量 , 默认为 20 - * @param {number} offset - 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*20, 其中 20 为 limit 的值 - * @param {string} before - 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过 5000 条评论的时候需要用到) - */ -export const commentDj = (id, limit, offset, before) => { - return axios({ - method: "GET", - url: "/comment/dj", - params: { - id, - limit, - offset, - before, - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/comment.ts b/src/api/comment.ts new file mode 100644 index 0000000..e3b28a9 --- /dev/null +++ b/src/api/comment.ts @@ -0,0 +1,58 @@ +import request from "@/utils/request"; + +/** + * 获取评论 + * @param {number} id - 对应资源的 id + * @param {string} type - 对应资源的类型,0: 歌曲, 1: mv, 2: 歌单, 3: 专辑, 4: 电台节目, 5: 视频, 6: 动态, 7: 电台 + * @param {number} pageNo - 分页参数,第 N 页, 默认 1 + * @param {number} pageSize - 分页参数,每页多少条数据, 默认 20 + * @param {number} sortType - 排序方式, 1:按推荐排序, 2:按热度排序, 3:按时间排序 + * @param {number} cursor - 当 sortType 为 3 时且页数不是第一页时需传入, 值为上一条数据的 time + */ +export const getComment = ( + id: number, + type: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 = 0, + pageNo: number = 1, + pageSize: number = 20, + sortType: 1 | 2 | 3 = 1, + cursor?: number, +) => { + return request({ + url: "/comment/new", + params: { id, type, pageNo, pageSize, sortType, cursor, timestamp: Date.now() }, + }); +}; + +/** + * 获取热门评论 + * @param {number} id - 对应资源的 id + * @param {string} type - 对应资源的类型,0: 歌曲, 1: mv, 2: 歌单, 3: 专辑, 4: 电台节目, 5: 视频, 6: 动态, 7: 电台 + * @param {number} limit - 取出评论数量 , 默认为 20 + * @param {number} offset - 偏移数量 , 用于分页 , 如 :( 评论页数 -1)*20, 其中 20 为 limit 的值 + * @param {string} before - 分页参数,取上一页最后一项的 time 获取下一页数据(获取超过 5000 条评论的时候需要用到) + */ +export const getHotComment = ( + id: number, + type: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 = 0, + limit: number = 20, + offset: number = 0, + before?: number, +) => { + return request({ + url: "/comment/hot", + params: { id, type, limit, offset, before, timestamp: Date.now() }, + }); +}; + +/** + * 评论点赞 + * @param {number} id - 对应资源的 id + * @param {number} t - 操作, 1 为点赞, 其他为取消点赞 + * @param {number} type - 资源类型 / 0: 歌曲 / 1: mv / 2: 歌单 / 3: 专辑 / 4: 电台节目 / 5: 视频 / 6: 动态 / 7: 电台 + */ +export const commentLike = (id: number, t: 1 | 2 = 1, type: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 = 0) => { + return request({ + url: "/resource/like", + params: { id, t, type, timestamp: Date.now() }, + }); +}; diff --git a/src/api/dj.js b/src/api/dj.js deleted file mode 100644 index ce7e7ce..0000000 --- a/src/api/dj.js +++ /dev/null @@ -1,150 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 电台部分 - */ - -/** - * 获取电台 - 分类 - */ -export const getDjCatelist = () => { - return axios({ - method: "GET", - url: "/dj/catelist", - }); -}; - -/** - * 获取电台 - 推荐 - */ -export const getDjRecommend = () => { - return axios({ - method: "GET", - url: "/dj/recommend", - }); -}; - -/** - * 电台个性推荐 - */ -export const getDjPersonalRec = () => { - return axios({ - method: "GET", - url: "/dj/personalize/recommend", - }); -}; - -/** - * 获取电台 - 推荐类型 - */ -export const getDjCategoryRec = () => { - return axios({ - method: "GET", - url: "/dj/category/recommend", - }); -}; - -/** - * 私人 DJ - */ -export const getPrivateDj = () => { - return axios({ - method: "GET", - url: "/aidj/content/rcmd", - }); -}; - -/** - * 电台 - 类别热门电台 - * @param {string} cateId - 类别 id - * @param {number} [limit=50] - 返回数量,默认 50 - * @param {number} [offset=0] - 偏移数量,默认 0 - */ -export const getRadioHot = (cateId, limit = 50, offset = 0) => { - return axios({ - method: "GET", - url: "/dj/radio/hot", - params: { - cateId, - limit, - offset, - }, - }); -}; - -/** - * 电台 - 分类推荐 - * @param {string} type - 类别 id - */ -export const getRecType = (type) => { - return axios({ - method: "GET", - url: "/dj/recommend/type", - params: { - type, - }, - }); -}; - -/** - * 电台 - 详情 - * @param {string} rid - 电台 的 id - */ -export const getDjDetail = (rid) => { - return axios({ - method: "GET", - url: "/dj/detail", - params: { - rid, - }, - }); -}; - -/** - * 电台 - 节目 - * @param {string} rid - 电台 的 id - * @param {number} [limit=50] - 返回数量,默认 50 - * @param {number} [offset=0] - 偏移数量,默认 0 - */ -export const getDjProgram = (rid, limit = 50, offset = 0) => { - return axios({ - method: "GET", - url: "/dj/program", - params: { - rid, - limit, - offset, - }, - }); -}; - -/** - * 电台 - 节目详情 - * @param {string} id - 电台 的 id - */ -export const getDjProgramDetail = (id) => { - return axios({ - method: "GET", - url: "/dj/program/detail", - params: { - id, - }, - }); -}; - -/** - * 电台 - 订阅 - * @param {number} rid - 电台 的 id - * @param {number} t - 操作类型,1为收藏,0为取消收藏 - */ -export const likeDj = (rid, t) => { - return axios({ - method: "GET", - url: "/dj/sub", - params: { - rid, - t, - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/login.js b/src/api/login.js deleted file mode 100644 index bf2909e..0000000 --- a/src/api/login.js +++ /dev/null @@ -1,140 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 登录部分 - */ - -/** - * 生成二维码 key - */ -export const getQrKey = () => { - return axios({ - method: "GET", - noCookie: true, - url: "/login/qr/key", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 生成二维码 - * @param {string} key 二维码key - * @param {boolean} qrimg 是否生成二维码图片,默认为true - */ -export const qrCreate = (key, qrimg = true) => { - return axios({ - method: "GET", - noCookie: true, - url: "/login/qr/create", - params: { - key, - qrimg, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 检查二维码状态 - * @param {string} key 二维码key - */ -export const checkQr = (key) => { - return axios({ - method: "GET", - noCookie: true, - url: "/login/qr/check", - params: { - key, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 手机号登录 - * @param {string} phone 手机号码 - * @param {string} captcha 验证码 - */ -export const toLogin = (phone, captcha) => { - return axios({ - method: "GET", - noCookie: true, - url: "/login/cellphone", - params: { - phone, - captcha, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 发送验证码 - * @param {string} phone 手机号码 - */ -export const sentCaptcha = (phone) => { - return axios({ - method: "GET", - noCookie: true, - url: "/captcha/sent", - params: { - phone, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 验证验证码是否正确 - * @param {string} phone 手机号码 - * @param {string} captcha 验证码 - */ -export const verifyCaptcha = (phone, captcha) => { - return axios({ - method: "GET", - noCookie: true, - url: "/captcha/verify", - params: { - phone, - captcha, - timestamp: new Date().getTime(), - }, - }); -}; - -// 获取登录状态 -export const getLoginState = () => { - return axios({ - method: "GET", - url: "/login/status", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -// 刷新登录 -export const refreshLogin = () => { - return axios({ - method: "GET", - url: "/login/refresh", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 退出登录 - */ -export const logOut = () => { - return axios({ - method: "GET", - url: "/logout", - params: { - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/login.ts b/src/api/login.ts new file mode 100644 index 0000000..b0e80c7 --- /dev/null +++ b/src/api/login.ts @@ -0,0 +1,114 @@ +import request from "@/utils/request"; + +// 生成二维码 key +export const qrKey = () => { + return request({ + url: "/login/qr/key", + params: { + noCookie: true, + timestamp: Date.now(), + }, + }); +}; + +// 生成二维码 +export const qrCreate = (key: string, qrimg: boolean = true) => { + return request({ + url: "/login/qr/create", + params: { + key, + qrimg, + noCookie: true, + timestamp: Date.now(), + }, + }); +}; + +// 检查二维码状态 +export const checkQr = (key: string) => { + return request({ + url: "/login/qr/check", + params: { + key, + noCookie: true, + timestamp: Date.now(), + }, + }); +}; + +// 手机号登录 +export const loginPhone = (phone: number, captcha: number, ctcode: number = 86) => { + return request({ + url: "/login/cellphone", + params: { + phone, + captcha, + ctcode, + noCookie: true, + timestamp: Date.now(), + }, + }); +}; + +// 发送验证码 +export const sentCaptcha = (phone: number, ctcode: number = 86) => { + return request({ + url: "/captcha/sent", + params: { + phone, + ctcode, + noCookie: true, + timestamp: Date.now(), + }, + }); +}; + +// 验证验证码是否正确 +export const verifyCaptcha = (phone: number, captcha: number, ctcode: number = 86) => { + return request({ + url: "/captcha/verify", + params: { + phone, + captcha, + ctcode, + timestamp: Date.now(), + }, + }); +}; + +// 获取登录状态 +export const getLoginState = () => { + return request({ + url: "/login/status", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 刷新登录 +export const refreshLogin = () => { + return request({ + url: "/login/refresh", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 退出登录 +export const logout = () => { + return request({ + url: "/logout", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 国家码列表 +export const countryList = () => { + return request({ + url: "/countries/code/list", + }); +}; diff --git a/src/api/other.js b/src/api/other.js deleted file mode 100644 index 862a8ac..0000000 --- a/src/api/other.js +++ /dev/null @@ -1,34 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 杂项 - */ - -/** - * 获取轮播图 - * @param {number} type - 资源类型 / 0: pc / 1: android / 2: iphone / 3: ipad - */ -export const getBanner = (type = 0) => { - return axios({ - method: "GET", - url: `/banner?type=${type}`, - }); -}; - -/** - * 资源点赞 ( MV,电台,视频 ) - * @param {number} id - 资源 id - * @param {number} t - 操作, 1 为点赞, 其他为取消点赞 - * @param {number} type - 资源类型 / 0: 歌曲 / 1: mv / 2: 歌单 / 3: 专辑 / 4: 电台节目 / 5: 视频 / 6: 动态 / 7: 电台 - */ -export const resourceLike = (id, t = 1, type = 0) => { - return axios({ - method: "GET", - url: "/resource/like", - params: { - id, - t, - type, - }, - }); -}; diff --git a/src/api/other.ts b/src/api/other.ts new file mode 100644 index 0000000..b515cdd --- /dev/null +++ b/src/api/other.ts @@ -0,0 +1,11 @@ +import request from "@/utils/request"; + +// 获取仓库更新日志 +export const updateLog = () => { + return request({ + baseURL: "https://api.github.com", + withCredentials: false, + url: "/repos/imsyy/SPlayer/releases/latest", + params: { noCookie: true }, + }); +}; diff --git a/src/api/playlist.js b/src/api/playlist.js deleted file mode 100644 index b2abc26..0000000 --- a/src/api/playlist.js +++ /dev/null @@ -1,209 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 歌单部分 - */ - -/** - * 获取歌单分类信息 - * @param {boolean} [hq=false] - 是否为精品歌单 - */ -export const getPlayListCatlist = (hq = false) => { - return axios({ - method: "GET", - url: `/playlist/${hq ? "highquality/tags" : "catlist"}`, - }); -}; - -/** - * 获取分类歌单列表 - * @param {string} [cat='全部'] - 歌单分类 - * @param {number} [limit=50] - 返回数量,默认50 - * @param {number} [offset=0] - 偏移数量,默认0 - * @param {boolean} [hq=false] - 是否为精品歌单 - * @param {boolean} [before] - 分页参数,取上一页最后一个歌单的 updateTime 获取下一页数据 - */ -export const getDscPlaylist = (cat = "全部", limit = 50, offset = 0, hq = false, before) => { - const url = hq ? "/top/playlist/highquality" : "/top/playlist"; - return axios({ - method: "GET", - url, - params: { - cat, - limit, - ...(!hq && { offset }), - ...(hq && { before }), - }, - }); -}; - -/** - * 获取专辑排行榜数据 - * @param {boolean} [detail=true] 是否获取详情数据,默认为 true - */ -export const getTopPlaylist = (detail = true) => { - const url = detail ? "/toplist/detail" : "/toplist"; - return axios({ - method: "GET", - url, - }); -}; - -/** - * 获取歌单详情 - * @param {number} id - 歌单 id - */ -export const getPlayListDetail = (id) => { - return axios({ - method: "GET", - url: "/playlist/detail", - params: { - id, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取歌单中所有歌曲信息 - * @param {number} id - 歌单id - * @param {number} [limit=50] - 返回数量,默认50 - * @param {number} [offset=0] - 偏移数量,默认0 - */ -export const getAllPlayList = (id, limit = 50, offset = 0) => { - return axios({ - method: "GET", - url: "/playlist/track/all", - params: { - id, - limit, - offset, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取心动模式播放列表 - * @param {number} id - 歌曲 id - * @param {number} pid - 歌单 id - * @param {number} sid - 要开始播放的歌曲的 id - * @param {number} [offset=0] - 偏移数量,默认0 - */ -export const getHeartRateList = (id, pid, sid) => { - return axios({ - method: "GET", - url: "/playmode/intelligence/list", - params: { - id, - pid, - sid, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 新建歌单 - * @param {string} name 歌单名称 - * @param {boolean} privacy 是否设置为隐私,默认为 false(公开) - */ -export const createPlaylist = (name, privacy = false) => { - return axios({ - method: "GET", - url: "/playlist/create", - params: { - name, - privacy, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 删除歌单 - * @param {number} id - 歌单 id - */ -export const delPlayList = (id) => { - return axios({ - method: "GET", - url: "/playlist/delete", - params: { - id, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 更新歌单信息 - * @param {number} id - 歌单 id - * @param {string} name - 歌单名称 - * @param {string|null} [desc=null] - 歌单描述,可选 - * @param {string|null} [tags=null] - 歌单标签,可选,多个用 `;` 隔开,只能用官方规定标签 - */ -export const playlistUpdate = (id, name, desc = null, tags = null) => { - return axios({ - method: "GET", - url: "/playlist/update", - params: { - id, - name, - desc, - tags, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 公开隐私歌单 - * @param {number} id - 歌单 id - */ -export const setPlaylistPrivacy = (id) => { - return axios({ - method: "GET", - url: "/playlist/privacy", - params: { - id, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 向歌单中添加或删除歌曲 - * @param {number} pid - 歌单 id - * @param {Array} tracks - 要添加或删除的歌曲id数组 - * @param {string} [op='add'] - 操作类型,可选,默认为添加 - */ -export const addSongToPlayList = (pid, tracks, op = "add") => { - return axios({ - method: "GET", - url: "/playlist/tracks", - params: { - op, - pid, - tracks, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 收藏/取消收藏歌单 - * @param {number} t - 操作类型,1为收藏,2为取消收藏 - * @param {number} id - 歌单id - */ -export const likePlaylist = (t, id) => { - return axios({ - method: "GET", - url: "/playlist/subscribe", - noCookie: true, // 临时解决无法收藏歌单 - params: { - t, - id, - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/playlist.ts b/src/api/playlist.ts new file mode 100644 index 0000000..9ed9aff --- /dev/null +++ b/src/api/playlist.ts @@ -0,0 +1,139 @@ +import request from "@/utils/request"; + +// 获取歌单详情 +export const playlistDetail = (id: number) => { + return request({ + url: "/playlist/detail", + params: { + id, + s: 0, // 去除返回收藏者 + noCookie: true, // 去除返回 privileges + timestamp: Date.now(), + }, + }); +}; + +// 获取歌单所有歌曲 +export const playlistAllSongs = (id: number, limit: number = 50, offset: number = 0) => { + return request({ + url: "/playlist/track/all", + params: { id, limit, offset, timestamp: Date.now() }, + }); +}; + +/** + * 获取心动模式播放列表 + * @param {number} id - 歌曲 id + * @param {number} pid - 歌单 id + * @param {number} sid - 要开始播放的歌曲的 id + */ +export const heartRateList = (id: number, pid: number, sid?: number) => { + return request({ + url: "/playmode/intelligence/list", + params: { id, pid, sid, timestamp: Date.now() }, + }); +}; + +// 获取歌单分类信息 +export const playlistCatlist = (hq: boolean = false) => { + return request({ + url: `/playlist/${hq ? "highquality/tags" : "catlist"}`, + params: { hq, timestamp: Date.now() }, + }); +}; + +/** + * 获取所有分类歌单 + * @param cat 歌单分类 + * @param {number} [limit=50] - 返回数量,默认 50 + * @param {number} [offset=0] - 偏移数量,默认 0 + * @param hq 是否精品歌单 + * @param before 分页参数,取上一页最后一个歌单的 updateTime 获取下一页数据 + * @returns + */ +export const allCatlistPlaylist = ( + cat: string, + limit: number = 50, + offset: number = 0, + hq: boolean = false, + before?: number, +) => { + // 是否精品歌单 + const url = hq ? "/top/playlist/highquality" : "/top/playlist"; + return request({ + url, + params: { cat, limit, offset, ...(hq && { before }), timestamp: Date.now() }, + }); +}; + +// 新建歌单 +export const createPlaylist = ( + name: string, + privacy: boolean = false, + type: "NORMAL" | "VIDEO" | "SHARED" = "NORMAL", +) => { + return request({ + url: "/playlist/create", + params: { name, privacy: privacy ? "10" : null, type, timestamp: Date.now() }, + }); +}; + +// 删除歌单 +export const deletePlaylist = (id: number) => { + return request({ + url: "/playlist/delete", + params: { id, timestamp: Date.now() }, + }); +}; + +// 更新歌单信息 +export const updatePlaylist = (id: number, name: string, desc: string, tags: string[]) => { + return request({ + url: "/playlist/update", + params: { id, name, desc, tags: tags.join(";"), timestamp: Date.now() }, + }); +}; + +// 公开隐私歌单 +export const updatePlaylistPrivacy = (id: number) => { + return request({ + url: "/playlist/privacy", + params: { id, timestamp: Date.now() }, + }); +}; + +/** + * 向歌单中添加或删除歌曲 + * @param {number} pid - 歌单 id + * @param {Array} tracks - 要添加或删除的歌曲id数组 + * @param {string} [op="add"] - 操作类型,可选,默认为添加 + */ +export const playlistTracks = (pid: number, tracks: number[], op: "add" | "del" = "add") => { + return request({ + url: "/playlist/tracks", + method: "post", + data: { pid, tracks: tracks.join(","), op }, + params: { timestamp: Date.now() }, + }); +}; + +/** + * 收藏/取消收藏歌单 + * @param {number} t - 操作类型,1为收藏,2为取消收藏 + * @param {number} id - 歌单id + */ +export const likePlaylist = (id: number, t: number = 1 | 2) => { + return request({ + url: "/playlist/subscribe", + params: { id, t, timestamp: Date.now() }, + }); +}; + +/** + * 获取专辑排行榜数据 + * @param {boolean} [detail=true] 是否获取详情数据,默认为 true + */ +export const topPlaylist = (detail: boolean = true) => { + const url = detail ? "/toplist/detail" : "/toplist"; + return request({ url }); +}; diff --git a/src/api/radio.ts b/src/api/radio.ts new file mode 100644 index 0000000..7a79686 --- /dev/null +++ b/src/api/radio.ts @@ -0,0 +1,99 @@ +import request from "@/utils/request"; + +/** + * 获取电台 - 分类 + */ +export const radioCatList = () => { + return request({ url: "/dj/catelist" }); +}; + +/** + * 获取电台 - 推荐 + */ +export const radioRecommend = () => { + return request({ url: "/dj/recommend" }); +}; + +/** + * 电台 - 新晋电台榜/热门电台榜 + * @param type "new" | "hot" - new: 新晋电台榜 / hot: 热门电台榜 + * @param limit 返回数量 + * @param offset 偏移数量 + */ +export const radioToplist = (type: "new" | "hot", limit: number = 20, offset: number = 0) => { + return request({ url: "/dj/toplist", params: { type, limit, offset } }); +}; + +/** + * 电台个性推荐 + */ +export const radioPersonalized = () => { + return request({ url: "/dj/personalize/recommend" }); +}; + +/** + * 获取电台 - 推荐类型 + */ +export const radioTypes = () => { + return request({ url: "/dj/category/recommend" }); +}; + +/** + * 私人 DJ + */ +export const radioPersonalDj = () => { + return request({ url: "/aidj/content/rcmd" }); +}; + +/** + * 电台 - 类别热门电台 + * @param cateId 类别 id,可通过 /dj/category/recommend 接口获取 + * @param limit 返回数量 + * @param offset 偏移数量 + */ +export const radioCatHot = (cateId: number, limit: number = 50, offset: number = 0) => { + return request({ url: "/dj/radio/hot", params: { cateId, limit, offset } }); +}; + +/** + * 电台 - 分类推荐 + * @param type 电台类型 , 数字 , 可通过/dj/catelist获取 , 对应关系为 id 对应 此接口的 type, name 对应类型 + */ +export const radioCatRecommend = (type: number) => { + return request({ url: "/dj/recommend/type", params: { type } }); +}; + +/** + * 电台 - 详情 + * @param rid 电台 id + */ +export const radioDetail = (rid: number) => { + return request({ url: "/dj/detail", params: { rid } }); +}; + +/** + * 电台 - 全部节目 + * @param rid 电台 id + * @param limit 返回数量 + * @param offset 偏移数量 + */ +export const radioAllProgram = (rid: number, limit: number = 50, offset: number = 0) => { + return request({ url: "/dj/program", params: { rid, limit, offset } }); +}; + +/** + * 电台 - 节目详情 + * @param id 节目 id + */ +export const radioProgramDetail = (id: number) => { + return request({ url: "/dj/program/detail", params: { id } }); +}; + +/** + * 电台 - 订阅 + * @param rid 电台 id + * @param t 订阅类型 1:订阅 0:取消订阅 + */ +export const radioSub = (rid: number, t: number = 1) => { + return request({ url: "/dj/sub", params: { rid, t, timestamp: Date.now() } }); +}; diff --git a/src/api/rec.ts b/src/api/rec.ts new file mode 100644 index 0000000..4606392 --- /dev/null +++ b/src/api/rec.ts @@ -0,0 +1,107 @@ +import request from "@/utils/request"; +import idMeta from "@/assets/data/idMeta.json"; + +/** + * 每日推荐 - 需要登录 + * @param {string} [type] - 推荐类型,songs 日推歌曲 / resource 推荐歌单 + */ +export const dailyRecommend = (type: "songs" | "resource" = "songs") => { + return request({ + url: `/recommend/${type}`, + params: { timestamp: Date.now() }, + }); +}; + +/** + * 推荐内容 + * @param {string} [type] - 推荐类型 + * @param {number} [limit=50] - 返回结果的数量 + */ +export const personalized = ( + type: "playlist" | "mv" | "newsong" | "djprogram" | "privatecontent" = "playlist", + limit: number = 50, +) => { + const url = type === "playlist" ? "/personalized" : `/personalized/${type}`; + return request({ + url, + params: { + limit, + }, + }); +}; + +// 雷达歌单 +export const radarPlaylist = async () => { + const allRadar = idMeta.radarPlaylist.map((playlist) => { + return request({ + url: "/playlist/detail", + params: { id: playlist.id }, + }); + }); + const result = await Promise.allSettled(allRadar); + return result.map((res: any) => res?.value.playlist); +}; + +/** + * 获取热门歌手 + * @param limit - 返回数量,默认为 10 + */ +export const topArtists = async (limit: number = 10) => { + return request({ + url: "/top/artists", + params: { limit }, + }); +}; + +/** + * 新歌速递 + * @param {number} type - 全部:0 / 华语:7 / 欧美:96 / 韩国:16 / 日本:8 + */ +export const newSongs = async (type: 0 | 7 | 96 | 16 | 8 = 0) => { + return request({ + url: "/top/song", + params: { type }, + }); +}; + +// 最新专辑 +export const newAlbums = async () => { + return request({ + url: "/album/new", + }); +}; + +/** + * 新碟上架 - 全部 + * @param {string} [cat="ALL"] - ALL:全部 / ZH:华语 / EA:欧美 / KR:韩国 / JP:日本 + * @param {number} [limit=20] - 返回数量,默认20 + * @param {number} [offset=0] - 偏移数量,默认0 + */ +export const newAlbumsAll = ( + cat: "ALL" | "ZH" | "EA" | "KR" | "JP" = "ALL", + limit: number = 20, + offset: number = 0, +) => { + return request({ + url: "/album/new", + params: { cat, limit, offset }, + }); +}; + +// 私人 FM +export const personalFm = () => { + return request({ + url: "/personal_fm", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 私人 FM - 垃圾桶 +export const personalFmToTrash = (id: number) => { + return request({ + url: "/fm_trash", + params: { id, timestamp: Date.now() }, + }); +}; diff --git a/src/api/recommend.js b/src/api/recommend.js deleted file mode 100644 index a03b4d0..0000000 --- a/src/api/recommend.js +++ /dev/null @@ -1,135 +0,0 @@ -import axios from "@/utils/request"; -import idMeta from "@/assets/idMeta.json"; - -/** - * 推荐部分 - */ - -/** - * 每日推荐 - 需要登录 - * @param {string} [type] - 推荐类型,songs 日推歌曲 / resource 推荐歌单 - */ -export const getDailyRec = (type = "songs") => { - return axios({ - method: "GET", - url: `/recommend/${type}`, - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 推荐内容 - * @param {string} [type] - 推荐类型,mv MV / newsong 新音乐 / djprogram 电台 / privatecontent 独家放送 - * @param {number} [limit=12] - 返回结果的数量,默认为 12 - */ -export const getPersonalized = (type, limit = 12) => { - const url = type ? `/personalized/${type}` : "/personalized"; - return axios({ - method: "GET", - url, - params: { - limit, - }, - }); -}; - -/** - * 雷达歌单 - */ -export const getRadarPlaylist = async () => { - const allRadar = idMeta.radarPlaylist.map((playlist) => { - return axios({ - method: "GET", - url: "/playlist/detail", - params: { id: playlist.id }, - }); - }); - const result = await Promise.allSettled(allRadar); - return result.map((res) => res?.value.playlist); -}; - -/** - * 热门歌手列表 - * @param {number} [limit=6] - 要返回的歌手数量,默认为 6 个 - */ -export const getTopArtists = (limit = 6) => { - return axios({ - method: "GET", - url: "/top/artists", - params: { - limit, - }, - }); -}; - -/** - * 新歌速递 - * @param {number} type - 全部:0 / 华语:7 / 欧美:96 / 韩国:16 / 日本:8 - */ -export const getNewSong = (type = 0) => { - return axios({ - method: "GET", - url: "/top/song", - params: { - type, - }, - }); -}; - -/** - * 新碟上架 - 首页 - */ -export const getNewAlbum = () => { - return axios({ - method: "GET", - url: "/album/newest", - }); -}; - -/** - * 新碟上架 - 全部 - * @param {string} [cat='ALL'] - ALL:全部 / ZH:华语 / EA:欧美 / KR:韩国 / JP:日本 - * @param {number} [limit=50] - 返回数量,默认50 - * @param {number} [offset=0] - 偏移数量,默认0 - */ -export const getAllNewAlbum = (area = "ALL", limit = 50, offset = 0) => { - return axios({ - method: "GET", - url: "/album/new", - params: { - area, - limit, - offset, - }, - }); -}; - -/** - * 获取私人FM数据 - */ -export const getPersonalFm = () => { - return axios({ - method: "GET", - url: "/personal_fm", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 将指定歌曲加入垃圾桶 - * @param {number} id 歌曲ID - */ -export const setFmToTrash = (id) => { - return axios({ - method: "GET", - url: "/fm_trash", - params: { - id, - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/search.js b/src/api/search.js deleted file mode 100644 index d7a69c8..0000000 --- a/src/api/search.js +++ /dev/null @@ -1,67 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 搜索部分 - */ - -/** - * 热搜列表 - 详细 - */ -export const getSearchHot = () => { - return axios({ - method: "GET", - url: "/search/hot/detail", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 搜索建议 - * @param {string} keywords - 搜索关键词 - * @param {Boolean} mobile - 如果传入 true 则返回移动端数据 - */ -export const getSearchSuggest = (keywords, mobile = false) => { - return axios({ - method: "GET", - url: "/search/suggest", - params: { - keywords, - ...(mobile && { type: "mobile" }), - }, - }); -}; - -/** - * 默认搜索关键词 - */ -export const getSearchDefault = () => { - return axios({ - method: "GET", - url: "/search/default", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 搜索结果 - * @param {string} keywords - 搜索关键词 - * @param {number} [limit=30] - 返回数量,默认30 - * @param {number} [offset=0] - 偏移数量,默认0 - * @param {number} [type=1] - 可选参数,搜索类型。1表示单曲,10表示专辑,100表示歌手,1000表示歌单,1002表示用户,1004表示MV,1006表示歌词,1009表示电台,1014表示视频,1018表示综合,2000表示声音。默认为 1 - */ -export const getSearchRes = (keywords, limit = 50, offset = 0, type = 1) => { - return axios({ - method: "GET", - url: "/cloudsearch", - params: { - keywords, - limit, - offset, - type, - }, - }); -}; diff --git a/src/api/search.ts b/src/api/search.ts new file mode 100644 index 0000000..f3eded8 --- /dev/null +++ b/src/api/search.ts @@ -0,0 +1,72 @@ +import request from "@/utils/request"; + +// 搜索类型枚举 +export enum SearchTypes { + Single = 1, + Album = 10, + Artist = 100, + Playlist = 1000, + User = 1002, + Mv = 1004, + Lyrics = 1006, + Radio = 1009, + Video = 1014, + All = 1018, + Audio = 2000, +} + +// 热搜 +export const searchHot = () => { + return request({ + url: "/search/hot/detail", + }); +}; + +// 搜索建议 +export const searchSuggest = (keywords: string, mobile: boolean = false) => { + return request({ + url: "/search/suggest", + params: { + keywords, + ...(mobile && { type: "mobile" }), + }, + }); +}; + +// 搜索多重匹配 +export const searchMultimatch = (keywords: string) => { + return request({ + url: "/search/multimatch", + params: { + keywords, + }, + }); +}; + +// 默认搜索关键词 +export const searchDefault = () => { + return request({ + url: "/search/default", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 搜索结果 +export const searchResult = ( + keywords: string, + limit: number = 50, + offset = 0, + type: SearchTypes = SearchTypes.All, +) => { + return request({ + url: "/cloudsearch", + params: { + keywords, + limit, + offset, + type, + }, + }); +}; diff --git a/src/api/song.js b/src/api/song.js deleted file mode 100644 index 06d4098..0000000 --- a/src/api/song.js +++ /dev/null @@ -1,86 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 歌曲部分 - */ - -/** - * 获取指定音乐的详情 - * @param {string} ids - 要获取详情的音乐ID,多个ID用逗号分隔 - */ -export const getSongDetail = (ids) => { - const timestamp = new Date().getTime(); - return axios({ - method: "POST", - url: `/song/detail?timestamp=${timestamp}`, - data: { - ids, - }, - }); -}; - -/** - * 获取音乐 URL - * @param {number} id - 要获取音乐的 ID。 - * @param {string} [level=standard] - 播放音质等级 / standard: 标准 / higher: 较高 / exhigh: 极高 / lossless: 无损 / hires: Hi-Res / jyeffect: 高清环绕声 / sky: 沉浸环绕声 / jymaster: 超清母带 - */ -export const getSongUrl = (id, level = "standard") => { - return axios({ - method: "GET", - url: "/song/url/v1", - params: { - id, - level, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取指定音乐的歌词 - * @param {number} id - 要获取歌词的音乐ID - */ -export const getSongLyric = (id) => { - return axios({ - method: "GET", - url: "/lyric/new", - params: { - id, - }, - }); -}; - -/** - * 获取客户端歌曲下载 - * @param {number} id - 要下载的音乐ID - * @param {number} br - 码率, 默认设置了 999000 即最大码率, 如果要 320k 则可设置为 320000, 其他类推 - */ -export const getSongDownload = (id, br = 999000) => { - return axios({ - method: "GET", - url: "/song/download/url", - params: { - id, - br, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 听歌打卡 - * @param {number} id - 音乐ID - * @param {number} sourceid - 来源ID - */ -export const songScrobble = (id, sourceid = 0, time = 0) => { - return axios({ - method: "GET", - url: "/scrobble", - params: { - id, - sourceid, - time, - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/song.ts b/src/api/song.ts new file mode 100644 index 0000000..9ae67f7 --- /dev/null +++ b/src/api/song.ts @@ -0,0 +1,111 @@ +import { songLevelData } from "@/utils/meta"; +import request from "@/utils/request"; + +// 获取歌曲详情 +export const songDetail = (ids: number | number[]) => { + return request({ + url: "/song/detail", + method: "post", + params: { timestamp: Date.now() }, + data: { ids: Array.isArray(ids) ? ids.join(",") : ids.toString() }, + }); +}; + +/** + * 歌曲音质详情 + * @param id 歌曲 id + */ +export const songQuality = (id: number) => { + return request({ + url: "/song/music/detail", + params: { id }, + }); +}; + +// 获取歌曲 URL +export const songUrl = ( + id: number, + level: + | "standard" + | "higher" + | "exhigh" + | "lossless" + | "hires" + | "jyeffect" + | "sky" + | "jymaster" = "exhigh", +) => { + return request({ + url: "/song/url/v1", + params: { + id, + level, + timestamp: Date.now(), + }, + }); +}; + +// 获取解锁歌曲 URL +export const unlockSongUrl = (id: number, keyword: string, server: "netease" | "kuwo") => { + const params = server === "netease" ? { id } : { keyword }; + return request({ + baseURL: "/api/unblock", + url: `/${server}`, + params, + }); +}; + +// 获取歌曲歌词 +export const songLyric = (id: number) => { + return request({ + url: "/lyric/new", + params: { + id, + }, + }); +}; + +/** + * 获取歌曲下载链接 + * @param id 音乐 id + * @param level 播放音质等级, 分为 standard => 标准,higher => 较高, exhigh=>极高, lossless=>无损, hires=>Hi-Res, jyeffect => 高清环绕声, sky => 沉浸环绕声, `dolby` => `杜比全景声`, jymaster => 超清母带 + * @returns + */ +export const songDownloadUrl = (id: number, level: keyof typeof songLevelData = "h") => { + // 获取对应音质 + const levelName = songLevelData[level].level; + return request({ + url: "/song/download/url/v1", + params: { id, level: levelName, timestamp: Date.now() }, + }); +}; + +// 喜欢歌曲 +export const likeSong = (id: number, like: boolean = true) => { + return request({ + url: "/like", + params: { id, like, timestamp: Date.now() }, + }); +}; + +/** + * 本地歌曲文件匹配 + * @param {string} title - 文件的标题信息,是文件属性里的标题属性,并非文件名 + * @param {string} album - 文件的专辑信息 + * @param {string} artist - 文件的艺术家信息 + * @param {number} duration - 文件的时长,单位为秒 + * @param {string} md5 - 文件的 md5 + */ + +export const matchSong = ( + title: string, + artist: string, + album: string, + duration: number, + md5: string, +) => { + return request({ + url: "/search/match", + params: { title, artist, album, duration, md5 }, + }); +}; diff --git a/src/api/user.js b/src/api/user.js deleted file mode 100644 index 62afd54..0000000 --- a/src/api/user.js +++ /dev/null @@ -1,206 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 用户部分 - */ - -/** - * 获取用户信息 - */ -export const getUserProfile = () => { - return axios({ - method: "GET", - url: "/user/account", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户全部信息 - */ -export const getUserDetail = (uid) => { - return axios({ - method: "GET", - url: "/user/detail", - params: { - uid, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户等级信息 - */ -export const getUserLevel = () => { - return axios({ - method: "GET", - url: "/user/level", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户订阅信息,包括歌单、收藏、MV 和 DJ 数量 - */ -export const getUserSubcount = () => { - return axios({ - method: "GET", - url: "/user/subcount", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户的歌单列表 - * @param {string} uid 用户的id - * @param {number} [limit=30] - 返回数量,默认30 - * @param {number} [offset=0] - 偏移数量,默认0 - */ -export const getUserPlaylist = (uid, limit = 30, offset = 0) => { - return axios({ - method: "GET", - url: "/user/playlist", - params: { - uid, - limit, - offset, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户的专辑列表 - * @param {number} [limit=30] - 返回数量,默认30 - * @param {number} [offset=0] - 偏移数量,默认0 - */ -export const getUserAlbum = (limit = 30, offset = 0) => { - return axios({ - method: "GET", - url: "/album/sublist", - params: { - limit, - offset, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户收藏的歌手列表 - */ -export const getUserArtist = () => { - return axios({ - method: "GET", - url: "/artist/sublist", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户收藏的 MV 列表 - */ -export const getUserMv = () => { - return axios({ - method: "GET", - url: "/mv/sublist", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户电台的订阅列表 - */ -export const getUserDj = () => { - return axios({ - method: "GET", - url: "/dj/sublist", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取用户喜欢的音乐列表 - * @param {string} uid 用户的id - */ -export const getLikelist = (uid) => { - return axios({ - method: "GET", - url: "/likelist", - params: { - uid, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 将指定音乐添加或移除喜欢列表 - * @param {number} id 音乐ID - * @param {boolean} [like=true] 是否添加到喜欢列表,默认为true - */ -export const setLikeSong = (id, like = true) => { - return axios({ - method: "GET", - url: "/like", - params: { - id, - like, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 退出登录 - */ -export const userLogOut = () => { - return axios({ - method: "GET", - url: "/logout", - params: { - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 每日签到 - * @param {type} type - 签到类型 , 默认 0, 其中 0 为安卓端签到 ,1 为 web/PC 签到 - */ -export const userDailySignin = (type = 0) => { - return axios({ - method: "GET", - url: "/daily_signin", - params: { - type, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 云贝签到 - */ -export const userYunbeiSign = () => { - return axios({ - method: "GET", - url: "/yunbei/sign", - params: { - timestamp: new Date().getTime(), - }, - }); -}; diff --git a/src/api/user.ts b/src/api/user.ts new file mode 100644 index 0000000..d2d1812 --- /dev/null +++ b/src/api/user.ts @@ -0,0 +1,134 @@ +import request from "@/utils/request"; + +// 获取账号详情 +export const userAccount = () => { + return request({ + url: "/user/account", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 获取用户详情 +export const userDetail = (uid: number) => { + return request({ + url: "/user/detail", + params: { + uid, + timestamp: Date.now(), + }, + }); +}; + +// 获取用户等级信息 +export const userLevel = () => { + return request({ + url: "/user/level", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 获取用户订阅信息,包括歌单、收藏、MV 和 DJ 数量 +export const userSubcount = () => { + return request({ + url: "/user/subcount", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 获取用户歌单 +export const userPlaylist = (limit: number = 50, offset: number = 0, uid: number) => { + return request({ + url: "/user/playlist", + params: { + uid, + limit, + offset, + timestamp: Date.now(), + }, + }); +}; + +// 获取用户收藏专辑 +export const userAlbum = (limit: number = 50, offset: number = 0) => { + return request({ + url: "/album/sublist", + params: { + limit, + offset, + timestamp: Date.now(), + }, + }); +}; + +// 获取用户收藏歌手 +export const userArtist = (limit: number = 50, offset: number = 0) => { + return request({ + url: "/artist/sublist", + params: { + limit, + offset, + timestamp: Date.now(), + }, + }); +}; + +// 获取用户收藏 MV +export const userMv = () => { + return request({ + url: "/mv/sublist", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 获取用户收藏电台 +export const userDj = () => { + return request({ + url: "/dj/sublist", + params: { + timestamp: Date.now(), + }, + }); +}; + +// 获取用户喜欢的音乐 +export const userLike = (uid: number) => { + return request({ + url: "/likelist", + params: { + uid, + timestamp: Date.now(), + }, + }); +}; + +// 听歌打卡 +export const scrobble = (id: number, sourceid?: number, time?: number) => { + return request({ + url: "/scrobble", + params: { + id, + sourceid, + time, + timestamp: Date.now(), + }, + }); +}; + +// 每日签到 +export const dailySignin = (type: 0 | 1 = 0) => { + return request({ + url: "/daily_signin", + params: { + type, + timestamp: Date.now(), + }, + }); +}; diff --git a/src/api/video.js b/src/api/video.js deleted file mode 100644 index 8b7e297..0000000 --- a/src/api/video.js +++ /dev/null @@ -1,121 +0,0 @@ -import axios from "@/utils/request"; - -/** - * 视频 - */ - -/** - * 获取指定 MV 的详细信息 - * @param {number} mvid - MV ID - */ -export const getVideoDetail = (mvid) => { - return axios({ - method: "GET", - url: "/mv/detail", - params: { - mvid, - }, - }); -}; - -/** - * 获取指定 MV 的点赞转发评论数 - * @param {number} mvid - MV ID - */ -export const getVideoInfo = (mvid) => { - return axios({ - method: "GET", - url: "/mv/detail/info", - params: { - mvid, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 获取指定 MV 的播放地址 - * @param {number} id - 要查询的MV ID - * @param {string} [r=null] - 分辨率。默认值为null - */ -export const getVideoUrl = (id, r = null) => { - return axios({ - method: "GET", - hiddenBar: true, - url: "/mv/url", - params: { - id, - r, - }, - }); -}; - -/** - * 获取与指定 MV 相似的 MV 列表 - * @param {number} mvid - 要查询的 MV ID - */ -export const getSimiVideo = (mvid) => { - return axios({ - method: "GET", - url: "/simi/mv", - params: { - mvid, - }, - }); -}; - -/** - * 收藏/取消收藏视频 - * @param {number} t - 操作类型,1为收藏,2为取消收藏 - * @param {number} id - 视频id - */ -export const likeVideo = (t, id) => { - return axios({ - method: "GET", - url: "/video/sub", - params: { - t, - id, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 收藏/取消收藏 MV - * @param {number} t - 操作类型,1为收藏,2为取消收藏 - * @param {number} mvid - MV id - */ -export const likeMv = (t, mvid) => { - return axios({ - method: "GET", - url: "/mv/sub", - params: { - t, - mvid, - timestamp: new Date().getTime(), - }, - }); -}; - -/** - * 全部 mv - * @param {string} area - 地区,可选值为全部,内地,港台,欧美,日本,韩国,不填则为全部 - * @param {string} type - 类型,可选值为全部,官方版,原生,现场版,网易出品,不填则为全部 - * @param {string} order - 排序,可选值为上升最快,最热,最新,不填则为上升最快 - * @param {number} [limit=12] - 返回数量,默认12 - * @param {number} [offset=0] - 偏移数量,默认0 - */ -export const allMv = (area, type, order, limit = 12, offset = 0) => { - return axios({ - method: "GET", - url: "/mv/all", - params: { - area, - type, - order, - limit, - offset, - }, - }); -}; diff --git a/src/api/video.ts b/src/api/video.ts new file mode 100644 index 0000000..09ca7f6 --- /dev/null +++ b/src/api/video.ts @@ -0,0 +1,46 @@ +import request from "@/utils/request"; + +// 视频详情 +export const videoDetail = (id: number, type: "mv" | "video") => { + return request({ + url: `/${type}/detail`, + params: type === "mv" ? { mvid: id } : { id }, + }); +}; + +// 视频地址 +export const videoUrl = (id: number, type: "mv" | "video", r: number) => { + return request({ + url: `/${type}/url`, + params: { id, r }, + }); +}; + +// 视频互动数据 +export const videoDetailInfo = (id: number, type: "mv" | "video") => { + return request({ + url: `/${type}/detail/info`, + params: type === "mv" ? { mvid: id } : { vid: id }, + }); +}; + +/** + * 全部 mv + * @param {Area} [area="全部"] - 地区, 可选值为全部, 内地, 港台, 欧美, 日本, 韩国, 默认为全部 + * @param {Type} [type="全部"] - 类型, 可选值为全部, 官方版, 原生, 现场版, 网易出品, 默认为全部 + * @param {Order} [order="上升最快"] - 排序, 可选值为上升最快, 最热, 最新, 默认为上升最快 + * @param {number} [limit=12] - 返回数量,默认12 + * @param {number} [offset=0] - 偏移数量,默认0 + */ +export const allMv = ( + area: "全部" | "内地" | "港台" | "欧美" | "日本" | "韩国", + type: "全部" | "官方版" | "原生" | "现场版" | "网易出品", + order: "上升最快" | "最热" | "最新", + limit: number = 12, + offset: number = 0, +) => { + return request({ + url: "/mv/all", + params: { area, type, order, limit, offset }, + }); +}; diff --git a/src/assets/emoji.json b/src/assets/data/emoji.json similarity index 100% rename from src/assets/emoji.json rename to src/assets/data/emoji.json diff --git a/src/assets/data/exclude.ts b/src/assets/data/exclude.ts new file mode 100644 index 0000000..04e05a2 --- /dev/null +++ b/src/assets/data/exclude.ts @@ -0,0 +1,77 @@ +export const keywords = [ + "词:", + "曲:", + "作曲", + "作词", + "编曲", + "翻唱", + "制作", + "调教", + "混音", + "监制", + "音响", + "文案", + "音统", + "策划", + "录音", + "制作", + "贝斯", + "工程", + "吉他", + "合成器", + "助理", + "编程", + "和声", + "合声", + "母带", + "人声", + "鼓", + "混音", + "提琴:", + "曲绘", + "视频", + "编写", + "钢琴:", + "出版", + "发行", + "出品", + "键盘", + "弦乐", + "设计", + "监制", + "原曲", + "演唱", + "声明", + "版权", + "封面", + "插画", + "统筹", + "企划", + "填词", + "原唱", + "后期", + "和音", + "和声", + "琵琶", + "二胡", + "笛子", + "古筝", + "主唱", + "伴唱", + "编排", + "剧务", + "音效", + "录音", + "纯音乐", + "缩混", + "音乐总监", + "音乐制作", + "OP", + "SP", + "op", + "sp", + "Talkbox", + "Producers", + "Producer", + "Produced", +]; diff --git a/src/assets/idMeta.json b/src/assets/data/idMeta.json similarity index 100% rename from src/assets/idMeta.json rename to src/assets/data/idMeta.json diff --git a/src/assets/data/themeColor.json b/src/assets/data/themeColor.json new file mode 100644 index 0000000..01ff920 --- /dev/null +++ b/src/assets/data/themeColor.json @@ -0,0 +1,57 @@ +{ + "default": { + "label": "default", + "name": "默认", + "color": "#fe7971" + }, + "orange": { + "label": "orange", + "name": "橙色", + "color": "#ff8c00" + }, + "blue": { + "label": "blue", + "name": "蓝色", + "color": "#3b5998" + }, + "pink": { + "label": "pink", + "name": "粉色", + "color": "#e91e63" + }, + "brown": { + "label": "brown", + "name": "棕色", + "color": "#795548" + }, + "indigo": { + "label": "indigo", + "name": "靛青色", + "color": "#3f51b5" + }, + "green": { + "label": "green", + "name": "绿色", + "color": "#2ecc71" + }, + "purple": { + "label": "purple", + "name": "紫色", + "color": "#9c27b0" + }, + "yellow": { + "label": "yellow", + "name": "黄色", + "color": "#FBC02D" + }, + "teal": { + "label": "teal", + "name": "青色", + "color": "#009688" + }, + "custom": { + "label": "custom", + "name": "自定义", + "color": "" + } +} diff --git a/src/assets/icon.json b/src/assets/icon.json deleted file mode 100644 index e80c71d..0000000 --- a/src/assets/icon.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "album": "M12 11a1 1 0 0 0-1 1a1 1 0 0 0 1 1a1 1 0 0 0 1-1a1 1 0 0 0-1-1m0 5.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5s4.5 2 4.5 4.5s-2 4.5-4.5 4.5M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2Z", - "chevron-up": "M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6l-6 6l1.41 1.41Z", - "chevron-down": "M7.41 8.58L12 13.17l4.59-4.59L18 10l-6 6l-6-6z", - "play": "M9.525 18.025q-.5.325-1.012.038T8 17.175V6.825q0-.6.513-.888t1.012.038l8.15 5.175q.45.3.45.85t-.45.85l-8.15 5.175Z", - "play-circle": "M10 16.5v-9l6 4.5M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2Z", - "pause-circle": "M15 16h-2V8h2m-4 8H9V8h2m1-6A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2", - "play-next": "m10 16.5l6-4.5l-6-4.5M22 12c0-5.54-4.46-10-10-10c-1.17 0-2.3.19-3.38.56l.7 1.94c.85-.34 1.74-.53 2.68-.53c4.41 0 8.03 3.62 8.03 8.03c0 4.41-3.62 8.03-8.03 8.03c-4.41 0-8.03-3.62-8.03-8.03c0-.94.19-1.88.53-2.72l-1.94-.66C2.19 9.7 2 10.83 2 12c0 5.54 4.46 10 10 10s10-4.46 10-10M5.47 3.97c.85 0 1.53.71 1.53 1.5C7 6.32 6.32 7 5.47 7c-.79 0-1.5-.68-1.5-1.53c0-.79.71-1.5 1.5-1.5Z", - "playlist-add": "M4 16q-.425 0-.713-.288T3 15q0-.425.288-.713T4 14h5q.425 0 .713.288T10 15q0 .425-.288.713T9 16H4Zm0-4q-.425 0-.713-.288T3 11q0-.425.288-.713T4 10h9q.425 0 .713.288T14 11q0 .425-.288.713T13 12H4Zm0-4q-.425 0-.713-.288T3 7q0-.425.288-.713T4 6h9q.425 0 .713.288T14 7q0 .425-.288.713T13 8H4Zm13 12q-.425 0-.713-.288T16 19v-3h-3q-.425 0-.713-.288T12 15q0-.425.288-.713T13 14h3v-3q0-.425.288-.713T17 10q.425 0 .713.288T18 11v3h3q.425 0 .713.288T22 15q0 .425-.288.713T21 16h-3v3q0 .425-.288.713T17 20Z", - "account-music": "M11 14c1 0 2.05.16 3.2.44c-.81.87-1.2 1.89-1.2 3.06c0 .89.25 1.73.78 2.5H3v-2c0-1.19.91-2.15 2.74-2.88C7.57 14.38 9.33 14 11 14m0-2c-1.08 0-2-.39-2.82-1.17C7.38 10.05 7 9.11 7 8c0-1.08.38-2 1.18-2.82C9 4.38 9.92 4 11 4c1.11 0 2.05.38 2.83 1.18C14.61 6 15 6.92 15 8c0 1.11-.39 2.05-1.17 2.83c-.78.78-1.72 1.17-2.83 1.17m7.5-2H22v2h-2v5.5a2.5 2.5 0 0 1-2.5 2.5a2.5 2.5 0 0 1-2.5-2.5a2.5 2.5 0 0 1 2.5-2.5c.36 0 .69.07 1 .21V10Z", - "music-note": "M12 3v10.55c-.59-.34-1.27-.55-2-.55c-2.21 0-4 1.79-4 4s1.79 4 4 4s4-1.79 4-4V7h4V3h-6Z", - "calendar-blank": "M19 19H5V8h14m-3-7v2H8V1H6v2H5c-1.11 0-2 .89-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2h-1V1", - "clock": "M12 2A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10A10 10 0 0 0 12 2m4.2 14.2L11 13V7h1.5v5.2l4.5 2.7l-.8 1.3Z", - "ip": "M16 11h-2V9h2v2M3 5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5m7 2H8v10h2V7m2 10h2v-4h2a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-4v10Z", - "cloud": "M6.5 20q-2.28 0-3.89-1.57Q1 16.85 1 14.58q0-1.95 1.17-3.48q1.18-1.53 3.08-1.95q.63-2.3 2.5-3.72Q9.63 4 12 4q2.93 0 4.96 2.04Q19 8.07 19 11q1.73.2 2.86 1.5q1.14 1.28 1.14 3q0 1.88-1.31 3.19T18.5 20Z", - "cloud-arrow-up": "M13 19c0 .34.04.67.09 1H6.5c-1.5 0-2.81-.5-3.89-1.57C1.54 17.38 1 16.09 1 14.58c0-1.3.39-2.46 1.17-3.48S4 9.43 5.25 9.15c.42-1.53 1.25-2.77 2.5-3.72S10.42 4 12 4c1.95 0 3.6.68 4.96 2.04C18.32 7.4 19 9.05 19 11c1.15.13 2.1.63 2.86 1.5c.51.57.84 1.21 1 1.92A5.908 5.908 0 0 0 19 13c-3.31 0-6 2.69-6 6m3-1h2v4h2v-4h2l-3-3l-3 3Z", - "cloud-clock": "M23 15.5c0-.71-.16-1.36-.45-1.96a6.998 6.998 0 0 0-3.69-3.92a6.547 6.547 0 0 0-1.9-3.58C15.6 4.68 13.95 4 12 4c-1.58 0-3 .47-4.25 1.43s-2.08 2.19-2.5 3.72c-1.25.28-2.29.93-3.08 1.95S1 13.28 1 14.58c0 1.51.54 2.8 1.61 3.85C3.69 19.5 5 20 6.5 20h3.76c1.27 1.81 3.36 3 5.74 3c3.87 0 7-3.13 7-7v-.5M16 21c-2.76 0-5-2.24-5-5s2.24-5 5-5s5 2.24 5 5s-2.24 5-5 5m.5-4.75l2.86 1.69l-.75 1.22L15 17v-5h1.5v4.25Z", - "window-close": "M13.46 12L19 17.54V19h-1.46L12 13.46L6.46 19H5v-1.46L10.54 12L5 6.46V5h1.46L12 10.54L17.54 5H19v1.46L13.46 12Z", - "window-restore": "M4 8h4V4h12v12h-4v4H4V8m12 0v6h2V6h-8v2h6M6 12v6h8v-6H6Z", - "window-maximize": "M4 4h16v16H4V4m2 4v10h12V8H6Z", - "window-minimize": "M20 14H4v-4h16", - "refresh": "M17.65 6.35A7.958 7.958 0 0 0 12 4a8 8 0 0 0-8 8a8 8 0 0 0 8 8c3.73 0 6.84-2.55 7.73-6h-2.08A5.99 5.99 0 0 1 12 18a6 6 0 0 1-6-6a6 6 0 0 1 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35Z", - "chevron-left": "M15.41 16.58L10.83 12l4.58-4.59L14 6l-6 6l6 6l1.41-1.42Z", - "chevron-right": "M8.59 16.58L13.17 12L8.59 7.41L10 6l6 6l-6 6l-1.41-1.42Z", - "account-circle": "M12 19.2c-2.5 0-4.71-1.28-6-3.2c.03-2 4-3.1 6-3.1s5.97 1.1 6 3.1a7.232 7.232 0 0 1-6 3.2M12 5a3 3 0 0 1 3 3a3 3 0 0 1-3 3a3 3 0 0 1-3-3a3 3 0 0 1 3-3m0-3A10 10 0 0 0 2 12a10 10 0 0 0 10 10a10 10 0 0 0 10-10c0-5.53-4.5-10-10-10Z", - "menu-down": "m7 10l5 5l5-5H7Z", - "menu": "M4 10.5c-.83 0-1.5.67-1.5 1.5s.67 1.5 1.5 1.5s1.5-.67 1.5-1.5s-.67-1.5-1.5-1.5zm0-6c-.83 0-1.5.67-1.5 1.5S3.17 7.5 4 7.5S5.5 6.83 5.5 6S4.83 4.5 4 4.5zm0 12c-.83 0-1.5.68-1.5 1.5s.68 1.5 1.5 1.5s1.5-.68 1.5-1.5s-.67-1.5-1.5-1.5zM8 19h12c.55 0 1-.45 1-1s-.45-1-1-1H8c-.55 0-1 .45-1 1s.45 1 1 1zm0-6h12c.55 0 1-.45 1-1s-.45-1-1-1H8c-.55 0-1 .45-1 1s.45 1 1 1zM7 6c0 .55.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1H8c-.55 0-1 .45-1 1z", - "calendar-check": "M19 19H5V8h14m0-5h-1V1h-2v2H8V1H6v2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2m-2.47 8.06L15.47 10l-4.88 4.88l-2.12-2.12l-1.06 1.06L10.59 17l5.94-5.94Z", - "calendar-badge": "M19.5 16c-1.9 0-3.5 1.6-3.5 3.5s1.6 3.5 3.5 3.5s3.5-1.6 3.5-3.5s-1.6-3.5-3.5-3.5m-5.29 5H5a2 2 0 0 1-2-2V5c0-1.11.89-2 2-2h1V1h2v2h8V1h2v2h1a2 2 0 0 1 2 2v9.21c-.5-.13-1-.21-1.5-.21c-.17 0-.33 0-.5.03V8H5v11h9.03c-.03.17-.03.33-.03.5c0 .5.08 1 .21 1.5Z", - "round-wb-sunny": "m6.05 4.14l-.39-.39a.993.993 0 0 0-1.4 0l-.01.01a.984.984 0 0 0 0 1.4l.39.39c.39.39 1.01.39 1.4 0l.01-.01a.984.984 0 0 0 0-1.4zM3.01 10.5H1.99c-.55 0-.99.44-.99.99v.01c0 .55.44.99.99.99H3c.56.01 1-.43 1-.98v-.01c0-.56-.44-1-.99-1zm9-9.95H12c-.56 0-1 .44-1 .99v.96c0 .55.44.99.99.99H12c.56.01 1-.43 1-.98v-.97c0-.55-.44-.99-.99-.99zm7.74 3.21c-.39-.39-1.02-.39-1.41-.01l-.39.39a.984.984 0 0 0 0 1.4l.01.01c.39.39 1.02.39 1.4 0l.39-.39a.984.984 0 0 0 0-1.4zm-1.81 15.1l.39.39a.996.996 0 1 0 1.41-1.41l-.39-.39a.993.993 0 0 0-1.4 0c-.4.4-.4 1.02-.01 1.41zM20 11.49v.01c0 .55.44.99.99.99H22c.55 0 .99-.44.99-.99v-.01c0-.55-.44-.99-.99-.99h-1.01c-.55 0-.99.44-.99.99zM12 5.5c-3.31 0-6 2.69-6 6s2.69 6 6 6s6-2.69 6-6s-2.69-6-6-6zm-.01 16.95H12c.55 0 .99-.44.99-.99v-.96c0-.55-.44-.99-.99-.99h-.01c-.55 0-.99.44-.99.99v.96c0 .55.44.99.99.99zm-7.74-3.21c.39.39 1.02.39 1.41 0l.39-.39a.993.993 0 0 0 0-1.4l-.01-.01a.996.996 0 0 0-1.41 0l-.39.39c-.38.4-.38 1.02.01 1.41z", - "round-dark-mode": "M11.01 3.05C6.51 3.54 3 7.36 3 12a9 9 0 0 0 9 9c4.63 0 8.45-3.5 8.95-8c.09-.79-.78-1.42-1.54-.95A5.403 5.403 0 0 1 11.1 7.5c0-1.06.31-2.06.84-2.89c.45-.67-.04-1.63-.93-1.56z", - "round-settings": "M19.5 12c0-.23-.01-.45-.03-.68l1.86-1.41c.4-.3.51-.86.26-1.3l-1.87-3.23a.987.987 0 0 0-1.25-.42l-2.15.91c-.37-.26-.76-.49-1.17-.68l-.29-2.31c-.06-.5-.49-.88-.99-.88h-3.73c-.51 0-.94.38-1 .88l-.29 2.31c-.41.19-.8.42-1.17.68l-2.15-.91c-.46-.2-1-.02-1.25.42L2.41 8.62c-.25.44-.14.99.26 1.3l1.86 1.41a7.343 7.343 0 0 0 0 1.35l-1.86 1.41c-.4.3-.51.86-.26 1.3l1.87 3.23c.25.44.79.62 1.25.42l2.15-.91c.37.26.76.49 1.17.68l.29 2.31c.06.5.49.88.99.88h3.73c.5 0 .93-.38.99-.88l.29-2.31c.41-.19.8-.42 1.17-.68l2.15.91c.46.2 1 .02 1.25-.42l1.87-3.23c.25-.44.14-.99-.26-1.3l-1.86-1.41c.03-.23.04-.45.04-.68zm-7.46 3.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5s3.5 1.57 3.5 3.5s-1.57 3.5-3.5 3.5z", - "logout": "m17 8l-1.4 1.4l1.6 1.6H9v2h8.2l-1.6 1.6L17 16l4-4l-4-4M5 5h7V3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h7v-2H5V5Z", - "login": "M11 7L9.6 8.4l2.6 2.6H2v2h10.2l-2.6 2.6L11 17l5-5l-5-5m9 12h-8v2h8c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2h-8v2h8v14Z", - "fullscreen-exit-rounded": "M8 16H6q-.425 0-.713-.288T5 15q0-.425.288-.713T6 14h3q.425 0 .713.288T10 15v3q0 .425-.288.713T9 19q-.425 0-.713-.288T8 18v-2Zm8 0v2q0 .425-.288.713T15 19q-.425 0-.713-.288T14 18v-3q0-.425.288-.713T15 14h3q.425 0 .713.288T19 15q0 .425-.288.713T18 16h-2ZM8 8V6q0-.425.288-.713T9 5q.425 0 .713.288T10 6v3q0 .425-.288.713T9 10H6q-.425 0-.713-.288T5 9q0-.425.288-.713T6 8h2Zm8 0h2q.425 0 .713.288T19 9q0 .425-.288.713T18 10h-3q-.425 0-.713-.288T14 9V6q0-.425.288-.713T15 5q.425 0 .713.288T16 6v2Z", - "fullscreen-rounded": "M7 17h2q.425 0 .713.288T10 18q0 .425-.288.713T9 19H6q-.425 0-.713-.288T5 18v-3q0-.425.288-.713T6 14q.425 0 .713.288T7 15v2ZM7 7v2q0 .425-.288.713T6 10q-.425 0-.713-.288T5 9V6q0-.425.288-.713T6 5h3q.425 0 .713.288T10 6q0 .425-.288.713T9 7H7Zm10 10v-2q0-.425.288-.713T18 14q.425 0 .713.288T19 15v3q0 .425-.288.713T18 19h-3q-.425 0-.713-.288T14 18q0-.425.288-.713T15 17h2Zm0-10h-2q-.425 0-.713-.288T14 6q0-.425.288-.713T15 5h3q.425 0 .713.288T19 6v3q0 .425-.288.713T18 10q-.425 0-.713-.288T17 9V7Z", - "keyboard-arrow-down-rounded": "M12 14.975q-.2 0-.375-.062T11.3 14.7l-4.6-4.6q-.275-.275-.275-.7t.275-.7q.275-.275.7-.275t.7.275l3.9 3.9l3.9-3.9q.275-.275.7-.275t.7.275q.275.275.275.7t-.275.7l-4.6 4.6q-.15.15-.325.213t-.375.062Z", - "pan-zoom-rounded": "M6.4 19H8q.425 0 .713.288T9 20q0 .425-.288.713T8 21H4q-.425 0-.713-.288T3 20v-4q0-.425.288-.713T4 15q.425 0 .713.288T5 16v1.6l2.4-2.4q.275-.275.7-.275t.7.275q.275.275.275.7t-.275.7L6.4 19ZM19 6.4l-2.4 2.4q-.275.275-.7.275t-.7-.275q-.275-.275-.275-.7t.275-.7L17.6 5H16q-.425 0-.713-.288T15 4q0-.425.288-.713T16 3h4q.425 0 .713.288T21 4v4q0 .425-.288.713T20 9q-.425 0-.713-.288T19 8V6.4Z", - "skip-previous-rounded": "M6.5 18q-.425 0-.713-.288T5.5 17V7q0-.425.288-.713T6.5 6q.425 0 .713.288T7.5 7v10q0 .425-.288.713T6.5 18Zm10.45-1.025l-6.2-4.15q-.45-.3-.45-.825t.45-.825l6.2-4.15q.5-.325 1.025-.037t.525.887v8.25q0 .6-.525.9t-1.025-.05Z", - "skip-next-rounded": "M17.5 18q-.425 0-.713-.288T16.5 17V7q0-.425.288-.713T17.5 6q.425 0 .713.288T18.5 7v10q0 .425-.288.713T17.5 18ZM7.05 16.975q-.5.35-1.025.05t-.525-.9v-8.25q0-.6.525-.888t1.025.038l6.2 4.15q.45.3.45.825t-.45.825l-6.2 4.15Z", - "pause-rounded": "M16 19q-.825 0-1.413-.588T14 17V7q0-.825.588-1.413T16 5q.825 0 1.413.588T18 7v10q0 .825-.588 1.413T16 19Zm-8 0q-.825 0-1.413-.588T6 17V7q0-.825.588-1.413T8 5q.825 0 1.413.588T10 7v10q0 .825-.588 1.413T8 19Z", - "play-arrow-rounded": "M9.525 18.025q-.5.325-1.012.038T8 17.175V6.825q0-.6.513-.888t1.012.038l8.15 5.175q.45.3.45.85t-.45.85l-8.15 5.175Z", - "speed-rounded": "M10.45 15.5q.625.625 1.575.588T13.4 15.4l4.225-6.325q.225-.35-.062-.638t-.638-.062L10.6 12.6q-.65.45-.712 1.363t.562 1.537ZM5.1 20q-.55 0-1.012-.238t-.738-.712q-.65-1.175-1-2.438T2 14q0-2.075.788-3.9t2.137-3.175q1.35-1.35 3.175-2.137T12 4q2.05 0 3.85.775T19 6.888q1.35 1.337 2.15 3.125t.825 3.837q.025 1.375-.313 2.688t-1.037 2.512q-.275.475-.738.713T18.875 20H5.1Z", - "no-sound-rounded": "m18 13.4l-1.9 1.9q-.275.275-.7.275t-.7-.275q-.275-.275-.275-.7t.275-.7l1.9-1.9l-1.9-1.9q-.275-.275-.275-.7t.275-.7q.275-.275.7-.275t.7.275l1.9 1.9l1.9-1.9q.275-.275.7-.275t.7.275q.275.275.275.7t-.275.7L19.4 12l1.9 1.9q.275.275.275.7t-.275.7q-.275.275-.7.275t-.7-.275L18 13.4ZM7 15H4q-.425 0-.713-.288T3 14v-4q0-.425.288-.713T4 9h3l3.3-3.3q.475-.475 1.088-.213t.612.938v11.15q0 .675-.613.938T10.3 18.3L7 15Z", - "volume-mute-rounded": "M11 15H8q-.425 0-.713-.288T7 14v-4q0-.425.288-.713T8 9h3l3.3-3.3q.475-.475 1.088-.213t.612.938v11.15q0 .675-.613.938T14.3 18.3L11 15Z", - "volume-down-rounded": "M9 15H6q-.425 0-.713-.288T5 14v-4q0-.425.288-.713T6 9h3l3.3-3.3q.475-.475 1.088-.213t.612.938v11.15q0 .675-.613.938T12.3 18.3L9 15Zm9.5-3q0 1.05-.475 1.988t-1.25 1.537q-.25.15-.512.013T16 15.1V8.85q0-.3.263-.438t.512.013q.775.625 1.25 1.575t.475 2Z", - "volume-up-rounded": "M19 11.975q0-2.075-1.1-3.787t-2.95-2.563q-.375-.175-.55-.537t-.05-.738q.15-.4.537-.575t.788 0Q18.1 4.85 19.55 7.063T21 11.974q0 2.7-1.45 4.913t-3.875 3.287q-.4.175-.788 0t-.537-.575q-.125-.375.05-.738t.55-.537q1.85-.85 2.95-2.563t1.1-3.787ZM7 15H4q-.425 0-.713-.288T3 14v-4q0-.425.288-.713T4 9h3l3.3-3.3q.475-.475 1.088-.213t.612.938v11.15q0 .675-.613.938T10.3 18.3L7 15Zm9.5-3q0 1.05-.475 1.988t-1.25 1.537q-.25.15-.513.013T14 15.1V8.85q0-.3.263-.438t.512.013q.775.625 1.25 1.575t.475 2Z", - "queue-music-rounded": "M16 20q-1.25 0-2.125-.875T13 17q0-1.25.875-2.125T16 14q.275 0 .525.038T17 14.2V7q0-.425.288-.713T18 6h3q.425 0 .713.288T22 7q0 .425-.288.713T21 8h-2v9q0 1.25-.875 2.125T16 20ZM4 16q-.425 0-.713-.288T3 15q0-.425.288-.713T4 14h6q.425 0 .713.288T11 15q0 .425-.288.713T10 16H4Zm0-4q-.425 0-.713-.288T3 11q0-.425.288-.713T4 10h10q.425 0 .713.288T15 11q0 .425-.288.713T14 12H4Zm0-4q-.425 0-.713-.288T3 7q0-.425.288-.713T4 6h10q.425 0 .713.288T15 7q0 .425-.288.713T14 8H4Z", - "favorite-outline-rounded": "M12 20.325q-.35 0-.713-.125t-.637-.4l-1.725-1.575q-2.65-2.425-4.788-4.813T2 8.15Q2 5.8 3.575 4.225T7.5 2.65q1.325 0 2.5.562t2 1.538q.825-.975 2-1.538t2.5-.562q2.35 0 3.925 1.575T22 8.15q0 2.875-2.125 5.275T15.05 18.25l-1.7 1.55q-.275.275-.637.4t-.713.125ZM11.05 6.75q-.725-1.025-1.55-1.562t-2-.538q-1.5 0-2.5 1t-1 2.5q0 1.3.925 2.763t2.213 2.837q1.287 1.375 2.65 2.575T12 18.3q.85-.775 2.213-1.975t2.65-2.575q1.287-1.375 2.212-2.837T20 8.15q0-1.5-1-2.5t-2.5-1q-1.175 0-2 .537T12.95 6.75q-.175.25-.425.375T12 7.25q-.275 0-.525-.125t-.425-.375Zm.95 4.725Z", - "favorite-rounded": "M12 20.325q-.35 0-.713-.125t-.637-.4l-1.725-1.575q-2.65-2.425-4.788-4.813T2 8.15Q2 5.8 3.575 4.225T7.5 2.65q1.325 0 2.5.562t2 1.538q.825-.975 2-1.538t2.5-.562q2.35 0 3.925 1.575T22 8.15q0 2.875-2.125 5.275T15.05 18.25l-1.7 1.55q-.275.275-.637.4t-.713.125Z", - "history": "M12 21q-3.15 0-5.575-1.913T3.275 14.2q-.1-.375.15-.687t.675-.363q.4-.05.725.15t.45.6q.6 2.25 2.475 3.675T12 19q2.925 0 4.963-2.038T19 12q0-2.925-2.038-4.963T12 5q-1.725 0-3.225.8T6.25 8H8q.425 0 .713.288T9 9q0 .425-.288.713T8 10H4q-.425 0-.713-.288T3 9V5q0-.425.288-.713T4 4q.425 0 .713.288T5 5v1.35q1.275-1.6 3.113-2.475T12 3q1.875 0 3.513.713t2.85 1.924q1.212 1.213 1.925 2.85T21 12q0 1.875-.713 3.513t-1.924 2.85q-1.213 1.212-2.85 1.925T12 21Zm1-9.4l2.5 2.5q.275.275.275.7t-.275.7q-.275.275-.7.275t-.7-.275l-2.8-2.8q-.15-.15-.225-.337T11 11.975V8q0-.425.288-.713T12 7q.425 0 .713.288T13 8v3.6Z", - "delete": "M19 4h-3.5l-1-1h-5l-1 1H5v2h14M6 19a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V7H6v12Z", - "delete-sweep": "M15 16h4v2h-4zm0-8h7v2h-7zm0 4h6v2h-6zM3 18c0 1.1.9 2 2 2h6c1.1 0 2-.9 2-2V8H3zM14 5h-3l-1-1H6L5 5H2v2h12z", - "fire": "M17.66 11.2c-.23-.3-.51-.56-.77-.82c-.67-.6-1.43-1.03-2.07-1.66C13.33 7.26 13 4.85 13.95 3c-.95.23-1.78.75-2.49 1.32c-2.59 2.08-3.61 5.75-2.39 8.9c.04.1.08.2.08.33c0 .22-.15.42-.35.5c-.23.1-.47.04-.66-.12a.58.58 0 0 1-.14-.17c-1.13-1.43-1.31-3.48-.55-5.12C5.78 10 4.87 12.3 5 14.47c.06.5.12 1 .29 1.5c.14.6.41 1.2.71 1.73c1.08 1.73 2.95 2.97 4.96 3.22c2.14.27 4.43-.12 6.07-1.6c1.83-1.66 2.47-4.32 1.53-6.6l-.13-.26c-.21-.46-.77-1.26-.77-1.26m-3.16 6.3c-.28.24-.74.5-1.1.6c-1.12.4-2.24-.16-2.9-.82c1.19-.28 1.9-1.16 2.11-2.05c.17-.8-.15-1.46-.28-2.23c-.12-.74-.1-1.37.17-2.06c.19.38.39.76.63 1.06c.77 1 1.98 1.44 2.24 2.8c.04.14.06.28.06.43c.03.82-.33 1.72-.93 2.27Z", - "search-rounded": "M9.5 16q-2.725 0-4.612-1.888T3 9.5q0-2.725 1.888-4.612T9.5 3q2.725 0 4.612 1.888T16 9.5q0 1.1-.35 2.075T14.7 13.3l5.6 5.6q.275.275.275.7t-.275.7q-.275.275-.7.275t-.7-.275l-5.6-5.6q-.75.6-1.725.95T9.5 16Zm0-2q1.875 0 3.188-1.313T14 9.5q0-1.875-1.313-3.188T9.5 5Q7.625 5 6.312 6.313T5 9.5q0 1.875 1.313 3.188T9.5 14Z", - "search-off": "m7 17.7l1.4 1.425q.15.15.35.15t.35-.15q.15-.15.15-.363T9.1 18.4L7.7 17l1.425-1.425q.15-.15.15-.35t-.15-.35q-.15-.15-.35-.15t-.35.15L7 16.3l-1.425-1.425q-.15-.15-.35-.15t-.35.15q-.15.15-.15.35t.15.35L6.3 17l-1.425 1.425q-.15.15-.15.35t.15.35q.15.15.35.15t.35-.15L7 17.7ZM7 22q-2.075 0-3.538-1.463T2 17q0-2.075 1.463-3.538T7 12q2.075 0 3.538 1.463T12 17q0 2.075-1.463 3.538T7 22Zm7.2-7.4q-.3-.325-.638-.663T12.9 13.3q.95-.6 1.525-1.6T15 9.5q0-1.875-1.313-3.188T10.5 5Q8.625 5 7.312 6.313T6 9.5q0 .15.013.288t.037.287q-.45.05-.987.2t-.963.35q-.05-.275-.075-.55T4 9.5q0-2.725 1.888-4.612T10.5 3q2.725 0 4.612 1.888T17 9.5q0 1.075-.338 2.038t-.937 1.762l5.575 5.6q.275.275.288.688t-.288.712q-.275.275-.7.275t-.7-.275l-5.7-5.7Z", - "folder-cog": "M4 4c-1.11 0-2 .89-2 2v12a2 2 0 0 0 2 2h8.08a7 7 0 0 1-.08-1a7 7 0 0 1 7-7a7 7 0 0 1 3 .69V8a2 2 0 0 0-2-2h-8l-2-2H4m14 10a.26.26 0 0 0-.26.21l-.19 1.32c-.3.13-.59.29-.85.47l-1.24-.5c-.11 0-.24 0-.31.13l-1 1.73c-.06.11-.04.24.06.32l1.06.82a4.193 4.193 0 0 0 0 1l-1.06.82a.26.26 0 0 0-.06.32l1 1.73c.06.13.19.13.31.13l1.24-.5c.26.18.54.35.85.47l.19 1.32c.02.12.12.21.26.21h2c.11 0 .22-.09.24-.21l.19-1.32c.3-.13.57-.29.84-.47l1.23.5c.13 0 .26 0 .33-.13l1-1.73a.26.26 0 0 0-.06-.32l-1.07-.82c.02-.17.04-.33.04-.5c0-.17-.01-.33-.04-.5l1.06-.82a.26.26 0 0 0 .06-.32l-1-1.73c-.06-.13-.19-.13-.32-.13l-1.23.5c-.27-.18-.54-.35-.85-.47l-.19-1.32A.236.236 0 0 0 20 14h-2m1 3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5c-.84 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5Z", - "folder-music": "M22 8v3h-5.5v5.11c-1.84.42-3.24 1.98-3.46 3.89H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h8a2 2 0 0 1 2 2m-3.5 5v5.21a2.5 2.5 0 1 0-1 4.79a2.5 2.5 0 0 0 2.5-2.5V15h2v-2h-3.5Z", - "folder-open": "M19 20H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h7a2 2 0 0 1 2 2H4v10l2.14-8h17.07l-2.28 8.5c-.23.87-1.01 1.5-1.93 1.5Z", - "folder-plus-outline": "M13 19c0 .34.04.67.09 1H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h8a2 2 0 0 1 2 2v5.81c-.61-.35-1.28-.59-2-.72V8H4v10h9.09c-.05.33-.09.66-.09 1m7-1v-3h-2v3h-3v2h3v3h2v-3h3v-2h-3Z", - "folder-plus": "M13 19c0 .34.04.67.09 1H4a2 2 0 0 1-2-2V6c0-1.11.89-2 2-2h6l2 2h8a2 2 0 0 1 2 2v5.81c-.88-.51-1.9-.81-3-.81c-3.31 0-6 2.69-6 6m7-1v-3h-2v3h-3v2h3v3h2v-3h3v-2h-3Z", - "video": "m10 15l5.19-3L10 9v6m11.56-7.83c.13.47.22 1.1.28 1.9c.07.8.1 1.49.1 2.09L22 12c0 2.19-.16 3.8-.44 4.83c-.25.9-.83 1.48-1.73 1.73c-.47.13-1.33.22-2.65.28c-1.3.07-2.49.1-3.59.1L12 19c-4.19 0-6.8-.16-7.83-.44c-.9-.25-1.48-.83-1.73-1.73c-.13-.47-.22-1.1-.28-1.9c-.07-.8-.1-1.49-.1-2.09L2 12c0-2.19.16-3.8.44-4.83c.25-.9.83-1.48 1.73-1.73c.47-.13 1.33-.22 2.65-.28c1.3-.07 2.49-.1 3.59-.1L12 5c4.19 0 6.8.16 7.83.44c.9.25 1.48.83 1.73 1.73Z", - "comment-text": "M9 22a1 1 0 0 1-1-1v-3H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6.1l-3.7 3.71c-.2.19-.45.29-.7.29H9M5 5v2h14V5H5m0 4v2h8V9H5m0 4v2h10v-2H5Z", - "comment-text-multiple": "M3 15H1V3a2 2 0 0 1 2-2h16v2H3v12m9 8a1 1 0 0 1-1-1v-3H7a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-4.1l-3.7 3.71c-.2.18-.44.29-.7.29H12M9 9v2h10V9H9m0 4v2h8v-2H9Z", - "thumb-up": "M23 10a2 2 0 0 0-2-2h-6.32l.96-4.57c.02-.1.03-.21.03-.32c0-.41-.17-.79-.44-1.06L14.17 1L7.59 7.58C7.22 7.95 7 8.45 7 9v10a2 2 0 0 0 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2M1 21h4V9H1v12Z", - "thumb-up-outline": "M5 9v12H1V9h4m4 12a2 2 0 0 1-2-2V9c0-.55.22-1.05.59-1.41L14.17 1l1.06 1.06c.27.27.44.64.44 1.05l-.03.32L14.69 8H21a2 2 0 0 1 2 2v2c0 .26-.05.5-.14.73l-3.02 7.05C19.54 20.5 18.83 21 18 21H9m0-2h9.03L21 12v-2h-8.79l1.13-5.32L9 9.03V19Z", - "thumb-down": "M3 16q-.8 0-1.4-.6T1 14v-2q0-.175.037-.375t.113-.375l3-7.05q.225-.5.75-.85T6 3h8q.825 0 1.413.587T16 5v10.175q0 .4-.163.763t-.437.637l-5.425 5.4q-.375.35-.887.425t-.988-.175q-.475-.25-.687-.7t-.088-.925L8.45 16H3ZM20 3q.825 0 1.413.588T22 5v9q0 .825-.588 1.413T20 16q-.825 0-1.413-.588T18 14V5q0-.825.588-1.413T20 3Z", - "share": "m21 12l-7-7v4C7 10 4 15 3 20c2.5-3.5 6-5.1 11-5.1V19l7-7Z", - "format-list-bulleted": "M7 5h14v2H7V5m0 8v-2h14v2H7M4 4.5A1.5 1.5 0 0 1 5.5 6A1.5 1.5 0 0 1 4 7.5A1.5 1.5 0 0 1 2.5 6A1.5 1.5 0 0 1 4 4.5m0 6A1.5 1.5 0 0 1 5.5 12A1.5 1.5 0 0 1 4 13.5A1.5 1.5 0 0 1 2.5 12A1.5 1.5 0 0 1 4 10.5M7 19v-2h14v2H7m-3-2.5A1.5 1.5 0 0 1 5.5 18A1.5 1.5 0 0 1 4 19.5A1.5 1.5 0 0 1 2.5 18A1.5 1.5 0 0 1 4 16.5Z", - "link": "M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7a5 5 0 0 0-5 5a5 5 0 0 0 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1M8 13h8v-2H8v2m9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1c0 1.71-1.39 3.1-3.1 3.1h-4V17h4a5 5 0 0 0 5-5a5 5 0 0 0-5-5Z", - "home": "M10 20v-6h4v6h5v-8h3L12 3L2 12h3v8h5Z", - "discover-fill": "M2 12C2 6.477 6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12Zm13-3l-3.693.739a2 2 0 0 0-1.568 1.568L9 15l3.693-.739a2 2 0 0 0 1.569-1.568L15 9Z", - "content-copy": "M9 18q-.825 0-1.413-.588T7 16V4q0-.825.588-1.413T9 2h9q.825 0 1.413.588T20 4v12q0 .825-.588 1.413T18 18H9Zm-4 4q-.825 0-1.413-.588T3 20V6h2v14h11v2H5Z", - "update-rounded": "M12 21q-1.875 0-3.513-.713t-2.85-1.924q-1.212-1.213-1.924-2.85T3 12q0-1.875.713-3.513t1.924-2.85q1.213-1.212 2.85-1.924T12 3q2.05 0 3.888.875T19 6.35V5q0-.425.288-.713T20 4q.425 0 .713.288T21 5v4q0 .425-.288.713T20 10h-4q-.425 0-.713-.288T15 9q0-.425.288-.713T16 8h1.75q-1.025-1.4-2.525-2.2T12 5Q9.075 5 7.037 7.038T5 12q0 2.925 2.038 4.963T12 19q2.375 0 4.25-1.425t2.475-3.675q.125-.4.45-.6t.725-.15q.425.05.675.362t.15.688q-.725 2.975-3.15 4.888T12 21Zm1-9.4l2.5 2.5q.275.275.275.7t-.275.7q-.275.275-.7.275t-.7-.275l-2.8-2.8q-.15-.15-.225-.337T11 11.975V8q0-.425.288-.713T12 7q.425 0 .713.288T13 8v3.6Z", - "headphones": "M9 21H5q-.825 0-1.413-.588T3 19v-7q0-1.875.713-3.513t1.924-2.85q1.213-1.212 2.85-1.924T12 3q1.875 0 3.513.713t2.85 1.924q1.212 1.213 1.925 2.85T21 12v7q0 .825-.588 1.413T19 21h-4v-8h4v-1q0-2.925-2.038-4.963T12 5Q9.075 5 7.037 7.038T5 12v1h4v8Z", - "edit": "M14 11c0 .55-.45 1-1 1H4c-.55 0-1-.45-1-1s.45-1 1-1h9c.55 0 1 .45 1 1zM3 7c0 .55.45 1 1 1h9c.55 0 1-.45 1-1s-.45-1-1-1H4c-.55 0-1 .45-1 1zm7 8c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1s.45 1 1 1h5c.55 0 1-.45 1-1zm8.01-2.13l.71-.71a.996.996 0 0 1 1.41 0l.71.71c.39.39.39 1.02 0 1.41l-.71.71l-2.12-2.12zm-.71.71l-5.16 5.16c-.09.09-.14.21-.14.35v1.41c0 .28.22.5.5.5h1.41c.13 0 .26-.05.35-.15l5.16-5.16l-2.12-2.11z", - "heartbit": "M14.9 6.5c2 0 3.7 1.6 4.1 3.6 1.3.4 2 1 2 1.9 0 1.1-1.1 1.7-3 2.1-.5.7-1.1 1.4-2 2.1-.7.6-1.4 1.1-2.2 1.6-.2.2-.5.3-.7.4-.1.1-.2.1-.3.2-.2.1-.5.1-.7 0-.1 0-.2-.1-.3-.2-.2-.1-.5-.3-.7-.4-.8-.5-1.5-1-2.2-1.6-.7-.7-1.4-1.4-1.9-2.1-2-.4-3-1-3-2.1 0-.9.7-1.5 2.1-1.9.3-2 2-3.6 4.1-3.6.9 0 1.7.3 2.4.8.6-.5 1.4-.8 2.3-.8zm-3.8 6.4c-.1.1-.2.2-.4.5-.1.1-.1.2-.2.3-.5.5-.8.7-1.2.7-.3 0-.6 0-.9-.1.3.4.7.7 1.2 1.1.7.6 1.4 1.1 2.1 1.6.2.2.5.3.7.4l.1.1s.1 0 .1-.1c.2-.1.4-.3.7-.4l2.1-1.5c.5-.4.9-.8 1.2-1.1-.4 0-.9.1-1.4.1l-.4.4-.1.1-.5.5c-.3.1-.4.2-.7.2-.3.1-.5-.1-.8-.6-.2-.3-.4-.5-.8-1.1-.4-.5-.5-.8-.7-1 0 0 0-.1-.1-.1zm3.8-5.4c-.7 0-1.5.3-2 .8l-.4.3-.3-.3c-.6-.5-1.3-.8-2-.8C8.4 7.5 7 9 7 10.9c0 .8.2 1.6.6 2.3.5.1 1.1.1 1.8.2 0 0 .1-.1.3-.4.1-.1.2-.1.3-.2.2-.3.4-.5.5-.6.3-.3.4-.4.7-.4s.5.2.8.7c.2.2.3.5.7 1.1s.5.8.7 1c0 .1.1.1.1.1l.5-.5c.5-.5.8-.7 1.1-.7.9-.1 1.6-.1 2.3-.2.4-.8.6-1.6.6-2.4 0-1.9-1.4-3.4-3.1-3.4zM6 11.2c-.7.2-1 .5-1 .8 0 .4.5.7 1.4.9-.2-.5-.4-1.1-.4-1.7zm13 0v.2c0 .5-.2 1-.4 1.5.9-.2 1.4-.5 1.4-.9 0-.3-.3-.6-1-.8z", - "location": "M11 22.95v-2q-3.125-.35-5.363-2.587T3.05 13h-2v-2h2q.35-3.125 2.588-5.363T11 3.05v-2h2v2q3.125.35 5.363 2.588T20.95 11h2v2h-2q-.35 3.125-2.587 5.363T13 20.95v2h-2ZM12 19q2.9 0 4.95-2.05T19 12q0-2.9-2.05-4.95T12 5Q9.1 5 7.05 7.05T5 12q0 2.9 2.05 4.95T12 19Zm0-3q-1.65 0-2.825-1.175T8 12q0-1.65 1.175-2.825T12 8q1.65 0 2.825 1.175T16 12q0 1.65-1.175 2.825T12 16Z", - "add": "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2Z", - "list-lock-open": "M23 17.3v3.5c0 .6-.6 1.2-1.3 1.2h-5.5c-.6 0-1.2-.6-1.2-1.3v-3.5c0-.6.6-1.2 1.2-1.2v-2.5c0-1.4 1.4-2.5 2.8-2.5s2.8 1.1 2.8 2.5v.5h-1.3v-.5c0-.8-.7-1.3-1.5-1.3s-1.5.5-1.5 1.3V16h4.3c.6 0 1.2.6 1.2 1.3M3 13v-2h12v2H3m0-7h18v2H3V6m0 12v-2h6v2H3", - "code": "M8.7 15.9L4.8 12l3.9-3.9a.984.984 0 0 0 0-1.4a.984.984 0 0 0-1.4 0l-4.59 4.59a.996.996 0 0 0 0 1.41l4.59 4.6c.39.39 1.01.39 1.4 0a.984.984 0 0 0 0-1.4zm6.6 0l3.9-3.9l-3.9-3.9a.984.984 0 0 1 0-1.4a.984.984 0 0 1 1.4 0l4.59 4.59c.39.39.39 1.02 0 1.41l-4.59 4.6a.984.984 0 0 1-1.4 0a.984.984 0 0 1 0-1.4z", - "more": "M6 10c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2z", - "more-vert": "M12 8c1.1 0 2-.9 2-2s-.9-2-2-2s-2 .9-2 2s.9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2s2-.9 2-2s-.9-2-2-2z", - "download": "M16.59 9H15V4c0-.55-.45-1-1-1h-4c-.55 0-1 .45-1 1v5H7.41c-.89 0-1.34 1.08-.71 1.71l4.59 4.59c.39.39 1.02.39 1.41 0l4.59-4.59c.63-.63.19-1.71-.7-1.71zM5 19c0 .55.45 1 1 1h12c.55 0 1-.45 1-1s-.45-1-1-1H6c-.55 0-1 .45-1 1z", - "radio": "M3.24 6.15C2.51 6.43 2 7.17 2 8v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8c0-1.11-.89-2-2-2H8.3l8.26-3.34L15.88 1L3.24 6.15zM7 20c-1.66 0-3-1.34-3-3s1.34-3 3-3s3 1.34 3 3s-1.34 3-3 3zm13-8h-2v-2h-2v2H4V8h16v4z", - "person-add": "M15.39 14.56C13.71 13.7 11.53 13 9 13s-4.71.7-6.39 1.56A2.97 2.97 0 0 0 1 17.22V20h16v-2.78c0-1.12-.61-2.15-1.61-2.66zM9 12c2.21 0 4-1.79 4-4s-1.79-4-4-4s-4 1.79-4 4s1.79 4 4 4zm11-3V7c0-.55-.45-1-1-1s-1 .45-1 1v2h-2c-.55 0-1 .45-1 1s.45 1 1 1h2v2c0 .55.45 1 1 1s1-.45 1-1v-2h2c.55 0 1-.45 1-1s-.45-1-1-1h-2z", - "person-remove": "M14 8c0-2.21-1.79-4-4-4S6 5.79 6 8s1.79 4 4 4s4-1.79 4-4zM2 18v1c0 .55.45 1 1 1h14c.55 0 1-.45 1-1v-1c0-2.66-5.33-4-8-4s-8 1.34-8 4zm16-8h4c.55 0 1 .45 1 1s-.45 1-1 1h-4c-.55 0-1-.45-1-1s.45-1 1-1z", - "github": "M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33c.85 0 1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2Z", - "phone": "M16 1H8C6.34 1 5 2.34 5 4v16c0 1.66 1.34 3 3 3h8c1.66 0 3-1.34 3-3V4c0-1.66-1.34-3-3-3zm1 17H7V4h10v14zm-3 3h-4v-1h4v1z", - "password": "M2 17h20v2H2v-2zm1.15-4.05L4 11.47l.85 1.48l1.3-.75l-.85-1.48H7v-1.5H5.3l.85-1.47L4.85 7L4 8.47L3.15 7l-1.3.75l.85 1.47H1v1.5h1.7l-.85 1.48l1.3.75zm6.7-.75l1.3.75l.85-1.48l.85 1.48l1.3-.75l-.85-1.48H15v-1.5h-1.7l.85-1.47l-1.3-.75L12 8.47L11.15 7l-1.3.75l.85 1.47H9v1.5h1.7l-.85 1.48zM23 9.22h-1.7l.85-1.47l-1.3-.75L20 8.47L19.15 7l-1.3.75l.85 1.47H17v1.5h1.7l-.85 1.48l1.3.75l.85-1.48l.85 1.48l1.3-.75l-.85-1.48H23v-1.5z", - "star": "m12 17.27l4.15 2.51c.76.46 1.69-.22 1.49-1.08l-1.1-4.72l3.67-3.18c.67-.58.31-1.68-.57-1.75l-4.83-.41l-1.89-4.46c-.34-.81-1.5-.81-1.84 0L9.19 8.63l-4.83.41c-.88.07-1.24 1.17-.57 1.75l3.67 3.18l-1.1 4.72c-.2.86.73 1.54 1.49 1.08l4.15-2.5z", - "record": "M17 18.25v3.25H7v-3.25c0-1.38 2.24-2.5 5-2.5s5 1.12 5 2.5M12 5.5a6.5 6.5 0 0 1 6.5 6.5c0 1.25-.35 2.42-.96 3.41L16 14.04c.32-.61.5-1.31.5-2.04c0-2.5-2-4.5-4.5-4.5s-4.5 2-4.5 4.5c0 .73.18 1.43.5 2.04l-1.54 1.37c-.61-.99-.96-2.16-.96-3.41A6.5 6.5 0 0 1 12 5.5m0-4A10.5 10.5 0 0 1 22.5 12c0 2.28-.73 4.39-1.96 6.11l-1.5-1.35c.92-1.36 1.46-3 1.46-4.76A8.5 8.5 0 0 0 12 3.5A8.5 8.5 0 0 0 3.5 12c0 1.76.54 3.4 1.46 4.76l-1.5 1.35A10.473 10.473 0 0 1 1.5 12A10.5 10.5 0 0 1 12 1.5m0 8a2.5 2.5 0 0 1 2.5 2.5a2.5 2.5 0 0 1-2.5 2.5A2.5 2.5 0 0 1 9.5 12A2.5 2.5 0 0 1 12 9.5Z", - "storage": "M4 20h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2s.9 2 2 2m0-3h2v2H4zM2 6c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2m4 1H4V5h2zm-2 7h16c1.1 0 2-.9 2-2s-.9-2-2-2H4c-1.1 0-2 .9-2 2s.9 2 2 2m0-3h2v2H4z", - "lrc-text": "M13.8 22H5c-1.7 0-3-1.3-3-3v-1h11.1c-.1.3-.1.7-.1 1c0 1.1.3 2.1.8 3m0-6H5V5c0-1.7 1.3-3 3-3h11c1.7 0 3 1.3 3 3v1h-2V5c0-.6-.4-1-1-1s-1 .4-1 1v8.1c-1.8.3-3.3 1.4-4.2 2.9M8 8h7V6H8zm0 4h6v-2H8zm9 4v6l5-3z" -} diff --git a/src/assets/icons/Add.svg b/src/assets/icons/Add.svg new file mode 100644 index 0000000..96c9831 --- /dev/null +++ b/src/assets/icons/Add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/AddList.svg b/src/assets/icons/AddList.svg new file mode 100644 index 0000000..2ed64a7 --- /dev/null +++ b/src/assets/icons/AddList.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Album.svg b/src/assets/icons/Album.svg new file mode 100644 index 0000000..270b24b --- /dev/null +++ b/src/assets/icons/Album.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Artist.svg b/src/assets/icons/Artist.svg new file mode 100644 index 0000000..85cf32c --- /dev/null +++ b/src/assets/icons/Artist.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/AutoFix.svg b/src/assets/icons/AutoFix.svg new file mode 100644 index 0000000..b268911 --- /dev/null +++ b/src/assets/icons/AutoFix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/AutoTheme.svg b/src/assets/icons/AutoTheme.svg new file mode 100644 index 0000000..22160ff --- /dev/null +++ b/src/assets/icons/AutoTheme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Batch.svg b/src/assets/icons/Batch.svg new file mode 100644 index 0000000..bc67f3f --- /dev/null +++ b/src/assets/icons/Batch.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Calendar-Empty.svg b/src/assets/icons/Calendar-Empty.svg new file mode 100644 index 0000000..f6c9adc --- /dev/null +++ b/src/assets/icons/Calendar-Empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Chat.svg b/src/assets/icons/Chat.svg new file mode 100644 index 0000000..247b3ea --- /dev/null +++ b/src/assets/icons/Chat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Cloud.svg b/src/assets/icons/Cloud.svg new file mode 100644 index 0000000..e027d47 --- /dev/null +++ b/src/assets/icons/Cloud.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/CloudLockOpen.svg b/src/assets/icons/CloudLockOpen.svg new file mode 100644 index 0000000..883b538 --- /dev/null +++ b/src/assets/icons/CloudLockOpen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Code.svg b/src/assets/icons/Code.svg new file mode 100644 index 0000000..e78346b --- /dev/null +++ b/src/assets/icons/Code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Copy.svg b/src/assets/icons/Copy.svg new file mode 100644 index 0000000..7d442d5 --- /dev/null +++ b/src/assets/icons/Copy.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/DarkTheme.svg b/src/assets/icons/DarkTheme.svg new file mode 100644 index 0000000..5b14538 --- /dev/null +++ b/src/assets/icons/DarkTheme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Delete.svg b/src/assets/icons/Delete.svg new file mode 100644 index 0000000..2b2d7f6 --- /dev/null +++ b/src/assets/icons/Delete.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/DeleteSweep.svg b/src/assets/icons/DeleteSweep.svg new file mode 100644 index 0000000..968daaf --- /dev/null +++ b/src/assets/icons/DeleteSweep.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/DesktopLyric.svg b/src/assets/icons/DesktopLyric.svg new file mode 100644 index 0000000..539fef3 --- /dev/null +++ b/src/assets/icons/DesktopLyric.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Discover.svg b/src/assets/icons/Discover.svg new file mode 100644 index 0000000..bfec787 --- /dev/null +++ b/src/assets/icons/Discover.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/Down.svg b/src/assets/icons/Down.svg new file mode 100644 index 0000000..515fc1a --- /dev/null +++ b/src/assets/icons/Down.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Download.svg b/src/assets/icons/Download.svg new file mode 100644 index 0000000..6bec268 --- /dev/null +++ b/src/assets/icons/Download.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/DropDown.svg b/src/assets/icons/DropDown.svg new file mode 100644 index 0000000..65d55fa --- /dev/null +++ b/src/assets/icons/DropDown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Earth.svg b/src/assets/icons/Earth.svg new file mode 100644 index 0000000..9b0b60c --- /dev/null +++ b/src/assets/icons/Earth.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/EditNote.svg b/src/assets/icons/EditNote.svg new file mode 100644 index 0000000..e4416c8 --- /dev/null +++ b/src/assets/icons/EditNote.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/ExitToApp.svg b/src/assets/icons/ExitToApp.svg new file mode 100644 index 0000000..eb4838a --- /dev/null +++ b/src/assets/icons/ExitToApp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Eye.svg b/src/assets/icons/Eye.svg new file mode 100644 index 0000000..a4fcfc6 --- /dev/null +++ b/src/assets/icons/Eye.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/EyeLock.svg b/src/assets/icons/EyeLock.svg new file mode 100644 index 0000000..9a6b04c --- /dev/null +++ b/src/assets/icons/EyeLock.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Favorite.svg b/src/assets/icons/Favorite.svg new file mode 100644 index 0000000..2679b8e --- /dev/null +++ b/src/assets/icons/Favorite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/FavoriteBorder.svg b/src/assets/icons/FavoriteBorder.svg new file mode 100644 index 0000000..f1f4402 --- /dev/null +++ b/src/assets/icons/FavoriteBorder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Fire.svg b/src/assets/icons/Fire.svg new file mode 100644 index 0000000..4775bb3 --- /dev/null +++ b/src/assets/icons/Fire.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Folder.svg b/src/assets/icons/Folder.svg new file mode 100644 index 0000000..e93bcab --- /dev/null +++ b/src/assets/icons/Folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/FolderCog.svg b/src/assets/icons/FolderCog.svg new file mode 100644 index 0000000..2ff442c --- /dev/null +++ b/src/assets/icons/FolderCog.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/FolderMusic.svg b/src/assets/icons/FolderMusic.svg new file mode 100644 index 0000000..d7dbf8c --- /dev/null +++ b/src/assets/icons/FolderMusic.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/FormatList.svg b/src/assets/icons/FormatList.svg new file mode 100644 index 0000000..56d376d --- /dev/null +++ b/src/assets/icons/FormatList.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Forward5.svg b/src/assets/icons/Forward5.svg new file mode 100644 index 0000000..7b244fa --- /dev/null +++ b/src/assets/icons/Forward5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Fullscreen.svg b/src/assets/icons/Fullscreen.svg new file mode 100644 index 0000000..1093565 --- /dev/null +++ b/src/assets/icons/Fullscreen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/FullscreenExit.svg b/src/assets/icons/FullscreenExit.svg new file mode 100644 index 0000000..1c38ff7 --- /dev/null +++ b/src/assets/icons/FullscreenExit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Github.svg b/src/assets/icons/Github.svg new file mode 100644 index 0000000..462a066 --- /dev/null +++ b/src/assets/icons/Github.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/HeartBit.svg b/src/assets/icons/HeartBit.svg new file mode 100644 index 0000000..99f7c6b --- /dev/null +++ b/src/assets/icons/HeartBit.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/HiRes.svg b/src/assets/icons/HiRes.svg new file mode 100644 index 0000000..5b341d7 --- /dev/null +++ b/src/assets/icons/HiRes.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/History.svg b/src/assets/icons/History.svg new file mode 100644 index 0000000..286dbca --- /dev/null +++ b/src/assets/icons/History.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Home.svg b/src/assets/icons/Home.svg new file mode 100644 index 0000000..a128a2c --- /dev/null +++ b/src/assets/icons/Home.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/IP.svg b/src/assets/icons/IP.svg new file mode 100644 index 0000000..5fd17b8 --- /dev/null +++ b/src/assets/icons/IP.svg @@ -0,0 +1,2 @@ + diff --git a/src/assets/icons/Info.svg b/src/assets/icons/Info.svg new file mode 100644 index 0000000..8e3fc70 --- /dev/null +++ b/src/assets/icons/Info.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Keyboard.svg b/src/assets/icons/Keyboard.svg new file mode 100644 index 0000000..88096e9 --- /dev/null +++ b/src/assets/icons/Keyboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/LightTheme.svg b/src/assets/icons/LightTheme.svg new file mode 100644 index 0000000..8f72b0c --- /dev/null +++ b/src/assets/icons/LightTheme.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Link.svg b/src/assets/icons/Link.svg new file mode 100644 index 0000000..51c80bc --- /dev/null +++ b/src/assets/icons/Link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/List.svg b/src/assets/icons/List.svg new file mode 100644 index 0000000..56d376d --- /dev/null +++ b/src/assets/icons/List.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/ListLockOpen.svg b/src/assets/icons/ListLockOpen.svg new file mode 100644 index 0000000..44b907c --- /dev/null +++ b/src/assets/icons/ListLockOpen.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Location.svg b/src/assets/icons/Location.svg new file mode 100644 index 0000000..2f7dbed --- /dev/null +++ b/src/assets/icons/Location.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Lyrics.svg b/src/assets/icons/Lyrics.svg new file mode 100644 index 0000000..29ae6bc --- /dev/null +++ b/src/assets/icons/Lyrics.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Menu.svg b/src/assets/icons/Menu.svg new file mode 100644 index 0000000..bf9b651 --- /dev/null +++ b/src/assets/icons/Menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Message.svg b/src/assets/icons/Message.svg new file mode 100644 index 0000000..105ad9b --- /dev/null +++ b/src/assets/icons/Message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Music.svg b/src/assets/icons/Music.svg new file mode 100644 index 0000000..adbec3c --- /dev/null +++ b/src/assets/icons/Music.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/MusicList.svg b/src/assets/icons/MusicList.svg new file mode 100644 index 0000000..6218d2f --- /dev/null +++ b/src/assets/icons/MusicList.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/NavigateBefore.svg b/src/assets/icons/NavigateBefore.svg new file mode 100644 index 0000000..ec89332 --- /dev/null +++ b/src/assets/icons/NavigateBefore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/NavigateNext.svg b/src/assets/icons/NavigateNext.svg new file mode 100644 index 0000000..9b15862 --- /dev/null +++ b/src/assets/icons/NavigateNext.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Password.svg b/src/assets/icons/Password.svg new file mode 100644 index 0000000..f474346 --- /dev/null +++ b/src/assets/icons/Password.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Paste.svg b/src/assets/icons/Paste.svg new file mode 100644 index 0000000..bba5fc1 --- /dev/null +++ b/src/assets/icons/Paste.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Pause.svg b/src/assets/icons/Pause.svg new file mode 100644 index 0000000..cf83d6a --- /dev/null +++ b/src/assets/icons/Pause.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/PauseCircle.svg b/src/assets/icons/PauseCircle.svg new file mode 100644 index 0000000..eab189e --- /dev/null +++ b/src/assets/icons/PauseCircle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Person.svg b/src/assets/icons/Person.svg new file mode 100644 index 0000000..70e5c96 --- /dev/null +++ b/src/assets/icons/Person.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Phone.svg b/src/assets/icons/Phone.svg new file mode 100644 index 0000000..9c2d3f2 --- /dev/null +++ b/src/assets/icons/Phone.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Play.svg b/src/assets/icons/Play.svg new file mode 100644 index 0000000..c355a47 --- /dev/null +++ b/src/assets/icons/Play.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/PlayCircle.svg b/src/assets/icons/PlayCircle.svg new file mode 100644 index 0000000..593681c --- /dev/null +++ b/src/assets/icons/PlayCircle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/PlayFilled.svg b/src/assets/icons/PlayFilled.svg new file mode 100644 index 0000000..fcb727e --- /dev/null +++ b/src/assets/icons/PlayFilled.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/PlayList.svg b/src/assets/icons/PlayList.svg new file mode 100644 index 0000000..6218d2f --- /dev/null +++ b/src/assets/icons/PlayList.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/PlayNext.svg b/src/assets/icons/PlayNext.svg new file mode 100644 index 0000000..42edb3d --- /dev/null +++ b/src/assets/icons/PlayNext.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/PlaylistAdd.svg b/src/assets/icons/PlaylistAdd.svg new file mode 100644 index 0000000..f071922 --- /dev/null +++ b/src/assets/icons/PlaylistAdd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/PlaylistAddCheck.svg b/src/assets/icons/PlaylistAddCheck.svg new file mode 100644 index 0000000..f9fdc74 --- /dev/null +++ b/src/assets/icons/PlaylistAddCheck.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Podcast.svg b/src/assets/icons/Podcast.svg new file mode 100644 index 0000000..c8b595f --- /dev/null +++ b/src/assets/icons/Podcast.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Power.svg b/src/assets/icons/Power.svg new file mode 100644 index 0000000..8dd1778 --- /dev/null +++ b/src/assets/icons/Power.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Radio.svg b/src/assets/icons/Radio.svg new file mode 100644 index 0000000..91b0e21 --- /dev/null +++ b/src/assets/icons/Radio.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Record.svg b/src/assets/icons/Record.svg new file mode 100644 index 0000000..f37f1a6 --- /dev/null +++ b/src/assets/icons/Record.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/Refresh.svg b/src/assets/icons/Refresh.svg new file mode 100644 index 0000000..e1e790d --- /dev/null +++ b/src/assets/icons/Refresh.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Repeat.svg b/src/assets/icons/Repeat.svg new file mode 100644 index 0000000..5c2b0aa --- /dev/null +++ b/src/assets/icons/Repeat.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/RepeatSong.svg b/src/assets/icons/RepeatSong.svg new file mode 100644 index 0000000..f7b5ecc --- /dev/null +++ b/src/assets/icons/RepeatSong.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Replay5.svg b/src/assets/icons/Replay5.svg new file mode 100644 index 0000000..f2de0f1 --- /dev/null +++ b/src/assets/icons/Replay5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Restart.svg b/src/assets/icons/Restart.svg new file mode 100644 index 0000000..bd1f66f --- /dev/null +++ b/src/assets/icons/Restart.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Right.svg b/src/assets/icons/Right.svg new file mode 100644 index 0000000..c705a78 --- /dev/null +++ b/src/assets/icons/Right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/RssFeed.svg b/src/assets/icons/RssFeed.svg new file mode 100644 index 0000000..155ea26 --- /dev/null +++ b/src/assets/icons/RssFeed.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SPlayer.svg b/src/assets/icons/SPlayer.svg new file mode 100644 index 0000000..bce3bc5 --- /dev/null +++ b/src/assets/icons/SPlayer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Search.svg b/src/assets/icons/Search.svg new file mode 100644 index 0000000..452ee90 --- /dev/null +++ b/src/assets/icons/Search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SearchOff.svg b/src/assets/icons/SearchOff.svg new file mode 100644 index 0000000..2f2ba34 --- /dev/null +++ b/src/assets/icons/SearchOff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Settings.svg b/src/assets/icons/Settings.svg new file mode 100644 index 0000000..ebb8b1e --- /dev/null +++ b/src/assets/icons/Settings.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SettingsLine.svg b/src/assets/icons/SettingsLine.svg new file mode 100644 index 0000000..c6c390a --- /dev/null +++ b/src/assets/icons/SettingsLine.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SettingsOther.svg b/src/assets/icons/SettingsOther.svg new file mode 100644 index 0000000..2fd9040 --- /dev/null +++ b/src/assets/icons/SettingsOther.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Share.svg b/src/assets/icons/Share.svg new file mode 100644 index 0000000..c55115a --- /dev/null +++ b/src/assets/icons/Share.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Shuffle.svg b/src/assets/icons/Shuffle.svg new file mode 100644 index 0000000..348f792 --- /dev/null +++ b/src/assets/icons/Shuffle.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SkipNext.svg b/src/assets/icons/SkipNext.svg new file mode 100644 index 0000000..5548222 --- /dev/null +++ b/src/assets/icons/SkipNext.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SkipPrev.svg b/src/assets/icons/SkipPrev.svg new file mode 100644 index 0000000..3d67f9e --- /dev/null +++ b/src/assets/icons/SkipPrev.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SnippetFolder.svg b/src/assets/icons/SnippetFolder.svg new file mode 100644 index 0000000..79f794f --- /dev/null +++ b/src/assets/icons/SnippetFolder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Sort.svg b/src/assets/icons/Sort.svg new file mode 100644 index 0000000..a7af730 --- /dev/null +++ b/src/assets/icons/Sort.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortAZ.svg b/src/assets/icons/SortAZ.svg new file mode 100644 index 0000000..7fe09e6 --- /dev/null +++ b/src/assets/icons/SortAZ.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortClockDown.svg b/src/assets/icons/SortClockDown.svg new file mode 100644 index 0000000..cde1ca9 --- /dev/null +++ b/src/assets/icons/SortClockDown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortClockUp.svg b/src/assets/icons/SortClockUp.svg new file mode 100644 index 0000000..98c4a07 --- /dev/null +++ b/src/assets/icons/SortClockUp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortDateDown.svg b/src/assets/icons/SortDateDown.svg new file mode 100644 index 0000000..a70b33e --- /dev/null +++ b/src/assets/icons/SortDateDown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortDateUp.svg b/src/assets/icons/SortDateUp.svg new file mode 100644 index 0000000..67d44b4 --- /dev/null +++ b/src/assets/icons/SortDateUp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortDown.svg b/src/assets/icons/SortDown.svg new file mode 100644 index 0000000..8ffdbfb --- /dev/null +++ b/src/assets/icons/SortDown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortUp.svg b/src/assets/icons/SortUp.svg new file mode 100644 index 0000000..ae6f58a --- /dev/null +++ b/src/assets/icons/SortUp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/SortZA.svg b/src/assets/icons/SortZA.svg new file mode 100644 index 0000000..4bc56d0 --- /dev/null +++ b/src/assets/icons/SortZA.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Star.svg b/src/assets/icons/Star.svg new file mode 100644 index 0000000..12a805b --- /dev/null +++ b/src/assets/icons/Star.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Storage.svg b/src/assets/icons/Storage.svg new file mode 100644 index 0000000..82054a6 --- /dev/null +++ b/src/assets/icons/Storage.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Tag.svg b/src/assets/icons/Tag.svg new file mode 100644 index 0000000..492f275 --- /dev/null +++ b/src/assets/icons/Tag.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/TextPlay.svg b/src/assets/icons/TextPlay.svg new file mode 100644 index 0000000..bd0df02 --- /dev/null +++ b/src/assets/icons/TextPlay.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/ThumbDown.svg b/src/assets/icons/ThumbDown.svg new file mode 100644 index 0000000..e3ca7bf --- /dev/null +++ b/src/assets/icons/ThumbDown.svg @@ -0,0 +1 @@ + diff --git a/src/assets/icons/ThumbUp.svg b/src/assets/icons/ThumbUp.svg new file mode 100644 index 0000000..d14d341 --- /dev/null +++ b/src/assets/icons/ThumbUp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/ThumbUpOff.svg b/src/assets/icons/ThumbUpOff.svg new file mode 100644 index 0000000..a7a7a16 --- /dev/null +++ b/src/assets/icons/ThumbUpOff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Time.svg b/src/assets/icons/Time.svg new file mode 100644 index 0000000..f7f877a --- /dev/null +++ b/src/assets/icons/Time.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Up.svg b/src/assets/icons/Up.svg new file mode 100644 index 0000000..8845581 --- /dev/null +++ b/src/assets/icons/Up.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Update.svg b/src/assets/icons/Update.svg new file mode 100644 index 0000000..1467c38 --- /dev/null +++ b/src/assets/icons/Update.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Video.svg b/src/assets/icons/Video.svg new file mode 100644 index 0000000..bdeb197 --- /dev/null +++ b/src/assets/icons/Video.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/VolumeDown.svg b/src/assets/icons/VolumeDown.svg new file mode 100644 index 0000000..54741df --- /dev/null +++ b/src/assets/icons/VolumeDown.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/VolumeMute.svg b/src/assets/icons/VolumeMute.svg new file mode 100644 index 0000000..7d61aac --- /dev/null +++ b/src/assets/icons/VolumeMute.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/VolumeOff.svg b/src/assets/icons/VolumeOff.svg new file mode 100644 index 0000000..9b1f929 --- /dev/null +++ b/src/assets/icons/VolumeOff.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/VolumeUp.svg b/src/assets/icons/VolumeUp.svg new file mode 100644 index 0000000..21c3938 --- /dev/null +++ b/src/assets/icons/VolumeUp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/WindowClose.svg b/src/assets/icons/WindowClose.svg new file mode 100644 index 0000000..7c43222 --- /dev/null +++ b/src/assets/icons/WindowClose.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/WindowHide.svg b/src/assets/icons/WindowHide.svg new file mode 100644 index 0000000..3d20f47 --- /dev/null +++ b/src/assets/icons/WindowHide.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/WindowMaximize.svg b/src/assets/icons/WindowMaximize.svg new file mode 100644 index 0000000..053b7ea --- /dev/null +++ b/src/assets/icons/WindowMaximize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/WindowMinimize.svg b/src/assets/icons/WindowMinimize.svg new file mode 100644 index 0000000..a0ea095 --- /dev/null +++ b/src/assets/icons/WindowMinimize.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/WindowRestore.svg b/src/assets/icons/WindowRestore.svg new file mode 100644 index 0000000..f3d4424 --- /dev/null +++ b/src/assets/icons/WindowRestore.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/icons/Zoom.svg b/src/assets/icons/Zoom.svg new file mode 100644 index 0000000..4662b85 --- /dev/null +++ b/src/assets/icons/Zoom.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/themeColor.json b/src/assets/themeColor.json deleted file mode 100644 index bbac932..0000000 --- a/src/assets/themeColor.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "red": { - "name": "欢快派对", - "label": "red", - "primaryColor": "#fe7971", - "primaryColorHover": "#F57B74", - "primaryColorSuppl": "#F57B74", - "primaryColorPressed": "#F64B41" - }, - "orange": { - "name": "柑橘桔梦", - "label": "orange", - "primaryColor": "#ff8c00", - "primaryColorHover": "#ffa033", - "primaryColorSuppl": "#ffa033", - "primaryColorPressed": "#ff6b00" - }, - "blue": { - "name": "深海蓝梦", - "label": "blue", - "primaryColor": "#3b5998", - "primaryColorHover": "#5475a3", - "primaryColorSuppl": "#8b9dc3", - "primaryColorPressed": "#2d4373" - }, - "pink": { - "name": "粉色梦幻", - "label": "pink", - "primaryColor": "#e91e63", - "primaryColorHover": "#f06292", - "primaryColorSuppl": "#f06292", - "primaryColorPressed": "#c2185b" - }, - "brown": { - "name": "深棕林荫", - "label": "brown", - "primaryColor": "#795548", - "primaryColorHover": "#8d6e63", - "primaryColorSuppl": "#8d6e63", - "primaryColorPressed": "#5d4037" - }, - "indigo": { - "name": "星空靛蓝", - "label": "indigo", - "primaryColor": "#3f51b5", - "primaryColorHover": "#5c6bc0", - "primaryColorSuppl": "#5c6bc0", - "primaryColorPressed": "#3949ab" - }, - "green": { - "name": "生命绿洲", - "label": "green", - "primaryColor": "#2ecc71", - "primaryColorHover": "#3ddc88", - "primaryColorSuppl": "#3ddc88", - "primaryColorPressed": "#27ae60" - }, - "purple": { - "name": "皇室紫梦", - "label": "purple", - "primaryColor": "#9c27b0", - "primaryColorHover": "#ba68c8", - "primaryColorSuppl": "#ba68c8", - "primaryColorPressed": "#7b1fa2" - }, - "yellow": { - "name": "金色阳光", - "label": "yellow", - "primaryColor": "#FBC02D", - "primaryColorHover": "#FFD54F", - "primaryColorSuppl": "#FFD54F", - "primaryColorPressed": "#FFC107" - }, - "teal": { - "name": "海洋碧绿", - "label": "teal", - "primaryColor": "#009688", - "primaryColorHover": "#26a69a", - "primaryColorSuppl": "#26a69a", - "primaryColorPressed": "#00796b" - } -} diff --git a/src/components/Card/SongDataCard.vue b/src/components/Card/SongDataCard.vue new file mode 100644 index 0000000..946bf93 --- /dev/null +++ b/src/components/Card/SongDataCard.vue @@ -0,0 +1,147 @@ + + + + + diff --git a/src/components/Card/SongListCard.vue b/src/components/Card/SongListCard.vue new file mode 100644 index 0000000..295ebd3 --- /dev/null +++ b/src/components/Card/SongListCard.vue @@ -0,0 +1,161 @@ + + + + + + diff --git a/src/components/Cover/CoverDropdown.vue b/src/components/Cover/CoverDropdown.vue deleted file mode 100644 index befdf05..0000000 --- a/src/components/Cover/CoverDropdown.vue +++ /dev/null @@ -1,87 +0,0 @@ - - - - diff --git a/src/components/Cover/CoverPlayBtn.vue b/src/components/Cover/CoverPlayBtn.vue deleted file mode 100644 index 4e52aef..0000000 --- a/src/components/Cover/CoverPlayBtn.vue +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - diff --git a/src/components/Cover/MainCover.vue b/src/components/Cover/MainCover.vue deleted file mode 100644 index a27cc1e..0000000 --- a/src/components/Cover/MainCover.vue +++ /dev/null @@ -1,467 +0,0 @@ - - - - - - diff --git a/src/components/Cover/SpecialCover.vue b/src/components/Cover/SpecialCover.vue deleted file mode 100644 index 0e3f5f4..0000000 --- a/src/components/Cover/SpecialCover.vue +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - diff --git a/src/components/Cover/SpecialCoverCard.vue b/src/components/Cover/SpecialCoverCard.vue deleted file mode 100644 index d7e2b13..0000000 --- a/src/components/Cover/SpecialCoverCard.vue +++ /dev/null @@ -1,234 +0,0 @@ - - - - - - diff --git a/src/components/Global/MainLayout.vue b/src/components/Global/MainLayout.vue deleted file mode 100644 index ce5094a..0000000 --- a/src/components/Global/MainLayout.vue +++ /dev/null @@ -1,50 +0,0 @@ - - - - - diff --git a/src/components/Global/Menu.vue b/src/components/Global/Menu.vue deleted file mode 100644 index 34ec473..0000000 --- a/src/components/Global/Menu.vue +++ /dev/null @@ -1,565 +0,0 @@ - - - - - - - - - diff --git a/src/components/Global/Pagination.vue b/src/components/Global/Pagination.vue deleted file mode 100644 index b52364d..0000000 --- a/src/components/Global/Pagination.vue +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - diff --git a/src/components/Global/Playlist.vue b/src/components/Global/Playlist.vue deleted file mode 100644 index 8cfed44..0000000 --- a/src/components/Global/Playlist.vue +++ /dev/null @@ -1,397 +0,0 @@ - - - - - - - - diff --git a/src/components/Global/Provider.vue b/src/components/Global/Provider.vue index 1812767..c48e016 100644 --- a/src/components/Global/Provider.vue +++ b/src/components/Global/Provider.vue @@ -3,19 +3,21 @@ - - + + + + @@ -23,113 +25,188 @@ - diff --git a/src/components/Global/SvgIcon.vue b/src/components/Global/SvgIcon.vue index aa1dac0..c7e65a7 100644 --- a/src/components/Global/SvgIcon.vue +++ b/src/components/Global/SvgIcon.vue @@ -1,121 +1,42 @@ - + + diff --git a/src/components/Global/TextContainer.vue b/src/components/Global/TextContainer.vue new file mode 100644 index 0000000..dc18fb7 --- /dev/null +++ b/src/components/Global/TextContainer.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/components/Layout/Menu.vue b/src/components/Layout/Menu.vue new file mode 100644 index 0000000..df4cfc2 --- /dev/null +++ b/src/components/Layout/Menu.vue @@ -0,0 +1,371 @@ + + + + + + + + diff --git a/src/components/Layout/Nav.vue b/src/components/Layout/Nav.vue new file mode 100644 index 0000000..4f356b2 --- /dev/null +++ b/src/components/Layout/Nav.vue @@ -0,0 +1,252 @@ + + + + + diff --git a/src/components/Layout/Sider.vue b/src/components/Layout/Sider.vue new file mode 100644 index 0000000..e73b8fc --- /dev/null +++ b/src/components/Layout/Sider.vue @@ -0,0 +1,102 @@ + + + + + + diff --git a/src/components/Layout/User.vue b/src/components/Layout/User.vue new file mode 100644 index 0000000..7e3e00e --- /dev/null +++ b/src/components/Layout/User.vue @@ -0,0 +1,215 @@ + + + + + diff --git a/src/components/List/ArtistList.vue b/src/components/List/ArtistList.vue new file mode 100644 index 0000000..26aba94 --- /dev/null +++ b/src/components/List/ArtistList.vue @@ -0,0 +1,219 @@ + + + + + diff --git a/src/components/List/CommentList.vue b/src/components/List/CommentList.vue index 2a7b78d..0cd438b 100644 --- a/src/components/List/CommentList.vue +++ b/src/components/List/CommentList.vue @@ -1,245 +1,196 @@ - - diff --git a/src/components/List/CoverList.vue b/src/components/List/CoverList.vue new file mode 100644 index 0000000..d141b81 --- /dev/null +++ b/src/components/List/CoverList.vue @@ -0,0 +1,415 @@ + + + + + diff --git a/src/components/List/SongList.vue b/src/components/List/SongList.vue index 12f4afa..91dca04 100644 --- a/src/components/List/SongList.vue +++ b/src/components/List/SongList.vue @@ -1,612 +1,561 @@ - - diff --git a/src/components/List/SongListDrawer.vue b/src/components/List/SongListDrawer.vue deleted file mode 100644 index 6662ed0..0000000 --- a/src/components/List/SongListDrawer.vue +++ /dev/null @@ -1,323 +0,0 @@ - - - - - - - - diff --git a/src/components/List/SongListDropdown.vue b/src/components/List/SongListDropdown.vue deleted file mode 100644 index 644e4d4..0000000 --- a/src/components/List/SongListDropdown.vue +++ /dev/null @@ -1,382 +0,0 @@ - - - - - - diff --git a/src/components/Menu/CoverMenu.vue b/src/components/Menu/CoverMenu.vue new file mode 100644 index 0000000..afb634e --- /dev/null +++ b/src/components/Menu/CoverMenu.vue @@ -0,0 +1,103 @@ + + + diff --git a/src/components/Menu/SearchInpMenu.vue b/src/components/Menu/SearchInpMenu.vue new file mode 100644 index 0000000..6c321cf --- /dev/null +++ b/src/components/Menu/SearchInpMenu.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/components/Menu/SongListMenu.vue b/src/components/Menu/SongListMenu.vue new file mode 100644 index 0000000..36dc0e4 --- /dev/null +++ b/src/components/Menu/SongListMenu.vue @@ -0,0 +1,286 @@ + + + + + + diff --git a/src/components/Modal/AddPlaylist.vue b/src/components/Modal/AddPlaylist.vue deleted file mode 100644 index 42fb39b..0000000 --- a/src/components/Modal/AddPlaylist.vue +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - diff --git a/src/components/Modal/CloudMatch.vue b/src/components/Modal/CloudMatch.vue new file mode 100644 index 0000000..87b9cb9 --- /dev/null +++ b/src/components/Modal/CloudMatch.vue @@ -0,0 +1,134 @@ + + + + + diff --git a/src/components/Modal/CloudSongMatch.vue b/src/components/Modal/CloudSongMatch.vue deleted file mode 100644 index f2a82a5..0000000 --- a/src/components/Modal/CloudSongMatch.vue +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - - diff --git a/src/components/Modal/CreatePlaylist.vue b/src/components/Modal/CreatePlaylist.vue index 8a2267c..5779dc0 100644 --- a/src/components/Modal/CreatePlaylist.vue +++ b/src/components/Modal/CreatePlaylist.vue @@ -1,77 +1,112 @@ - - + + diff --git a/src/components/Modal/DownloadSong.vue b/src/components/Modal/DownloadSong.vue index acd877e..9318963 100644 --- a/src/components/Modal/DownloadSong.vue +++ b/src/components/Modal/DownloadSong.vue @@ -1,255 +1,217 @@ - - diff --git a/src/components/Modal/JumpArtist.vue b/src/components/Modal/JumpArtist.vue new file mode 100644 index 0000000..2d00593 --- /dev/null +++ b/src/components/Modal/JumpArtist.vue @@ -0,0 +1,132 @@ + + + + + + diff --git a/src/components/Modal/Login.vue b/src/components/Modal/Login.vue index 016ed09..425d346 100644 --- a/src/components/Modal/Login.vue +++ b/src/components/Modal/Login.vue @@ -1,189 +1,79 @@ - - - diff --git a/src/components/Modal/LoginPhone.vue b/src/components/Modal/LoginPhone.vue index e88626f..4e87956 100644 --- a/src/components/Modal/LoginPhone.vue +++ b/src/components/Modal/LoginPhone.vue @@ -1,149 +1,208 @@ - - diff --git a/src/components/Modal/LoginQRCode.vue b/src/components/Modal/LoginQRCode.vue index 42cf73a..fd6e24d 100644 --- a/src/components/Modal/LoginQRCode.vue +++ b/src/components/Modal/LoginQRCode.vue @@ -1,160 +1,134 @@ - - diff --git a/src/components/Modal/PlaylistAdd.vue b/src/components/Modal/PlaylistAdd.vue new file mode 100644 index 0000000..3a0e25b --- /dev/null +++ b/src/components/Modal/PlaylistAdd.vue @@ -0,0 +1,131 @@ + + + + + + diff --git a/src/components/Modal/PlaylistUpdate.vue b/src/components/Modal/PlaylistUpdate.vue deleted file mode 100644 index 43569fa..0000000 --- a/src/components/Modal/PlaylistUpdate.vue +++ /dev/null @@ -1,140 +0,0 @@ - - - diff --git a/src/components/Modal/SongInfoEditor.vue b/src/components/Modal/SongInfoEditor.vue new file mode 100644 index 0000000..22481aa --- /dev/null +++ b/src/components/Modal/SongInfoEditor.vue @@ -0,0 +1,344 @@ + + + + + diff --git a/src/components/Modal/UpCloudSong.vue b/src/components/Modal/UpCloudSong.vue deleted file mode 100644 index 16cd2ef..0000000 --- a/src/components/Modal/UpCloudSong.vue +++ /dev/null @@ -1,201 +0,0 @@ - - - - - - diff --git a/src/components/Modal/UpdateApp.vue b/src/components/Modal/UpdateApp.vue new file mode 100644 index 0000000..e916c9c --- /dev/null +++ b/src/components/Modal/UpdateApp.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/src/components/Modal/UpdatePlaylist.vue b/src/components/Modal/UpdatePlaylist.vue new file mode 100644 index 0000000..8062b99 --- /dev/null +++ b/src/components/Modal/UpdatePlaylist.vue @@ -0,0 +1,135 @@ + + + + + diff --git a/src/components/Modal/UserAgreement.vue b/src/components/Modal/UserAgreement.vue new file mode 100644 index 0000000..c8218ce --- /dev/null +++ b/src/components/Modal/UserAgreement.vue @@ -0,0 +1,164 @@ + + + + + + diff --git a/src/components/Modal/batchList.vue b/src/components/Modal/batchList.vue new file mode 100644 index 0000000..23d0ae0 --- /dev/null +++ b/src/components/Modal/batchList.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/src/components/Nav/MainNav.vue b/src/components/Nav/MainNav.vue deleted file mode 100644 index d4eec02..0000000 --- a/src/components/Nav/MainNav.vue +++ /dev/null @@ -1,271 +0,0 @@ - - - - - - diff --git a/src/components/Nav/UserData.vue b/src/components/Nav/UserData.vue deleted file mode 100644 index 95df98f..0000000 --- a/src/components/Nav/UserData.vue +++ /dev/null @@ -1,267 +0,0 @@ - - - - - - - - diff --git a/src/components/Player/CountDown.vue b/src/components/Player/CountDown.vue index e16e8ff..66f3f1b 100644 --- a/src/components/Player/CountDown.vue +++ b/src/components/Player/CountDown.vue @@ -2,77 +2,54 @@
- @@ -90,7 +67,8 @@ const pointOpacity = (index) => { height: 28px; margin-right: 12px; border-radius: 50%; - background-color: var(--cover-main-color); + background-color: rgb(var(--main-color)); + transition: opacity 0.5s; @media (max-width: 900px) { width: 24px; height: 24px; @@ -101,17 +79,4 @@ const pointOpacity = (index) => { } } } -@keyframes breathe { - 0% { - transform: scale(0.95); - } - - 50% { - transform: scale(1.1); - } - - 100% { - transform: scale(0.95); - } -} diff --git a/src/components/Player/FullPlayer.vue b/src/components/Player/FullPlayer.vue index 29a8df4..1beea86 100644 --- a/src/components/Player/FullPlayer.vue +++ b/src/components/Player/FullPlayer.vue @@ -1,360 +1,197 @@ - - diff --git a/src/components/Player/Lyric.vue b/src/components/Player/Lyric.vue deleted file mode 100644 index 78cccb5..0000000 --- a/src/components/Player/Lyric.vue +++ /dev/null @@ -1,534 +0,0 @@ - - - - - - diff --git a/src/components/Player/MainAMLyric.vue b/src/components/Player/MainAMLyric.vue new file mode 100644 index 0000000..18c6b87 --- /dev/null +++ b/src/components/Player/MainAMLyric.vue @@ -0,0 +1,119 @@ + + + + + diff --git a/src/components/Player/MainControl.vue b/src/components/Player/MainControl.vue deleted file mode 100644 index 298b326..0000000 --- a/src/components/Player/MainControl.vue +++ /dev/null @@ -1,933 +0,0 @@ - - - - - - diff --git a/src/components/Player/MainLyric.vue b/src/components/Player/MainLyric.vue new file mode 100644 index 0000000..0fb95cd --- /dev/null +++ b/src/components/Player/MainLyric.vue @@ -0,0 +1,601 @@ + + + + + diff --git a/src/components/Player/MainPlayList.vue b/src/components/Player/MainPlayList.vue new file mode 100644 index 0000000..0d79647 --- /dev/null +++ b/src/components/Player/MainPlayList.vue @@ -0,0 +1,300 @@ + + + + + + + + diff --git a/src/components/Player/MainPlayer.vue b/src/components/Player/MainPlayer.vue new file mode 100644 index 0000000..002327b --- /dev/null +++ b/src/components/Player/MainPlayer.vue @@ -0,0 +1,609 @@ + + + + + diff --git a/src/components/Player/PersonalFM.vue b/src/components/Player/PersonalFM.vue new file mode 100644 index 0000000..9a3d77a --- /dev/null +++ b/src/components/Player/PersonalFM.vue @@ -0,0 +1,237 @@ + + + + + diff --git a/src/components/Player/PlayerBackground.vue b/src/components/Player/PlayerBackground.vue new file mode 100644 index 0000000..9f04ea1 --- /dev/null +++ b/src/components/Player/PlayerBackground.vue @@ -0,0 +1,71 @@ + + + + diff --git a/src/components/Player/PlayerComment.vue b/src/components/Player/PlayerComment.vue new file mode 100644 index 0000000..3c1e1be --- /dev/null +++ b/src/components/Player/PlayerComment.vue @@ -0,0 +1,156 @@ + + + + + + diff --git a/src/components/Player/PlayerControl.vue b/src/components/Player/PlayerControl.vue index bbd4208..cdec843 100644 --- a/src/components/Player/PlayerControl.vue +++ b/src/components/Player/PlayerControl.vue @@ -1,379 +1,189 @@ - - diff --git a/src/components/Player/PlayerCover.vue b/src/components/Player/PlayerCover.vue index 6ee009c..6e76c85 100644 --- a/src/components/Player/PlayerCover.vue +++ b/src/components/Player/PlayerCover.vue @@ -1,79 +1,65 @@ - - diff --git a/src/components/Player/PlayerMenu.vue b/src/components/Player/PlayerMenu.vue new file mode 100644 index 0000000..2f7aa0b --- /dev/null +++ b/src/components/Player/PlayerMenu.vue @@ -0,0 +1,104 @@ + + + + + diff --git a/src/components/Player/Spectrum.vue b/src/components/Player/PlayerSpectrum.vue similarity index 73% rename from src/components/Player/Spectrum.vue rename to src/components/Player/PlayerSpectrum.vue index debfbe3..343bcd8 100644 --- a/src/components/Player/Spectrum.vue +++ b/src/components/Player/PlayerSpectrum.vue @@ -1,63 +1,50 @@ - - diff --git a/src/components/Search/SearchDefault.vue b/src/components/Search/SearchDefault.vue new file mode 100644 index 0000000..2e814da --- /dev/null +++ b/src/components/Search/SearchDefault.vue @@ -0,0 +1,215 @@ + + + + + diff --git a/src/components/Search/SearchHot.vue b/src/components/Search/SearchHot.vue deleted file mode 100644 index d3df344..0000000 --- a/src/components/Search/SearchHot.vue +++ /dev/null @@ -1,285 +0,0 @@ - - - - - - diff --git a/src/components/Search/SearchInp.vue b/src/components/Search/SearchInp.vue index d6a2b26..2ad46b2 100644 --- a/src/components/Search/SearchInp.vue +++ b/src/components/Search/SearchInp.vue @@ -1,94 +1,86 @@ - - diff --git a/src/components/Search/SearchSuggest.vue b/src/components/Search/SearchSuggest.vue new file mode 100644 index 0000000..908d20b --- /dev/null +++ b/src/components/Search/SearchSuggest.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/src/components/Search/SearchSuggestions.vue b/src/components/Search/SearchSuggestions.vue deleted file mode 100644 index 11c5a5a..0000000 --- a/src/components/Search/SearchSuggestions.vue +++ /dev/null @@ -1,252 +0,0 @@ - - - - - - diff --git a/src/components/Setting/AboutSetting.vue b/src/components/Setting/AboutSetting.vue new file mode 100644 index 0000000..93d6571 --- /dev/null +++ b/src/components/Setting/AboutSetting.vue @@ -0,0 +1,138 @@ + + + + + diff --git a/src/components/Setting/GeneralSetting.vue b/src/components/Setting/GeneralSetting.vue new file mode 100644 index 0000000..4031cfc --- /dev/null +++ b/src/components/Setting/GeneralSetting.vue @@ -0,0 +1,348 @@ + + + + diff --git a/src/components/Setting/KeyboardSetting.vue b/src/components/Setting/KeyboardSetting.vue new file mode 100644 index 0000000..a61e38a --- /dev/null +++ b/src/components/Setting/KeyboardSetting.vue @@ -0,0 +1,292 @@ + + + + + + + diff --git a/src/components/Setting/LocalSetting.vue b/src/components/Setting/LocalSetting.vue new file mode 100644 index 0000000..1cdd569 --- /dev/null +++ b/src/components/Setting/LocalSetting.vue @@ -0,0 +1,100 @@ + + + + diff --git a/src/components/Setting/LyricsSetting.vue b/src/components/Setting/LyricsSetting.vue new file mode 100644 index 0000000..75d6a0f --- /dev/null +++ b/src/components/Setting/LyricsSetting.vue @@ -0,0 +1,422 @@ + + + + + diff --git a/src/components/Setting/MainSetting.vue b/src/components/Setting/MainSetting.vue new file mode 100644 index 0000000..ae5b65b --- /dev/null +++ b/src/components/Setting/MainSetting.vue @@ -0,0 +1,253 @@ + + + + + + + diff --git a/src/components/Setting/OtherSetting.vue b/src/components/Setting/OtherSetting.vue new file mode 100644 index 0000000..a862954 --- /dev/null +++ b/src/components/Setting/OtherSetting.vue @@ -0,0 +1,202 @@ + + + + diff --git a/src/components/Setting/PlaySetting.vue b/src/components/Setting/PlaySetting.vue new file mode 100644 index 0000000..741df9f --- /dev/null +++ b/src/components/Setting/PlaySetting.vue @@ -0,0 +1,330 @@ + + + + diff --git a/src/components/WinDom/TitleBar.vue b/src/components/WinDom/TitleBar.vue deleted file mode 100644 index d70461f..0000000 --- a/src/components/WinDom/TitleBar.vue +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..4af4bfd --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,8 @@ +/// + +declare module "*.vue" { + import type { DefineComponent } from "vue"; + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types + const component: DefineComponent<{}, {}, any>; + export default component; +} diff --git a/src/main.js b/src/main.js deleted file mode 100644 index c201e75..0000000 --- a/src/main.js +++ /dev/null @@ -1,74 +0,0 @@ -import { createApp } from "vue"; -import { createPinia } from "pinia"; -import { checkPlatform, loadCSS } from "@/utils/helper"; -import App from "@/App.vue"; -import router from "@/router"; -import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; -import packageJson from "@/../package.json"; - -// 全局样式 -import "@/style/main.scss"; -import "@/style/animate.scss"; - -// 是否为 Electron -const isElectron = checkPlatform.electron(); - -// 分设备添加字体 -if (isElectron) { - loadCSS(`${import.meta.env.BASE_URL}font/font.css`); -} else { - loadCSS("https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css"); -} - -// 分设备类名 -document.body.classList.add(isElectron ? "electron" : "webapp"); - -// 程序重置 -window.$cleanAll = (tip = true) => { - if (tip) { - const isConfirmed = window.confirm(`确认要重置${isElectron ? "应用程序" : "该站点"}吗?`); - if (!isConfirmed) return false; - } - // 清除 localStorage - localStorage.clear(); - // 清除 IndexedDB 数据库 - indexedDB.deleteDatabase("filesDB"); - // 清除所有 Cookie - document.cookie.split(";").forEach((cookie) => { - var eqPos = cookie.indexOf("="); - var name = eqPos > -1 ? cookie.substring(0, eqPos) : cookie; - document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT"; - }); - // 清除缓存 - if (caches) { - caches.keys().then((names) => { - for (let name of names) caches.delete(name); - }); - } - return "已重置应用,请" + (isElectron ? "重启应用" : "刷新页面"); -}; - -// 版权声明 -const logoText = import.meta.env.RENDERER_VITE_SITE_TITLE; -const copyrightNotice = `\n\n版本: ${packageJson.version}\n作者: ${packageJson.author}\n作者主页: ${packageJson.home}\nGitHub: ${packageJson.github}`; -console.info( - `%c${logoText} %c ${copyrightNotice}`, - "color:#f55e55;font-size:26px;font-weight:bold;", - "font-size:16px", -); -console.info( - "若站点出现异常,可尝试在下方输入 %c$cleanAll()%c 然后按回车来重置", - "background: #eaeffd;color:#f55e55;padding: 4px 6px;border-radius:8px;", - "background:unset;color:unset;", -); - -// 挂载 -const app = createApp(App); -// pinia -const pinia = createPinia(); -pinia.use(piniaPluginPersistedstate); -app.use(pinia); -// router -app.use(router); -// app -app.mount("#app"); diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..6fec215 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,37 @@ +import { createApp } from "vue"; +import App from "./App.vue"; +// pinia +import { createPinia } from "pinia"; +import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; +// router +import router from "@/router"; +// 自定义指令 +import { debounceDirective, throttleDirective, visibleDirective } from "@/utils/instruction"; +// VueVirtualScroller +import VueVirtualScroller from "vue-virtual-scroller"; +import "vue-virtual-scroller/dist/vue-virtual-scroller.css"; +// ipc +import initIpc from "@/utils/initIpc"; +// 全局样式 +import "@/style/main.scss"; +import "@/style/animate.scss"; + +// 初始化 ipc +initIpc(); + +// 挂载 +const app = createApp(App); +// pinia +const pinia = createPinia(); +pinia.use(piniaPluginPersistedstate); +app.use(pinia); +// router +app.use(router); +// VueVirtualScroller +app.use(VueVirtualScroller); +// 自定义指令 +app.directive("debounce", debounceDirective); +app.directive("throttle", throttleDirective); +app.directive("visible", visibleDirective); +// app +app.mount("#app"); diff --git a/src/router/index.js b/src/router/index.js deleted file mode 100644 index 4130b70..0000000 --- a/src/router/index.js +++ /dev/null @@ -1,64 +0,0 @@ -import { nextTick } from "vue"; -import { createRouter, createWebHashHistory } from "vue-router"; -import { checkPlatform } from "@/utils/helper"; -import { isLogin } from "@/utils/auth"; -import routes from "@/router/routes"; - -// 基础配置 -const router = createRouter({ - history: createWebHashHistory(import.meta.env.BASE_URL), - routes, -}); - -// 页面回顶 -const scrollToTop = () => { - nextTick().then(() => { - const mainLayout = document.getElementById("main-layout"); - mainLayout?.scrollIntoView({ behavior: "smooth" }); - }); -}; - -// 路由守卫 -router.beforeEach((to, from, next) => { - // 开始进度条 - if (to.path !== from.path) { - if (typeof $loadingBar !== "undefined" && !checkPlatform.electron()) { - $loadingBar.start(); - } - } - // 判断是否需要登录 - if (to.meta.needLogin) { - if (isLogin()) { - next(); - } else { - $message.warning("请登录后使用"); - if (typeof $loadingBar !== "undefined" && !checkPlatform.electron()) { - $loadingBar.error(); - } - if (typeof $changeLogin !== "undefined") $changeLogin(); - } - } - // 是否为本地功能 - else if (to.meta.needLocal) { - if (checkPlatform.electron()) { - next(); - } else { - $message.error("客户端独占功能"); - if (typeof $loadingBar !== "undefined" && !checkPlatform.electron()) { - $loadingBar.error(); - } - next("/403"); - } - } else { - next(); - } -}); - -router.afterEach(() => { - // 结束进度条 - if (typeof $loadingBar !== "undefined" && !checkPlatform.electron()) $loadingBar.finish(); - // 页面回顶 - scrollToTop(); -}); - -export default router; diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..5c1829b --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,58 @@ +import { createRouter, createWebHashHistory, Router } from "vue-router"; +import { openUserLogin } from "@/utils/modal"; +import { isElectron } from "@/utils/helper"; +import { isLogin } from "@/utils/auth"; +import routes from "./routes"; + +// 基础配置 +const router: Router = createRouter({ + history: createWebHashHistory(import.meta.env.BASE_URL), + routes, + // 保留滚动 + scrollBehavior(to, _, savedPosition) { + if (savedPosition) { + return new Promise((resolve) => { + setTimeout(() => { + resolve(savedPosition); + }, 300); + }); + } else if (to.hash) { + return { + el: to.hash, + behavior: "smooth", + }; + } else { + return { top: 0, left: 0, behavior: "smooth" }; + } + }, +}); + +// 前置守卫 +router.beforeEach((to, from, next) => { + // console.log("前置守卫", to, from); + // 进度条 + if (!isElectron && to.path !== from.path) { + window.$loadingBar.start(); + } + // 需要登录 + if (to.meta.needLogin && !isLogin()) { + if (!isElectron) window.$loadingBar.error(); + window.$message.warning("请登录后使用"); + openUserLogin(); + return; + } + // 需要客户端 + else if (to.meta.needApp && !isElectron) { + window.$message.warning("该功能为客户端独占功能"); + next("/403"); + } + next(); +}); + +// 后置守卫 +router.afterEach(() => { + // 进度条 + window.$loadingBar.finish(); +}); + +export default router; diff --git a/src/router/routes.js b/src/router/routes.js deleted file mode 100644 index 4688561..0000000 --- a/src/router/routes.js +++ /dev/null @@ -1,355 +0,0 @@ -import { checkPlatform } from "@/utils/helper"; - -const routes = [ - // 首页 - { - path: "/", - name: "home", - meta: { - title: "主页", - }, - component: () => import("@/views/Home.vue"), - }, - // 搜索 - { - path: "/search", - name: "search", - meta: { - title: "搜索", - }, - component: () => import("@/views/Search/index.vue"), - redirect: "/search/songs", - children: [ - { - path: "songs", - name: "sea-songs", - component: () => import("@/views/Search/songs.vue"), - }, - { - path: "artists", - name: "sea-artists", - component: () => import("@/views/Search/artists.vue"), - }, - { - path: "albums", - name: "sea-albums", - component: () => import("@/views/Search/albums.vue"), - }, - { - path: "videos", - name: "sea-videos", - component: () => import("@/views/Search/videos.vue"), - }, - { - path: "playlists", - name: "sea-playlists", - component: () => import("@/views/Search/playlists.vue"), - }, - { - path: "djs", - name: "sea-djs", - component: () => import("@/views/Search/djs.vue"), - }, - ], - }, - // 发现音乐 - { - path: "/discover", - name: "discover", - meta: { - title: "发现", - }, - component: () => import("@/views/Discover/index.vue"), - redirect: "/Discover/playlists", - children: [ - { - path: "playlists", - name: "dsc-playlists", - component: () => import("@/views/Discover/playlists.vue"), - }, - { - path: "toplists", - name: "dsc-toplists", - component: () => import("@/views/Discover/toplists.vue"), - }, - { - path: "artists", - name: "dsc-artists", - component: () => import("@/views/Discover/artists.vue"), - }, - { - path: "new", - name: "dsc-new", - component: () => import("@/views/Discover/new.vue"), - }, - ], - }, - // 视频播放 - { - path: "/videos-player", - name: "videos-player", - meta: { - title: "视频播放器", - }, - component: () => import("@/views/Player.vue"), - }, - // 每日推荐 - { - path: "/daily-songs", - name: "daily-songs", - meta: { - title: "每日推荐", - needLogin: true, - }, - component: () => import("@/views/DailySongs.vue"), - }, - // 评论 - { - path: "/comment", - name: "comment", - meta: { - title: "评论", - }, - component: () => import("@/views/Comment.vue"), - }, - // 歌曲详情 - { - path: "/song", - name: "song", - meta: { - title: "歌曲详情", - }, - component: () => import("@/views/Song.vue"), - }, - // 最近播放 - { - path: "/history", - name: "history", - meta: { - title: "最近播放", - }, - component: () => import("@/views/History.vue"), - }, - // 我的云盘 - { - path: "/cloud", - name: "cloud", - meta: { - title: "我的云盘", - needLogin: true, - }, - component: () => import("@/views/Cloud.vue"), - }, - // 歌单 - { - path: "/playlist", - name: "playlist", - meta: { - title: "歌单", - }, - component: () => import("@/views/List/playlist.vue"), - }, - // 歌单 - 用户喜欢 - { - path: "/like-songs", - name: "like-songs", - meta: { - title: "歌单", - needLogin: true, - }, - component: () => import("@/views/List/playlist.vue"), - }, - // 专辑 - { - path: "/album", - name: "album", - meta: { - title: "歌单", - }, - component: () => import("@/views/List/album.vue"), - }, - // 播客电台 - { - path: "/dj", - name: "dj", - meta: { - title: "播客电台", - }, - component: () => import("@/views/List/dj.vue"), - }, - // 歌手 - { - path: "/artist", - name: "artist", - meta: { - title: "歌手", - }, - component: () => import("@/views/Artist/index.vue"), - redirect: "/artist/hot", - children: [ - { - path: "hot", - name: "ar-hot", - component: () => import("@/views/Artist/hot.vue"), - }, - { - path: "songs", - name: "ar-songs", - component: () => import("@/views/Artist/songs.vue"), - }, - { - path: "albums", - name: "ar-albums", - component: () => import("@/views/Artist/albums.vue"), - }, - { - path: "videos", - name: "ar-videos", - component: () => import("@/views/Artist/videos.vue"), - }, - ], - }, - // 我的收藏 - { - path: "/like", - name: "like", - meta: { - title: "我的收藏", - needLogin: true, - }, - component: () => import("@/views/Like/index.vue"), - redirect: "/like/albums", - children: [ - { - path: "albums", - name: "like-albums", - component: () => import("@/views/Like/albums.vue"), - }, - { - path: "artists", - name: "like-artists", - component: () => import("@/views/Like/artists.vue"), - }, - { - path: "videos", - name: "like-videos", - component: () => import("@/views/Like/videos.vue"), - }, - { - path: "playlists", - name: "like-playlists", - component: () => import("@/views/Like/playlists.vue"), - }, - { - path: "djs", - name: "like-djs", - component: () => import("@/views/Like/djs.vue"), - }, - ], - }, - // 本地歌曲 - { - path: "/local", - name: "local", - meta: { - title: "本地歌曲", - needLocal: true, - show: checkPlatform.electron(), - }, - component: () => import("@/views/Local/index.vue"), - redirect: "/local/songs", - children: [ - { - path: "songs", - name: "local-songs", - component: () => import("@/views/Local/songs.vue"), - }, - { - path: "artists", - name: "local-artists", - component: () => import("@/views/Local/artists.vue"), - }, - { - path: "albums", - name: "local-albums", - component: () => import("@/views/Local/albums.vue"), - }, - ], - }, - // 播客 - { - path: "/dj-hot", - name: "dj-hot", - meta: { - title: "热门播客", - }, - component: () => import("@/views/Dj/index.vue"), - }, - // 播客 -分类 - { - path: "/dj-type", - name: "dj-type", - meta: { - title: "播客分类", - }, - component: () => import("@/views/Dj/type.vue"), - }, - // 全局设置 - { - path: "/setting", - name: "setting", - meta: { - title: "全局设置", - }, - component: () => import("@/views/Setting/index.vue"), - }, - // 单曲页面 - { - path: "/song", - name: "song", - meta: { - title: "全局设置", - }, - component: () => import("@/views/Song.vue"), - }, - // 测试页面 - { - path: "/test", - name: "test", - meta: { - title: "测试页面", - }, - component: () => import("@/views/Test.vue"), - }, - // 状态页 - { - path: "/404", - name: "404", - meta: { - title: "404", - }, - component: () => import("@/views/State/404.vue"), - }, - { - path: "/403", - name: "403", - meta: { - title: "403", - }, - component: () => import("@/views/State/403.vue"), - }, - { - path: "/500", - name: "500", - meta: { - title: "500", - }, - component: () => import("@/views/State/500.vue"), - }, - { - path: "/:pathMatch(.*)", - redirect: "/404", - }, -]; - -export default routes; diff --git a/src/router/routes.ts b/src/router/routes.ts new file mode 100644 index 0000000..f665b03 --- /dev/null +++ b/src/router/routes.ts @@ -0,0 +1,271 @@ +import { type RouteRecordRaw } from "vue-router"; + +const routes: Array = [ + // 首页 + { + path: "", + name: "home", + component: () => import("@/views/Home/index.vue"), + }, + // 搜索 + { + path: "/search", + name: "search", + component: () => import("@/views/Search/layout.vue"), + beforeEnter: (to, _, next) => { + if (!to.query.keyword) next({ path: "/403" }); + else next(); + }, + redirect: "/search/songs", + children: [ + { + path: "songs", + name: "search-songs", + component: () => import("@/views/Search/songs.vue"), + }, + { + path: "playlists", + name: "search-playlists", + component: () => import("@/views/Search/playlists.vue"), + }, + { + path: "artists", + name: "search-artists", + component: () => import("@/views/Search/artists.vue"), + }, + { + path: "albums", + name: "search-albums", + component: () => import("@/views/Search/albums.vue"), + }, + { + path: "videos", + name: "search-videos", + component: () => import("@/views/Search/videos.vue"), + }, + { + path: "radios", + name: "search-radios", + component: () => import("@/views/Search/radios.vue"), + }, + ], + }, + // 发现 + { + path: "/discover", + name: "discover", + component: () => import("@/views/Discover/layout.vue"), + redirect: "/discover/playlists", + children: [ + { + path: "playlists", + name: "discover-playlists", + component: () => import("@/views/Discover/playlists.vue"), + }, + { + path: "toplists", + name: "discover-toplists", + component: () => import("@/views/Discover/toplists.vue"), + }, + { + path: "artists", + name: "discover-artists", + component: () => import("@/views/Discover/artists.vue"), + }, + { + path: "new", + name: "discover-new", + component: () => import("@/views/Discover/new.vue"), + }, + ], + }, + // 歌手 + { + path: "/artist", + name: "artist", + beforeEnter: (to, _, next) => { + if (!to.query.id) next({ path: "/403" }); + else next(); + }, + component: () => import("@/views/Artist/layout.vue"), + redirect: "/artist/songs", + children: [ + { + path: "songs", + name: "artist-songs", + component: () => import("@/views/Artist/songs.vue"), + }, + { + path: "albums", + name: "artist-albums", + component: () => import("@/views/Artist/albums.vue"), + }, + { + path: "videos", + name: "artist-videos", + component: () => import("@/views/Artist/videos.vue"), + }, + ], + }, + // 歌单 + { + path: "/video", + name: "video", + beforeEnter: (to, _, next) => { + if (!to.query.id) next({ path: "/403" }); + else next(); + }, + component: () => import("@/views/Video.vue"), + }, + // 专辑 + { + path: "/album", + name: "album", + beforeEnter: (to, _, next) => { + if (!to.query.id) next({ path: "/403" }); + else next(); + }, + component: () => import("@/views/List/album.vue"), + }, + // 歌单 + { + path: "/playlist", + name: "playlist", + beforeEnter: (to, _, next) => { + if (!to.query.id) next({ path: "/403" }); + else next(); + }, + component: () => import("@/views/List/playlist.vue"), + }, + // 播客 + { + path: "/radio", + name: "radio", + beforeEnter: (to, _, next) => { + if (!to.query.id) next({ path: "/403" }); + else next(); + }, + component: () => import("@/views/List/radio.vue"), + }, + // 热门播客 + { + path: "/radio-hot", + name: "radio-hot", + component: () => import("@/views/Radio/hot.vue"), + }, + // 播客分类 + { + path: "/radio-type", + name: "radio-type", + beforeEnter: (to, _, next) => { + if (!to.query.id || !to.query.name) next({ path: "/403" }); + else next(); + }, + component: () => import("@/views/Radio/type.vue"), + }, + // 我喜欢的音乐 + { + path: "/like-songs", + name: "like-songs", + meta: { needLogin: true }, + component: () => import("@/views/List/liked.vue"), + }, + // 我的云盘 + { + path: "/cloud", + name: "cloud", + meta: { needLogin: true }, + component: () => import("@/views/Cloud.vue"), + }, + // 每日推荐 + { + path: "/daily-songs", + name: "daily-songs", + meta: { needLogin: true }, + component: () => import("@/views/DailySongs.vue"), + }, + // 收藏 + { + path: "/like", + name: "like", + meta: { needLogin: true }, + component: () => import("@/views/Like/layout.vue"), + redirect: "/like/playlists", + children: [ + { + path: "playlists", + name: "like-playlists", + component: () => import("@/views/Like/playlists.vue"), + }, + { + path: "albums", + name: "like-albums", + component: () => import("@/views/Like/albums.vue"), + }, + { + path: "artists", + name: "like-artists", + component: () => import("@/views/Like/artists.vue"), + }, + { + path: "videos", + name: "like-videos", + component: () => import("@/views/Like/videos.vue"), + }, + { + path: "radios", + name: "like-radios", + component: () => import("@/views/Like/radios.vue"), + }, + ], + }, + // 本地歌曲 + { + path: "/local", + name: "local", + meta: { needApp: true }, + component: () => import("@/views/Local/layout.vue"), + redirect: "/local/songs", + children: [ + { + path: "songs", + name: "local-songs", + component: () => import("@/views/Local/song.vue"), + }, + { + path: "artists", + name: "local-artists", + component: () => import("@/views/Local/artists.vue"), + }, + { + path: "albums", + name: "local-albums", + component: () => import("@/views/Local/albums.vue"), + }, + ], + }, + // 最近播放 + { + path: "/history", + name: "history", + component: () => import("@/views/History.vue"), + }, + // 状态 + { + path: "/403", + name: "403", + component: () => import("@/views/Status/403.vue"), + }, + { + path: "/404", + name: "404", + component: () => import("@/views/Status/404.vue"), + }, + { + path: "/500", + name: "500", + component: () => import("@/views/Status/500.vue"), + }, +]; + +export default routes; diff --git a/src/stores/data.ts b/src/stores/data.ts new file mode 100644 index 0000000..dcc4c23 --- /dev/null +++ b/src/stores/data.ts @@ -0,0 +1,290 @@ +import { defineStore } from "pinia"; +import type { SongType, CoverType, UserDataType, UserLikeDataType, CatType } from "@/types/main"; +import { playlistCatlist } from "@/api/playlist"; +import { cloneDeep, isEmpty } from "lodash-es"; +import { isLogin } from "@/utils/auth"; +import localforage from "localforage"; +import { formatCategoryList } from "@/utils/format"; + +interface ListState { + playList: SongType[]; + historyList: SongType[]; + cloudPlayList: SongType[]; + searchHistory: string[]; + localPlayList: CoverType[]; + userLoginStatus: boolean; + userData: UserDataType; + userLikeData: UserLikeDataType; + likeSongsList: { + detail: CoverType; + data: SongType[]; + }; + catData: { + type: Record; + cats: CatType[]; + hqCats: CatType[]; + }; +} + +type UserDataKeys = keyof ListState["userLikeData"]; + +// musicDB +const musicDB = localforage.createInstance({ + name: "music-data", + description: "List data of the application", + storeName: "music", +}); + +// userDB +const userDB = localforage.createInstance({ + name: "user-data", + description: "User data of the application", + storeName: "user", +}); + +export const useDataStore = defineStore({ + id: "data", + state: (): ListState => ({ + // 播放列表 + playList: [], + // 播放历史 + historyList: [], + // 搜索历史 + searchHistory: [], + // 本地歌单 + localPlayList: [], + // 云盘歌单 + cloudPlayList: [], + // 用户状态 + userLoginStatus: false, + // 用户数据 + userData: { + userId: 0, + userType: 0, + vipType: 0, + name: "", + }, + // 用户喜欢数据 + userLikeData: { + songs: [], + playlists: [], + artists: [], + albums: [], + mvs: [], + djs: [], + }, + // 我喜欢的音乐 + likeSongsList: { + detail: { + id: 0, + name: "我喜欢的音乐", + cover: "/images/album.jpg?assest", + }, + data: [], + }, + // 分类数据 + catData: { + type: {}, + cats: [], + hqCats: [], + }, + }), + getters: { + // 是否为喜欢歌曲 + isLikeSong: (state) => (id: number) => state.userLikeData.songs.includes(id), + }, + actions: { + async loadData() { + try { + // 获取 music-data + const musicDataKeys = await musicDB.keys(); + console.log(musicDataKeys); + await Promise.all( + musicDataKeys.map(async (key) => { + const data = await musicDB.getItem(key); + this[key] = data || []; + }), + ); + // 获取 user-data + const userDataKeys = await userDB.keys(); + await Promise.all( + userDataKeys.map(async (key) => { + const data = await userDB.getItem(key); + this.userLikeData[key] = data; + }), + ); + } catch (error) { + console.error("Error loading data from localforage:", error); + } + }, + // 更新播放列表 + async setPlayList(data: SongType | SongType[]): Promise { + try { + // 若为列表 + if (Array.isArray(data)) { + this.playList = data; + // 更新本地存储 + data = cloneDeep(data); + await musicDB.setItem("playList", data); + return 0; + } + // 若为单曲 + else { + // 若为单曲 + const song = cloneDeep(data as SongType); + // 歌曲去重 + const playList = this.playList.filter((s) => s.id !== song.id); + // 添加到歌单末尾 + playList.push(song); + // 获取索引 + const index = playList.length - 1; + // 更新本地存储 + this.playList = playList; + await musicDB.setItem("playList", playList); + return index; + } + } catch (error) { + console.error("Error updating playlist:", error); + throw error; + } + }, + // 新增下一首播放歌曲 + async setNextPlaySong(song: SongType, index: number): Promise { + // 移除重复的歌曲(如果存在) + const playList = this.playList.filter((item) => item.id !== song.id); + // 在当前播放位置之后插入歌曲 + const indexAdd = index + 1; + playList.splice(indexAdd, 0, song); + // 更新本地存储 + this.playList = playList; + await musicDB.setItem("playList", cloneDeep(playList)); + return indexAdd; + }, + // 更改播放历史 + async setHistory(song: SongType) { + try { + let historyList: ListState["historyList"] | null = await musicDB.getItem("historyList"); + // 是否无数据 + if (historyList === null) { + historyList = []; + } else if (!Array.isArray(historyList)) return; + // 深拷贝 + song = cloneDeep(song); + // 添加到首项并移除重复项 + const updatedList = [song, ...historyList.filter((item) => item.id !== song.id)]; + // 最多 500 首 + if (updatedList.length > 500) updatedList.splice(500); + await musicDB.setItem("historyList", updatedList); + // 更新播放历史 + this.historyList = updatedList as SongType[]; + } catch (error) { + console.error("Error updating history:", error); + throw error; + } + }, + // 清除播放历史 + async clearHistory(): Promise { + try { + await musicDB.setItem("historyList", []); + this.historyList = []; + } catch (error) { + console.error("Error clearing history:", error); + throw error; + } + }, + // 更改我喜欢的音乐 + async setLikeSongsList(detail: CoverType, data: SongType[]) { + await musicDB.setItem("likeSongsList", { + detail: cloneDeep(detail), + data: cloneDeep(data), + }); + this.likeSongsList = { detail, data }; + }, + // 获取我喜欢的歌单数据 + async getUserLikePlaylist() { + if (!isLogin() || !this.userData.userId) return; + const result = await musicDB.getItem("likeSongsList"); + return result; + }, + // 更改云盘歌单 + async setCloudPlayList(data: SongType[]) { + await musicDB.setItem("cloudPlayList", cloneDeep(data)); + this.cloudPlayList = data; + }, + // 更改用户数据 + async setUserLikeData( + name: K, + data: ListState["userLikeData"][K], + ): Promise { + try { + // 更新本地存储 + await userDB.setItem(name, cloneDeep(data)); + this.userLikeData[name] = data; + } catch (error) { + console.error("Error updating user data:", error); + throw error; + } + }, + // 清除用户数据 + async clearUserData() { + try { + this.userLoginStatus = false; + this.userData = { + userId: 0, + userType: 0, + vipType: 0, + name: "", + }; + await Promise.all( + Object.keys(this.userLikeData).map(async (key) => { + const userDataKey = key as UserDataKeys; + await this.setUserLikeData(userDataKey, []); + this.userLikeData[userDataKey] = []; + }), + ); + } catch (error) { + console.error("Error clearing user data:", error); + throw error; + } + }, + // 删除数据库 + async deleteDB(name?: string): Promise { + try { + if (name) { + await localforage.dropInstance({ name }); + console.log(`Dropped ${name} database`); + return; + } + await musicDB.clear(); + await userDB.clear(); + console.log("All databases cleared"); + } catch (error) { + console.error("Error deleting database:", error); + throw error; + } + }, + // 获取歌单分类 + async getPlaylistCatList() { + if (!isEmpty(this.catData.cats) && !isEmpty(this.catData.hqCats)) return; + // 获取歌单分类 + try { + const [catsRes, hqCatsRes] = await Promise.all([playlistCatlist(), playlistCatlist(true)]); + console.log(catsRes, hqCatsRes); + this.catData = { + type: catsRes.categories, + cats: formatCategoryList(catsRes.sub), + hqCats: formatCategoryList(hqCatsRes.tags), + }; + } catch (error) { + console.error("Error getting playlist cat list:", error); + throw error; + } + }, + }, + // 持久化 + persist: { + key: "data-store", + storage: localStorage, + paths: ["userLoginStatus", "userData", "searchHistory", "catData"], + }, +}); diff --git a/src/stores/index.js b/src/stores/index.js deleted file mode 100644 index da4819e..0000000 --- a/src/stores/index.js +++ /dev/null @@ -1,12 +0,0 @@ -// stores -import useSiteDataStore from "@/stores/siteData"; -import useSiteStatusStore from "@/stores/siteStatus"; -import useSiteSettingsStore from "@/stores/siteSettings"; -import useMusicDataStore from "@/stores/musicData"; -import useIndexedDBStore from "@/stores/indexedDB"; - -export const siteData = () => useSiteDataStore(); -export const siteStatus = () => useSiteStatusStore(); -export const siteSettings = () => useSiteSettingsStore(); -export const musicData = () => useMusicDataStore(); -export const indexedDBData = () => useIndexedDBStore(); diff --git a/src/stores/index.ts b/src/stores/index.ts new file mode 100644 index 0000000..5c29b60 --- /dev/null +++ b/src/stores/index.ts @@ -0,0 +1,8 @@ +export { useShortcutStore } from "./shortcut"; +export { useSettingStore } from "./setting"; +export { useStatusStore } from "./status"; +export { useMusicStore } from "./music"; +export { useDataStore } from "./data"; + +// local-localforage +export { useLocalStore } from "./local"; diff --git a/src/stores/indexedDB.js b/src/stores/indexedDB.js deleted file mode 100644 index 966844a..0000000 --- a/src/stores/indexedDB.js +++ /dev/null @@ -1,36 +0,0 @@ -// indexedDB -import { defineStore } from "pinia"; -import localforage from "localforage"; - -const useIndexedDBStore = defineStore("indexedDB", { - state: () => ({ - filesDB: localforage.createInstance({ - name: "filesDB", - }), - usersDB: localforage.createInstance({ - name: "usersDB", - }), - }), - getters: {}, - actions: { - async setfilesDB(key, value) { - try { - await this.filesDB.setItem(key, value); - } catch (error) { - console.error("Error setting data in IndexedDB:", error); - throw error; - } - }, - async getfilesDB(key) { - try { - const value = await this.filesDB.getItem(key); - return value; - } catch (error) { - console.error("Error retrieving data from IndexedDB:", error); - throw error; - } - }, - }, -}); - -export default useIndexedDBStore; diff --git a/src/stores/local.ts b/src/stores/local.ts new file mode 100644 index 0000000..c7c9ca7 --- /dev/null +++ b/src/stores/local.ts @@ -0,0 +1,62 @@ +import { ref, reactive } from "vue"; +import type { SongType } from "@/types/main"; +import { cloneDeep } from "lodash-es"; +import localforage from "localforage"; + +// localDB +const localDB = localforage.createInstance({ + name: "local-data", + description: "Local data of the application", + storeName: "local", +}); + +export const useLocalStore = () => { + // 本地歌曲 + const localSongs = ref([]); + + // 读取本地歌曲 + const readLocalSong = async (): Promise => { + try { + const result = await localDB.getItem("local-songs"); + localSongs.value = (result as SongType[]) || []; + return localSongs.value; + } catch (error) { + console.error("Error reading local songs:", error); + throw error; + } + }; + + // 更新本地歌曲 + const updateLocalSong = async (songs: SongType[]) => { + try { + await localDB.setItem("local-songs", cloneDeep(songs)); + localSongs.value = songs; + } catch (error) { + console.error("Error updating local songs:", error); + throw error; + } + }; + + // 删除指定歌曲 + const deleteLocalSong = async (index: number) => { + try { + const playlist = cloneDeep(localSongs.value); + playlist.splice(index, 1); + await localDB.setItem("local-songs", playlist); + localSongs.value = playlist; + } catch (error) { + console.error("Error deleting local song:", error); + throw error; + } + }; + + // 直接初始化数据 + readLocalSong(); + + return reactive({ + localSongs, + readLocalSong, + updateLocalSong, + deleteLocalSong, + }); +}; diff --git a/src/stores/music.ts b/src/stores/music.ts new file mode 100644 index 0000000..4a16274 --- /dev/null +++ b/src/stores/music.ts @@ -0,0 +1,111 @@ +import { defineStore } from "pinia"; +import type { LyricLine } from "@applemusic-like-lyrics/core"; +import type { SongType, LyricType } from "@/types/main"; + +interface MusicState { + playSong: SongType; + playPlaylistId: number; + songLyric: { + lrcData: LyricType[]; + yrcData: LyricType[]; + lrcAMData: LyricLine[]; + yrcAMData: LyricLine[]; + }; + personalFM: { + playIndex: number; + list: SongType[]; + }; + dailySongsData: { + timestamp: number | null; + list: SongType[]; + }; +} + +// 默认音乐数据 +const defaultMusicData: SongType = { + id: 0, + name: "未播放歌曲", + artists: "未知歌手", + album: "未知专辑", + cover: "/images/song.jpg?assest", + duration: 0, + free: 0, + mv: null, + type: "song", +}; + +export const useMusicStore = defineStore({ + id: "music", + state: (): MusicState => ({ + // 当前播放歌曲 + playSong: { ...defaultMusicData }, + // 当前播放歌单 + playPlaylistId: 0, + // 当前歌曲歌词 + songLyric: { + lrcData: [], // 普通歌词 + yrcData: [], // 逐字歌词 + lrcAMData: [], // 普通歌词-AM + yrcAMData: [], // 逐字歌词-AM + }, + // 私人FM数据 + personalFM: { + playIndex: 0, + list: [], + }, + // 每日推荐 + dailySongsData: { + timestamp: null, // 更新时间 + list: [], // 歌曲数据 + }, + }), + getters: { + // 是否具有歌词 + isHasLrc(state): boolean { + return state.songLyric.lrcData.length > 0 && state.playSong.type !== "radio"; + }, + // 是否具有逐字歌词 + isHasYrc(state): boolean { + return state.songLyric.yrcData.length > 0; + }, + // 是否有播放器 + isHasPlayer(state): boolean { + return state.playSong?.id !== 0; + }, + // 歌曲封面 + songCover(state): string { + return state.playSong.path + ? state.playSong.cover + : state.playSong.coverSize?.s || state.playSong.cover; + }, + // 私人FM播放歌曲 + personalFMSong(state): SongType { + return state.personalFM.list?.[state.personalFM.playIndex] || defaultMusicData; + }, + }, + actions: { + // 恢复默认音乐数据 + resetMusicData() { + this.playSong = defaultMusicData; + this.songLyric = { + lrcData: [], + yrcData: [], + lrcAMData: [], + yrcAMData: [], + }; + }, + // 获取歌曲封面 + getSongCover(size: "s" | "m" | "l" | "xl" | "cover" = "s") { + return this.playSong.path + ? this.playSong.cover + : size === "cover" + ? this.playSong.cover + : this.playSong.coverSize?.[size] || this.playSong.cover; + }, + }, + // 持久化 + persist: { + key: "music-store", + storage: localStorage, + }, +}); diff --git a/src/stores/musicData.js b/src/stores/musicData.js deleted file mode 100644 index bc329ae..0000000 --- a/src/stores/musicData.js +++ /dev/null @@ -1,152 +0,0 @@ -// 音乐数据 -import { defineStore } from "pinia"; -import { getPersonalFm, setFmToTrash } from "@/api/recommend"; -import { changePlayIndex } from "@/utils/Player"; -import { isLogin } from "@/utils/auth"; -import { siteStatus } from "@/stores"; -import formatData from "@/utils/formatData"; - -const useMusicDataStore = defineStore("musicData", { - state: () => { - return { - // 播放列表 - playList: [], - playListOld: [], - historyPlaylist: [], - // 当前歌曲数据 - playSongData: {}, - // 当前歌曲来源 - playSongSource: 0, - // 当前歌曲歌词数据 - playSongLyric: { - // 是否具有普通翻译 - hasLrcTran: false, - // 是否具有普通音译 - hasLrcRoma: false, - // 是否具有逐字歌词 - hasYrc: false, - // 是否具有逐字翻译 - hasYrcTran: false, - // 是否具有逐字音译 - hasYrcRoma: false, - // 普通歌词数组 - lrc: [], - // 逐字歌词数据 - yrc: [], - }, - // 本地歌曲目录 - localSongPath: [], - // 私人 FM 数据 - privateFmIndex: 0, - privateFmData: [], - privateFmSong: {}, - }; - }, - getters: { - // 获取当前播放歌曲 - getPlaySongData(state) { - const status = siteStatus(); - return status.playMode === "fm" && state.privateFmSong - ? state.privateFmSong - : state.playSongData; - }, - }, - actions: { - // 更改播放历史 - setPlayHistory(data, clean = false) { - if (clean) { - this.historyPlaylist = []; - } else { - const index = this.historyPlaylist.findIndex((item) => item?.id === data?.id); - if (index !== -1) { - this.historyPlaylist.splice(index, 1); - } - // 只有在数据存在时才进行插入操作 - if (data && Object.keys(data).length > 0) { - // 如果数组为空,则直接插入 - if (this.historyPlaylist.length === 0) { - this.historyPlaylist.push(data); - } else { - // 避免插入重复数据 - const existingIndex = this.historyPlaylist.findIndex((item) => item?.id === data?.id); - if (existingIndex === -1) { - // 在数组头部插入数据 - this.historyPlaylist.unshift(data); - // 限制历史记录长度为 500 - if (this.historyPlaylist.length > 500) { - this.historyPlaylist.pop(); - } - } - } - } - } - }, - // 更改私人FM - async setPersonalFm(getNext = false) { - try { - const status = siteStatus(); - // 获取私人FM数据 - const getPersonalFmData = async () => { - const result = await getPersonalFm(); - this.privateFmData = formatData(result.data, "song"); - }; - // 若私人FM数据为空,则获取 - if (!this.privateFmData?.length) { - await getPersonalFmData(); - } - // 若当前无歌曲或上次索引为旧列表 - if (Object.keys(this.privateFmSong).length === 0 || this.privateFmIndex === -1) { - this.privateFmSong = this.privateFmData[0]; - } - // 若需要播放下一首 - if (getNext) { - // 更改播放模式 - status.playMode = "fm"; - // 增加索引 - this.privateFmIndex++; - // 判断索引是否在列表范围内 - if (this.privateFmIndex < this.privateFmData.length) { - this.privateFmSong = this.privateFmData[this.privateFmIndex]; - } else { - // 索引超出范围,重新加载列表 - this.privateFmIndex = 0; - await getPersonalFmData(); - this.privateFmSong = this.privateFmData[0]; - } - } - } catch (error) { - // 处理错误情况 - this.privateFmSong = {}; - console.error("私人FM加载失败:", error); - $message.error("私人FM出现错误,请重试"); - } - }, - // 私人FM垃圾桶 - async setPersonalFmToTrash(id) { - try { - if (!isLogin()) return $message.warning("请登录后使用"); - const status = siteStatus(); - const result = await setFmToTrash(id); - if (result.code === 200) { - $message.success("已移至垃圾桶"); - // 更改播放模式 - status.playMode = "fm"; - // 下一曲 - changePlayIndex("next", true); - } - } catch (error) { - console.error("移至垃圾桶失败:", error); - $message.error("移至垃圾桶失败,请重试"); - } - }, - }, - // 数据持久化 - persist: [ - { - key: "musicData", - storage: localStorage, - }, - ], -}); - -export default useMusicDataStore; diff --git a/src/stores/setting.ts b/src/stores/setting.ts new file mode 100644 index 0000000..6be6ba0 --- /dev/null +++ b/src/stores/setting.ts @@ -0,0 +1,190 @@ +import { defineStore } from "pinia"; + +interface SettingState { + themeMode: "light" | "dark" | "auto"; + themeColorType: + | "default" + | "orange" + | "blue" + | "pink" + | "brown" + | "indigo" + | "green" + | "purple" + | "yellow" + | "teal" + | "custom"; + themeCustomColor: string; + themeGlobalColor: boolean; + themeFollowCover: boolean; + globalFont: "default" | string; + LyricFont: "follow" | string; + showCloseAppTip: boolean; + closeAppMethod: "exit" | "hide"; + showTaskbarProgress: boolean; + useOnlineService: boolean; + checkUpdateOnStart: boolean; + hideVipTag: boolean; + lyricFontSize: number; + lyricTranFontSize: number; + lyricRomaFontSize: number; + lyricFontBold: boolean; + showYrc: boolean; + showYrcAnimation: boolean; + showTran: boolean; + showRoma: boolean; + lyricsPosition: "flex-start" | "center" | "flex-end"; + lyricsScrollPosition: "start" | "center"; + downloadPath: string; + downloadMeta: boolean; + downloadCover: boolean; + downloadLyric: boolean; + saveMetaFile: boolean; + proxyProtocol: "off" | "http" | "https"; + proxyServe: string; + proxyPort: number; + songLevel: + | "standard" + | "higher" + | "exhigh" + | "lossless" + | "hires" + | "jyeffect" + | "sky" + | "jymaster"; + playDevice: "default" | string; + autoPlay: boolean; + songVolumeFade: boolean; + songVolumeFadeTime: number; + useSongUnlock: boolean; + countDownShow: boolean; + barLyricShow: boolean; + playerType: "cover" | "record"; + playerBackgroundType: "none" | "animation" | "blur" | "color"; + memoryLastSeek: boolean; + showPlaylistCount: boolean; + showSpectrums: boolean; + smtcOpen: boolean; + smtcOutputHighQualityCover: boolean; + lyricsBlur: boolean; + lrcMousePause: boolean; + playSongDemo: boolean; + showSearchHistory: boolean; + useAMLyrics: boolean; + useAMSpring: boolean; + menuShowCover: boolean; + preventSleep: boolean; + localFilesPath: string[]; + localSeparators: string[]; + showLocalCover: boolean; + routeAnimation: "none" | "fade" | "zoom" | "slide" | "up"; + useRealIP: boolean; + realIP: string; +} + +export const useSettingStore = defineStore({ + id: "setting", + state: (): SettingState => ({ + // 个性化 + themeMode: "auto", // 明暗模式 + themeColorType: "default", // 主题类别 + themeCustomColor: "#fe7971", // 主题自定义颜色 + themeFollowCover: false, // 主题跟随歌曲封面 + themeGlobalColor: false, // 全局着色 + globalFont: "default", // 全局字体 + LyricFont: "follow", // 歌词区域字体 + hideVipTag: false, // 隐藏 VIP 标签 + showSearchHistory: true, // 显示搜索历史 + menuShowCover: true, // 菜单显示封面 + routeAnimation: "slide", // 路由动画 + // 系统 + useOnlineService: true, // 是否使用在线服务 + showCloseAppTip: true, // 显示关闭应用提示 + closeAppMethod: "hide", // 关闭方式 + showTaskbarProgress: false, // 显示任务栏进度 + checkUpdateOnStart: true, // 启动时检查更新 + preventSleep: false, // 是否禁止休眠 + // 播放 + songLevel: "exhigh", // 音质 + playDevice: "default", // 播放设备 + autoPlay: false, // 自动播放 + songVolumeFade: true, // 渐入渐出 + songVolumeFadeTime: 300, // 渐入渐出时间 + useSongUnlock: true, // 是否使用解灰 + countDownShow: true, // 显示倒计时 + barLyricShow: true, // 显示歌词条 + playerType: "cover", // 播放器类型 + playerBackgroundType: "blur", // 背景类型 + memoryLastSeek: true, // 记忆最后进度 + showPlaylistCount: true, // 显示播放列表数量 + showSpectrums: true, // 是否显示音乐频谱 + smtcOpen: true, // 是否开启 SMTC + smtcOutputHighQualityCover: false, // 是否输出高清封面 + playSongDemo: false, // 是否播放试听歌曲 + // 歌词 + lyricFontSize: 46, // 歌词大小 + lyricTranFontSize: 22, // 歌词翻译大小 + lyricRomaFontSize: 18, // 歌词音译大小 + lyricFontBold: true, // 歌词字体加粗 + useAMLyrics: false, // 是否使用 AM 歌词 + useAMSpring: false, // 是否使用 AM 歌词弹簧效果 + showYrc: true, // 显示逐字歌词 + showYrcAnimation: true, // 显示逐字歌词动画 + showTran: true, // 显示歌词翻译 + showRoma: true, // 显示歌词音译 + lyricsPosition: "flex-start", // 歌词位置 + lyricsBlur: false, // 歌词模糊 + lyricsScrollPosition: "start", // 歌词滚动位置 + lrcMousePause: false, // 鼠标悬停暂停 + // 本地 + localFilesPath: [], + localSeparators: ["/", "&"], + showLocalCover: true, + // 下载 + downloadPath: "", // 默认下载路径 + downloadMeta: true, // 同时下载元信息 + downloadCover: true, // 同时下载封面 + downloadLyric: true, // 同时下载歌词 + saveMetaFile: false, // 保留为独立文件 + // 网络 + proxyProtocol: "off", // 代理协议 + proxyServe: "127.0.0.1", // 代理地址 + proxyPort: 80, // 代理端口 + useRealIP: false, // 是否使用真实 IP + realIP: "116.25.146.177", // 真实IP地址 + }), + getters: {}, + actions: { + // 更换明暗模式 + setThemeMode(mode?: "auto" | "light" | "dark") { + // 若未传入 + if (mode === undefined) { + this.themeMode === "auto" + ? (this.themeMode = "light") + : this.themeMode === "light" + ? (this.themeMode = "dark") + : (this.themeMode = "auto"); + } else { + this.themeMode = mode; + } + window.$message.info( + `已切换至 + ${ + this.themeMode === "auto" + ? "跟随系统" + : this.themeMode === "light" + ? "浅色模式" + : "深色模式" + }`, + { + showIcon: false, + }, + ); + }, + }, + // 持久化 + persist: { + key: "setting-store", + storage: localStorage, + }, +}); diff --git a/src/stores/shortcut.ts b/src/stores/shortcut.ts new file mode 100644 index 0000000..14bc654 --- /dev/null +++ b/src/stores/shortcut.ts @@ -0,0 +1,85 @@ +import { cloneDeep } from "lodash-es"; +import { defineStore } from "pinia"; + +type ShortcutType = { + name: string; + shortcut: string; + globalShortcut: string; + // 是否被注册 + isRegistered?: boolean; +}; + +interface ShortcutStore { + globalOpen: boolean; + shortcutList: { + playOrPause: ShortcutType; + playPrev: ShortcutType; + playNext: ShortcutType; + volumeUp: ShortcutType; + volumeDown: ShortcutType; + toogleDesktopLyric: ShortcutType; + }; +} + +export const useShortcutStore = defineStore({ + id: "shortcut", + state: (): ShortcutStore => ({ + // 全局快捷键开启 + globalOpen: true, + // 全部快捷键 + shortcutList: { + // 播放或暂停 + playOrPause: { + name: "播放 / 暂停", + shortcut: "CmdOrCtrl+Space", + globalShortcut: "CmdOrCtrl+Shift+Space", + }, + // 上一曲 / 下一曲 + playPrev: { + name: "上一曲", + shortcut: "CmdOrCtrl+ArrowLeft", + globalShortcut: "CmdOrCtrl+Shift+Left", + }, + playNext: { + name: "下一曲", + shortcut: "CmdOrCtrl+ArrowRight", + globalShortcut: "CmdOrCtrl+Shift+Right", + }, + // 音量加减 + volumeUp: { + name: "音量加", + shortcut: "CmdOrCtrl+ArrowUp", + globalShortcut: "CmdOrCtrl+Shift+Up", + }, + volumeDown: { + name: "音量减", + shortcut: "CmdOrCtrl+ArrowDown", + globalShortcut: "CmdOrCtrl+Shift+Down", + }, + // 桌面歌词 + toogleDesktopLyric: { + name: "桌面歌词", + shortcut: "CmdOrCtrl+KeyD", + globalShortcut: "CmdOrCtrl+Shift+D", + }, + }, + }), + getters: {}, + actions: { + // 注册全部全局快捷键 + async registerAllShortcuts() { + if (!this.globalOpen) return; + const result = await window.electron.ipcRenderer.invoke( + "register-all-shortcut", + cloneDeep(this.shortcutList), + ); + console.log(result); + return result; + }, + }, + // 持久化 + persist: { + key: "shortcut-store", + storage: localStorage, + }, +}); diff --git a/src/stores/siteData.js b/src/stores/siteData.js deleted file mode 100644 index d0288f6..0000000 --- a/src/stores/siteData.js +++ /dev/null @@ -1,275 +0,0 @@ -// 站点数据 -import { defineStore } from "pinia"; -import { getDailyRec } from "@/api/recommend"; -import { getPlayListCatlist } from "@/api/playlist"; -import { - getUserProfile, - getUserDetail, - getUserSubcount, - getLikelist, - setLikeSong, - getUserPlaylist, - getUserArtist, - getUserAlbum, - getUserMv, - getUserDj, -} from "@/api/user"; -import { isLogin } from "@/utils/auth"; -import formatData from "@/utils/formatData"; -import throttle from "@/utils/throttle"; - -const useSiteDataStore = defineStore("siteData", { - state: () => { - return { - // 搜索历史 - searchHistory: [], - // 用户部分 - userLoginStatus: false, - userData: { - userId: null, // 用户 id - detail: {}, // 基础信息 - subcount: {}, // 订阅信息 - }, - userLikeData: { - songs: [], - playlists: [], - artists: [], - albums: [], - mvs: [], - djs: [], - }, - // 每日推荐 - dailySongsData: { - timestamp: null, // 储存时间 - data: [], // 歌曲数据 - }, - // 歌单分类 - plCatList: { - allCat: [], // 总分类 - catList: [], // 普通分类 - hqCatList: [], // 精品分类 - }, - }; - }, - getters: { - // 获取用户喜欢的音乐歌单 id - getUserLikePlaylistId() { - return isLogin() ? this.userLikeData.playlists?.[0]?.id || null : null; - }, - }, - actions: { - // 获取每日推荐 - async setDailySongsData(refresh = false) { - try { - if (!isLogin()) { - this.dailySongsData = { timestamp: null, data: [] }; - return false; - } - const songsData = this.dailySongsData.data; - const timestamp = this.dailySongsData.timestamp; - // 下一天六点 - const nextDay6AM = new Date(timestamp); - nextDay6AM.setDate(nextDay6AM.getDate() + 1); - nextDay6AM.setHours(6, 0, 0, 0); - // 是否小于今日 6:00 - const originalHour = new Date(timestamp).getHours(); - const isAfter6AM = - new Date(timestamp).toDateString() === new Date().toDateString() && originalHour >= 6; - if (!refresh && songsData?.[0] && isAfter6AM && timestamp <= nextDay6AM.getTime()) { - console.log("日推缓存未过期,不更新"); - return true; - } else { - const res = await getDailyRec(); - const songsData = formatData(res.data.dailySongs, "song"); - console.log("日推缓存不存在或已过期", songsData); - this.dailySongsData = { timestamp: new Date().getTime(), data: songsData }; - if (refresh) $message.success("日推更新成功"); - } - } catch (error) { - showError(error, "每日推荐加载失败"); - } - }, - // 获取歌单分类 - async setPlCatList() { - if (this.plCatList.catList?.length && this.plCatList.hqCatList?.length) { - return false; - } - try { - const [plCatListRes, plHqCatListRes] = await Promise.all([ - getPlayListCatlist(), - getPlayListCatlist(true), - ]); - console.log(plCatListRes, plHqCatListRes); - this.plCatList.allCat = plCatListRes.categories; - this.plCatList.catList = plCatListRes.sub; - this.plCatList.hqCatList = plHqCatListRes.tags; - } catch (error) { - showError(error, "分类数据加载失败"); - } - }, - // 获取用户信息 - async setUserProfile() { - try { - if (!isLogin()) return false; - // 获取用户基本数据 - const userProfile = await getUserProfile(); - this.userData.detail = userProfile; - this.userData.userId = userProfile.profile.userId; - // 获取用户全部信息 - const userDetail = await getUserDetail(this.userData.userId); - if (userDetail) this.userData.detail = userDetail; - // 获取用户订阅信息 - this.userData.subcount = await getUserSubcount(); - // 获取用户基础数据 - const allUserLikeResult = [ - this.setUserLikeSongs(), - this.setUserLikePlaylists(), - this.setUserLikeArtists(), - this.setUserLikeAlbums(), - this.setUserLikeMvs(), - this.setUserLikeDjs(), - ]; - await Promise.all(allUserLikeResult); - } catch (error) { - showError(error, "用户信息加载失败"); - } - }, - // 获取用户喜欢歌曲 - async setUserLikeSongs() { - try { - if (!isLogin() || !this.userData.userId) return false; - // 获取数据 - getLikelist(this.userData.userId).then((res) => { - this.userLikeData.songs = res.ids; - }); - } catch (error) { - showError(error, "用户喜欢歌曲加载失败"); - } - }, - // 获取用户喜欢歌单 - async setUserLikePlaylists() { - try { - if (!isLogin() || !this.userData.userId) return false; - // 计算数量 - const { createdPlaylistCount, subPlaylistCount } = this.userData.subcount; - const number = createdPlaylistCount + subPlaylistCount ?? 50; - // 获取数据 - getUserPlaylist(this.userData.userId, number).then((res) => { - this.userLikeData.playlists = formatData(res.playlist); - }); - } catch (error) { - showError(error, "用户喜欢歌单加载失败"); - } - }, - // 更改用户喜欢歌手 - async setUserLikeArtists() { - try { - if (!isLogin()) return false; - // 获取数据 - getUserArtist().then((res) => { - this.userLikeData.artists = formatData(res.data, "artist"); - }); - } catch (error) { - showError(error, "用户喜欢歌手加载失败"); - } - }, - // 更改用户喜欢专辑 - async setUserLikeAlbums() { - try { - if (!isLogin()) return false; - // 必要数据 - let offset = 0; - let totalCount = null; - this.userLikeData.albums = []; - // 获取数据 - while (totalCount === null || offset < totalCount) { - const res = await getUserAlbum(50, offset); - const albumsData = formatData(res.data, "album"); - this.userLikeData.albums = this.userLikeData.albums.concat(albumsData); - totalCount = res.count; - offset += 50; - } - } catch (error) { - showError(error, "用户喜欢专辑加载失败"); - } - }, - // 更改用户喜欢视频 - async setUserLikeMvs() { - try { - if (!isLogin()) return false; - // 获取数据 - getUserMv().then((res) => { - this.userLikeData.mvs = formatData(res.data, "mv"); - }); - } catch (error) { - showError(error, "用户喜欢歌手加载失败"); - } - }, - // 更改用户喜欢电台 - async setUserLikeDjs() { - try { - if (!isLogin()) return false; - // 获取数据 - getUserDj().then((res) => { - this.userLikeData.djs = formatData(res.djRadios, "dj"); - }); - } catch (error) { - showError(error, "用户喜欢电台加载失败"); - } - }, - // 查找歌曲是否处于喜欢列表 - getSongIsLike(id) { - return this.userLikeData.songs.includes(id); - }, - // 移入移除喜欢列表 - async changeLikeList(id, like = true, isPath = false) { - changeLikeListsData(id, like, isPath, this); - }, - }, - // 数据持久化 - persist: [ - { - key: "siteData", - storage: localStorage, - }, - ], -}); - -// 输出错误 -const showError = (error, msg, show = true) => { - console.error(msg, error); - if (show && typeof $message !== "undefined") $message.error(msg); -}; - -// 移入移除喜欢列表 -const changeLikeListsData = throttle( - async (id, like, isPath, $this) => { - try { - if (!isLogin()) { - $message.warning("请登录后使用"); - if (typeof $changeLogin !== "undefined") $changeLogin(); - return false; - } - if (isPath) return $message.warning("本地歌曲暂不支持该操作"); - const list = $this.userLikeData.songs; - const exists = list.includes(id); - const res = await setLikeSong(id, like); - if (res.code === 200) { - if (like && !exists) { - list.push(id); - } else if (!like && exists) { - list.splice(list.indexOf(id), 1); - } else if (like && exists) { - $message.info("我喜欢的音乐中已存在该歌曲"); - } - } else $message.error(like ? "喜欢音乐时发生错误" : "取消喜欢音乐时发生错误"); - } catch (error) { - console.error("歌曲喜欢操作失败:", error); - $message.error("歌曲喜欢失败,请重试"); - } - }, - 2000, - "请稍后再操作", -); - -export default useSiteDataStore; diff --git a/src/stores/siteSettings.js b/src/stores/siteSettings.js deleted file mode 100644 index 2a14bf8..0000000 --- a/src/stores/siteSettings.js +++ /dev/null @@ -1,107 +0,0 @@ -// 站点设置 -import { defineStore } from "pinia"; - -const useSiteSettingsStore = defineStore("siteSettings", { - state: () => { - return { - // 基础配置 - closeTip: true, // 关闭软件提醒弹窗 - closeType: "hide", // 关闭方式 close 直接关闭 / hide 最小化到任务栏 - showTaskbarProgress: false, // 显示歌曲任务栏进度 - showSearchHistory: true, // 搜索历史 - autoSignIn: true, // 自动签到 - showGithub: true, - showSider: true, // 显示侧边栏 - siderShowCover: false, // 侧边栏显示封面 - autoCheckUpdates: true, // 自动检查更新 - systemFonts: "HarmonyOS Sans", // 全局字体 - justLyricArea: false, // 仅在歌词区域生效 - hiddenVipTags: false, // 隐藏 VIP 标签 - // 主题部分 - themeType: "dark", - themeAuto: false, - themeTypeName: "red", - themeTypeData: {}, - themeAutoCover: true, // 主题色跟随封面 - themeAutoCoverType: "secondary", - // 播放部分 - playCoverType: "cover", // 播放器样式 - songLevel: "exhigh", // 歌曲音质 - autoPlay: false, // 程序启动时自动播放 - songVolumeFade: true, // 歌曲渐入渐出 - useUnmServer: true, // 是否使用网易云解灰 - countDownShow: true, // 是否显示前奏等待 - bottomLyricShow: true, // 底栏歌词显示 - playerBackgroundType: "blur", // 播放器背景类别 animation 流动 / blur 模糊 - memorySeek: true, // 记忆上次播放位置 - playSearch: false, // 是否播放全部搜索结果 - showPlaylistCount: true, // 是否显示播放列表数量 - showSpectrums: false, // 是否显示音乐频谱 - useMusicCache: false, // 是否采用音乐缓存 - // 数量部分 - loadSize: 50, // 每页加载数量 - // 歌词部分 - lrcMousePause: false, // 鼠标移入歌词区域暂停滚动 - lyricsFontSize: 46, // 歌词大小 - lyricsBlur: false, // 歌词模糊 - lyricsBold: true, // 歌词加粗 - showYrc: true, // 是否显示逐字歌词 - showYrcAnimation: true, // 是否显示逐字歌词动画 - lyricsPosition: "left", // 歌词位置 - lyricsBlock: "start", // 歌词滚动位置 - showTransl: true, // 是否显示歌词翻译 - showRoma: true, // 是否显示歌词音译 - // 下载部分 - downloadPath: null, // 默认下载路径 - downloadMeta: true, // 同时下载元信息 - downloadCover: true, // 同时下载封面 - downloadLyrics: true, // 同时下载歌词 - // 网络部分 - useRealIP: true, // 是否使用真实IP地址 - realIP: "116.25.146.177", // 真实IP地址 - proxyProtocol: "off", // 代理协议 - proxyServe: "127.0.0.1", // 代理地址 - proxyPort: 80, // 代理端口 - }; - }, - getters: {}, - actions: { - // 调整主题类别 - setThemeType(value) { - this.themeType = value; - this.themeAuto = false; - $message.info(`已切换至${value === "light" ? "浅色" : "深色"}模式`, { showIcon: false }); - }, - // 更改系统字体 - changeSystemFonts(font = this.systemFonts) { - this.systemFonts = font; - const root = document.documentElement; - if (!root) return false; - // 若仅歌词生效 - if (this.justLyricArea) { - root.style.setProperty( - "--main-font-family-lyric", - `"${font}", "HarmonyOS_Regular", system-ui, -apple-system, sans-serif`, - ); - root.style.setProperty( - "--main-font-family", - `"HarmonyOS Sans", "HarmonyOS_Regular", system-ui, -apple-system, sans-serif`, - ); - return true; - } - root.style.setProperty( - "--main-font-family", - `"${font}", "HarmonyOS_Regular", system-ui, -apple-system, sans-serif`, - ); - }, - }, - // 数据持久化 - persist: [ - { - key: "siteSettings", - storage: localStorage, - }, - ], -}); - -export default useSiteSettingsStore; diff --git a/src/stores/siteStatus.js b/src/stores/siteStatus.js deleted file mode 100644 index a36a4e8..0000000 --- a/src/stores/siteStatus.js +++ /dev/null @@ -1,86 +0,0 @@ -// 站点状态 -import { defineStore } from "pinia"; - -const useSiteStatusStore = defineStore("siteStatus", { - state: () => { - return { - // 菜单折叠状态 - asideMenuCollapsed: false, - // 搜索框状态 - searchInputFocus: false, - // 是否展示播放控制条 - showPlayBar: true, - // 播放状态 - playState: false, - playLoading: false, - playUseOtherSource: false, - // 播放列表状态 - playListShow: false, - // 全屏播放器状态 - showFullPlayer: false, - // 播放器功能显示 - playerControlShow: true, - controlTimeOut: null, - // 实时播放进度 - playSeek: 0, - // 是否下一首 - hasNextSong: false, - // 封面主题 - coverTheme: {}, - coverBackground: null, - // 纯净歌词模式 - pureLyricMode: false, - // 音乐频谱数据 - spectrumsData: [], - spectrumsScaleData: 1, - // 当前歌曲歌词播放索引 - playSongLyricIndex: -1, - // 播放时长数据 - playTimeData: { - currentTime: 0, - duration: 0, - bar: 0, - played: "00:00", - durationTime: "00:00", - }, - // 默认倍速 - playRate: 1, - // 默认音量 - playVolume: 0.7, - // 静音前音量 - playVolumeMute: 0, - // 当前播放索引 - playIndex: 0, - // 当前模式 - // normal 正常 / fm 私人 FM / dj 电台 - playMode: "normal", - // normal 顺序播放 / random 随机播放 / repeat 单曲循环 - playSongMode: "normal", - // 是否为心动模式 - playHeartbeatMode: false, - }; - }, - getters: {}, - actions: {}, - // 数据持久化 - persist: [ - { - key: "siteStatus", - storage: localStorage, - paths: [ - "asideMenuCollapsed", - "pureLyricMode", - "playRate", - "playVolume", - "playVolumeMute", - "playIndex", - "playMode", - "playSongMode", - "playHeartbeatMode", - "playTimeData", - ], - }, - ], -}); - -export default useSiteStatusStore; diff --git a/src/stores/status.ts b/src/stores/status.ts new file mode 100644 index 0000000..2e5b5c7 --- /dev/null +++ b/src/stores/status.ts @@ -0,0 +1,126 @@ +import { defineStore } from "pinia"; +import type { SortType } from "@/types/main"; +import type { PlayModeType, RGB, ColorScheme } from "@/types/main"; + +interface StatusState { + menuCollapsed: boolean; + searchFocus: boolean; + searchInputValue: string; + showPlayBar: boolean; + showFullPlayer: boolean; + fullPlayerActive: boolean; + playerMetaShow: boolean; + playListShow: boolean; + playStatus: boolean; + playLoading: boolean; + playRate: number; + playVolume: number; + playVolumeMute: number; + playSongMode: PlayModeType; + playHeartbeatMode: boolean; + songCoverTheme: { + main?: RGB; + light?: ColorScheme; + dark?: ColorScheme; + }; + spectrumsData: number[]; + pureLyricMode: boolean; + playIndex: number; + lyricIndex: number; + currentTime: number; + duration: number; + progress: number; + currentTimeOffset: number; + playUblock: boolean; + mainContentHeight: number; + listSort: SortType; + showDesktopLyric: boolean; + showPlayerComment: boolean; + personalFmMode: boolean; +} + +export const useStatusStore = defineStore({ + id: "status", + state: (): StatusState => ({ + // 菜单折叠状态 + menuCollapsed: false, + // 搜索框状态 + searchFocus: false, + searchInputValue: "", + // 播放控制条 + showPlayBar: true, + // 播放状态 + playStatus: false, + playLoading: false, + playUblock: false, + // 播放列表状态 + playListShow: false, + // 全屏播放器状态 + showFullPlayer: false, + // 全屏播放器激活状态 + fullPlayerActive: false, + // 播放器功能显示 + playerMetaShow: true, + // 实时播放进度 + currentTime: 0, + duration: 0, + progress: 0, + // 进度偏移 + currentTimeOffset: 0, + // 封面主题 + songCoverTheme: {}, + // 纯净歌词模式 + pureLyricMode: false, + // 音乐频谱数据 + spectrumsData: [], + // 当前播放索引 + playIndex: 0, + // 歌词播放索引 + lyricIndex: -1, + // 默认倍速 + playRate: 1, + // 默认音量 + playVolume: 0.7, + // 静音前音量 + playVolumeMute: 0, + // 播放模式 + playSongMode: "repeat", + // 心动模式 + playHeartbeatMode: false, + // 私人FM模式 + personalFmMode: false, + // 主内容高度 + mainContentHeight: 0, + // 列表排序 + listSort: "default", + // 桌面歌词 + showDesktopLyric: false, + // 播放器评论 + showPlayerComment: false, + }), + getters: {}, + actions: {}, + // 持久化 + persist: { + key: "status-store", + storage: localStorage, + paths: [ + "menuCollapsed", + "currentTime", + "duration", + "progress", + "pureLyricMode", + "playIndex", + "playRate", + "playVolume", + "playVolumeMute", + "playSongType", + "playSongMode", + "songCoverTheme", + "listSort", + "showDesktopLyric", + "playHeartbeatMode", + "personalFmMode", + ], + }, +}); diff --git a/src/style/animate.scss b/src/style/animate.scss index bc696a5..764fa9f 100644 --- a/src/style/animate.scss +++ b/src/style/animate.scss @@ -1,3 +1,54 @@ +// 路由动画 +.router-slide-enter-active, +.router-slide-leave-active { + transition: all 0.2s ease; +} +.router-slide-enter-from, +.router-slide-leave-to { + opacity: 0; + transform: translateX(10px); +} + +.router-fade-enter-active, +.router-fade-leave-active { + transition: all 0.2s ease; +} +.router-fade-enter-from, +.router-fade-leave-to { + opacity: 0; +} + +.router-zoom-enter-active, +.router-zoom-leave-active { + transition: all 0.2s ease; +} +.router-zoom-enter-from, +.router-zoom-leave-to { + opacity: 0; + transform: scale(0.95); +} + +.router-up-enter-active, +.router-up-leave-active { + transition: + opacity 0.2s ease, + transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); +} +.router-up-enter-from { + opacity: 0; + transform: translateY(20px); +} +.router-up-enter-to { + opacity: 1; + transform: translateY(0); +} +.router-up-leave-active { + transform: translateY(0); +} +.router-up-leave-to { + opacity: 0; +} + // fade .fade-enter-active, .fade-leave-active { @@ -23,17 +74,19 @@ transform: translateY(-10px); } -// router -.router-enter-active, -.router-leave-active { - transition: all 0.2s ease; +// left-sm +.left-sm-enter-active, +.left-sm-leave-active { + opacity: 1; + transform: translateX(0); + transition: + transform 0.3s, + opacity 0.3s; } - -.router-enter-from, -.router-leave-to { +.left-sm-enter-from, +.left-sm-leave-to { opacity: 0; - // transform: scale(0.98); - transform: translateX(10px); + transform: translateX(-5px); } // shrink @@ -118,6 +171,17 @@ } @keyframes fade-down { + 0% { + opacity: 0; + transform: translateY(-10px); + } + 100% { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes fade-up { 0% { opacity: 0; transform: translateY(10px); @@ -127,3 +191,17 @@ transform: translateY(0); } } + +@keyframes breathe { + 0% { + transform: scale(0.95); + } + + 50% { + transform: scale(1.1); + } + + 100% { + transform: scale(0.95); + } +} diff --git a/src/style/main.scss b/src/style/main.scss index 5ab659e..45ff5c7 100644 --- a/src/style/main.scss +++ b/src/style/main.scss @@ -1,71 +1,74 @@ -:root { - --main-font-family: "HarmonyOS Sans", "HarmonyOS_Regular", system-ui, -apple-system, sans-serif; -} - * { margin: 0; padding: 0; - user-select: none !important; - -webkit-user-drag: none !important; + user-select: none; + box-sizing: border-box; + -webkit-user-drag: none; + ::after { + box-sizing: border-box; + } } -html, -body, -#app { +body { width: 100vw; height: 100vh; overflow: hidden; } -body { - font-family: var(--main-font-family) !important; +#app { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; } -// n-text -.n-text { +// text-hidden +.text-hidden { display: -webkit-box; overflow: hidden; word-break: break-all; + line-clamp: 1; -webkit-box-orient: vertical; -webkit-line-clamp: 1; } -// n-image -.n-image { - .cover-loading { +// tabs +.n-tabs { + width: 100%; + --n-tab-border-radius: 6px !important; + .n-tabs-nav { position: relative; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 0; - padding-bottom: 100%; - background-color: var(--n-color); - border-radius: 8px; - .n-spin-body { - position: absolute; - height: 100%; - top: 0; - } - &.mv { - padding-bottom: 56%; - } - .loading-img { - position: absolute; - top: 0; - width: 100%; - height: 100%; - opacity: 1 !important; + } +} + +.n-switch { + &.n-switch--active { + .n-switch__rail { + background-color: rgba(var(--primary), 0.8); } } } -// n-scrollbar -.n-scrollbar { - .n-scrollbar-rail { - right: 0 !important; - z-index: 20; - } +// modal +.n-modal { + max-width: calc(100vw - 40px); + border-radius: 8px; +} +.n-modal-mask { + backdrop-filter: blur(16px); +} +.n-modal-scroll-content { + justify-content: center; +} + +// drawer +.n-drawer-mask { + backdrop-filter: blur(20px); +} + +// dropdown +.n-dropdown { + --n-border-radius: 8px !important; } // n-message @@ -78,93 +81,20 @@ body { } } -// n-dropdown -.n-dropdown { - --n-border-radius: 8px !important; -} - -// n-notification -.n-notification { - --n-border-radius: 8px !important; -} - -// n-skeleton -.n-skeleton { - background: linear-gradient( - 90deg, - var(--n-color-end) 25%, - var(--n-color-start) 37%, - var(--n-color-end) 63% - ); - background-size: 400% 100%; - animation: skeleton-loading 1.4s ease infinite; -} - -// n-tabs -.n-tabs { - width: 100%; - --n-tab-border-radius: 6px !important; - .n-tabs-nav { - position: relative; +// slider +.n-slider { + .n-slider-rail { + backdrop-filter: blur(10px); } } -// n-modal -.n-modal { - width: 60vw; - max-width: 700px; - min-width: min(24rem, 100vw); - border-radius: 8px; -} -.n-modal-mask { - backdrop-filter: blur(16px); -} - -// n-result -.n-result { - min-height: calc(100vh - 178px); - display: flex; - flex-direction: column; - justify-content: center; -} - -// n-popover +// popover .n-popover { border-radius: 8px !important; backdrop-filter: blur(10px); -} - -// n-back-top -.n-back-top { - transition: - color 0.3s cubic-bezier(0.4, 0, 0.2, 1), - box-shadow 0.3s cubic-bezier(0.4, 0, 0.2, 1), - background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1), - transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); - &:active { - transform: scale(0.9); - } -} - -// n-data -.n-data-table { - --n-merged-th-color: transparent !important; - --n-merged-td-color: transparent !important; - --n-merged-border-color: transparent !important; - --n-merged-th-color-hover: transparent !important; - --n-merged-td-color-hover: transparent !important; - --n-merged-td-color-striped: transparent !important; - .n-data-table__pagination { - margin-top: 40px; - margin-bottom: 30px; - justify-content: center; - } -} - -// n-image-preview -.n-image-preview-container { - .n-image-preview-overlay { - backdrop-filter: blur(16px); + overflow: hidden; + &:not(.n-popover--raw) { + color: var(--primary-hex); } } @@ -180,3 +110,130 @@ body { top: 20px !important; } } + +// n-scrollbar +.n-scrollbar { + .n-scrollbar-rail { + right: 0 !important; + } + .n-scrollbar-rail__scrollbar { + right: 0; + transition: + width 0.3s, + background-color 0.2s var(--n-scrollbar-bezier) !important; + &:hover { + width: 8px; + } + } +} + +// notification +.n-notification { + --n-border-radius: 8px !important; +} + +// image +.n-image { + width: 100%; + height: 100%; + .cover-loading { + position: relative; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + border-radius: 8px; + .loading-img { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 1 !important; + } + } + img { + transition: all 0.3s; + } +} + +// image-preview +.n-image-preview-container { + .n-image-preview-overlay { + backdrop-filter: blur(16px); + } + .n-image-preview-toolbar { + .n-base-icon { + padding: 0; + margin: 0 8px; + } + } +} + +// skeleton +.n-skeleton { + background: linear-gradient( + 90deg, + rgba(var(--primary), 0.08) 25%, + rgba(var(--primary), 0.14) 37%, + rgba(var(--primary), 0.08) 63% + ); + background-size: 400% 100%; + animation: skeleton-loading 1.4s ease infinite; +} + +// n-back-top +.n-back-top { + --n-height: 42px !important; + --n-width: 42px !important; + border: 1px solid rgba(var(--primary), 0.28); +} + +// select +.n-select { + .n-base-selection { + .n-base-selection-label { + background-color: var(--n-border-color); + } + } +} + +// alert +.n-alert { + --n-border-radius: 8px !important; +} + +// tag +.n-tag { + font-size: 13px; + padding: 0 16px; + line-height: 0; + cursor: pointer; + transition: + transform 0.3s, + background-color 0.3s, + color 0.3s; + background-color: rgba(var(--primary), 0.08); + &.choose { + background-color: rgba(var(--primary), 0.28); + color: var(--primary-hex); + } + &:hover { + background-color: rgba(var(--primary), 0.28); + color: var(--primary-hex); + } + &:active { + transform: scale(0.98); + } +} + +// input +.n-input-number { + width: 100%; +} + +::selection { + background-color: var(--primary-hex); + color: var(--background-hex); +} diff --git a/src/types/global.d.ts b/src/types/global.d.ts new file mode 100644 index 0000000..cd8e28a --- /dev/null +++ b/src/types/global.d.ts @@ -0,0 +1,14 @@ +import { Howl } from "howler"; +import { MessageApi, DialogApi, NotificationApi, LoadingBarApi, ModalApi } from "naive-ui"; + +declare global { + interface Window { + player?: null | Howl; + // naiveui + $message: MessageApi; + $dialog: DialogApi; + $notification: NotificationApi; + $loadingBar: LoadingBarApi; + $modal: ModalApi; + } +} diff --git a/src/types/main.d.ts b/src/types/main.d.ts new file mode 100644 index 0000000..6f781a8 --- /dev/null +++ b/src/types/main.d.ts @@ -0,0 +1,235 @@ +import { sortOptions } from "@/utils/helper"; +import { songLevelData } from "@/utils/meta"; + +export type MetaData = { + id: number; + name: string; + cover?: string; + alias?: string[]; +}; + +export type DjData = { + id: number; + name: string; + creator?: string; +}; + +export type CoverSize = { + s: string; + m: string; + l: string; + xl: string; +}; + +export type UserType = { + id: number; + name: string; + avatarUrl: string | undefined; + vipType?: number; + vipLevel?: number; + vipIconUrl?: string; + isAnnualCount?: boolean; +}; + +export type SongType = { + id: number; + name: string; + artists: MetaData[] | string; + album: MetaData | string; + dj?: DjData; + cover: string; + coverSize?: CoverSize; + duration: number; + // 0: 未知 | 1: 原曲 | 2: 翻唱 + originCoverType?: number; + alia?: string; + // 0: 免费或无版权 | 1: VIP 歌曲 | 4: 购买专辑 | 8: 非会员可免费播放低音质,会员可播放高音质及下载 + free: 0 | 1 | 4 | 8; + mv: number | null; + path?: string; + pc?: boolean; + size?: number; + quality?: "Hi-Res" | "HQ" | "SQ"; + createTime?: number; + updateTime?: number; + playCount?: number; + // 歌曲类型 + type: "song" | "radio"; +}; + +// Cover +export type CoverType = { + id: number; + name: string; + cover: string; + coverSize?: CoverSize; + description?: string; + creator?: UserType; + artists?: MetaData[] | string; + count?: number; + tags?: string[]; + userId?: number | null; + count?: number; + privacy?: number; + playCount?: number; + liked?: boolean; + likedCount?: number; + commentCount?: number; + shareCount?: number; + subCount?: number; + playCount?: number; + createTime?: number; + updateTime?: number; + loading?: boolean; + updateTip?: string; + tracks?: { + first: string; + second: string; + }[]; +}; + +// Artist +export type ArtistType = { + id: number; + name: string; + cover: string; + coverSize?: CoverSize; + alia?: string; + identify?: string; + description?: string; + albumSize?: number; + musicSize?: number; + mvSize?: number; + fansSize?: number; +}; + +// Comment +export type CommentType = { + id: number; + content: string; + beReplied?: { + content: string; + user: UserType; + }; + time: number; + user: UserType; + ip?: { + ip: string; + location: string; + }; + liked?: boolean; + likedCount?: number; +}; + +export type PlayModeType = "repeat" | "repeat-once" | "shuffle"; + +export type LyricContentType = { + time: number; + endTime: number; + duration: number; + content: string; + endsWithSpace: boolean; +}; + +export type LyricType = { + time: number; + endTime: number; + tran?: string; + roma?: string; + content: string; + contents: LyricContentType[]; +}; + +export interface RGB { + r: number; + g: number; + b: number; +} + +export interface ColorScheme { + [key: string]: RGB; +} + +export interface CoverColors { + main?: RGB; + light?: ColorScheme; + dark?: ColorScheme; +} + +export interface CatType { + name: string; + category: number; + hot?: boolean; + count?: number; +} + +// userData +export interface UserDataType { + userId: number; + userType: number; + vipType: number; + name: string; + level?: number; + avatarUrl?: string; + backgroundUrl?: string; + createTime?: number; + createDays?: number; + artistCount?: number; + djRadioCount?: number; + mvCount?: number; + subPlaylistCount?: number; + createdPlaylistCount?: number; +} + +export interface UserLikeDataType { + songs: number[]; + playlists: CoverType[]; + artists: ArtistType[]; + albums: CoverType[]; + mvs: CoverType[]; + djs: CoverType[]; +} + +// sort +export type SortType = keyof typeof sortOptions; + +// songLevel +export type SongLevelType = keyof typeof songLevelData; +export type SongLevelDataType = { + name: string; + level: string; + value: SongLevelType; + size?: number; + br?: number; +}; + +// setting +export type SettingType = "general" | "play" | "lyrics" | "keyboard" | "local" | "other" | "about"; + +// UpdateLog +export type UpdateLogType = { + version: string; + changelog: string; + time: number; + url: string; + force?: boolean; +}; + +// 文件信息 +interface FileInfoType { + url: string; + sha512: string; + size: number; +} + +// 更新信息 +interface UpdateInfoType { + tag: string; + version: string; + files: FileInfoType[]; + path: string; + sha512: string; + releaseDate: string; + releaseName: string; + releaseNotes: string; +} diff --git a/src/utils/Player.js b/src/utils/Player.js deleted file mode 100644 index d3153ef..0000000 --- a/src/utils/Player.js +++ /dev/null @@ -1,855 +0,0 @@ -import { Howl, Howler } from "howler"; -import { musicData, siteStatus, siteSettings } from "@/stores"; -import { getSongUrl, getSongLyric, songScrobble } from "@/api/song"; -import { checkPlatform, getLocalCoverData, getBlobUrlFromUrl } from "@/utils/helper"; -import { decode as base642Buffer } from "@/utils/base64"; -import { getSongPlayTime } from "@/utils/timeTools"; -import { getCoverGradient } from "@/utils/cover-color"; -import { isLogin } from "@/utils/auth"; -import { parseLyric, parseLocalLrc } from "@/utils/parseLyric"; - -// 全局播放器 -let player; -// 时长定时器 -let seekInterval; -let justSeekInterval; -let scrobbleTimeout; -// 重试次数 -let testNumber = 0; -// 是否结束 -let isPlayEnd = true; -// 频谱数据 -let spectrumsData = { - audio: null, - analyser: null, - audioCtx: null, - scale: 1, -}; -// 默认标题 -let defaultTitle = document.title; - -/** - * 初始化播放器 - */ -export const initPlayer = async (playNow = false) => { - try { - // 停止播放器 - soundStop(); - // 获取基础数据 - const music = musicData(); - const status = siteStatus(); - const settings = siteSettings(); - const { playIndex, playMode } = status; - const { playList } = music; - // 当前播放歌曲数据 - const playSongData = music.getPlaySongData; - // 是否为本地歌曲 - const isLocalSong = playSongData?.path ? true : false; - console.log("当前为本地歌曲"); - // 获取封面 - if (isLocalSong) { - music.playSongData.localCover = await getLocalCoverData(playSongData?.path); - } - const cover = isLocalSong ? music.playSongData?.localCover : playSongData?.coverSize; - // 歌词归位 - status.playSongLyricIndex = -1; - // 若为 fm 模式,则清除当前歌曲信息 - if (playMode === "fm") music.playSongData = {}; - // 在线歌曲 - if (!isLocalSong) { - // 获取歌曲 ID - let songId = playSongData?.id; - if (!songId) return false; - // 若为电台模式 - if (playMode === "dj") songId = music.getPlaySongData?.djId; - // 开启加载状态 - status.playLoading = true; - // 获取播放地址 - const url = await getNormalSongUrl(songId, status, playNow); - // 正常播放地址 - if (url) { - status.playUseOtherSource = false; - createPlayer(url); - } - // 无法正常获取播放地址 - else if (checkPlatform.electron() && playMode !== "dj" && settings.useUnmServer) { - const url = await getFromUnblockMusic(playSongData, status, playNow); - if (url) { - status.playUseOtherSource = true; - createPlayer(url); - } else { - isPlayEnd = true; - status.playUseOtherSource = false; - // 是否为最后一首 - if (playIndex === playList.length - 1) { - status.playState = false; - $message.warning("当前列表歌曲无法播放,请更换歌曲"); - } else { - $message.error("该歌曲暂无音源,跳至下一首"); - changePlayIndex("next", true); - } - } - } - // 下一曲 - else { - if (playIndex !== playList.length - 1) { - // changePlayIndex(); - } else { - status.playLoading = false; - status.playState = false; - $message.warning("列表中暂无可播放歌曲", { closable: true, duration: 5000 }); - } - } - } - // 本地歌曲 - else if (isLocalSong && playList?.length) { - const url = playList[playIndex]?.path; - if (playNow && url) status.playState = true; - if (url) { - // 创建播放器 - createPlayer(url); - } else { - changePlayIndex("next", playNow); - } - } - // 获取歌词 - if (playMode !== "dj") getSongLyricData(isLocalSong, playSongData); - // 初始化媒体会话控制 - initMediaSession(playSongData, cover, isLocalSong, playMode === "dj"); - // 获取图片主色 - getColorMainColor(isLocalSong, cover); - } catch (error) { - testNumber++; - // 错误次数过多 - if (testNumber > 10) { - $dialog.error({ - title: "致命性错误", - content: "歌曲播放中出现错误次数过多,请刷新后重试", - positiveText: "刷新", - onPositiveClick: () => { - location.reload(); - }, - }); - return false; - } - // 下一曲 - // changePlayIndex(); - console.error("初始化音乐播放器出错:", error); - $message.error("初始化音乐播放器出错"); - } -}; - -/** - * 获取普通模式下的音乐播放地址 - * @param {number} id - 歌曲 id - * @returns {Promise} - 歌曲播放地址,如果获取失败或歌曲无法播放则返回 null - */ -const getNormalSongUrl = async (id, status, playNow) => { - try { - const settings = siteSettings(); - const res = await getSongUrl(id, settings.songLevel); - // 检查是否有有效的响应数据 - if (!res.data?.[0] || !res.data?.[0]?.url) return null; - // 检查是否只能试听 - if (res.data?.[0]?.freeTrialInfo !== null && checkPlatform.electron()) return null; - // 返回歌曲地址,将 http 转换为 https - const url = res.data[0].url.replace(/^http:/, "https:"); - // 更改状态 - if (playNow && url) status.playState = true; - return url; - } catch (error) { - status.playLoading = false; - console.error("获取歌曲地址遇到错误:" + error); - throw error; - } -}; - -/** - * 网易云解灰 - * @param {string} id - 歌曲 id - * @returns {Promise} - 创建播放器 - */ -const getFromUnblockMusic = async (data, status, playNow) => { - try { - console.info("🎵 开始解灰:", data); - // 调用解灰 - let musicUrl = await electron.ipcRenderer.invoke("getMusicNumUrl", JSON.stringify(data)); - if (!musicUrl) { - status.playLoading = false; - return null; - } - // 处理 bili 音源 - if (musicUrl.includes("bilivideo.com")) { - const result = await electron.ipcRenderer.invoke("getBiliUrlData", musicUrl); - // 将获取的数据转换为 ArrayBuffer - const buffer = base642Buffer(result); - // 创建一个新的 Blob,并生成相应的对象 URL - const source = URL.createObjectURL(new Blob([buffer])); - // 如果之前的 musicUrl 存在,则销毁旧的对象 URL - if (musicUrl) { - URL.revokeObjectURL(musicUrl); - } - // 更新 musicUrl 为新的对象 URL - musicUrl = source; - } - if (playNow) status.playState = true; - status.playLoading = false; - return musicUrl; - } catch (error) { - status.playLoading = false; - console.error("歌曲解灰遇到错误:" + error.message); - $message.error("歌曲解灰遇到错误"); - throw error; - } -}; - -/** - * 创建播放器 - * @param {string} src - 音频文件地址 - * @param {number} volume - 音量( 默认为 0.7 ) - * @param {number} seek - 初始播放进度( 默认为 0 ) - */ -export const createPlayer = async (src, autoPlay = true) => { - try { - // pinia - const music = musicData(); - const status = siteStatus(); - const settings = siteSettings(); - const { playMode } = status; - const { playSongSource, playList } = music; - const { showSpectrums, memorySeek, useMusicCache } = settings; - // 当前播放歌曲数据 - const playSongData = music.getPlaySongData; - // 获取播放链接(非电台及云盘歌曲) - const songUrl = - useMusicCache && playMode !== "dj" && !playSongData.pc ? await getBlobUrlFromUrl(src) : src; - console.log("播放地址:", songUrl); - // 初始化播放器 - if (player) soundStop(); - player = new Howl({ - src: [songUrl], - format: ["mp3", "flac", "dolby", "webm"], - html5: true, - preload: "metadata", - volume: status.playVolume, - rate: status.playRate, - }); - // 允许跨域 - const audioDom = player._sounds[0]._node; - audioDom.crossOrigin = "anonymous"; - // 写入播放历史 - if (playMode !== "dj") music.setPlayHistory(playSongData); - // 生成音乐频谱 - // 由于浏览器安全策略,无法在此处启动 - if (showSpectrums && checkPlatform.electron()) processSpectrum(player); - // 加载完成 - player?.once("load", () => { - console.info("🎵 加载完成", player, status.playState); - // 自动播放 - if (autoPlay && status.playState) { - setSeek(); - fadePlayOrPause("play"); - } - // 恢复进度(防止播放到结尾时触发 bug) - if (memorySeek && status.playTimeData?.duration - status.playTimeData?.currentTime > 2) { - setSeek(status.playTimeData?.currentTime ?? 0); - } else { - setSeek(); - status.playTimeData.bar = "0"; - } - // 取消加载状态 - status.playLoading = false; - // 发送歌曲名 - if (checkPlatform.electron()) { - electron.ipcRenderer.send("songNameChange", getPlaySongName()); - } - // 听歌打卡 - if (isLogin() && !playSongData?.path) { - clearTimeout(scrobbleTimeout); - scrobbleTimeout = setTimeout(async () => { - const result = await songScrobble(playSongData.id, playSongSource, 5); - if (result.code === 200) console.log("歌曲打卡完成:", result); - }, 5000); - } - }); - // 开始播放 - player?.on("play", () => { - console.info("🎵 开始播放:", playSongData); - isPlayEnd = false; - setAllInterval(); - // 更改状态 - status.playState = true; - // 发送状态 - if (checkPlatform.electron()) { - electron.ipcRenderer.send("songStateChange", true); - } - // 更改页面标题 - if (!checkPlatform.electron()) document.title = getPlaySongName(); - }); - // 暂停播放 - player?.on("pause", () => { - console.info("⏸ 暂停播放"); - cleanAllInterval(); - // 更改状态 - status.playState = false; - // 发送状态 - if (checkPlatform.electron()) { - electron.ipcRenderer.send("songStateChange", false); - } - // 更改页面标题 - if (!checkPlatform.electron()) document.title = defaultTitle || "SPlayer"; - }); - // 结束播放 - player?.on("end", () => { - console.info("🎵 播放结束"); - isPlayEnd = true; - // 停止定时器 - cleanAllInterval(); - // 下一曲 - changePlayIndex(); - // 发送状态 - if (checkPlatform.electron()) { - electron.ipcRenderer.send("songStateChange", false); - } - }); - // 加载失败 - player?.on("loaderror", (id, errCode) => { - console.log("播放出现错误:", id, errCode); - // 更改状态 - status.playLoading = false; - // https://github.com/goldfire/howler.js?tab=readme-ov-file#onloaderror-function - switch (errCode) { - case 1: - $message.error("播放出错,用户代理中止了获取媒体"); - break; - case 2: - $message.error("播放出错,未知的网络错误"); - break; - case 3: - $message.error("播放出错,媒体进行解码时发生错误"); - break; - case 4: - $message.error("播放出错,不支持的音频格式或媒体资源不合适"); - break; - default: - $message.error("播放遇到未知错误"); - break; - } - // 下一曲 - if (playList.length > 1) { - changePlayIndex(); - } else { - status.playState = false; - } - }); - // 返回音频对象 - return (window.$player = player); - } catch (error) { - console.error("播放遇到错误:" + error); - $message.error("播放遇到错误,请重试"); - throw error; - } -}; - -/** - * 播放下一首或上一首歌曲 - * @param {string} type - 更改索引的类型 "next" / "prev" - */ -export const changePlayIndex = async (type = "next", play = false) => { - // pinia - const music = musicData(); - const status = siteStatus(); - // 解构音乐数据 - const { playList } = music; - const { playSongMode, playMode, playHeartbeatMode } = status; - // 清除定时器 - cleanAllInterval(); - // 歌词归位 - status.playSongLyricIndex = -1; - // 私人FM模式 - if (playMode === "fm") { - await music.setPersonalFm(true); - // 渐出音乐 - if (!isPlayEnd) fadePlayOrPause("pause"); - // 初始化播放器 - initPlayer(play); - return true; - } - // 根据播放模式确定要操作的播放列表和其长度 - const listLength = playList?.length || 0; - // 根据播放歌曲模式执行不同的操作 - if (status.hasNextSong) { - status.playIndex += type === "next" ? 1 : -1; - status.hasNextSong = false; - } else { - if (playSongMode === "normal" || playHeartbeatMode) { - // 正常模式 - status.playIndex += type === "next" ? 1 : -1; - } else if (playSongMode === "random") { - // 随机模式 - status.playIndex = Math.floor(Math.random() * listLength); - } else if (playSongMode === "repeat") { - // 单曲循环模式 - setSeek(); - fadePlayOrPause("play"); - } - } - // 检查播放索引是否越界 - if (playSongMode !== "repeat") { - if (status.playIndex < 0) { - status.playIndex = listLength - 1; - } else if (status.playIndex >= listLength) { - status.playIndex = 0; - } - // 赋值当前播放歌曲信息 - const songData = playList?.[status.playIndex]; - if (songData) { - music.playSongData = songData; - // 渐出音乐 - if (!isPlayEnd) fadePlayOrPause("pause"); - // 初始化播放器 - initPlayer(play); - } else { - $message.error("歌曲信息读取错误,跳至下一曲"); - changePlayIndex("next", play); - } - } -}; - -/** - * 在当前播放歌曲后添加 - * @param {Object} data - 歌曲信息 - */ -export const addSongToNext = (data, play = false) => { - try { - const music = musicData(); - const status = siteStatus(); - // 更改播放模式 - status.hasNextSong = true; - // 查找是否存在于播放列表 - const index = music.playList.findIndex((v) => v.id === data.id); - // 若存在 - if (index !== -1) { - console.log("已存在", index); - // 移动至当前歌曲的下一曲 - const currentSongIndex = status.playIndex; - const nextSongIndex = currentSongIndex + 1; - // 如果移动的位置不是当前位置,且不是最后一首歌曲 - if (index !== currentSongIndex && nextSongIndex < music.playList.length) { - // 移动歌曲 - music.playList.splice(nextSongIndex, 0, music.playList.splice(index, 1)[0]); - } - // 更新播放索引 - if (play) status.playIndex = nextSongIndex; - } - // 添加至播放列表 - else { - // music.playList.push(data); - music.playList.splice(status.playIndex + 1, 0, data); - if (play) status.playIndex++; - } - // 是否立即播放 - play ? fadePlayOrPause("play") : $message.success("已添加至下一首播放"); - } catch (error) { - console.error("添加播放歌曲失败:", error); - } -}; - -/** - * 音频渐入渐出 - * @param {String} [type="play"] - 渐入渐出 - */ -export const fadePlayOrPause = (type = "play") => { - const status = siteStatus(); - const settings = siteSettings(); - const duration = settings.songVolumeFade ? 300 : 0; - // 渐入 - if (type === "play") { - if (player?.playing()) return; - player?.play(); - // 更新播放进度 - setAllInterval(); - player?.once("play", () => { - player?.fade(0, status.playVolume, duration); - }); - } - // 渐出 - else if (type === "pause") { - player?.fade(status.playVolume, 0, duration); - player?.once("fade", () => { - player?.pause(); - cleanAllInterval(); - }); - } -}; - -/** - * 播放或暂停 - */ -export const playOrPause = async () => { - const status = player?.playing(); - fadePlayOrPause(status ? "pause" : "play"); -}; - -/** - * 设置倍速 - * @param {number} rate - 设置的倍速值 - */ -export const setRate = (rate) => { - player?.rate(Number(rate)); -}; - -/** - * 设置音量 - * @param {number} volume - 设置的音量值,0-1之间的浮点数 - */ -export const setVolume = (volume) => { - player?.volume(Number(volume)); -}; - -/** - * 停止播放器 - */ -export const soundStop = () => { - // player?.stop(); - // setSeek(); - Howler.unload(); -}; - -/** - * 调整静音 - */ -export const setVolumeMute = () => { - const status = siteStatus(); - if (status.playVolume > 0) { - status.playVolumeMute = status.playVolume; - status.playVolume = 0; - } else { - status.playVolume = status.playVolumeMute; - } - player?.volume(status.playVolume); -}; - -/** - * 设置进度 - * @param {number} seek - 设置的进度值,0-1之间的浮点数 - */ -export const setSeek = (seek = 0) => { - player?.seek(seek); -}; - -/** - * 获取进度 - * @return {number} seek - 获取的进度值,0-1之间的浮点数 - */ -export const getSeek = () => { - if (typeof player !== "undefined") { - return player.seek(); - } - return 0; -}; - -/** - * 更改播放进度 - */ -const setAudioTime = () => { - if (player?.playing()) { - const music = musicData(); - const status = siteStatus(); - const settings = siteSettings(); - const currentTime = player?.seek(); - const duration = player?._duration; - // 计算数据 - const bar = duration ? ((currentTime / duration) * 100).toFixed(2) : 0; - const played = getSongPlayTime(currentTime); - const durationTime = getSongPlayTime(duration); - // 计算当前歌词播放索引 - const lrcType = !music.playSongLyric.hasYrc || !settings.showYrc; - const lyrics = lrcType ? music.playSongLyric.lrc : music.playSongLyric.yrc; - const lyricsIndex = lyrics?.findIndex((v) => v?.time >= currentTime); - // 赋值数据 - status.playTimeData = { currentTime, duration, bar, played, durationTime }; - status.playSongLyricIndex = lyricsIndex === -1 ? lyrics.length - 1 : lyricsIndex - 1; - // 显示进度条 - if (checkPlatform.electron() && settings.showTaskbarProgress) { - electron.ipcRenderer.send("setProgressBar", bar); - } - } -}; - -/** - * 更改播放进度(频繁) - */ -const justSetSeek = () => { - if (player?.playing()) { - const status = siteStatus(); - status.playSeek = getSeek(); - requestAnimationFrame(justSetSeek); - } -}; - -/** - * 获取歌曲的歌词数据并解析 - * @param {object} data - 歌曲的数据 - */ -const getSongLyricData = async (islocal, data) => { - if (!data?.id) return false; - try { - const music = musicData(); - const setDefaults = () => { - music.playSongLyric = { - hasLrcTran: false, - hasLrcRoma: false, - hasYrc: false, - hasYrcTran: false, - hasYrcRoma: false, - lrc: [], - yrc: [], - }; - }; - if (islocal) { - const lyricData = await electron.ipcRenderer.invoke("getMusicLyric", data?.path); - if (lyricData) { - const result = parseLocalLrc(lyricData); - music.playSongLyric = result ? (music.playSongLyric = result) : setDefaults(); - } else { - console.log("该歌曲暂无歌词"); - setDefaults(); - } - } else { - const lyricResponse = await getSongLyric(data?.id); - const lyricData = lyricResponse?.lrc; - if (lyricData) { - const result = parseLyric(lyricResponse); - result ? (music.playSongLyric = result) : setDefaults(); - } else { - console.log("该歌曲暂无歌词"); - setDefaults(); - } - } - } catch (err) { - $message.error("歌词处理出错"); - console.error("歌词处理出错:", err); - } -}; - -/** - * 初始化媒体会话控制 - * 如果浏览器支持媒体会话控制( Media Session API ),则关联各类操作 - * @param {object} data - 当前播放数据 - * @param {string} islocal - 是否为本地歌曲 - * @param {string} cover - 封面图像的URL或数据 - */ -const initMediaSession = async (data, cover, islocal, isDj) => { - if ("mediaSession" in navigator) { - // 歌曲信息 - navigator.mediaSession.metadata = new MediaMetadata({ - title: data.name, - artist: isDj - ? "电台节目" - : islocal - ? data.artists - : data.artists?.map((a) => a.name)?.join(" & "), - album: isDj ? "电台节目" : islocal ? data.album : data.album.name, - artwork: islocal - ? [ - { - src: cover, - sizes: "1024x1024", - }, - ] - : [ - { - src: cover?.s, - sizes: "100x100", - }, - { - src: cover?.m, - sizes: "300x300", - }, - { - src: cover?.l, - sizes: "1024x1024", - }, - ], - length: data?.duration, - }); - // 按键关联 - navigator.mediaSession.setActionHandler("play", async () => { - fadePlayOrPause("play"); - }); - navigator.mediaSession.setActionHandler("pause", async () => { - fadePlayOrPause("pause"); - }); - navigator.mediaSession.setActionHandler("previoustrack", () => { - changePlayIndex("prev", true); - }); - navigator.mediaSession.setActionHandler("nexttrack", () => { - changePlayIndex("next", true); - }); - } -}; - -/** - * 从封面图像中提取主要颜色,并根据亮度进行选择 - * @param {string} islocal - 是否为本地歌曲 - * @param {string} cover - 封面图像的URL或数据 - * @returns {string} - 主要颜色的RGB十六进制表示 - */ -const getColorMainColor = async (islocal, cover) => { - const status = siteStatus(); - try { - // 获取封面图像的URL - if (!cover) return (status.coverTheme = {}); - const colorUrl = islocal ? cover : cover.s; - // 获取渐变色背景 - const gradientColor = await getCoverGradient(colorUrl); - status.coverBackground = gradientColor; - } catch (error) { - console.error("封面颜色获取失败:", error); - status.coverTheme = {}; - } -}; - -/** - * 生成频谱数据 - 快速傅里叶变换( FFT ) - * @param {Object} sound - Howler.js 的音频对象 - * @returns {void} - */ -export const processSpectrum = (sound) => { - try { - if (!spectrumsData.audioCtx) { - // 断开之前的连接 - spectrumsData.audio?.disconnect(); - spectrumsData.analyser?.disconnect(); - spectrumsData.audioCtx?.close(); - // 创建新的连接 - spectrumsData.audioCtx = new (window.AudioContext || window.webkitAudioContext)(); - // 获取音频元素 - const audioDom = sound._sounds[0]._node; - // 允许跨域请求 - audioDom.crossOrigin = "anonymous"; - // 创建音频源和分析器 - const source = spectrumsData.audioCtx.createMediaElementSource(audioDom); - const analyser = spectrumsData.audioCtx.createAnalyser(); - // 频谱分析器 FFT - analyser.fftSize = 512; - // 连接音频源和分析器,再连接至音频上下文的目标 - source.connect(analyser); - analyser.connect(spectrumsData.audioCtx.destination); - // 更新频谱数据 - const dataArray = new Uint8Array(analyser.frequencyBinCount); - updateSpectrums(analyser, dataArray); - // 保存当前链接 - spectrumsData.audio = source; - spectrumsData.analyser = analyser; - } - } catch (err) { - console.error("音乐频谱生成失败:" + err); - } -}; - -/** - * 更新音乐频谱数据 - * @param {Object} analyser - 音频分析器 - * @param {Uint8Array} dataArray - 频谱数据数组 - */ -const updateSpectrums = (analyser, dataArray) => { - // pinia - const status = siteStatus(); - // 获取频率数据 - analyser.getByteFrequencyData(dataArray); - status.spectrumsData = [...dataArray]; - // 计算 scale - const averageAmplitude = dataArray.reduce((acc, val) => acc + val, 0) / dataArray.length; - status.spectrumsScaleData = (averageAmplitude / 512 + 1).toFixed(2); - // 递归调用,持续更新频谱数据 - requestAnimationFrame(() => { - updateSpectrums(analyser, dataArray); - }); -}; - -/** - * 获取当前播放歌曲名 - */ -const getPlaySongName = () => { - // pinia - const status = siteStatus(); - const music = musicData(); - const playSongData = music.getPlaySongData; - // 返回歌曲数据 - const songName = playSongData.name || "未知曲目"; - const songArtist = - status.playMode === "dj" - ? "电台节目" - : Array.isArray(playSongData.artists) - ? playSongData.artists.map((ar) => ar.name).join(" / ") - : playSongData.artists || "未知歌手"; - return songName + " - " + songArtist; -}; - -/** - * 播放所有歌曲 - * @param {Array} playlist - 包含歌曲信息的数组 - * @param {string} mode - 播放模式 - */ -export const playAllSongs = async (playlist, mode = "normal") => { - try { - // pinia - const music = musicData(); - const status = siteStatus(); - if (!playlist) return false; - // 关闭心动模式 - status.playHeartbeatMode = false; - // 更改模式和歌单 - status.playMode = mode; - music.playList = playlist.slice(); - // 是否处于歌单内 - const songId = music.getPlaySongData?.id; - const existingIndex = playlist.findIndex((song) => song.id === songId); - // 若不处于 - if (existingIndex === -1 || !songId) { - console.log("不在歌单内"); - music.playSongData = playlist[0]; - status.playIndex = 0; - // 初始化播放器 - await initPlayer(true); - } else { - console.log("处于歌单内"); - music.playSongData = playlist[existingIndex]; - status.playIndex = existingIndex; - // 播放 - fadePlayOrPause(); - } - // 获取封面 - if (music.getPlaySongData?.path) { - music.playSongData.localCover = await getLocalCoverData(music.getPlaySongData?.path); - } - $message.info("已开始播放", { showIcon: false }); - } catch (error) { - console.error("播放全部歌曲出错:", error); - $message.error("播放全部歌曲出现错误"); - } -}; - -/* - * 清除定时器 - */ -const cleanAllInterval = () => { - clearInterval(seekInterval); - // clearInterval(justSeekInterval); - cancelAnimationFrame(justSeekInterval); - seekInterval = null; - justSeekInterval = null; -}; - -/** - * 更新定时器 - */ -const setAllInterval = () => { - cleanAllInterval(); - // 启动定时器 - seekInterval = setInterval(() => setAudioTime(), 250); - // justSeekInterval = setInterval(() => justSetSeek(), 17); - justSeekInterval = requestAnimationFrame(justSetSeek); -}; diff --git a/src/utils/auth.js b/src/utils/auth.js deleted file mode 100644 index ff64566..0000000 --- a/src/utils/auth.js +++ /dev/null @@ -1,71 +0,0 @@ -import { logOut } from "@/api/login"; -import { siteData } from "@/stores"; -import Cookies from "js-cookie"; - -/** - * 将服务器返回的 Cookie 数据设置到浏览器的 Cookie 和本地存储中 - */ -export const setCookies = (cookieValue) => { - const cookies = cookieValue.split(";;"); - cookies.map((cookie) => { - document.cookie = cookie; - const cookieKeyValue = cookie.split(";")[0].split("="); - localStorage.setItem(`cookie-${cookieKeyValue[0]}`, cookieKeyValue[1]); - }); -}; - -/** - * 获取指定 Cookie 值 - * @param {string} key - 要获取的 Cookie 键名 - * @returns {string|null} Cookie 值,如果不存在则返回 null - */ -export const getCookie = (key) => { - return Cookies.get(key) ?? localStorage.getItem(`cookie-${key}`); -}; - -/** - * 移除指定 Cookie - * @param {string} key - 要移除的 Cookie 键名 - */ -export const removeCookie = (key) => { - Cookies.remove(key); - localStorage.removeItem(`cookie-${key}`); -}; - -/** - * 检查用户是否已登录 - * @returns {boolean} 如果用户已登录,则返回 true;否则返回 false - */ -export const isLogin = () => { - const data = siteData(); - const status = getCookie("MUSIC_U") === undefined || getCookie("MUSIC_U") === null; - // 更改状态 - data.userLoginStatus = !status; - return !status; -}; - -/** - * 退出用户登录 - */ -export const toLogout = async (show = true) => { - const data = siteData(); - // 去除 cookie - await logOut(); - removeCookie("MUSIC_U"); - removeCookie("__csrf"); - sessionStorage.clear(); - // 去除用户信息 - data.userLoginStatus = false; - data.userData = {}; - data.userLikeData = { - songs: [], - playlists: [], - albums: [], - mvs: [], - }; - data.dailySongsData = { - timestamp: null, - data: [], - }; - if (show) $message.success("成功退出登录"); -}; diff --git a/src/utils/auth.ts b/src/utils/auth.ts new file mode 100644 index 0000000..ab47b3d --- /dev/null +++ b/src/utils/auth.ts @@ -0,0 +1,257 @@ +import { getCookie, removeCookie, setCookies } from "./cookie"; +import type { UserLikeDataType, CoverType, ArtistType, SongType } from "@/types/main"; +import { + userAccount, + userDetail, + userSubcount, + userLike, + userDj, + userMv, + userArtist, + userAlbum, + userPlaylist, +} from "@/api/user"; +import { likeSong } from "@/api/song"; +import { formatCoverList, formatArtistsList, formatSongsList } from "@/utils/format"; +import { useDataStore, useMusicStore } from "@/stores"; +import { logout, refreshLogin } from "@/api/login"; +import { openUserLogin } from "./modal"; +import { debounce } from "lodash-es"; +import { isBeforeSixAM } from "./time"; +import { dailyRecommend } from "@/api/rec"; + +// 是否登录 +export const isLogin = () => !!getCookie("MUSIC_U"); + +// 退出登录 +export const toLogout = async () => { + const dataStore = useDataStore(); + // 退出登录 + await logout(); + // 去除 cookie + removeCookie("MUSIC_U"); + removeCookie("__csrf"); + sessionStorage.clear(); + // 清除用户数据 + await dataStore.clearUserData(); + window.$message.success("成功退出登录"); +}; + +// 刷新登录 +export const refreshLoginData = async () => { + // lastLoginTime 是否超过 3 天 + const lastLoginTime = localStorage.getItem("lastLoginTime"); + // 超时时长 + const timeout = 3 * 24 * 60 * 60 * 1000; + if (lastLoginTime && Date.now() - Number(lastLoginTime) > timeout) { + // 刷新登录 + const result = await refreshLogin(); + if (result?.code === 200) { + setCookies(result.cookie); + localStorage.setItem("lastLoginTime", Date.now().toString()); + } + return result; + } +}; + +// 更新用户信息 +export const updateUserData = async () => { + try { + if (!isLogin()) return; + const dataStore = useDataStore(); + // userId + const { profile } = await userAccount(); + const userId = profile.userId; + // 获取用户信息 + const userDetailData = await userDetail(userId); + const userData = Object.assign(profile, userDetailData); + // 获取用户订阅信息 + const subcountData = await userSubcount(); + // 更改用户信息 + dataStore.userData = { + userId, + userType: userData.userType, + vipType: userData.vipType, + name: userData.nickname, + level: userData.level, + avatarUrl: userData.avatarUrl, + backgroundUrl: userData.backgroundUrl, + createTime: userData.createTime, + createDays: userData.createDays, + artistCount: subcountData.artistCount, + djRadioCount: subcountData.djRadioCount, + mvCount: subcountData.mvCount, + subPlaylistCount: subcountData.subPlaylistCount, + createdPlaylistCount: subcountData.createdPlaylistCount, + }; + + // 获取用户喜欢数据 + const allUserLikeResult = await Promise.allSettled([ + updateUserLikeSongs(), + updateUserLikePlaylist(), + updateUserLikeArtists(), + updateUserLikeAlbums(), + updateUserLikeMvs(), + updateUserLikeDjs(), + // 每日推荐 + updateDailySongsData(), + ]); + // 若部分失败 + const hasFailed = allUserLikeResult.some((result) => result.status === "rejected"); + console.log(allUserLikeResult); + + if (hasFailed) throw new Error("Failed to update some user data"); + } catch (error) { + console.error("❌ Error updating user data:", error); + throw error; + } +}; + +// 更新用户喜欢歌曲 +export const updateUserLikeSongs = async () => { + const dataStore = useDataStore(); + if (!isLogin() || !dataStore.userData.userId) return; + const result = await userLike(dataStore.userData.userId); + dataStore.setUserLikeData("songs", result.ids); +}; + +// 更新用户喜欢歌单 +export const updateUserLikePlaylist = async () => { + const dataStore = useDataStore(); + const userId = dataStore.userData.userId; + if (!isLogin() || !userId) return; + // 计算数量 + const { createdPlaylistCount, subPlaylistCount } = dataStore.userData; + const number = (createdPlaylistCount || 0) + (subPlaylistCount || 0) || 50; + const result = await userPlaylist(number, 0, userId); + dataStore.setUserLikeData("playlists", formatCoverList(result.playlist)); +}; + +// 更新用户喜欢歌手 +export const updateUserLikeArtists = async () => { + await setUserLikeDataLoop(userArtist, formatArtistsList, "artists"); +}; + +// 更新用户喜欢专辑 +export const updateUserLikeAlbums = async () => { + await setUserLikeDataLoop(userAlbum, formatCoverList, "albums"); +}; + +// 更新用户喜欢电台 +export const updateUserLikeDjs = async () => { + const dataStore = useDataStore(); + if (!isLogin() || !dataStore.userData.userId) return; + const result = await userDj(); + dataStore.setUserLikeData("djs", formatCoverList(result.djRadios)); +}; + +// 更新用户喜欢MV +export const updateUserLikeMvs = async () => { + const dataStore = useDataStore(); + if (!isLogin() || !dataStore.userData.userId) return; + const result = await userMv(); + dataStore.setUserLikeData("mvs", formatCoverList(result.data)); +}; + +// 喜欢歌曲 +export const toLikeSong = debounce( + async (song: SongType, like: boolean) => { + if (!isLogin()) { + window.$message.warning("请登录后使用"); + openUserLogin(); + return; + } + const dataStore = useDataStore(); + const { id, path } = song; + if (path) { + window.$message.warning("本地歌曲暂不支持该操作"); + return; + } + const likeList = dataStore.userLikeData.songs; + const exists = likeList.includes(id); + const { code } = await likeSong(id, like); + if (code === 200) { + if (like && !exists) { + likeList.push(id); + window.$message.success("已添加到我喜欢的音乐"); + } else if (!like && exists) { + likeList.splice(likeList.indexOf(id), 1); + window.$message.success("已取消喜欢"); + } else if (like && exists) { + window.$message.info("我喜欢的音乐中已存在该歌曲"); + } + // 更新 + dataStore.setUserLikeData("songs", likeList); + } else { + window.$message.error(`${like ? "喜欢" : "取消"}音乐时发生错误`); + return; + } + }, + 300, + { leading: true, trailing: false }, +); + +// 循环获取用户喜欢数据 +const setUserLikeDataLoop = async ( + apiFunction: (limit: number, offset: number) => Promise<{ data: any[]; count: number }>, + formatFunction: (data: any[]) => T[], + key: keyof UserLikeDataType, +) => { + const dataStore = useDataStore(); + const userId = dataStore.userData.userId; + if (!isLogin() || !userId) return; + // 必要数据 + let offset: number = 0; + const allData: T[] = []; + const limit: number = 100; + // 是否可循环 + let canLoop: boolean = true; + // 循环获取 + while (canLoop) { + const { data, count } = await apiFunction(limit, offset); + // 数据处理 + const formattedData = formatFunction(data); + // 若为空 + if (formattedData.length === 0) break; + // 合并数据 + allData.push(...formattedData); + // 更新偏移量 + offset += limit; + canLoop = offset < count && formattedData.length > 0; + } + // 更新数据 + if (key === "artists") { + dataStore.setUserLikeData(key, allData as ArtistType[]); + } else if (key === "albums" || key === "mvs" || key === "djs") { + dataStore.setUserLikeData(key, allData as CoverType[]); + } else { + console.error(`Unsupported key: ${key}`); + } + return allData; +}; + +/** + * 更新每日推荐 + * @param refresh 是否强制刷新 + */ +export const updateDailySongsData = async (refresh = false) => { + try { + const musicStore = useMusicStore(); + if (!isLogin()) { + musicStore.dailySongsData = { timestamp: null, list: [] }; + return; + } + const { timestamp, list } = musicStore.dailySongsData; + // 是否需要刷新 + if (!refresh && list.length > 0 && timestamp && !isBeforeSixAM(timestamp)) return; + // 获取每日推荐 + const result = await dailyRecommend("songs"); + const songsData = formatSongsList(result.data.dailySongs); + // 更新数据 + musicStore.dailySongsData = { timestamp: Date.now(), list: songsData }; + if (refresh) window.$message.success("每日推荐更新成功"); + } catch (error) { + console.error("❌ Error updating daily songs data:", error); + throw error; + } +}; diff --git a/src/utils/base64.js b/src/utils/base64.js deleted file mode 100644 index 25fc956..0000000 --- a/src/utils/base64.js +++ /dev/null @@ -1,66 +0,0 @@ -// https://github.com/niklasvh/base64-arraybuffer/blob/master/src/index.ts -// Copyright (c) 2012 Niklas von Hertzen Licensed under the MIT license. - -const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -// Use a lookup table to find the index. -const lookup = typeof Uint8Array === "undefined" ? [] : new Uint8Array(256); -for (let i = 0; i < chars.length; i++) { - lookup[chars.charCodeAt(i)] = i; -} - -export const encode = (arraybuffer) => { - let bytes = new Uint8Array(arraybuffer), - i, - len = bytes.length, - base64 = ""; - - for (i = 0; i < len; i += 3) { - base64 += chars[bytes[i] >> 2]; - base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)]; - base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)]; - base64 += chars[bytes[i + 2] & 63]; - } - - if (len % 3 === 2) { - base64 = base64.substring(0, base64.length - 1) + "="; - } else if (len % 3 === 1) { - base64 = base64.substring(0, base64.length - 2) + "=="; - } - - return base64; -}; - -export const decode = (base64) => { - let bufferLength = base64.length * 0.75, - len = base64.length, - i, - p = 0, - encoded1, - encoded2, - encoded3, - encoded4; - - if (base64[base64.length - 1] === "=") { - bufferLength--; - if (base64[base64.length - 2] === "=") { - bufferLength--; - } - } - - const arraybuffer = new ArrayBuffer(bufferLength), - bytes = new Uint8Array(arraybuffer); - - for (i = 0; i < len; i += 4) { - encoded1 = lookup[base64.charCodeAt(i)]; - encoded2 = lookup[base64.charCodeAt(i + 1)]; - encoded3 = lookup[base64.charCodeAt(i + 2)]; - encoded4 = lookup[base64.charCodeAt(i + 3)]; - - bytes[p++] = (encoded1 << 2) | (encoded2 >> 4); - bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2); - bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63); - } - - return arraybuffer; -}; diff --git a/src/utils/blob.ts b/src/utils/blob.ts new file mode 100644 index 0000000..597c211 --- /dev/null +++ b/src/utils/blob.ts @@ -0,0 +1,64 @@ +class BlobURLManager { + private blobURLs: Map; + + constructor() { + this.blobURLs = new Map(); + } + + /** + * 从给定的 Buffer 数据生成 Blob URL + * @param data - 要转换为 Blob 的二进制数据 + * @param format - 数据的 MIME 类型('image/jpeg') + * @param key - 用于标识 Blob URL 的唯一键(文件路径) + * @returns Blob URL + */ + createBlobURL(data: Buffer, format: string, key: string): string { + try { + if (this.blobURLs.has(key)) { + // console.log("🌱 Blob URL already exists:", key); + return this.blobURLs.get(key)!; + } + const blob = new Blob([data], { type: format }); + const blobURL = URL.createObjectURL(blob); + // 存储 Blob URL + this.blobURLs.set(key, blobURL); + return blobURL; + } catch (error) { + console.error("❌ Error creating Blob URL:", error); + throw error; + } + } + + /** + * 清理 Blob URL + * @param key - 要清理的 Blob URL 对应的键 + */ + revokeBlobURL(key: string): void { + try { + const blobURL = this.blobURLs.get(key); + if (blobURL) { + URL.revokeObjectURL(blobURL); + this.blobURLs.delete(key); + } + } catch (error) { + console.error("❌ Error revoking Blob URL:", error); + } + } + + /** + * 清理所有 Blob URL + */ + revokeAllBlobURLs(): void { + try { + this.blobURLs.forEach((blobURL) => { + URL.revokeObjectURL(blobURL); + }); + // 清空存储 + this.blobURLs.clear(); + } catch (error) { + console.error("❌ Error revoking all Blob URLs:", error); + } + } +} + +export default new BlobURLManager(); diff --git a/src/utils/cache.ts b/src/utils/cache.ts new file mode 100644 index 0000000..6a5445c --- /dev/null +++ b/src/utils/cache.ts @@ -0,0 +1,51 @@ +type StorageType = "localStorage" | "sessionStorage"; + +interface CacheOptions { + key: string; + time: number; // 缓存时长,单位为分钟 + storage?: StorageType; // 默认为 sessionStorage + useCache?: boolean; // 是否使用缓存,默认为 true +} + +/** + * 获取接口请求缓存 + * @template T + * @param {(...args: any[]) => Promise} promiseFunc - 异步请求函数 + * @param {Object} options - 缓存选项 + * @param {string} options.key - 用于存储和检索缓存数据的键值 + * @param {number} options.time - 缓存有效时间(分钟)。如果为 -1,则表示永久有效 + * @param {string} [options.storage="sessionStorage"] - 储存方式,默认为 `sessionStorage`,可选 `localStorage` + * @param {...any} args - 传递的参数 + * @returns {Promise} + * @returns + */ +export const getCacheData = async ( + promiseFunc: (...args: any[]) => Promise, + options: CacheOptions, + ...args: any[] +): Promise => { + const { key, time, storage = "sessionStorage", useCache = true } = options; + // 储存方式 + const storageObj = window[storage]; + try { + // 获取缓存数据 + const cachedData = storageObj.getItem(key); + if (cachedData && useCache) { + // 判断缓存是否过期 + const { value, expiry } = JSON.parse(cachedData); + if (expiry === 0 || new Date().getTime() < expiry) { + console.log(`✅ Cached data found for key: ${key}`, value); + return value; + } + } + // 请求数据 + const result = await promiseFunc(...args); + const expiry = time === -1 ? -1 : new Date().getTime() + time * 60 * 1000; + // 存储数据 + storageObj.setItem(key, JSON.stringify({ value: result, expiry })); + return result; + } catch (error) { + console.error(`❌ Error in getCacheData: ${error}`); + throw error; + } +}; diff --git a/src/utils/color-utils.js b/src/utils/color-utils.js deleted file mode 100644 index e9f81b4..0000000 --- a/src/utils/color-utils.js +++ /dev/null @@ -1,314 +0,0 @@ -/** - * 将 RGB 颜色值转换为 HSL(色调、饱和度、亮度)颜色值 - * @param {number[]} rgb - 一个包含红色、绿色和蓝色通道值的数组(范围:0-255) - * @returns {number[]} - 一个包含色调(H)、饱和度(S)和亮度(L)的数组,值的范围分别为 [0, 1]、[0, 1] 和 [0, 1] - */ -export const rgb2Hsl = ([r, g, b]) => { - // 将 RGB 值转换为范围 [0, 1] 的值 - r /= 255; - g /= 255; - b /= 255; - // 查找最大和最小的颜色通道值 - const max = Math.max(r, g, b); - const min = Math.min(r, g, b); - // 初始化色调(H)、饱和度(S)、亮度(L) - let h, - s, - l = (max + min) / 2; - if (max === min) { - // 如果最大和最小通道值相等,颜色为灰色 - h = s = 0; - } else { - const d = max - min; - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - // 计算色调(H) - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - case g: - h = (b - r) / d + 2; - break; - case b: - h = (r - g) / d + 4; - break; - } - h /= 6; - } - // 返回 HSL 颜色值的数组 - return [h, s, l]; -}; - -/** - * 将HSL(色相、饱和度、亮度)颜色值转换为RGB颜色值 - * - * @param {number[]} hsl - 包含色相(0-1)、饱和度(0-1)和亮度(0-1)的数组 - * @returns {number[]} - 包含红色、绿色和蓝色分量的RGB颜色值数组(0-255) - */ -export const hsl2Rgb = ([h, s, l]) => { - let r, g, b; - if (s == 0) { - // 如果饱和度为0,将RGB三个分量都设置为亮度 - r = g = b = l; - } else { - const hue2rgb = (p, q, t) => { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - }; - const q = l < 0.5 ? l * (1 + s) : l + s - l * s; - const p = 2 * l - q; - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - // 将RGB分量值从0-1映射到0-255,并返回RGB颜色值数组 - return [r * 255, g * 255, b * 255]; -}; - -/** - * 根据输入的RGB颜色值,对颜色进行规范化处理(暂时无用) - * - * @param {number[]} rgb - 包含红色、绿色和蓝色分量的RGB颜色值数组(0-255) - * @returns {number[]} - 规范化后的RGB颜色值数组(0-255) - */ -export const normalizeColor = ([r, g, b]) => { - // 如果RGB三个分量之间的差值小于5,返回灰色 - if (Math.max(r, g, b) - Math.min(r, g, b) < 5) { - return [150, 150, 150]; - } - // 辅助函数,用于混合两个值 - const mix = (a, b, p) => Math.round(a * (1 - p) + b * p); - // 计算颜色的亮度 - const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b; - // 根据亮度调整颜色 - if (luminance < 60) { - [r, g, b] = [r, g, b].map((c) => mix(c, 255, 0.3 * (1 - luminance / 60))); - } else if (luminance > 180) { - [r, g, b] = [r, g, b].map((c) => mix(c, 0, 0.5 * ((luminance - 180) / 76))); - } - // 将RGB颜色值转换为HSL颜色值 - let [h, s, l] = rgb2Hsl([r, g, b]); - // 限制饱和度和亮度的范围 - s = Math.max(0.3, Math.min(0.8, s)); - l = Math.max(0.5, Math.min(0.8, l)); - // 将HSL颜色值转换回RGB颜色值 - [r, g, b] = hsl2Rgb([h, s, l]); - // 返回规范化后的RGB颜色值数组 - return [r, g, b]; -}; - -/** - * 计算输入颜色的白色调色板版本,通过混合颜色和白色来改变亮度(暂时无用) - * - * @param {number[]} rgb - 包含红色、绿色和蓝色分量的RGB颜色值数组(0-255) - * @param {number} [p=0.5] - 混合颜色和白色的比例,范围为0到1,默认为0.5 - * @returns {number[]} - 新的RGB颜色值数组,表示经过白色调色板处理后的颜色 - */ -export const calcWhiteShadeColor = ([r, g, b], p = 0.5) => { - /** - * 辅助函数,用于混合两个值 - * @param {number} a - 第一个值 - * @param {number} b - 第二个值 - * @param {number} p - 混合比例,范围为0到1 - * @returns {number} - 混合后的值 - */ - const mix = (a, b, p) => Math.round(a * (1 - p) + b * p); - // 将输入颜色的每个分量与255进行混合,改变亮度 - return [r, g, b].map((c) => mix(c, 255, p)); -}; - -/** - * 计算给定颜色的亮度 - * - * @param {number[]} color - 包含红色、绿色和蓝色分量的颜色值数组(0-255) - * @returns {number} - 颜色的亮度值,范围从0到1 - */ -export const calcLuminance = (color) => { - // 将颜色值从0-255映射到0-1范围 - let [r, g, b] = color.map((c) => c / 255); - // 对每个分量进行 gamma 校正 - [r, g, b] = [r, g, b].map((c) => { - if (c <= 0.03928) { - return c / 12.92; - } - return Math.pow((c + 0.055) / 1.055, 2.4); - }); - // 计算颜色的亮度值 - return 0.2126 * r + 0.7152 * g + 0.0722 * b; -}; - -/** - * 将RGB颜色值转换为CIELAB颜色空间中的LAB颜色值 - * - * @param {number[]} color - 包含红色、绿色和蓝色分量的RGB颜色值数组(0-255) - * @returns {number[]} - LAB颜色值数组,包含亮度(L)和色度(A、B)分量 - */ -export const rgb2Lab = (color) => { - if (!color) return [0, 0, 0]; - // 将颜色值从0-255映射到0-1范围 - let [r, g, b] = color.map((c) => c / 255); - // 对每个分量进行 gamma 校正 - [r, g, b] = [r, g, b].map((c) => { - if (c <= 0.03928) { - return c / 12.92; - } - return Math.pow((c + 0.055) / 1.055, 2.4); - }); - // 将RGB颜色值映射到0-100范围 - [r, g, b] = [r, g, b].map((c) => c * 100); - // 计算XYZ颜色值 - const x = r * 0.4124 + g * 0.3576 + b * 0.1805; - const y = r * 0.2126 + g * 0.7152 + b * 0.0722; - const z = r * 0.0193 + g * 0.1192 + b * 0.9505; - // 辅助函数,用于将XYZ分量映射到LAB分量 - const xyz2Lab = (c) => { - if (c > 0.008856) { - return Math.pow(c, 1 / 3); - } - return 7.787 * c + 16 / 116; - }; - // 计算LAB颜色值的亮度(L)和色度(A、B)分量 - const L = 116 * xyz2Lab(y / 100) - 16; - const A = 500 * (xyz2Lab(x / 95.047) - xyz2Lab(y / 100)); - const B = 200 * (xyz2Lab(y / 100) - xyz2Lab(z / 108.883)); - // 返回LAB颜色值数组 - return [L, A, B]; -}; - -/** - * 计算两个颜色之间的颜色差异,使用CIELAB颜色空间中的欧氏距离 - * - * @param {number[]} color1 - 包含红色、绿色和蓝色分量的RGB颜色值数组(0-255) - * @param {number[]} color2 - 包含红色、绿色和蓝色分量的RGB颜色值数组(0-255) - * @returns {number} - 两个颜色之间的颜色差异值 - */ -export const calcColorDifference = (color1, color2) => { - // 将颜色值转换为LAB颜色值 - const [L1, A1, B1] = rgb2Lab(color1); - const [L2, A2, B2] = rgb2Lab(color2); - // 计算LAB颜色值之间的欧氏距离 - const deltaL = L1 - L2; - const deltaA = A1 - A2; - const deltaB = B1 - B2; - // 返回颜色差异值 - return Math.sqrt(deltaL * deltaL + deltaA * deltaA + deltaB * deltaB); -}; - -/** - * 从给定调色板中生成渐变背景颜色 - * - * @param {number[][]} palette - 包含多个颜色的调色板,每个颜色由红色、绿色和蓝色分量组成的数组(0-255) - * @returns {string} - 表示渐变背景颜色的CSS线性渐变字符串 - */ -export const getGradientFromPalette = (palette) => { - // 根据亮度对调色板进行排序 - palette = palette.sort((a, b) => { - return calcLuminance(a) - calcLuminance(b); - }); - // 选择亮度中间的8个颜色 - palette = palette.slice(palette.length / 2 - 4, palette.length / 2 + 4); - // 根据饱和度对颜色进行排序 - palette = palette.sort((a, b) => { - return rgb2Hsl(b)[1] - rgb2Hsl(a)[1]; - }); - // 选择最饱和的6个颜色 - palette = palette.slice(0, 6); - // 计算颜色之间的差异 - let differences = new Array(6); - for (let i = 0; i < differences.length; i++) { - differences[i] = new Array(6).fill(0); - } - for (let i = 0; i < palette.length; i++) { - for (let j = i + 1; j < palette.length; j++) { - differences[i][j] = calcColorDifference(palette[i], palette[j]); - differences[j][i] = differences[i][j]; - } - } - // 使用深度优先搜索找到最佳颜色序列 - let used = new Array(6).fill(false); - let min = 10000000, - ansSeq = []; - const dfs = (depth, seq = [], currentMax = -1) => { - if (depth === 6) { - if (currentMax < min) { - min = currentMax; - ansSeq = seq; - } - return; - } - for (let i = 0; i < 6; i++) { - if (used[i]) continue; - used[i] = true; - dfs(depth + 1, seq.concat(i), Math.max(currentMax, differences[seq[depth - 1]][i])); - used[i] = false; - } - }; - for (let i = 0; i < 6; i++) { - used[i] = true; - dfs(1, [i]); - used[i] = false; - } - // 根据最佳颜色序列构建渐变字符串 - let colors = []; - for (let i of ansSeq) { - colors.push(palette[i]); - } - let ans = "linear-gradient(-45deg,"; - for (let i = 0; i < colors.length; i++) { - ans += `rgb(${colors[i][0]}, ${colors[i][1]}, ${colors[i][2]})`; - if (i !== colors.length - 1) { - ans += ","; - } - } - ans += ")"; - return ans; -}; - -/** - * 将32位ARGB颜色值转换为24位RGB颜色值 - * - * @param {number} x - 32位ARGB颜色值 - * @returns {number[]} - 包含红色、绿色和蓝色分量的24位RGB颜色值数组(0-255) - */ -export const argb2Rgb = (x) => { - // 提取红色、绿色和蓝色分量 - const r = (x >> 16) & 0xff; - const g = (x >> 8) & 0xff; - const b = x & 0xff; - // 返回24位RGB颜色值数组 - return [r, g, b]; -}; - -/** - * 将24位RGB颜色值转换为32位ARGB颜色值 - * - * @param {number} r - 红色分量(0-255) - * @param {number} g - 绿色分量(0-255) - * @param {number} b - 蓝色分量(0-255) - * @returns {number} - 32位ARGB颜色值 - */ -export const rgb2Argb = (r, g, b) => { - // 使用位运算将RGB分量组合成32位ARGB颜色值 - return (0xff << 24) | (r << 16) | (g << 8) | b; -}; - -/** - * 将24位RGB颜色值转换为16进制表示的颜色字符串 - * - * @param {number} r - 红色分量(0-255) - * @param {number} g - 绿色分量(0-255) - * @param {number} b - 蓝色分量(0-255) - * @returns {string} - 16进制表示的颜色字符串,以"#"开头 - */ -export const Rgb2Hex = (r, g, b) => { - // 将每个分量转换为16进制,并确保每个分量都有两位 - const hexR = (r < 16 ? "0" : "") + r.toString(16); - const hexG = (g < 16 ? "0" : "") + g.toString(16); - const hexB = (b < 16 ? "0" : "") + b.toString(16); - // 使用"#"开头并拼接红色、绿色和蓝色的16进制值 - return `#${hexR}${hexG}${hexB}`; -}; diff --git a/src/utils/color.ts b/src/utils/color.ts new file mode 100644 index 0000000..7775c49 --- /dev/null +++ b/src/utils/color.ts @@ -0,0 +1,153 @@ +import type { CoverColors } from "@/types/main"; +import { + themeFromSourceColor, + QuantizerCelebi, + Hct, + Score, +} from "@material/material-color-utilities"; +import { getMDColor, rgbToHex } from "@imsyy/color-utils"; +import { useSettingStore } from "@/stores"; +import { argbToRgb } from "./helper"; +import { chunk } from "lodash-es"; + +/** + * 主色以 RGB 格式返回 + * @param {number} argb - 表示颜色的 ARGB 格式整数 + */ +const getAccentColor = (argb: number) => { + // 将 ARGB 转换为 RGB + const [r, g, b] = [...argbToRgb(argb)]; + // 返回 rgb + return { r, g, b }; +}; + +// 修改全局颜色 +export const setGlobalColor = (name: string, colorValue: string): void => { + if (!name.startsWith("--")) { + throw new Error("Variable name must start with '--'"); + } + const root = document.body; + // const root = document.documentElement; + // 检查变量是否已经存在 + const existingValue = getComputedStyle(root).getPropertyValue(name).trim(); + if (existingValue === colorValue) return; + // 设置变量 + root.style.setProperty(name, colorValue); +}; + +// 设置动态配色 +export const setColorSchemes = ( + color: string | CoverColors, + // 明暗模式 + mode: "dark" | "light", +): { [key: string]: string } => { + const settingStore = useSettingStore(); + const colorData = typeof color === "string" ? getMDColor(color) : color; + if (!colorData) throw new Error("Color data not found"); + // 指定模式颜色数据 + const colorModeData = colorData[mode]; + const modifiedColorModeData: { [key: string]: string } = {}; + // 是否全局应用 + if (!settingStore.themeGlobalColor && colorModeData) { + // 修改关键颜色 + colorModeData.background = + mode === "dark" ? { r: 16, g: 16, b: 20 } : { r: 239, g: 239, b: 239 }; + colorModeData["surface-container"] = + mode === "dark" ? { r: 24, g: 24, b: 28 } : { r: 255, g: 255, b: 255 }; + console.log(colorModeData); + } + // 遍历颜色并修改 + for (const key in colorModeData) { + const color = colorModeData[key]; + if (typeof color === "object" && "r" in color && "g" in color && "b" in color) { + const hexValue = rgbToHex(color.r, color.g, color.b); + // 修改后的颜色值存储在新的对象中 + modifiedColorModeData[`${key}-hex`] = hexValue; + modifiedColorModeData[key] = `${color.r}, ${color.g}, ${color.b}`; + // 设置样式 + setGlobalColor(`--${key}`, `${color.r}, ${color.g}, ${color.b}`); + setGlobalColor(`--${key}-hex`, hexValue); + } else { + console.error(`Invalid color data for key: ${key}`); + } + } + return modifiedColorModeData; +}; + +// 获取封面主题 +export const getCoverColorData = (dom: HTMLImageElement) => { + if (!dom) return null; + // canvas + const canvas = document.createElement("canvas"); + canvas.width = 50; + canvas.height = 50; + // 获取 50x50 大小的图像颜色数据 + const ctx = canvas.getContext("2d"); + if (!ctx) return null; + ctx.drawImage(dom, 0, 0, dom.naturalWidth, dom.naturalHeight, 0, 0, 50, 50); + const pixels = chunk(ctx.getImageData(0, 0, 50, 50).data, 4).map((pixel) => { + // 将颜色数据转换为整数表示 + return ( + (((pixel[3] << 24) >>> 0) | ((pixel[0] << 16) >>> 0) | ((pixel[1] << 8) >>> 0) | pixel[2]) >>> + 0 + ); + }); + // 使用 QuantizerCelebi 进行颜色量化 + const quantizedColors = QuantizerCelebi.quantize(pixels, 128); + const sortedQuantizedColors = Array.from(quantizedColors).sort((a, b) => b[1] - a[1]); + // 获取最频繁的颜色,并转换为 RGB 格式 + const mostFrequentColors = sortedQuantizedColors.slice(0, 5).map((x) => argbToRgb(x[0])); + // 如果最频繁的颜色差异很小,使用灰色强调色 + if (mostFrequentColors.every((x) => Math.max(...x) - Math.min(...x) < 5)) { + console.log("该封面颜色单调"); + return { + main: { r: 239, g: 239, b: 239 }, + light: { + primary: { r: 10, g: 10, b: 10 }, + background: { r: 238, g: 238, b: 238 }, + "surface-container": { r: 212, g: 212, b: 212 }, + }, + dark: { + primary: { r: 239, g: 239, b: 239 }, + background: { r: 31, g: 31, b: 31 }, + "surface-container": { r: 39, g: 39, b: 39 }, + }, + }; + } + // 使用 Score 库对颜色进行评分 + const ranked = Score.score(new Map(sortedQuantizedColors.slice(0, 50))); + const topColor = ranked[0]; + const theme = themeFromSourceColor(topColor); + // 颜色主题 + const variant = "secondary"; + // 移除 canvas + canvas.remove(); + // 返回主题 + return { + main: getAccentColor( + Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 90).toInt(), + ), + light: { + primary: getAccentColor( + Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 10).toInt(), + ), + background: getAccentColor( + Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 94).toInt(), + ), + "surface-container": getAccentColor( + Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 90).toInt(), + ), + }, + dark: { + primary: getAccentColor( + Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 90).toInt(), + ), + background: getAccentColor( + Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 20).toInt(), + ), + "surface-container": getAccentColor( + Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 16).toInt(), + ), + }, + }; +}; diff --git a/src/utils/cookie.ts b/src/utils/cookie.ts new file mode 100644 index 0000000..5ec7e22 --- /dev/null +++ b/src/utils/cookie.ts @@ -0,0 +1,26 @@ +import Cookies from "js-cookie"; + +// 获取 Cookie +export const getCookie = (key: string) => { + return Cookies.get(key) ?? localStorage.getItem(`cookie-${key}`); +}; + +// 移除 Cookie +export const removeCookie = (key: string) => { + Cookies.remove(key); + localStorage.removeItem(`cookie-${key}`); +}; + +// 设置 Cookie +export const setCookies = (cookieValue: string) => { + const cookies = cookieValue.split(";;"); + cookies.forEach((cookie) => { + document.cookie = cookie; + const cookieParts = cookie.split(";"); + const nameValuePair = cookieParts[0].split("="); + const name = nameValuePair[0].trim(); + const value = nameValuePair[1].trim(); + // 保存 cookie + localStorage.setItem(`cookie-${name}`, value); + }); +}; diff --git a/src/utils/cover-color.js b/src/utils/cover-color.js deleted file mode 100644 index e9bc207..0000000 --- a/src/utils/cover-color.js +++ /dev/null @@ -1,161 +0,0 @@ -import { - themeFromSourceColor, - QuantizerCelebi, - Hct, - Score, -} from "@material/material-color-utilities"; -import { siteSettings, siteStatus } from "@/stores"; -import { getGradientFromPalette, argb2Rgb, rgb2Argb } from "@/utils/color-utils"; -import { chunk } from "@/utils/helper"; -import ColorThief from "colorthief"; - -/** - * 根据图像的主色获取渐变色 - * @param {string} coverSrc - 图片 URL - * @returns {string} - 生成的渐变色 - */ -export const getCoverGradient = (coverSrc) => { - return new Promise((resolve, reject) => { - try { - const colorThief = new ColorThief(); - // 创建图像元素 - const image = new Image(); - image.crossOrigin = "Anonymous"; - image.src = coverSrc; - // 图像加载完成 - image.onload = async () => { - // 获取渐变色 - const palette = await colorThief.getPalette(image); - const gradient = getGradientFromPalette(palette); - console.log("图片加载完成:", gradient); - // 获取图片主色 - calcAccentColor(image); - resolve(gradient); - }; - } catch (error) { - console.error("图片渐变色生成失败:", error); - reject("linear-gradient(-45deg, #666, #fff)"); - } - }); -}; - -/** - * 从图像中计算强调色并更新页面主题 - * @param {HTMLImageElement} dom - 包含图像的 DOM 元素 - */ -const calcAccentColor = (dom) => { - // pinia - const status = siteStatus(); - const settings = siteSettings(); - // 创建一个用于提取颜色的 canvas - const canvas = document.createElement("canvas"); - canvas.width = 50; - canvas.height = 50; - // 获取 50x50 大小的图像颜色数据 - const ctx = canvas.getContext("2d"); - ctx.drawImage(dom, 0, 0, dom.naturalWidth, dom.naturalHeight, 0, 0, 50, 50); - const pixels = chunk(ctx.getImageData(0, 0, 50, 50).data, 4).map((pixel) => { - // 将颜色数据转换为整数表示 - return ( - (((pixel[3] << 24) >>> 0) | ((pixel[0] << 16) >>> 0) | ((pixel[1] << 8) >>> 0) | pixel[2]) >>> - 0 - ); - }); - // 使用 QuantizerCelebi 库进行颜色量化 - const quantizedColors = QuantizerCelebi.quantize(pixels, 128); - const sortedQuantizedColors = Array.from(quantizedColors).sort((a, b) => b[1] - a[1]); - // 获取最频繁的颜色,并转换为 RGB 格式 - const mostFrequentColors = sortedQuantizedColors.slice(0, 5).map((x) => argb2Rgb(x[0])); - // 如果最频繁的颜色差异很小,使用灰色强调色 - if (mostFrequentColors.every((x) => Math.max(...x) - Math.min(...x) < 5)) { - console.log("封面单调"); - useGreyAccentColor(); - return true; - } - // 使用 Score 库对颜色进行评分 - const ranked = Score.score(new Map(sortedQuantizedColors.slice(0, 50))); - const top = ranked[0]; - const theme = themeFromSourceColor(top); - // 错误 error, 中性 neutral, 中性的变体 neutralVariant, 主要的 primary, 二次 secondary, 三级 tertiary - const variant = settings.themeAutoCoverType; - // 更新主题色 - status.coverTheme = { - dark: { - dark: getAccentColor(theme.schemes.dark[variant]), - primary: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 100).toInt(), - ), - shade: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 25).toInt(), - ), - shadeTwo: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 15).toInt(), - ), - bg: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 90).toInt(), - ), - mainBg: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 10).toInt(), - ), - }, - light: { - light: getAccentColor(theme.schemes.light[variant]), - primary: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 20).toInt(), - ), - shade: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 80).toInt(), - ), - shadeTwo: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 90).toInt(), - ), - bg: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 20).toInt(), - ), - mainBg: getAccentColor( - Hct.from(theme.palettes[variant].hue, theme.palettes[variant].chroma, 100).toInt(), - ), - }, - }; - // 尝试更新主题色 - if (typeof $changeThemeColor !== "undefined" && settings.themeAutoCover) { - $changeThemeColor(status.coverTheme, settings.themeAutoCover); - } -}; - -/** - * 使用灰色强调色更新页面主题 - */ -const useGreyAccentColor = () => { - // pinia - const status = siteStatus(); - status.coverTheme = { - dark: { - dark: getAccentColor(rgb2Argb(120, 120, 120)), - primary: getAccentColor(rgb2Argb(250, 250, 250)), - shade: getAccentColor(rgb2Argb(40, 40, 40)), - shadeTwo: getAccentColor(rgb2Argb(20, 20, 20)), - bg: getAccentColor(rgb2Argb(190, 190, 190)), - mainBg: getAccentColor(rgb2Argb(16, 16, 20)), - }, - light: { - light: getAccentColor(rgb2Argb(150, 150, 150)), - primary: getAccentColor(rgb2Argb(10, 10, 10)), - shade: getAccentColor(rgb2Argb(210, 210, 210)), - shadeTwo: getAccentColor(rgb2Argb(255, 255, 255)), - bg: getAccentColor(rgb2Argb(24, 24, 28)), - mainBg: getAccentColor(rgb2Argb(11, 11, 11)), - }, - }; -}; - -/** - * 主色以 RGB 格式返回 - * @param {number} argb - 表示颜色的 ARGB 格式整数 - */ -const getAccentColor = (argb) => { - // 将 ARGB 转换为 RGB - const [r, g, b] = [...argb2Rgb(argb)]; - // 返回 rgb - return `${r}, ${g}, ${b}`; -}; diff --git a/src/utils/debounce.js b/src/utils/debounce.js deleted file mode 100644 index 03314f1..0000000 --- a/src/utils/debounce.js +++ /dev/null @@ -1,34 +0,0 @@ -/** - * 防抖函数 - * @param {Function} func - 要进行防抖处理的函数 - * @param {number} delay - 延迟时间,单位毫秒 - * @param {string} errorMessage - 重复触发时的提醒消息 - * @returns {Function} - 返回一个新的函数,该函数在指定的时间间隔内最多只会执行一次 - */ -const debounce = (func, delay, errorMessage) => { - let timerId; - let lastCallTime = 0; - - // 返回一个新的函数 - return (...args) => { - const currentTime = Date.now(); - const elapsed = currentTime - lastCallTime; - - // 如果两次触发时间间隔小于 delay,弹出提醒 - if (elapsed < delay && errorMessage) { - $message.warning(errorMessage); - return; - } - - // 清除上一个定时器 - clearTimeout(timerId); - - // 设置新的定时器,在指定的延迟时间后执行函数 - timerId = setTimeout(() => { - func.apply(this, args); - lastCallTime = Date.now(); - }, delay); - }; -}; - -export default debounce; diff --git a/src/utils/fluidBackground.ts b/src/utils/fluidBackground.ts new file mode 100644 index 0000000..13c0c1c --- /dev/null +++ b/src/utils/fluidBackground.ts @@ -0,0 +1,195 @@ +import type { RGB } from "@/types/main"; + +// 配置选项 +interface FluidBackgroundType { + canvas: HTMLCanvasElement; + colors?: RGB[]; + totalParticles?: number; + maxRadius?: number; + minRadius?: number; + speed?: number; +} + +// App 类,负责管理整个画布和动画的主逻辑 +export class FluidBackground { + private canvas: HTMLCanvasElement; + private ctx: CanvasRenderingContext2D; + private pixelRatio: number; + private colors: RGB[]; + private totalParticles: number; + private maxRadius: number; + private minRadius: number; + private speed: number; + private particles: GlowParticle[]; + private stageWidth!: number; + private stageHeight!: number; + + constructor({ + canvas, + colors, + totalParticles, + maxRadius, + minRadius, + speed, + }: FluidBackgroundType) { + // 使用传入的 canvas 元素 + this.canvas = canvas; + + // 获取 2D 绘图上下文 + this.ctx = this.canvas.getContext("2d")!; + + // 根据设备像素比设置比例,处理高清屏幕的显示问题 + this.pixelRatio = window.devicePixelRatio > 1 ? 2 : 1; + + // 设置颜色数组,粒子的颜色将从这个数组中选择 + this.colors = colors || [ + { r: 45, g: 74, b: 227 }, + { r: 250, g: 255, b: 89 }, + { r: 255, g: 104, b: 248 }, + { r: 44, g: 209, b: 252 }, + { r: 54, g: 233, b: 84 }, + ]; + + // 设置色块球的数量,默认值为 15 + this.totalParticles = totalParticles || 15; + + // 设置色块球的最大和最小半径,默认值分别为 200 和 150 + this.maxRadius = maxRadius || 200; + this.minRadius = minRadius || 150; + + // 设置色块球的运动速度,默认值为 2 + this.speed = speed || 2; + + // 保存色块球的数组 + this.particles = []; + + // 监听窗口大小变化,调整画布尺寸 + window.addEventListener("resize", this.resize.bind(this), false); + + // 初始化画布大小和色块球 + this.resize(); + + // 启动动画 + this.animate(); + } + + // 处理画布大小调整的方法 + private resize() { + // 获取当前窗口的宽度和高度 + this.stageWidth = window.innerWidth; + this.stageHeight = window.innerHeight; + + // 设置画布的宽度和高度,并根据设备像素比进行缩放 + this.canvas.width = this.stageWidth * this.pixelRatio; + this.canvas.height = this.stageHeight * this.pixelRatio; + this.ctx.scale(this.pixelRatio, this.pixelRatio); + + // 设置混合模式,使色块球重叠时产生更丰富的颜色效果 + this.ctx.globalCompositeOperation = "saturation"; + + // 创建色块球 + this.createParticles(); + } + + // 创建色块球的逻辑 + private createParticles() { + let curColor = 0; + this.particles = []; // 清空粒子数组 + for (let i = 0; i < this.totalParticles; i++) { + // 随机生成色块球的初始位置和半径 + this.particles.push( + new GlowParticle( + Math.random() * this.stageWidth, // 随机生成 X 位置 + Math.random() * this.stageHeight, // 随机生成 Y 位置 + Math.random() * (this.maxRadius - this.minRadius) + this.minRadius, // 随机生成半径 + this.colors[curColor % this.colors.length], // 循环选择颜色 + this.speed, // 传递速度 + ), + ); + curColor++; // 颜色索引递增 + } + } + + // 动画帧渲染方法 + private animate() { + // 使用 requestAnimationFrame 来创建动画循环 + window.requestAnimationFrame(this.animate.bind(this)); + + // 清除画布上的内容 + this.ctx.clearRect(0, 0, this.stageWidth, this.stageHeight); + + // 遍历每个色块球并调用其 animate 方法进行绘制和更新位置 + for (let i = 0; i < this.totalParticles; i++) { + const item = this.particles[i]; + item.animate(this.ctx, this.stageWidth, this.stageHeight); + } + } +} + +// GlowParticle 类,表示单个色块球 +class GlowParticle { + private x: number; + private y: number; + private radius: number; + private rgb: RGB; + private vx: number; + private vy: number; + private sinValue: number; + + constructor(x: number, y: number, radius: number, rgb: RGB, speed: number) { + this.x = x; // 初始 X 位置 + this.y = y; // 初始 Y 位置 + this.radius = radius; // 半径 + this.rgb = rgb; // 颜色对象 {r, g, b} + this.vx = Math.random() * speed; // 随机生成 X 方向的速度 + this.vy = Math.random() * speed; // 随机生成 Y 方向的速度 + this.sinValue = Math.random(); // 用于控制半径变化的正弦值 + } + + // 动画方法,更新位置和绘制色块球 + animate(ctx: CanvasRenderingContext2D, stageWidth: number, stageHeight: number) { + // 更新正弦值,使色块球的半径产生波动效果 + this.sinValue += 0.01; + this.radius += Math.sin(this.sinValue); // 半径在正弦波动下变化 + + // 更新 X 和 Y 位置 + this.x += this.vx; + this.y += this.vy; + + // 边界检测,如果超出画布边界则反向运动 + if (this.x < -10 || this.x > stageWidth + 10) { + this.vx *= -1; + } + if (this.y < -10 || this.y > stageHeight + 10) { + this.vy *= -1; + } + + // 开始绘制色块球 + ctx.beginPath(); + + // 创建径向渐变,用于色块球的颜色过渡效果 + const g = ctx.createRadialGradient( + this.x, + this.y, + this.radius * 0.01, // 渐变起始半径 + this.x, + this.y, + this.radius, // 渐变结束半径 + ); + + // 定义渐变颜色的起始点和结束点 + g.addColorStop(0, `rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b},1)`); + g.addColorStop(1, `rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b},0)`); + + // 设置填充样式为渐变 + ctx.fillStyle = g; + + // 画一个圆,表示色块球 + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, false); + + // 填充圆形 + ctx.fill(); + } +} + +export default FluidBackground; diff --git a/src/utils/formRules.js b/src/utils/formRules.js deleted file mode 100644 index a39038b..0000000 --- a/src/utils/formRules.js +++ /dev/null @@ -1,51 +0,0 @@ -// 表单规则 -const formRules = () => { - return { - // 普通验证 - textRule: { - required: true, - message: "请填写必要信息", - trigger: "blur", - }, - // 数字验证 - numberRule: { - type: "number", - required: true, - message: "请填写必要信息", - trigger: "blur", - }, - // 邮箱验证 - emailRule: { - required: true, - validator(_, value) { - if (!value) { - return new Error("请输入电子邮箱"); - } else if ( - !/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( - value, - ) - ) { - return new Error("请输入正确的电子邮箱"); - } - return true; - }, - trigger: ["input", "blur"], - }, - // 手机号验证 - mobileRule: { - key: "phone", - required: true, - validator(_, value) { - if (!value) { - return new Error("请输入手机号码"); - } else if (!/^(?:(?:\+|00)86)?1[3-9]\d{9}$/.test(value)) { - return new Error("请输入正确的手机号码"); - } - return true; - }, - trigger: ["input", "blur"], - }, - }; -}; - -export { formRules }; diff --git a/src/utils/format.ts b/src/utils/format.ts new file mode 100644 index 0000000..20d2c43 --- /dev/null +++ b/src/utils/format.ts @@ -0,0 +1,237 @@ +import type { SongType, CoverType, ArtistType, CommentType, MetaData, CatType } from "@/types/main"; +import { msToTime } from "./time"; +import { isArray } from "lodash-es"; + +type CoverDataType = { + cover: string; + coverSize?: { + s: string; + m: string; + l: string; + xl: string; + }; +}; + +// 格式化歌曲列表 +export const formatSongsList = (data: any[]): SongType[] => { + if (!data) return []; + data = isArray(data) ? data : [data]; + return data.map((item) => { + // 特殊处理 + item = item?.simpleSong ? { ...item.simpleSong, pc: true } : item?.songInfo || item; + // 歌手数据 + const artist = (): MetaData[] | string => { + const artistData = item.artist ?? item.artists ?? item.ar; + if (!artistData) return ""; + if (typeof artistData === "string") return artistData; + const artistArr = [item.artist, item.artists, item.ar].flat().filter(Boolean); + if (!artistArr.length) return ""; + return artistArr.map((ar) => ({ + id: ar?.id, + name: typeof ar === "string" ? ar : ar.name, + cover: ar?.img1v1Url || ar?.picUrl, + alias: ar?.alias, + })); + }; + return { + id: item.id, + name: item.name, + artists: artist(), + album: + typeof item.album === "string" + ? item.album + : { + id: (item.album || item.al)?.id, + name: (item.album || item.al)?.name, + cover: (item.album || item.al)?.picUrl, + }, + alia: isArray(item.alia || item.alias || item.transNames) + ? item.alia?.[0] || item.alias?.[0] || item.transNames?.[0] + : item.alia, + dj: item.dj + ? { + id: item.mainTrackId || item.id, + name: item.dj?.brand, + creator: item.dj?.nickname, + } + : undefined, + ...getCoverUrl(item), + duration: Number(item.duration || item.dt || 0), + originCoverType: item?.originCoverType, + free: item.fee || 0, + mv: item.mv, + size: Number(item.size || 0), + path: item.path, + pc: !!item.pc, + quality: item?.quality, + playCount: Number(item.playCount || item.listenerCount || 0), + createTime: Number(item.createTime || item.publishTime) || undefined, + updateTime: Number(item.lastProgramCreateTime || item.scheduledPublishTime) || undefined, + type: item?.dj ? "radio" : "song", + }; + }); +}; + +// 格式化封面列表 +export const formatCoverList = (data: any[]): CoverType[] => { + if (!data) return []; + data = isArray(data) ? data : [data]; + return data.map((item) => { + // 处理数据 + const creator = isArray(item.creator) ? item.creator[0] : item.creator; + // 获取歌手信息 + const artists = (): string | MetaData[] => { + const artistData = [item.artist, item.artists, item.ar].flat().filter(Boolean); + if (artistData.length === 0) return ""; + return artistData.map((artist) => ({ + id: artist?.id, + name: artist?.name, + cover: artist?.img1v1Url || artist?.picUrl, + alias: artist?.alias, + })); + }; + return { + id: item.id || item.vid, + name: item.name || item.title, + ...getCoverUrl(item), + description: item.description || item.desc, + updateTip: item.updateFrequency, + creator: { + id: creator?.userId || item.dj?.userId || 0, + name: creator?.nickname || creator?.name || creator?.userName || item.dj?.nickname || "", + avatarUrl: creator?.avatarUrl || item.dj?.avatarUrl || "", + }, + artists: artists(), + count: item.trackCount ?? item.size ?? item.programCount ?? 0, + tags: + item.tags || + item.algTags || + item.videoGroup?.map((tag: any) => tag.name) || + (item.category ? [item.category] : []), + userId: item.userId, + playCount: item.playCount, + commentCount: item.commentCount, + shareCount: item.shareCount, + subCount: item.subCount, + privacy: item.privacy, + liked: item.liked, + likedCount: item.likedCount, + duration: msToTime(item.duration || item.dt || item.playTime), + createTime: item.createTime || item.publishTime, + updateTime: item.updateTime || item.trackNumberUpdateTime, + // 热榜特殊数据 + tracks: item.tracks, + }; + }); +}; + +// 格式化歌手列表 +export const formatArtistsList = (data: any[]): ArtistType[] => { + if (!data) return []; + data = isArray(data) ? data : [data]; + return data.map((item) => ({ + id: item.id, + name: item.name, + ...getCoverUrl(item), + alia: item.alias?.[0], + identify: item?.identifyTag?.[0], + description: item.description || item.briefDesc, + albumSize: item.albumSize, + musicSize: item.musicSize, + mvSize: item.mvSize, + fansSize: item.fans, + })); +}; + +// 格式化评论列表 +export const formatCommentList = (data: any[]): CommentType[] => { + data = isArray(data) ? data : [data]; + return data.map((item) => ({ + id: item.commentId, + content: item.content, + beReplied: + item.beReplied?.length > 0 + ? { + content: item.beReplied[0]?.content, + user: { + id: item.beReplied[0]?.user.userId, + name: item.beReplied[0]?.user.nickname, + avatarUrl: item.beReplied[0]?.user.avatarUrl, + }, + } + : undefined, + time: item.time, + likedCount: item.likedCount, + liked: item.liked, + user: { + id: item.user.userId, + name: item.user.nickname, + avatarUrl: item.user.avatarUrl, + vipType: item.user.vipType, + vipLevel: item.user.vipRights?.redVipLevel, + vipIconUrl: item.user.vipRights?.associator?.iconUrl, + isAnnualCount: item.user.vipRights?.redVipAnnualCount > 0, + }, + ip: item?.ip + ? { + ip: item.ip, + location: item.location, + } + : undefined, + })); +}; + +// 格式化分类列表 +export const formatCategoryList = (data: any[]): CatType[] => { + data = isArray(data) ? data : [data]; + return data.map((item) => ({ + name: item.name, + category: item.category, + hot: item.hot, + count: item.resourceCount, + })); +}; + +// 获取图片的 url +const getCoverUrl = (item: any): CoverDataType => { + const cover = + item.cover || + item.picUrl || + item.coverUrl || + item.coverImgUrl || + item.imgurl || + item.img1v1Url || + (item.album || item.al)?.picUrl || + item.al?.xInfo?.picUrl; + const coverSize = { + s: getCoverSizeUrl(cover, 100), + m: getCoverSizeUrl(cover, 300), + l: getCoverSizeUrl(cover, 1024), + xl: getCoverSizeUrl(cover, 1920), + }; + return { cover, coverSize }; +}; + +// 获取图片不同尺寸 +const getCoverSizeUrl = (url: string, size: number | null = null) => { + try { + if (!url) return "/images/song.jpg?assest"; + const sizeUrl = size + ? typeof size === "number" + ? `?param=${size}y${size}` + : `?param=${size}` + : ""; + const imageUrl = url?.replace(/^http:/, "https:"); + if (imageUrl.endsWith(".jpg")) { + return imageUrl + sizeUrl; + } + if (imageUrl.endsWith("&")) { + const url = imageUrl + "cl"; + return url.replace(/(thumbnail=[0-9]+y[0-9]+&cl)/, `thumbnail=${size}y${size}&`); + } + return imageUrl; + } catch (error) { + console.error("图片链接处理出错:", error); + return "/images/song.jpg?assest"; + } +}; diff --git a/src/utils/formatData.js b/src/utils/formatData.js deleted file mode 100644 index bec10eb..0000000 --- a/src/utils/formatData.js +++ /dev/null @@ -1,165 +0,0 @@ -import { getSongTime } from "@/utils/timeTools"; - -/** - * 格式化原始数据 - * @param {Array} data - 必选参数,输入的原始数据 - * @param {String} type - 必选参数,格式化的类型 - * @return {string} 返回根据 type 参数生成的列表数据 - */ -const formatData = (data, type = "playlist", noTracks = false) => { - if (!data) return null; - // 若传入的是单个数据对象,转为数组 - const dataArray = Array.isArray(data) ? data : [data]; - // 遍历 - return dataArray.map((v) => { - // 特殊处理 - if (type === "song") v?.songInfo ? (v = v.songInfo) : v?.simpleSong ? (v = v.simpleSong) : v; - // 封面处理 - const imgUrl = - v && - (v.picUrl || - v.coverUrl || - v.coverImgUrl || - v.imgurl || - v.cover || - (v.album && v.album.picUrl) || - (v.al && (v.al.picUrl || v.al.xInfo?.picUrl))); - const cover = getCoverUrl(imgUrl); - const coverSize = { - s: getCoverUrl(imgUrl, 100), - m: getCoverUrl(imgUrl, 300), - l: getCoverUrl(imgUrl, 1024), - xl: getCoverUrl(imgUrl, 1920), - }; - // 类型判断 - switch (type) { - // 歌单 - case "playlist": - return { - id: v.id, - name: v.name, - cover, - coverSize, - count: v.trackCount, - creator: v.creator || v.updateFrequency, - tracks: noTracks ? null : v.tracks, - playCount: v.playCount, - createTime: v.createTime, - updateTime: v.updateTime || v.trackNumberUpdateTime, - description: v.description, - tags: v.tags || v.algTags, - userId: v.userId, - }; - // 歌曲 - case "song": - return { - id: v.id, - name: v.name, - artists: v.artists || v.ar, - album: v.album || v.al, - cover, - coverSize, - mv: v.mv, - alia: v.alia?.[0] || v.alias?.[0] || v.transNames?.[0], - fee: v.fee, - pc: v.pc, - size: v.size, - duration: getSongTime(v.duration || v.dt), - }; - // 歌手 - case "artist": - return { - id: v.id, - name: v.name, - description: v.briefDesc, - cover, - coverSize, - alias: v.alias, - size: { - music: v.musicSize, - album: v.albumSize, - mv: v.mvSize, - fans: v.fansCount, - }, - }; - // 专辑 - case "album": - return { - id: v.id, - name: v.name, - alia: v.alias?.[0], - cover, - coverSize, - artists: v.artists, - description: v.description, - publishTime: v.publishTime, - tags: v.tags || v.algTags, - count: v.size, - share: v.info?.shareCount, - }; - // mv - case "mv": - return { - id: v.id || v.vid, - name: v.name || v.title, - artists: v.artists || v.creator, - desc: v.copywriter, - cover, - coverSize: getCoverUrl(cover, "464y260"), - duration: v.duration || v.durationms, - playCount: v.playCount || v.playTime, - }; - // dj - case "dj": - return { - id: v.id || v.vid, - djId: v.mainTrackId || v.id, - name: v.name, - creator: v.dj, - count: v.programCount, - desc: v.copywriter || v.lastProgramName || v.desc, - cover, - coverSize, - tags: { id: v.categoryId, name: v.category }, - rcmdText: v.rcmdtext || v.rcmdText, - playCount: v.playCount || v.listenerCount, - createTime: v.createTime, - updateTime: v.lastProgramCreateTime || v.scheduledPublishTime, - duration: getSongTime(v.duration), - }; - default: - return null; - } - }); -}; - -/** - * 获取图片的 url - * @param {string} url - 必选参数,输入的原始图片 url - * @param {number} size - 可选参数,需要生成的图片尺寸,默认为 null - * @return {string} 返回根据 url 和 size 参数生成的图片 url - */ -const getCoverUrl = (url, size = null) => { - try { - if (!url) return "/imgs/pic/song.jpg?assest"; - const sizeUrl = size - ? typeof size === "number" - ? `?param=${size}y${size}` - : `?param=${size}` - : ""; - const imageUrl = url?.replace(/^http:/, "https:"); - if (imageUrl.endsWith(".jpg")) { - return imageUrl + sizeUrl; - } - if (imageUrl.endsWith("&")) { - const url = imageUrl + "cl"; - return url.replace(/(thumbnail=[0-9]+y[0-9]+&cl)/, `thumbnail=${size}y${size}&`); - } - return imageUrl; - } catch (error) { - console.error("图片链接处理出错:", error); - return "/imgs/pic/song.jpg?assest"; - } -}; - -export default formatData; diff --git a/src/utils/globalEvents.js b/src/utils/globalEvents.js deleted file mode 100644 index 67ded07..0000000 --- a/src/utils/globalEvents.js +++ /dev/null @@ -1,32 +0,0 @@ -import { checkPlatform } from "@/utils/helper"; -import { playOrPause, changePlayIndex } from "@/utils/Player"; -import { siteStatus } from "@/stores"; - -/** - * 全局事件 - * @param {import('vue-router').Router} router - router - */ -const globalEvents = (router) => { - if (!checkPlatform.electron()) return false; - // 显示播放器 - electron.ipcRenderer.on("showPlayer", () => { - const status = siteStatus(); - status.showFullPlayer = true; - }); - // 播放或暂停 - electron.ipcRenderer.on("playOrPause", () => { - playOrPause(); - }); - // 上一曲或下一曲 - electron.ipcRenderer.on("playNextOrPrev", (_, val) => { - changePlayIndex(val, true); - }); - // 全局设置 - electron.ipcRenderer.on("open-setting", () => { - if (router) router.push("/setting"); - const status = siteStatus(); - status.showFullPlayer = false; - }); -}; - -export default globalEvents; diff --git a/src/utils/globalShortcut.js b/src/utils/globalShortcut.js deleted file mode 100644 index af588e6..0000000 --- a/src/utils/globalShortcut.js +++ /dev/null @@ -1,36 +0,0 @@ -import { playOrPause, setVolume } from "@/utils/Player"; -import { siteStatus } from "@/stores"; - -/** - * 全局快捷键监听 - * @param {KeyboardEvent} e - 键盘事件对象 - * @param {import('vue-router').Router} router - router - * @returns {boolean} - 如果事件对象不存在,则返回false - */ -const globalShortcut = (e, router) => { - if (!e) return false; - - // 是否按下 Ctrl - if (!e.ctrlKey) return false; - e.preventDefault(); - e.stopPropagation(); - - // 播放或暂停 - if (e.code === "Space") { - if (e.target.tagName === "INPUT") return false; - if (router.currentRoute.value.name === "videos-player") return false; - playOrPause(); - } - - // 调整音量 - if (e.code === "ArrowUp" || e.code === "ArrowDown") { - const status = siteStatus(); - const volume = status.playVolume; - const delta = e.code === "ArrowUp" ? 0.1 : -0.1; - const newVolume = Math.min(1, Math.max(0, volume + delta)); - setVolume(newVolume); - status.playVolume = newVolume; - } -}; - -export default globalShortcut; diff --git a/src/utils/helper.js b/src/utils/helper.js deleted file mode 100644 index 976c0a7..0000000 --- a/src/utils/helper.js +++ /dev/null @@ -1,397 +0,0 @@ -// BlobUrl -let lastSongBlobUrl = null; -let lastCoverBlobUrl = null; -let lastDownloadBlobUrl = null; - -/** - * 判断当前运行环境 - */ -export const checkPlatform = { - electron: () => { - // return typeof electron !== "undefined"; - if (typeof process !== "undefined" && process.versions) { - return process.versions.electron ? true : false; - } - const userAgent = navigator.userAgent.toLowerCase(); - return userAgent.includes("electron"); - }, - macOS: () => { - if (!checkPlatform.electron()) return false; - return electron.process.platform === "darwin"; - }, - windows: () => { - if (!checkPlatform.electron()) return false; - return electron.process.platform === "win32"; - }, - linux: () => { - if (!checkPlatform.electron()) return false; - return electron.process.platform === "linux"; - }, -}; - -/** - * 引入 CSS - */ -export const loadCSS = (href) => { - const linkElement = document.createElement("link"); - linkElement.rel = "stylesheet"; - linkElement.href = href; - document.head.appendChild(linkElement); -}; - -/** - * 获取缓存数据或请求数据并进行缓存 - * @param {string} key - 缓存数据的键名 - * @param {number} time - 缓存的有效时间,以分钟为单位 - * @param {Function} request - 请求数据的函数,应返回 Promise - * @returns {Promise} 缓存数据或请求的数据 - */ -export const getCacheData = async (key, time, request, params) => { - try { - const storedData = sessionStorage.getItem(`${key}Data`); - const storedTimestamp = sessionStorage.getItem(`${key}Timestamp`); - if (storedData && storedTimestamp) { - const currentTime = new Date().getTime(); - const storedTime = parseInt(storedTimestamp, 10); - const elapsedTime = (currentTime - storedTime) / (1000 * 60); - if (elapsedTime <= time) { - console.log(`${key}Data` + " 触发缓存"); - return JSON.parse(storedData); - } - } - const data = params ? await request(params) : await request(); - const currentTime = new Date().getTime(); - if (data !== undefined) { - sessionStorage.setItem(`${key}Data`, JSON.stringify(data)); - sessionStorage.setItem(`${key}Timestamp`, currentTime.toString()); - } - return data; - } catch (error) { - console.error("缓存操作出错:", error); - throw error; - } -}; - -/** - * 获取本地音乐封面的 Blob URL - * @param {string} path - 音乐文件的路径 - * @returns {Promise} 返回封面的 Blob URL,如果没有封面数据则返回默认 URL - */ -export const getLocalCoverData = async (path, isAlbum = false) => { - try { - // 清理过期的 Blob 链接 - if (lastCoverBlobUrl) URL.revokeObjectURL(lastCoverBlobUrl); - const coverData = await electron.ipcRenderer.invoke("getMusicCover", path); - if (coverData) { - // 将 Uint8Array 数据转换为 Blob - const blob = new Blob([coverData.coverData], { type: `image/${coverData.coverFormat}` }); - // 生成Blob URL - lastCoverBlobUrl = URL.createObjectURL(blob); - return lastCoverBlobUrl; - } else { - // 如果没有封面数据 - return `/imgs/pic/${isAlbum ? "album" : "song"}.jpg?assest`; - } - } catch (error) { - console.error("获取本地音乐封面出错:", error); - throw error; - } -}; - -/** - * 内容复制 - */ -export const copyData = async (data, info) => { - try { - const isElectron = checkPlatform.electron(); - // electron - if (isElectron) { - const result = await electron.ipcRenderer.invoke("copyData", data); - result ? $message.success(`${info || "复制"}成功`) : $message.error(`${info || "复制"}失败`); - } - // 浏览器端 - else { - if (navigator.clipboard) { - try { - await navigator.clipboard.writeText(data); - $message.success(`${info || "复制"}成功`); - } catch (error) { - console.error("复制出错:", error); - $message.error("复制失败"); - } - } else { - // 如果浏览器不支持 navigator.clipboard - const textArea = document.createElement("textarea"); - textArea.value = data; - document.body.appendChild(textArea); - textArea.select(); - try { - const successful = document.execCommand("copy"); - successful - ? $message.success(`${info || "复制"}成功`) - : $message.error(`${info || "复制"}失败`); - } catch (err) { - console.error("复制出错:", err); - $message.error("复制失败"); - } finally { - document.body.removeChild(textArea); - } - } - } - } catch (error) { - console.error("复制出错:", error); - $message.error("复制出现错误,请重试"); - } -}; - -/** - * 过万/亿数字转化 - * @param {number} num 需要格式化的数字 - * @returns {string|number} 格式化后的字符串或原样返回的数字 - */ -export const formatNumber = (num) => { - const n = Number(num); - if (n === 0 || n < 10000) { - return n; - } else if (n < 100000000) { - const numString = (n / 10000).toFixed(1); - return numString.endsWith(".0") ? numString.slice(0, -2) + " 万" : numString + " 万"; - } else { - const numString = (n / 100000000).toFixed(1); - return numString.endsWith(".0") ? numString.slice(0, -2) + " 亿" : numString + " 亿"; - } -}; - -/** - * 将输入数组拆分成指定大小的块 - * @param {Array} input - 要拆分的数组 - * @param {number} size - 每个块的大小 - * @returns {Array} - 包含拆分块的数组 - */ -export const chunk = (input, size) => { - // 使用 reduce 方法迭代数组,arr 是累加器,item 是当前元素,idx 是当前元素的索引 - return input.reduce((arr, item, idx) => { - // 如果当前索引是块大小的倍数,创建一个新块并将当前元素放入 - return idx % size === 0 - ? [...arr, [item]] - : // 如果不是块的起始索引,将当前元素添加到最后一个块中 - [...arr.slice(0, -1), [...arr.slice(-1)[0], item]]; - }, []); -}; - -/** - * 将字符串转换为小驼峰形式(Camel Case) - * @param {string} str - 需要转换的字符串 - * @returns {string} - 转换后的小驼峰形式字符串 - */ -export const toCamelCase = (str) => { - // 使用正则表达式将字符串中每个单词的首字母大写 - return str.replace(/(\w)(\w*)/g, (_, firstChar, rest) => { - // 对第一个单词的首字母进行小写转换 - return firstChar.toLowerCase() + rest.toLowerCase(); - }); -}; - -/** - * 获取 localStorage 的存储信息,包括总容量、剩余容量和百分比 - * @returns {{total: string, free: string, percentageFree: string}} 存储信息对象 - */ -export const getLocalStorageInfo = () => { - /** @type {number} 总容量为 5MB */ - const totalSpace = 5 * 1024 * 1024; - /** @type {string} 用于测试的键名 */ - const testKey = "testData"; - /** @type {string} 用于测试的数据 */ - let testData = ""; - try { - // 尝试存储大量数据 - for (let i = 0; i < 1024 * 1024; i++) { - testData += "a"; - } - // 存储数据 - localStorage.setItem(testKey, testData); - // 获取存储后的数据大小 - const dataSize = localStorage.getItem(testKey).length; - // 计算剩余容量 - const freeSpace = totalSpace - dataSize; - // 计算剩余容量的百分比 - const percentageFree = (freeSpace / totalSpace) * 100; - // 删除测试数据 - localStorage.removeItem(testKey); - // 返回包含总容量、剩余容量和百分比的对象 - return { - total: (totalSpace / (1024 * 1024)).toFixed(2), - free: (freeSpace / (1024 * 1024)).toFixed(2), - percentageFree: percentageFree.toFixed(2) + "%", - }; - } catch (e) { - // 可能出现 QuotaExceededError 异常 - return { - total: (totalSpace / (1024 * 1024)).toFixed(2), - free: 0, - percentageFree: "0.00%", - }; - } -}; - -/** - * 模糊搜索 - * @param {string} keyword - 要搜索的关键词 - * @param {Array} array - 要搜索的对象数组 - * @returns {Array} - 包含关键词的对象数组 - */ -/** - * 模糊搜索工具函数(支持深度搜索) - * @param {string} keyword - 要搜索的关键词 - * @param {Array|Object} data - 要搜索的数据,可以是对象或对象数组 - * @returns {Array} - 包含关键词的对象数组 - */ -export const fuzzySearch = (keyword, data) => { - try { - /** - * 递归函数:遍历对象及其嵌套属性,过滤包含关键词的对象 - * @param {Object} obj - 要检查的对象 - * @returns {boolean} - 如果找到匹配的属性值,返回 true;否则返回 false - */ - const searchInObject = (obj) => { - for (const key in obj) { - if (Object.prototype.hasOwnProperty.call(obj, key)) { - const value = obj[key]; - // 如果属性值是对象,则递归调用 - if (typeof value === "object" && value !== null) { - if (searchInObject(value)) { - return true; - } - } - // 检查属性值是否是字符串并包含关键词 - if (value && typeof value === "string" && value.includes(keyword)) { - return true; - } - } - } - return false; - }; - if (!data) return []; - // 如果传入的是数组,遍历数组 - if (Array.isArray(data)) { - return data.filter(searchInObject); - } - // 如果传入的是对象,直接调用递归函数 - return searchInObject(data); - } catch (error) { - console.error("模糊搜索出现错误:", error); - return []; - } -}; - -/** - * 从文件名生成数字 ID - * @param {string} fileName - 文件名 - * @returns {number} - 生成的数字ID - */ -export const generateId = (fileName) => { - if (!fileName) return 1000000000; - // 将文件名转换为哈希值 - let hash = 0; - for (let i = 0; i < fileName.length; i++) { - hash = (hash << 5) - hash + fileName.charCodeAt(i); - } - // 将哈希值转换为正整数 - const numericId = Math.abs(hash % 10000000000); - return numericId; -}; - -/** - * 下载文件 - * @param {Object} data - 下载信息 - * @param {String} songName - 歌曲名称 - * @returns {number} - 生成的数字ID - */ -export const downloadFile = async (data, song, lyric, options) => { - try { - const isElectron = checkPlatform.electron(); - const songType = data.type.toLowerCase(); - // 歌曲名称 - const songName = - song.name + - "-" + - (Array.isArray(song.artists) - ? song.artists.map((ar) => ar.name).join("&") - : song.artists || "未知歌手"); - if (isElectron && options.path) { - console.log("开始下载:", data, song, songName, songType, options.path); - return await electron.ipcRenderer.invoke( - "downloadFile", - JSON.stringify({ - url: data?.url, - data: song, - lyric: lyric, - name: songName, - type: songType, - }), - JSON.stringify(options), - ); - } else { - // 清理过期的 Blob 链接 - if (lastDownloadBlobUrl) URL.revokeObjectURL(lastDownloadBlobUrl); - const songRes = await fetch(data?.url.replace(/^http:/, "https:")); - if (!songRes.ok) throw new Error("下载出错,请重试"); - const blob = await songRes.blob(); - lastDownloadBlobUrl = URL.createObjectURL(blob); - // 下载数据 - const a = document.createElement("a"); - a.href = lastDownloadBlobUrl; - a.download = `${songName}.${songType}`; - document.body.appendChild(a); - a.click(); - a.remove(); - return true; - } - } catch (error) { - console.error("下载出错:", error); - return false; - } -}; - -/** - * 将字节数格式化为可读的大小字符串。 - * @param {number} bytes - 要格式化的字节数 - * @param {number} [decimals=2] - 小数点位数 - * @returns {string} - 格式化后的大小字符串("10 KB") - */ -export const formatBytes = (bytes, decimals = 2) => { - if (bytes === 0) return "0 K"; - const k = 1024; - const dm = decimals < 0 ? 0 : decimals; - const sizes = ["K", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - const i = Math.floor(Math.log(bytes) / Math.log(k)); - return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i]; -}; - -/** - * 获取音频文件的 Blob 链接 - * @param {string} url - 音频文件的网络链接 - */ -export const getBlobUrlFromUrl = async (url) => { - try { - // 清理过期的 Blob 链接 - if (lastSongBlobUrl) URL.revokeObjectURL(lastSongBlobUrl); - // 是否为网络链接 - if (!url.startsWith("http://") && !url.startsWith("https://") && !url.startsWith("blob:")) { - return url; - } - // 获取音频文件数据 - const response = await fetch(url); - // 检查请求是否成功 - if (!response.ok) { - throw new Error("获取音频资源失败:", response.statusText); - } - const blob = await response.blob(); - // 转换为本地 Blob 链接 - lastSongBlobUrl = URL.createObjectURL(blob); - return lastSongBlobUrl; - } catch (error) { - console.error("获取 Blob 链接遇到错误:" + error); - throw error; - } -}; diff --git a/src/utils/helper.ts b/src/utils/helper.ts new file mode 100644 index 0000000..0db8b9b --- /dev/null +++ b/src/utils/helper.ts @@ -0,0 +1,277 @@ +import { type ImageRenderToolbarProps, NTooltip, SelectOption } from "naive-ui"; +import type { SongType, UpdateLogType } from "@/types/main"; +import { h, VNode } from "vue"; +import { useClipboard } from "@vueuse/core"; +import { getCacheData } from "./cache"; +import { updateLog } from "@/api/other"; +import { marked } from "marked"; +import SvgIcon from "@/components/Global/SvgIcon.vue"; + +type AnyObject = { [key: string]: any }; + +// 必要数据 +let imageBlobURL: string = ""; + +// 环境判断 +export const isDev = import.meta.env.MODE === "development" || import.meta.env.DEV; + +// 系统判断 +const userAgent = window.navigator.userAgent; +export const isWin = userAgent.includes("Windows"); +export const isMac = userAgent.includes("Macintosh"); +export const isLinux = userAgent.includes("Linux"); +export const isElectron = userAgent.includes("Electron"); + +// 链接跳转 +export const openLink = (url: string, target: "_self" | "_blank" = "_blank") => { + window.open(url, target); +}; + +// 图标渲染 +export const renderIcon = ( + iconName: string, + option: { + size?: number; + style?: AnyObject; + } = {}, +) => { + const { size, style } = option; + return () => { + return h(SvgIcon, { name: iconName, size, style }); + }; +}; + +/** + * 延时函数 + * @param ms 延时时间(毫秒) + */ +export const sleep = (ms: number): Promise => { + return new Promise((resolve) => setTimeout(resolve, ms)); +}; + +// 选项渲染 +export const renderOption = ({ node, option }: { node: VNode; option: SelectOption }) => + h( + NTooltip, + { placement: "left" }, + { + trigger: () => node, + default: () => option.label, + }, + ); + +// 排序选项 +export const sortOptions = { + default: { name: "默认排序", show: "all", icon: renderIcon("Sort") }, + titleAZ: { name: "标题升序( A - Z )", show: "all", icon: renderIcon("SortAZ") }, + titleZA: { name: "标题降序( Z - A )", show: "all", icon: renderIcon("SortZA") }, + arAZ: { name: "歌手升序( A - Z )", show: "song", icon: renderIcon("SortAZ") }, + arZA: { name: "歌手降序( Z - A )", show: "song", icon: renderIcon("SortZA") }, + timeUp: { name: "时长升序", show: "all", icon: renderIcon("SortClockUp") }, + timeDown: { name: "时长降序", show: "all", icon: renderIcon("SortClockDown") }, + dateUp: { name: "日期升序", show: "radio", icon: renderIcon("SortDateUp") }, + dateDown: { name: "日期降序", show: "radio", icon: renderIcon("SortDateDown") }, +}; + +// 模糊搜索 +export const fuzzySearch = (keyword: string, data: SongType[]): SongType[] => { + try { + const result: SongType[] = []; + const regex = new RegExp(keyword, "i"); + + /** + * 递归函数:遍历对象及其嵌套属性,过滤包含关键词的对象 + * @param {Object} obj - 要检查的对象 + * @returns {boolean} - 如果找到匹配的属性值,返回 true;否则返回 false + */ + const searchInObject = (obj: AnyObject): boolean => { + for (const key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + const value = obj[key]; + // 如果属性值是对象,则递归调用 + if (typeof value === "object" && value !== null) { + if (searchInObject(value)) { + return true; + } + } + // 检查属性值是否是字符串并包含关键词 + if (value && typeof value === "string" && regex.test(value)) { + return true; + } + } + } + return false; + }; + + if (!data) return []; + + // 如果传入的是数组,遍历数组 + if (Array.isArray(data)) { + for (const item of data) { + if (searchInObject(item)) { + result.push(item); + } + } + } else { + // 如果传入的是对象,直接调用递归函数 + if (searchInObject(data)) { + result.push(data); + } + } + + return result; + } catch (error) { + console.error("模糊搜索出现错误:", error); + return []; + } +}; + +/** + * 将 32 位 ARGB 颜色值转换为 24 位 RGB 颜色值 + * + * @param {number} x - 32位ARGB颜色值 + * @returns {number[]} - 包含红色、绿色和蓝色分量的24位RGB颜色值数组(0-255) + */ +export const argbToRgb = (x: number): number[] => { + // 提取红色、绿色和蓝色分量 + const r = (x >> 16) & 0xff; + const g = (x >> 8) & 0xff; + const b = x & 0xff; + // 返回24位RGB颜色值数组 + return [r, g, b]; +}; + +// 封面加载完成 +export const coverLoaded = (e: Event) => { + const target = e.target as HTMLElement | null; + if (target && target.nodeType === Node.ELEMENT_NODE) { + target.style.opacity = "1"; + } +}; + +// 数字处理 +export const formatNumber = (num: number): string => { + if (num < 10000) { + return num.toString(); + } else if (num < 100000000) { + return `${(num / 10000).toFixed(1)}万`; + } else { + return `${(num / 100000000).toFixed(1)}亿`; + } +}; + +// 文件大小处理 +export const formatFileSize = (bytes: number): string => { + if (bytes < 1024) { + return `${bytes} B`; + } else if (bytes < 1024 * 1024) { + return `${(bytes / 1024).toFixed(1)} KB`; + } else if (bytes < 1024 * 1024 * 1024) { + return `${(bytes / 1024 / 1024).toFixed(1)} MB`; + } else { + return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GB`; + } +}; + +// 将图片链接转为 BlobUrl +export const convertImageUrlToBlobUrl = async (imageUrl: string) => { + const response = await fetch(imageUrl); + if (!response.ok) { + throw new Error("Network response was not ok"); + } + // 将响应数据转换为 Blob 对象 + const blob = await response.blob(); + // 撤销之前生成的对象 URL + if (imageBlobURL) URL.revokeObjectURL(imageBlobURL); + // 生成对象 URL + imageBlobURL = URL.createObjectURL(blob); + return imageBlobURL; +}; + +// 自定义图片工具栏 +export const renderToolbar = ({ nodes }: ImageRenderToolbarProps) => { + return [ + nodes.prev, + nodes.next, + nodes.rotateCounterclockwise, + nodes.rotateClockwise, + nodes.resizeToOriginalSize, + nodes.zoomOut, + nodes.zoomIn, + nodes.close, + ]; +}; + +// 复制文本 +export const copyData = async (text: any, message?: string) => { + const { copy, copied, isSupported } = useClipboard({ legacy: true }); + if (!isSupported.value) { + window.$message.error("暂时无法使用复制功能"); + return; + } + // 开始复制 + try { + if (!text) return; + text = typeof text === "string" ? text.trim() : JSON.stringify(text, null, 2); + await copy(text); + if (copied.value) { + window.$message.success(message ?? "已复制到剪贴板"); + } else { + window.$message.error("复制出错,请重试"); + } + } catch (error) { + window.$message.error("复制出错,请重试"); + console.error("复制出错:", error); + } +}; + +// 获取剪贴板内容 +export const getClipboardData = async (): Promise => { + try { + const text = await navigator.clipboard.readText(); + return text; + } catch (error) { + console.error("Failed to read clipboard content:", error); + return null; + } +}; + +/** + * 格式化为 Electron 快捷键 + * @param shortcut 快捷键 + * @returns Accelerator + */ +export const formatForGlobalShortcut = (shortcut: string): string => { + return shortcut + .split("+") + .map((part) => { + // 字母 + if (part.startsWith("Key")) { + return part.replace("Key", ""); + } + // 数字 + if (part.startsWith("Digit")) { + return part.replace("Digit", "num"); + } + if (part.startsWith("Numpad")) { + return part.replace("Numpad", "num"); + } + // 方向键 + if (part.startsWith("Arrow")) { + return part.replace("Arrow", ""); + } + return part; + }) + .join("+"); +}; + +// 获取更新日志 +export const getUpdateLog = async (): Promise => { + const result = await getCacheData(updateLog, { key: "updateLog", time: 60 }); + return { + version: result.tag_name, + changelog: await marked(result.body), + time: result.published_at, + url: result.html_url, + }; +}; diff --git a/src/utils/init.ts b/src/utils/init.ts new file mode 100644 index 0000000..2b7af85 --- /dev/null +++ b/src/utils/init.ts @@ -0,0 +1,104 @@ +import { useDataStore, useSettingStore, useShortcutStore, useStatusStore } from "@/stores"; +import { useEventListener } from "@vueuse/core"; +import { openUserAgreement } from "@/utils/modal"; +import { debounce } from "lodash-es"; +import { isElectron } from "./helper"; +import player from "@/utils/player"; + +// 应用初始化时需要执行的操作 +const init = async () => { + // init pinia-data + const dataStore = useDataStore(); + const statusStore = useStatusStore(); + const settingStore = useSettingStore(); + const shortcutStore = useShortcutStore(); + + // 用户协议 + openUserAgreement(); + + // 事件监听 + initEventListener(); + + // 加载数据 + await dataStore.loadData(); + // 初始化播放器 + player.initPlayer(settingStore.autoPlay); + // 同步播放模式 + player.playModeSyncIpc(); + + if (isElectron) { + // 注册全局快捷键 + shortcutStore.registerAllShortcuts(); + // 显示窗口 + window.electron.ipcRenderer.send("win-loaded"); + // 显示桌面歌词 + window.electron.ipcRenderer.send("change-desktop-lyric", statusStore.showDesktopLyric); + // 检查更新 + if (settingStore.checkUpdateOnStart) window.electron.ipcRenderer.send("check-update"); + } +}; + +// 事件监听 +const initEventListener = () => { + // 键盘事件 + useEventListener(window, "keydown", keyDownEvent); +}; + +// 键盘事件 +const keyDownEvent = debounce((event: KeyboardEvent) => { + const shortcutStore = useShortcutStore(); + const target = event.target as HTMLElement; + // 排除元素 + const extendsDom = ["input", "textarea"]; + if (extendsDom.includes(target.tagName.toLowerCase())) return; + event.preventDefault(); + event.stopPropagation(); + // 获取按键信息 + const key = event.code; + const isCtrl = event.ctrlKey || event.metaKey; + const isShift = event.shiftKey; + const isAlt = event.altKey; + // 循环注册快捷键 + for (const shortcutKey in shortcutStore.shortcutList) { + const shortcut = shortcutStore.shortcutList[shortcutKey]; + const shortcutParts = shortcut.shortcut.split("+"); + // 标志位 + let match = true; + // 检查修饰键 + if (shortcutParts.includes("CmdOrCtrl") && !isCtrl) match = false; + if (shortcutParts.includes("Shift") && !isShift) match = false; + if (shortcutParts.includes("Alt") && !isAlt) match = false; + // 检查实际按键 + const mainKey = shortcutParts.find( + (part: string) => part !== "CmdOrCtrl" && part !== "Shift" && part !== "Alt", + ); + if (mainKey !== key) match = false; + if (match && shortcutKey) { + console.log(shortcutKey, `快捷键触发: ${shortcut.name}`); + switch (shortcutKey) { + case "playOrPause": + player.playOrPause(); + break; + case "playPrev": + player.nextOrPrev("next"); + break; + case "playNext": + player.nextOrPrev("prev"); + break; + case "volumeUp": + player.setVolume("up"); + break; + case "volumeDown": + player.setVolume("down"); + break; + case "toogleDesktopLyric": + player.toggleDesktopLyric(); + break; + default: + break; + } + } + } +}, 100); + +export default init; diff --git a/src/utils/initIpc.ts b/src/utils/initIpc.ts new file mode 100644 index 0000000..c780415 --- /dev/null +++ b/src/utils/initIpc.ts @@ -0,0 +1,47 @@ +import { isElectron } from "./helper"; +import { openUpdateApp } from "./modal"; +import player from "./player"; + +// 全局 IPC 事件 +const initIpc = () => { + try { + if (!isElectron) return; + // 播放 + window.electron.ipcRenderer.on("play", () => player.play()); + // 暂停 + window.electron.ipcRenderer.on("pause", () => player.pause()); + // 播放或暂停 + window.electron.ipcRenderer.on("playOrPause", () => player.playOrPause()); + // 上一曲 + window.electron.ipcRenderer.on("playPrev", () => player.nextOrPrev("prev")); + // 下一曲 + window.electron.ipcRenderer.on("playNext", () => player.nextOrPrev("next")); + // 音量加 + window.electron.ipcRenderer.on("volumeUp", () => player.setVolume("up")); + // 音量减 + window.electron.ipcRenderer.on("volumeDown", () => player.setVolume("down")); + // 播放模式切换 + window.electron.ipcRenderer.on("changeMode", (_, mode) => player.togglePlayMode(mode)); + // 桌面歌词开关 + window.electron.ipcRenderer.on("toogleDesktopLyric", () => player.toggleDesktopLyric()); + window.electron.ipcRenderer.on("closeDesktopLyric", () => player.toggleDesktopLyric()); + // 无更新 + window.electron.ipcRenderer.on("update-not-available", () => { + window.$message.success("当前已是最新版本"); + }); + // 有更新 + window.electron.ipcRenderer.on("update-available", (_, info) => { + console.log(info); + openUpdateApp(info); + }); + // 更新错误 + window.electron.ipcRenderer.on("update-error", (_, error) => { + console.error("Error updating:", error); + window.$message.error("更新过程出现错误"); + }); + } catch (error) { + console.log(error); + } +}; + +export default initIpc; diff --git a/src/utils/instruction.ts b/src/utils/instruction.ts new file mode 100644 index 0000000..f64aec9 --- /dev/null +++ b/src/utils/instruction.ts @@ -0,0 +1,93 @@ +import { useIntersectionObserver } from "@vueuse/core"; +import { debounce, throttle } from "lodash-es"; +import { DirectiveBinding } from "vue"; + +// 防抖指令 +export const debounceDirective = { + mounted(el: HTMLElement, binding: DirectiveBinding) { + if (typeof binding.value !== "function") { + console.warn("v-debounce directive expects a function as the value"); + return; + } + + const delay = binding.arg ? parseInt(binding.arg) : 300; + const debouncedFn = debounce(binding.value, delay, { + leading: true, + trailing: false, + }); + + el.addEventListener("click", debouncedFn); + (el as any)._debouncedFn = debouncedFn; + }, + beforeUnmount(el: HTMLElement) { + if ((el as any)._debouncedFn) { + el.removeEventListener("click", (el as any)._debouncedFn); + delete (el as any)._debouncedFn; + } + }, +}; + +// 节流指令 +export const throttleDirective = { + mounted(el: HTMLElement, binding: DirectiveBinding) { + if (typeof binding.value !== "function") { + console.warn("v-throttle directive expects a function as the value"); + return; + } + + const delay = binding.arg ? parseInt(binding.arg) : 300; + const throttledFn = throttle(binding.value, delay, { + leading: true, + trailing: false, + }); + + el.addEventListener("click", throttledFn); + (el as any)._throttledFn = throttledFn; + }, + beforeUnmount(el: HTMLElement) { + if ((el as any)._throttledFn) { + el.removeEventListener("click", (el as any)._throttledFn); + delete (el as any)._throttledFn; + } + }, +}; + +// 元素可见 +// export const visibleDirective = { +// mounted(el: HTMLElement, binding: any) { +// const { modifiers, value } = binding; + +// const { stop } = useIntersectionObserver( +// el, +// ([entry]) => { +// if (entry.isIntersecting) { +// el.classList.add("visible"); +// // 触发回调 +// if (typeof value === "function") value(entry); +// // 只触发一次 +// if (modifiers.once) stop(); +// } else if (!modifiers.once) { +// el.classList.remove("visible"); +// } +// }, +// { +// threshold: 0.1, +// }, +// ); +// }, +// }; +export const visibleDirective = { + mounted(el: HTMLElement, binding: any) { + const { modifiers, value } = binding; + + const handleIntersection = (entries: IntersectionObserverEntry[]) => { + entries.forEach((entry) => { + const isVisible = entry.isIntersecting; + el.classList.toggle("hidden", !isVisible); + if (typeof value === "function") value(isVisible); + if (modifiers.once && isVisible) stop(); + }); + }; + const { stop } = useIntersectionObserver(el, handleIntersection, { threshold: 0.1 }); + }, +}; diff --git a/src/utils/lyric.ts b/src/utils/lyric.ts new file mode 100644 index 0000000..797dfa4 --- /dev/null +++ b/src/utils/lyric.ts @@ -0,0 +1,204 @@ +import { LyricLine, parseLrc, parseYrc } from "@applemusic-like-lyrics/lyric"; +import { keywords } from "@/assets/data/exclude"; +import type { LyricType } from "@/types/main"; +import { useMusicStore } from "@/stores"; +import { msToS } from "./time"; + +// 恢复默认 +export const resetSongLyric = () => { + const musicStore = useMusicStore(); + musicStore.songLyric = { + lrcData: [], + lrcAMData: [], + yrcData: [], + yrcAMData: [], + }; +}; + +// 解析歌词数据 +export const parsedLyricsData = (lyricData: any) => { + const musicStore = useMusicStore(); + if (lyricData.code !== 200) { + resetSongLyric(); + return; + } + let lrcData: LyricType[] = []; + let yrcData: LyricType[] = []; + // 处理后歌词 + let lrcParseData: LyricLine[] = []; + let tlyricParseData: LyricLine[] = []; + let romalrcParseData: LyricLine[] = []; + let yrcParseData: LyricLine[] = []; + let ytlrcParseData: LyricLine[] = []; + let yromalrcParseData: LyricLine[] = []; + // 普通歌词 + if (lyricData?.lrc?.lyric) { + lrcParseData = parseLrc(lyricData.lrc.lyric); + lrcData = parseLrcData(lrcParseData); + // 其他翻译 + if (lyricData?.tlyric?.lyric) { + tlyricParseData = parseLrc(lyricData.tlyric.lyric); + lrcData = alignLyrics(lrcData, parseLrcData(tlyricParseData), "tran"); + } + if (lyricData?.romalrc?.lyric) { + romalrcParseData = parseLrc(lyricData.romalrc.lyric); + lrcData = alignLyrics(lrcData, parseLrcData(romalrcParseData), "roma"); + } + } + // 逐字歌词 + if (lyricData?.yrc?.lyric) { + yrcParseData = parseYrc(lyricData.yrc.lyric); + yrcData = parseYrcData(yrcParseData); + // 其他翻译 + if (lyricData?.ytlrc?.lyric) { + ytlrcParseData = parseLrc(lyricData.ytlrc.lyric); + yrcData = alignLyrics(yrcData, parseLrcData(ytlrcParseData), "tran"); + } + if (lyricData?.yromalrc?.lyric) { + yromalrcParseData = parseLrc(lyricData.yromalrc.lyric); + yrcData = alignLyrics(yrcData, parseLrcData(yromalrcParseData), "roma"); + } + } + musicStore.songLyric = { + lrcData, + yrcData, + lrcAMData: parseAMData(lrcParseData, tlyricParseData, romalrcParseData), + yrcAMData: parseAMData(yrcParseData, ytlrcParseData, yromalrcParseData), + }; +}; + +// 解析普通歌词 +export const parseLrcData = (lrcData: LyricLine[]): LyricType[] => { + if (!lrcData) return []; + // 数据处理 + const lrcList = lrcData + .map((line) => { + const words = line.words; + const time = msToS(words[0].startTime); + const content = words[0].word.trim(); + // 排除内容 + if (!content || keywords.some((keyword) => content.includes(keyword))) { + return null; + } + return { + time, + content, + }; + }) + .filter((line): line is LyricType => line !== null); + // 筛选出非空数据并返回 + return lrcList; +}; + +// 解析逐字歌词 +export const parseYrcData = (yrcData: LyricLine[]): LyricType[] => { + if (!yrcData) return []; + // 数据处理 + const yrcList = yrcData + .map((line) => { + const words = line.words; + const time = msToS(words[0].startTime); + const endTime = msToS(words[words.length - 1].endTime); + const contents = words.map((word) => { + return { + time: msToS(word.startTime), + endTime: msToS(word.endTime), + duration: msToS(word.endTime - word.startTime), + content: word.word.trim(), + endsWithSpace: word.word.endsWith(" "), + }; + }); + // 完整歌词 + const contentStr = contents + .map((word) => word.content + (word.endsWithSpace ? " " : "")) + .join(""); + // 排除内容 + if (!contentStr || keywords.some((keyword) => contentStr.includes(keyword))) { + return null; + } + return { + time, + endTime, + content: contentStr, + contents, + }; + }) + .filter((line): line is LyricType => line !== null); + return yrcList; +}; + +// 歌词内容对齐 +export const alignLyrics = ( + lyrics: LyricType[], + otherLyrics: LyricType[], + key: "tran" | "roma", +): LyricType[] => { + const lyricsData = lyrics; + if (lyricsData.length && otherLyrics.length) { + lyricsData.forEach((v: LyricType) => { + otherLyrics.forEach((x: LyricType) => { + if (v.time === x.time || Math.abs(v.time - x.time) < 0.6) { + v[key] = x.content; + } + }); + }); + } + return lyricsData; +}; + +// 处理本地歌词 +export const parseLocalLyric = (lyric: string) => { + if (!lyric) { + resetSongLyric(); + return; + } + const musicStore = useMusicStore(); + // 解析 + const lrc: LyricLine[] = parseLrc(lyric); + const lrcData: LyricType[] = parseLrcData(lrc); + // 处理结果 + const lrcDataParsed: LyricType[] = []; + // 翻译提取 + for (let i = 0; i < lrcData.length; i++) { + // 当前歌词 + const lrcItem = lrcData[i]; + // 是否具有翻译 + const existingObj = lrcDataParsed.find((v) => v.time === lrcItem.time); + if (existingObj) { + existingObj.tran = lrcItem.content; + } else { + lrcDataParsed.push(lrcItem); + } + } + // 更新歌词 + musicStore.songLyric = { + lrcData: lrcDataParsed, + lrcAMData: lrcDataParsed.map((line, index, lines) => ({ + words: [{ startTime: line.time, endTime: 0, word: line.content }], + startTime: line.time * 1000, + endTime: lines[index + 1]?.time * 1000, + translatedLyric: line.tran ?? "", + romanLyric: line.roma ?? "", + isBG: false, + isDuet: false, + })), + yrcData: [], + yrcAMData: [], + }; +}; + +// 处理 AM 歌词 +const parseAMData = (lrcData: LyricLine[], tranData?: LyricLine[], romaData?: LyricLine[]) => { + return lrcData.map((line, index, lines) => ({ + words: line.words, + startTime: line.words[0]?.startTime ?? 0, + endTime: + lines[index + 1]?.words?.[0]?.startTime ?? + line.words?.[line.words.length - 1]?.endTime ?? + Infinity, + translatedLyric: tranData?.[index]?.words?.[0]?.word ?? "", + romanLyric: romaData?.[index]?.words?.[0]?.word ?? "", + isBG: line.isBG ?? false, + isDuet: line.isDuet ?? false, + })); +}; diff --git a/src/utils/meta.ts b/src/utils/meta.ts new file mode 100644 index 0000000..acfc9bd --- /dev/null +++ b/src/utils/meta.ts @@ -0,0 +1,60 @@ +import type { SongLevelType } from "@/types/main"; +import { compact, findKey, keys, pick, takeWhile } from "lodash-es"; + +// 音质数据 +export const songLevelData = { + l: { + level: "standard", + name: "标准音质", + }, + m: { + level: "higher", + name: "较高音质", + }, + h: { + level: "exhigh", + name: "极高音质", + }, + sq: { + level: "lossless", + name: "无损音质", + }, + hr: { + level: "hires", + name: "Hi-Res", + }, + je: { + level: "jyeffect", + name: "高清环绕声", + }, + sk: { + level: "sky", + name: "沉浸环绕声", + }, + db: { + level: "dolby", + name: "杜比全景声", + }, + jm: { + level: "jymaster", + name: "超清母带", + }, +}; + +/** + * 根据传入的 level,筛选出包含该 level 及之前的音质数据 + * @param level 音质等级名称 + * @returns 包含指定 level 及之前音质数据的部分 songLevelData + */ +export function getLevelsUpTo(level: string): Partial { + // 从数组中取出符合条件的所有元素 + const resultKeys = takeWhile( + keys(songLevelData), + (key) => songLevelData[key as SongLevelType].level !== level, + ); + // 包含传入的 level + const levelKey = findKey(songLevelData, { level }); + if (levelKey) resultKeys.push(levelKey); + // 过滤空值 + return pick(songLevelData, compact(resultKeys)); +} diff --git a/src/utils/modal.ts b/src/utils/modal.ts new file mode 100644 index 0000000..8f71970 --- /dev/null +++ b/src/utils/modal.ts @@ -0,0 +1,234 @@ +import { h } from "vue"; +import type { CoverType, UpdateInfoType, SettingType, SongType } from "@/types/main"; +import { isLogin } from "./auth"; +import { isArray, isFunction } from "lodash-es"; +import { useDataStore } from "@/stores"; +import router from "@/router"; +import Login from "@/components/Modal/Login.vue"; +import JumpArtist from "@/components/Modal/JumpArtist.vue"; +import UserAgreement from "@/components/Modal/UserAgreement.vue"; +import SongInfoEditor from "@/components/Modal/SongInfoEditor.vue"; +import PlaylistAdd from "@/components/Modal/PlaylistAdd.vue"; +import batchList from "@/components/Modal/batchList.vue"; +import CloudMatch from "@/components/Modal/CloudMatch.vue"; +import CreatePlaylist from "@/components/Modal/CreatePlaylist.vue"; +import UpdatePlaylist from "@/components/Modal/UpdatePlaylist.vue"; +import DownloadSong from "@/components/Modal/DownloadSong.vue"; +import MainSetting from "@/components/Setting/MainSetting.vue"; +import UpdateApp from "@/components/Modal/UpdateApp.vue"; + +// 用户协议 +export const openUserAgreement = () => { + const isAgree = window.localStorage.getItem("isAgree"); + if (isAgree) return; + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + maskClosable: false, + closeOnEsc: false, + closable: false, + style: { + maxWidth: "70vw", + }, + content: () => { + return h(UserAgreement, { + onClose: () => { + modal.destroy(); + // 储存状态 + window.localStorage.setItem("isAgree", Date.now().toString()); + }, + }); + }, + onEsc: () => { + window.$message.warning("请先阅读并同意用户协议"); + }, + }); +}; + +// 用户登录 +export const openUserLogin = (showTip: boolean = false) => { + if (showTip) window.$message.warning("请登录后使用"); + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + maskClosable: false, + closeOnEsc: false, + closable: false, + style: { width: "400px" }, + content: () => { + return h(Login, { onClose: () => modal.destroy() }); + }, + }); +}; + +// 跳转到歌手 +export const openJumpArtist = (data: SongType["artists"]) => { + // 若 data 为数组且只有一个元素,则直接跳转 + if (isArray(data) && data.length === 1) { + const id = data[0].id; + router.push({ name: "artist", query: { id } }); + return; + } + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { width: "600px" }, + title: "跳转到歌手", + content: () => { + return h(JumpArtist, { artist: data, onClose: () => modal.destroy() }); + }, + }); +}; + +// 编辑歌曲信息 +export const openSongInfoEditor = (song: SongType) => { + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + // contentStyle: { padding: 0 }, + style: { width: "600px" }, + title: "编辑歌曲信息", + content: () => { + return h(SongInfoEditor, { song, onClose: () => modal.destroy() }); + }, + }); +}; + +// 添加到歌单 +export const openPlaylistAdd = (data: SongType[], isLocal: boolean) => { + if (!data.length) return window.$message.warning("请正确选择歌曲"); + if (!isLogin()) return openUserLogin(); + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { width: "600px" }, + title: "添加到歌单", + content: () => { + return h(PlaylistAdd, { data, isLocal, onClose: () => modal.destroy() }); + }, + }); +}; + +/** + * 开启批量操作 + * @param data 歌曲列表 + * @param isLocal 是否为本地音乐 + */ +export const openBatchList = (data: SongType[], isLocal: boolean) => { + window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { + maxWidth: "70vw", + }, + title: "批量操作", + content: () => h(batchList, { data, isLocal }), + }); +}; + +// 云盘歌曲纠正 +export const openCloudMatch = (id: number, index: number) => { + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { width: "600px" }, + title: "云盘歌曲纠正", + content: () => { + return h(CloudMatch, { id, index, onClose: () => modal.destroy() }); + }, + }); +}; + +// 新建歌单 +export const openCreatePlaylist = () => { + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { width: "600px" }, + title: "新建歌单", + content: () => { + return h(CreatePlaylist, { onClose: () => modal.destroy() }); + }, + }); +}; + +// 编辑歌单 +export const openUpdatePlaylist = (id: number, data: CoverType, func: () => Promise) => { + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { width: "600px" }, + title: "编辑歌单", + content: () => { + return h(UpdatePlaylist, { + id, + data, + onSuccess: () => { + modal.destroy(); + // 触发回调 + isFunction(func) && func(); + }, + }); + }, + }); +}; + +// 下载歌曲 +export const openDownloadSong = (song: SongType) => { + const dataStore = useDataStore(); + if (!isLogin()) return openUserLogin(); + // 是否可下载 + if (!song) return window.$message.warning("请正确选择歌曲"); + if (song.free !== 0 && dataStore.userData.vipType === 0 && !song?.pc) { + return window.$message.warning("账号会员等级不足,请提升权限"); + } + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { width: "600px" }, + title: "下载歌曲", + content: () => { + return h(DownloadSong, { id: song.id, onClose: () => modal.destroy() }); + }, + }); +}; + +// 打开设置 +export const openSetting = (type: SettingType = "general") => { + window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + maskClosable: false, + closeOnEsc: false, + bordered: true, + class: "main-setting", + content: () => { + return h(MainSetting, { type }); + }, + }); +}; + +// 软件更新 +export const openUpdateApp = (data: UpdateInfoType) => { + const modal = window.$modal.create({ + preset: "card", + transformOrigin: "center", + autoFocus: false, + style: { width: "600px" }, + title: "发现新版本", + content: () => { + return h(UpdateApp, { data, onClose: () => modal.destroy() }); + }, + }); +}; diff --git a/src/utils/parseLyric.js b/src/utils/parseLyric.js deleted file mode 100644 index 63d1c51..0000000 --- a/src/utils/parseLyric.js +++ /dev/null @@ -1,254 +0,0 @@ -/* eslint-disable no-unused-vars */ -/** - * 将歌词接口数据解析出对应数据 - * @param {string} data 接口数据 - * @returns {Array} 对应数据 - */ -export const parseLyric = (data) => { - try { - // 判断是否具有内容 - const checkLyric = (lyric) => (lyric ? (lyric.lyric ? true : false) : false); - // 初始化数据 - const { lrc, tlyric, romalrc, yrc, ytlrc, yromalrc } = data; - const lrcData = { - lrc: lrc?.lyric || null, - tlyric: tlyric?.lyric || null, - romalrc: romalrc?.lyric || null, - yrc: yrc?.lyric || null, - ytlrc: ytlrc?.lyric || null, - yromalrc: yromalrc?.lyric || null, - }; - // 初始化输出结果 - const result = { - // 是否具有普通翻译 - hasLrcTran: checkLyric(tlyric), - // 是否具有普通音译 - hasLrcRoma: checkLyric(romalrc), - // 是否具有逐字歌词 - hasYrc: checkLyric(yrc), - // 是否具有逐字翻译 - hasYrcTran: checkLyric(ytlrc), - // 是否具有逐字音译 - hasYrcRoma: checkLyric(yromalrc), - // 普通歌词数组 - lrc: [], - // 逐字歌词数据 - yrc: [], - }; - // 普通歌词 - if (lrcData.lrc) { - result.lrc = parseLrc(lrcData.lrc); - //判断是否有其他翻译 - result.lrc = lrcData.tlyric - ? parseOtherLrc(result.lrc, parseLrc(lrcData.tlyric), "tran") - : result.lrc; - result.lrc = lrcData.romalrc - ? parseOtherLrc(result.lrc, parseLrc(lrcData.romalrc), "roma") - : result.lrc; - } - // 逐字歌词 - if (lrcData.yrc) { - result.yrc = parseYrc(lrcData.yrc); - //判断是否有其他翻译 - result.yrc = lrcData.ytlrc - ? parseOtherLrc(result.yrc, parseLrc(lrcData.ytlrc), "tran") - : result.yrc; - result.yrc = lrcData.yromalrc - ? parseOtherLrc(result.yrc, parseLrc(lrcData.yromalrc, false), "roma") - : result.yrc; - } - console.log(result); - return result; - } catch (error) { - console.error("解析歌词时出现错误:", error); - return false; - } -}; - -/** - * 解析本地歌词数据 - * @param {string} data - 歌词字符串 - * @returns {Object} - 包含解析后的歌词信息的对象 - */ -export const parseLocalLrc = (data) => { - try { - const lyric = parseLrc(data); - const parsedLyrics = []; - // 初始化输出结果 - const result = { - hasLrcTran: false, - hasLrcRoma: false, - hasYrc: false, - hasYrcTran: false, - hasYrcRoma: false, - lrc: [], - yrc: [], - }; - // 遍历本地歌词数据 - for (let i = 0; i < lyric.length; i++) { - // 当前歌词 - let currentObj = lyric[i]; - // 是否有相同时间 - let existingObj = parsedLyrics.find((v) => Number(v.time) === Number(currentObj.time)); - // 如果存在翻译 - if (existingObj) { - result.hasLrcTran = true; - existingObj.tran = currentObj.content; - } - // 若不存在翻译 - else { - parsedLyrics.push({ - time: currentObj.time, - content: currentObj.content, - }); - } - } - // 改变输出结果 - result.lrc = parsedLyrics; - console.log(result); - return result; - } catch (error) { - console.error("解析本地歌词时出现错误:", error); - return false; - } -}; - -/** - * 翻译文本对齐 - * @param {string} lrc 歌词字符串 - * @param {string} tranLrc 翻译歌词字符串 - * @returns {Array} 包含翻译的歌词对象数组 - */ -const parseOtherLrc = (lrc, tranLrc, name) => { - const lyric = lrc; - const tranLyric = tranLrc; - if (lyric[0] && tranLyric[0]) { - lyric.forEach((v) => { - tranLyric.forEach((x) => { - if (Number(v.time) === Number(x.time) || Math.abs(Number(v.time) - Number(x.time)) < 0.6) { - v[name] = x.content; - } - }); - }); - } - return lyric; -}; - -/** - * 普通歌词解析 - * @param {string} lyrics 歌词字符串 - * @returns {Array} 歌词对象数组 - */ -const parseLrc = (lyrics, isTrim = true) => { - if (!lyrics) return []; - try { - // 匹配时间轴和歌词文本的正则表达式 - const regex = /^\[([^\]]+)\]\s*(.+?)\s*$/; - // 匹配歌曲信息的正则表达式 - // const infoRegex = /\].*[::-]/; - // 将歌词字符串按行分割为数组 - const lines = lyrics.split("\n"); - // 对每一行进行转换 - const parsedLyrics = lines - // 筛选出包含时间轴和歌词文本的行 - .filter((line) => regex.test(line)) - // 转换时间轴和歌词文本为对象 - .map((line) => { - // 过滤掉包含信息的文本 - // if (infoRegex.test(line)) return null; - // 继续解析 - const [, time, text] = line.match(regex); - const parts = time.split(":"); - const seconds = - Number(parts[0]) * 60 + - Number(parts[1]) + - (parts.length > 2 ? Number(parts[2]) / 1000 : 0); - return { time: Number(seconds.toFixed(2)), content: isTrim ? text.trim() : text }; - }) - .filter((c) => c && c.content.trim() !== ""); - // 检查是否为纯音乐,是则返回空数组 - if (parsedLyrics.length && /纯音乐,请欣赏/.test(parsedLyrics[0].content)) { - console.log("该歌曲为纯音乐"); - return []; - } - return parsedLyrics; - } catch (err) { - console.error("普通歌词处理出错:" + err); - return []; - } -}; - -/** - * 逐字歌词解析 - * @param {string} lyrics 逐字歌词字符串 - * @returns {Array} 歌词对象数组 - */ -const parseYrc = (lyrics) => { - if (!lyrics) return []; - try { - // 遍历每一行逐字歌词 - const parsedLyrics = lyrics - .split("\n") - .map((line) => { - // 匹配每一行中的时间戳信息 - const timeReg = /\[(\d+),(\d+)\]/; - const timeMatch = line.match(timeReg); - if (!timeMatch) { - return null; - } - // 解构出起始时间和结束时间 - const [_, startTime, endTime] = timeMatch; - if (isNaN(startTime) || isNaN(endTime)) { - return null; - } - // 去除当前行中的时间戳信息,得到歌词内容 - const content = line.replace(timeReg, ""); - if (!content) { - return null; - } - // 去除歌曲信息 - // const contentInfoReg = /\s*[^::\n]*[::]\s*.+/; - // const contentFilter = content.replace(/\(\d+,\d+,\d+\)/g, ""); - // if (!contentFilter || contentInfoReg.test(contentFilter)) { - // return null; - // } - // 对歌词内容中的时间戳和歌词内容分离 - const contentArray = content - .split(/(\([1-9]\d*,[1-9]\d*,\d*\)[^(]*)/g) - .filter((c) => c.trim()) - .map((c) => { - // 匹配当前片段中的时间戳信息 - const timeReg = /\((\d+),(\d+),(\d+)\)/; - const timeMatch = c.match(timeReg); - if (!timeMatch) { - return null; - } - // 解构出时间戳,持续时间和歌词内容 - const [_, time, duration] = timeMatch; - const contentReg = /\(\d+,\d+,\d+\)/g; - const content = c.replace(timeReg, "").replace(contentReg, ""); - if (!content || !content.trim()) { - return null; - } - return { - time: Number(time) / 1000, - duration: Number(duration) / 1000, - content: content.trim(), - endsWithSpace: content.endsWith(" "), - }; - }) - .filter((c) => c); - // 返回当前行解析出的时间信息和歌词内容信息 - return { - time: Number(startTime) / 1000, - endTime: Number(endTime) / 1000, - content: contentArray, - }; - }) - .filter((line) => line); - return parsedLyrics; - } catch (err) { - console.error("逐字歌词处理出错:" + err); - return []; - } -}; diff --git a/src/utils/player.ts b/src/utils/player.ts new file mode 100644 index 0000000..61d3092 --- /dev/null +++ b/src/utils/player.ts @@ -0,0 +1,1161 @@ +import type { SongType, PlayModeType } from "@/types/main"; +import type { MessageReactive } from "naive-ui"; +import { Howl, Howler } from "howler"; +import { cloneDeep } from "lodash-es"; +import { useMusicStore, useStatusStore, useDataStore, useSettingStore } from "@/stores"; +import { parsedLyricsData, resetSongLyric, parseLocalLyric } from "./lyric"; +import { songUrl, unlockSongUrl, songLyric } from "@/api/song"; +import { getCoverColorData } from "@/utils/color"; +import { calculateProgress } from "./time"; +import { isElectron, isDev, sleep } from "./helper"; +import { heartRateList } from "@/api/playlist"; +import { formatSongsList } from "./format"; +import { isLogin } from "./auth"; +import { openUserLogin } from "./modal"; +import { scrobble } from "@/api/user"; +import { personalFm, personalFmToTrash } from "@/api/rec"; +import blob from "./blob"; + +// 播放器核心 +// Howler.js + +// 允许播放格式 +const allowPlayFormat = ["mp3", "flac", "webm", "ogg", "wav"]; + +class Player { + // 播放器 + private player: Howl; + // 定时器 + private playerInterval: ReturnType | undefined; + // 频谱数据 + private audioContext: AudioContext | null = null; + private analyser: AnalyserNode | null = null; + private dataArray: Uint8Array | null = null; + private source: MediaElementAudioSourceNode | null = null; + // 其他数据 + private testNumber: number = 0; + private message: MessageReactive | null = null; + constructor() { + // 创建播放器实例 + this.player = new Howl({ src: [""], format: allowPlayFormat, autoplay: false }); + // 初始化媒体会话 + this.initMediaSession(); + } + /** + * 重置状态 + */ + async resetStatus() { + const statusStore = useStatusStore(); + const musicStore = useMusicStore(); + // 停止播放 + this.player?.stop(); + // 重置状态 + statusStore.$patch({ + currentTime: 0, + duration: 0, + progress: 0, + currentTimeOffset: 0, + lyricIndex: -1, + playStatus: false, + playLoading: false, + }); + musicStore.$patch({ + playPlaylistId: 0, + playSong: {}, + }); + // 延时防止 bug + await sleep(50); + } + /** + * 清理播放器 + */ + private cleanPlayer() { + Howler.unload(); + // this.player?.stop(); + // this.player?.unload(); + } + /** + * 获取当前播放歌曲 + * @returns 当前播放歌曲 + */ + private getPlaySongData(): SongType | null { + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + // 若为私人FM + if (statusStore.personalFmMode) { + return musicStore.personalFMSong; + } + // 播放列表 + const playlist = dataStore.playList; + if (!playlist.length) return null; + return playlist[statusStore.playIndex]; + } + /** + * 获取淡入淡出时间 + * @returns 播放音量 + */ + private getFadeTime(): number { + const settingStore = useSettingStore(); + const { songVolumeFade, songVolumeFadeTime } = settingStore; + return songVolumeFade ? songVolumeFadeTime : 0; + } + /** + * 处理播放状态 + */ + private handlePlayStatus() { + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + const settingStore = useSettingStore(); + // 清理定时器 + clearInterval(this.playerInterval); + // 更新播放状态 + this.playerInterval = setInterval(() => { + if (!this.player.playing()) return; + const currentTime = this.getSeek(); + const duration = this.player.duration(); + // 计算进度条距离 + const progress = calculateProgress(currentTime, duration); + // 计算歌词索引 + const hasYrc = !musicStore.songLyric.yrcData.length || !settingStore.showYrc; + const lyrics = hasYrc ? musicStore.songLyric.lrcData : musicStore.songLyric.yrcData; + // 歌词实时偏移量 + const currentTimeOffset = statusStore.currentTimeOffset; + const index = lyrics?.findIndex((v) => v?.time >= currentTime + currentTimeOffset); + // 歌词跨界处理 + const lyricIndex = index === -1 ? lyrics.length - 1 : index - 1; + // 更新状态 + statusStore.$patch({ + currentTime, + duration, + progress, + lyricIndex, + }); + // 客户端事件 + if (isElectron) { + // 歌词变化 + window.electron.ipcRenderer.send("play-lyric-change", { + index: lyricIndex, + lyric: cloneDeep( + settingStore.showYrc && musicStore.songLyric.yrcData?.length + ? musicStore.songLyric.yrcData + : musicStore.songLyric.lrcData, + ), + }); + // 进度条 + if (settingStore.showTaskbarProgress) { + window.electron.ipcRenderer.send("set-bar", progress); + } + } + }, 500); + } + /** + * 获取在线播放链接 + * @param id 歌曲id + * @returns 播放链接 + */ + private async getOnlineUrl(id: number): Promise { + const settingStore = useSettingStore(); + const res = await songUrl(id, settingStore.songLevel); + console.log(`🌐 ${id} music data:`, res); + const songData = res.data?.[0]; + // 是否有播放地址 + if (!songData || !songData?.url) return null; + // 是否仅能试听 + if (songData?.freeTrialInfo !== null) { + if (settingStore.playSongDemo) { + window.$message.warning("当前歌曲仅可试听,请开通会员后重试"); + } else return null; + } + // 返回歌曲地址 + // 客户端直接返回,网页端转 https + const url = isElectron ? songData.url : songData.url.replace(/^http:/, "https:"); + return url; + } + /** + * 获取解锁播放链接 + * @param songData 歌曲数据 + * @returns + */ + private async getUnlockSongUrl(songData: SongType): Promise { + try { + const songId = songData.id; + const artist = Array.isArray(songData.artists) ? songData.artists[0].name : songData.artists; + const keyWord = songData.name + "-" + artist; + if (!songId || !keyWord) return null; + // 尝试解锁 + const [neteaseUrl, kuwoUrl] = await Promise.all([ + unlockSongUrl(songId, keyWord, "netease"), + unlockSongUrl(songId, keyWord, "kuwo"), + ]); + if (neteaseUrl.code === 200 && neteaseUrl.url !== "") return neteaseUrl.url; + if (kuwoUrl.code === 200 && kuwoUrl.url !== "") return kuwoUrl.url; + return null; + } catch (error) { + console.error("Error in getUnlockSongUrl", error); + return null; + } + } + /** + * 创建播放器 + * @param src 播放地址 + * @param autoPlay 是否自动播放 + */ + private createPlayer(src: string, autoPlay: boolean = true) { + // 获取数据 + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + const settingStore = useSettingStore(); + // 播放信息 + const { id, path, type } = musicStore.playSong; + // 清理播放器 + this.cleanPlayer(); + // 禁用自动解锁 + Howler.autoUnlock = false; + // 创建播放器 + this.player = new Howl({ + src, + format: allowPlayFormat, + html5: true, + autoplay: autoPlay, + preload: "metadata", + pool: 1, + volume: statusStore.playVolume, + rate: statusStore.playRate, + }); + // 播放器事件 + this.playerEvent(); + // 播放设备 + if (!settingStore.showSpectrums) this.toggleOutputDevice(); + // 自动播放 + if (autoPlay) this.play(); + // 获取歌词数据 - 非电台和本地 + if (type !== "radio" && !path) this.getLyricData(id); + else resetSongLyric(); + // 定时获取状态 + if (!this.playerInterval) this.handlePlayStatus(); + // 新增播放历史 + if (type !== "radio") dataStore.setHistory(musicStore.playSong); + // 获取歌曲封面主色 + if (!path) this.getCoverColor(musicStore.songCover); + // 更新 MediaSession + if (!path) this.updateMediaSession(); + // 开发模式 + if (isDev) window.player = this.player; + } + /** + * 播放器事件 + */ + private playerEvent() { + // 获取数据 + const statusStore = useStatusStore(); + const settingStore = useSettingStore(); + const playSongData = this.getPlaySongData(); + // 初次加载 + this.player.once("load", () => { + // 允许跨域 + const audioDom = this.getAudioDom(); + audioDom.crossOrigin = "anonymous"; + // 恢复进度( 需距离本曲结束大于 2 秒 ) + if (settingStore.memoryLastSeek && statusStore.duration - statusStore.currentTime > 2) { + this.setSeek(statusStore.currentTime); + } else { + this.setSeek(0); + } + // 更新状态 + statusStore.playLoading = false; + // ipc + if (isElectron) { + window.electron.ipcRenderer.send("play-song-change", this.getPlayerInfo()); + } + }); + // 播放 + this.player.on("play", () => { + // ipc + if (isElectron) { + window.electron.ipcRenderer.send("play-status-change", true); + window.electron.ipcRenderer.send("play-song-change", this.getPlayerInfo()); + } + // 更改标题 + if (!isElectron) window.document.title = this.getPlayerInfo() || "SPlayer"; + console.log("▶️ song play:", playSongData); + }); + // 暂停 + this.player.on("pause", () => { + // ipc + if (isElectron) window.electron.ipcRenderer.send("play-status-change", false); + // 更改标题 + if (!isElectron) window.document.title = "SPlayer"; + console.log("⏸️ song pause:", playSongData); + }); + // 结束 + this.player.on("end", () => { + // statusStore.playStatus = false; + console.log("⏹️ song end:", playSongData); + this.nextOrPrev("next"); + }); + // 错误 + this.player.on("loaderror", (sourceid, err: any) => { + this.errorNext(err); + console.error("❌ song error:", sourceid, playSongData, err); + }); + } + /** + * 初始化 MediaSession + */ + private initMediaSession() { + if (!("mediaSession" in navigator)) return; + navigator.mediaSession.setActionHandler("play", () => this.play()); + navigator.mediaSession.setActionHandler("pause", () => this.pause()); + navigator.mediaSession.setActionHandler("previoustrack", () => this.nextOrPrev("prev")); + navigator.mediaSession.setActionHandler("nexttrack", () => this.nextOrPrev("next")); + // 跳转进度 + navigator.mediaSession.setActionHandler("seekto", (event) => { + if (event.seekTime) this.setSeek(event.seekTime); + }); + } + /** + * 更新 MediaSession + */ + private updateMediaSession() { + if (!("mediaSession" in navigator)) return; + const musicStore = useMusicStore(); + const settingStore = useSettingStore(); + // 获取播放数据 + const playSongData = this.getPlaySongData(); + if (!playSongData) return; + // 播放状态 + const isRadio = playSongData.type === "radio"; + // 获取数据 + const metaData: MediaMetadataInit = { + title: playSongData.name, + artist: isRadio + ? "播客电台" + : // 非本地歌曲且歌手列表为数组 + Array.isArray(playSongData.artists) + ? playSongData.artists.map((item) => item.name).join(" / ") + : String(playSongData.artists), + album: isRadio + ? "播客电台" + : // 是否为对象 + typeof playSongData.album === "object" + ? playSongData.album.name + : String(playSongData.album), + artwork: settingStore.smtcOutputHighQualityCover + ? [ + { + src: musicStore.getSongCover("xl"), + sizes: "1920x1920", + type: "image/jpeg", + }, + ] + : [ + { + src: musicStore.getSongCover("cover"), + sizes: "512x512", + type: "image/jpeg", + }, + { + src: musicStore.getSongCover("s"), + sizes: "100x100", + type: "image/jpeg", + }, + { + src: musicStore.getSongCover("m"), + sizes: "300x300", + type: "image/jpeg", + }, + { + src: musicStore.getSongCover("l"), + sizes: "1024x1024", + type: "image/jpeg", + }, + { + src: musicStore.getSongCover("xl"), + sizes: "1920x1920", + type: "image/jpeg", + }, + ], + }; + // 更新数据 + navigator.mediaSession.metadata = new window.MediaMetadata(metaData); + } + // 生成频谱数据 + private generateSpectrumData() { + const statusStore = useStatusStore(); + if (!this.analyser || !this.dataArray) { + this.initSpectrumData(); + } + // 更新频谱数据 + const updateSpectrumData = () => { + if (this.analyser && this.dataArray) { + this.analyser.getByteFrequencyData(this.dataArray); + // 保存数据 + statusStore.spectrumsData = Array.from(this.dataArray); + } + requestAnimationFrame(updateSpectrumData); + }; + updateSpectrumData(); + } + /** + * 获取歌词 + * @param id 歌曲id + */ + private async getLyricData(id: number) { + if (!id) { + resetSongLyric(); + return; + } + const lyricRes = await songLyric(id); + parsedLyricsData(lyricRes); + } + /** + * 播放错误 + * 在播放错误时,播放下一首 + */ + private errorNext(errCode?: number) { + const dataStore = useDataStore(); + const statusStore = useStatusStore(); + // 错误 2 通常为网络地址过期 + if (errCode === 2) { + // 替换播放链接 + } + // 清除进度 + // this.resetStatus(); + // statusStore.playStatus = false; + // ipc + // if (isElectron) window.electron.ipcRenderer.send("play-status-change", false); + // 次数加一 + this.testNumber++; + if (this.testNumber > 5) { + this.testNumber = 0; + statusStore.playLoading = false; + window.$message.error("当前重试次数过多,请稍后再试"); + return; + } + // 播放下一曲 + if (dataStore.playList.length > 1) { + this.nextOrPrev("next"); + } else { + statusStore.playStatus = false; + window.$message.error("当前列表暂无可播放歌曲"); + } + } + /** + * 获取 Audio Dom + */ + private getAudioDom() { + const audioDom = (this.player as any)._sounds[0]._node; + if (!audioDom) { + throw new Error("Audio Dom is null"); + } + return audioDom; + } + /** + * 获取本地歌曲元信息 + * @param path 歌曲路径 + */ + private async parseLocalMusicInfo(path: string) { + try { + const musicStore = useMusicStore(); + // 获取封面数据 + const coverData = await window.electron.ipcRenderer.invoke("get-music-cover", path); + if (coverData) { + const { data, format } = coverData; + const blobURL = blob.createBlobURL(data, format, path); + if (blobURL) { + musicStore.playSong.cover = blobURL; + } + } else { + musicStore.playSong.cover = "/images/song.jpg?assest"; + } + // 获取主色 + this.getCoverColor(musicStore.playSong.cover); + // 获取歌词数据 + const lrcData = await window.electron.ipcRenderer.invoke("get-music-lyric", path); + parseLocalLyric(lrcData); + // 更新媒体会话 + this.updateMediaSession(); + } catch (error) { + window.$message.error("获取本地歌曲元信息失败"); + console.error("Failed to parse local music info:", error); + } + } + /** + * 获取播放信息 + * @param song 歌曲 + * @param sep 分隔符 + * @returns 播放信息 + */ + getPlayerInfo(song?: SongType, sep: string = "&"): string | null { + const playSongData = song || this.getPlaySongData(); + if (!playSongData) return null; + // 标题 + const title = `${playSongData.name || "未知歌曲"}`; + // 歌手 + const artist = + playSongData.type === "radio" + ? "播客电台" + : Array.isArray(playSongData.artists) + ? playSongData.artists.map((artists: { name: string }) => artists.name).join(sep) + : String(playSongData?.artists || "未知歌手"); + return `${title} - ${artist}`; + } + /** + * 初始化播放器 + * 核心外部调用 + * @param autoPlay 是否自动播放 + */ + async initPlayer(autoPlay: boolean = true) { + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + const settingStore = useSettingStore(); + try { + // 获取播放数据 + const playSongData = this.getPlaySongData(); + if (!playSongData) return; + const { id, dj, path, type } = playSongData; + // 清理播放器 + // this.cleanPlayer(); + // 更改当前播放歌曲 + musicStore.playSong = playSongData; + // 更改状态 + statusStore.playLoading = true; + // 本地歌曲 + if (path) { + this.createPlayer(path, autoPlay); + // 获取歌曲元信息 + await this.parseLocalMusicInfo(path); + } + // 在线歌曲 + else if (id && dataStore.playList.length) { + const songId = type === "radio" ? dj?.id : id; + if (!songId) throw new Error("Get song id error"); + const url = await this.getOnlineUrl(songId); + // 正常播放地址 + if (url) { + statusStore.playUblock = false; + this.createPlayer(url, autoPlay); + } + // 尝试解灰 + else if (isElectron && type !== "radio" && settingStore.useSongUnlock) { + const unlockUrl = await this.getUnlockSongUrl(playSongData); + if (unlockUrl) { + statusStore.playUblock = true; + console.log("🎼 Song unlock successfully:", unlockUrl); + this.createPlayer(unlockUrl, autoPlay); + } else { + statusStore.playUblock = false; + // 是否为最后一首 + if (statusStore.playIndex === dataStore.playList.length - 1) { + statusStore.$patch({ playStatus: false, playLoading: false }); + window.$message.warning("当前列表歌曲无法播放,请更换歌曲"); + } else { + window.$message.error("该歌曲暂无音源,跳至下一首"); + this.nextOrPrev("next"); + } + } + } else { + if (dataStore.playList.length === 1) { + // this.cleanPlayer(); + await this.resetStatus(); + window.$message.warning("当前播放列表已无可播放歌曲,请更换"); + return; + } else { + window.$message.error("该歌曲无法播放,跳至下一首"); + this.nextOrPrev(); + return; + } + } + } + } catch (error) { + console.error("❌ 初始化音乐播放器出错:", error); + window.$message.error("播放器遇到错误,请尝试软件热重载"); + // this.errorNext(); + } + } + /** + * 播放 + * @param fade 是否淡入 + */ + play(fade: boolean = true) { + const statusStore = useStatusStore(); + if (this.player.playing()) { + statusStore.playStatus = true; + return; + } + this.player.play(); + statusStore.playStatus = true; + this.player.once("play", () => { + this.player.fade(0, statusStore.playVolume, fade ? this.getFadeTime() : 0); + }); + } + /** + * 暂停 + * @param fade 是否淡出 + */ + pause(fade: boolean = true) { + const statusStore = useStatusStore(); + this.player.fade(statusStore.playVolume, 0, fade ? this.getFadeTime() : 0); + this.player.once("fade", () => { + this.player.pause(); + statusStore.playStatus = false; + }); + } + /** + * 播放或暂停 + */ + playOrPause() { + const statusStore = useStatusStore(); + statusStore.playStatus ? this.pause() : this.play(); + } + /** + * 下一首或上一首 + * @param type 切换类别 next 下一首 prev 上一首 + * @param play 是否立即播放 + */ + async nextOrPrev(type: "next" | "prev" = "next", play: boolean = true) { + const statusStore = useStatusStore(); + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + // 获取数据 + const { playList } = dataStore; + const { playSong } = musicStore; + const { playSongMode, playHeartbeatMode } = statusStore; + // 列表长度 + const playListLength = playList.length; + // 播放列表是否为空 + if (playListLength === 0) throw new Error("The play list is empty"); + // 打卡 + this.scrobbleSong(); + // 若为私人FM + if (statusStore.personalFmMode) { + await this.initPersonalFM(true); + return; + } + // 只有一首歌的特殊处理 + if (playListLength === 1) { + this.setSeek(0); + statusStore.lyricIndex = -1; + const songData = playList[0]; + if (!songData) throw new Error("The song data is not found"); + musicStore.playSong = songData; + await this.initPlayer(play); + return; + } + // 列表循环或处于心动模式 + if (playSongMode === "repeat" || playHeartbeatMode || playSong.type === "radio") { + statusStore.playIndex += type === "next" ? 1 : -1; + } + // 随机播放 + else if (playSongMode === "shuffle") { + let newIndex: number; + // 确保不会随机到同一首 + do { + newIndex = Math.floor(Math.random() * playListLength); + } while (newIndex === statusStore.playIndex); + statusStore.playIndex = newIndex; + } + // 单曲循环 + else if (playSongMode === "repeat-once") { + statusStore.lyricIndex = -1; + this.setSeek(0); + this.play(); + return; + } else { + throw new Error("The play mode is not supported"); + } + // 索引是否越界 + if (statusStore.playIndex < 0) { + statusStore.playIndex = playListLength - 1; + } else if (statusStore.playIndex >= playListLength) { + statusStore.playIndex = 0; + } + // 停止播放 + await this.resetStatus(); + // 初始化播放器 + this.initPlayer(play); + } + /** + * 切换播放模式 + * @param mode 播放模式 repeat repeat-once shuffle + */ + togglePlayMode(mode: PlayModeType | false) { + const statusStore = useStatusStore(); + // 退出心动模式 + if (statusStore.playHeartbeatMode) this.toggleHeartMode(false); + // 若传入了指定模式 + if (mode) { + statusStore.playSongMode = mode; + } else { + switch (statusStore.playSongMode) { + case "repeat": + statusStore.playSongMode = "repeat-once"; + break; + case "shuffle": + statusStore.playSongMode = "repeat"; + break; + case "repeat-once": + statusStore.playSongMode = "shuffle"; + break; + default: + statusStore.playSongMode = "repeat"; + } + } + this.playModeSyncIpc(); + } + /** + * 播放模式同步 ipc + */ + playModeSyncIpc() { + const statusStore = useStatusStore(); + if (isElectron) { + window.electron.ipcRenderer.send("play-mode-change", statusStore.playSongMode); + } + } + /** + * 设置播放进度 + * @param time 播放进度 + */ + setSeek(time: number) { + const statusStore = useStatusStore(); + this.player.seek(time); + statusStore.currentTime = time; + } + /** + * 获取播放进度 + * @returns 播放进度 + */ + getSeek(): number { + return this.player.seek(); + } + /** + * 设置播放速率 + * @param rate 播放速率 + */ + setRate(rate: number) { + const statusStore = useStatusStore(); + this.player.rate(rate); + statusStore.playRate = rate; + } + /** + * 设置播放音量 + * @param volume 音量 + */ + setVolume(volume: number | "up" | "down") { + const statusStore = useStatusStore(); + // 直接设置 + if (typeof volume === "number") { + volume = Math.max(0, Math.min(volume, 1)); + } else { + const increment = 0.05; + statusStore.playVolume = Math.max( + 0, + Math.min(statusStore.playVolume + (volume === "up" ? increment : -increment), 1), + ); + } + // 调整音量 + this.player.volume(statusStore.playVolume); + } + /** + * 切换静音 + */ + toggleMute() { + const statusStore = useStatusStore(); + // 是否静音 + const isMuted = statusStore.playVolume === 0; + // 恢复音量 + if (isMuted) { + statusStore.playVolume = statusStore.playVolumeMute; + } + // 保存当前音量并静音 + else { + statusStore.playVolumeMute = this.player.volume(); + statusStore.playVolume = 0; + } + this.player.volume(statusStore.playVolume); + } + /** + * 获取歌曲封面颜色数据 + * @param coverUrl 歌曲封面地址 + */ + async getCoverColor(coverUrl: string) { + if (!coverUrl) return; + const statusStore = useStatusStore(); + // 创建图像元素 + const image = new Image(); + image.crossOrigin = "Anonymous"; + image.src = coverUrl; + // 图像加载完成 + image.onload = () => { + // 获取图片数据 + const coverColorData = getCoverColorData(image); + if (coverColorData) statusStore.songCoverTheme = coverColorData; + // 移除元素 + image.remove(); + }; + } + /** + * 更新播放列表 + * @param data 播放列表 + * @param song 当前播放歌曲 + * @param pid 播放列表id + * @param options 配置 + * @param options.showTip 是否显示提示 + * @param options.scrobble 是否打卡 + * @param options.play 是否直接播放 + */ + async updatePlayList( + data: SongType[], + song?: SongType, + pid?: number, + options: { + showTip?: boolean; + scrobble?: boolean; + play?: boolean; + } = { + showTip: true, + scrobble: true, + play: true, + }, + ) { + if (!data || !data.length) return; + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + // 获取配置 + const { showTip, scrobble, play } = options; + // 打卡 + scrobble && this.scrobbleSong(); + // 更新列表 + await dataStore.setPlayList(cloneDeep(data)); + // 关闭特殊模式 + if (statusStore.playHeartbeatMode) this.toggleHeartMode(false); + if (statusStore.personalFmMode) statusStore.personalFmMode = false; + // 是否直接播放 + if (song && typeof song === "object" && "id" in song) { + // 是否为当前播放歌曲 + if (musicStore.playSong.id === song.id) { + if (play) this.play(); + } else { + // 查找索引 + const playIndex = data.findIndex((item) => item.id === song.id); + statusStore.$patch({ playIndex, lyricIndex: -1 }); + // 清理并播放 + await this.resetStatus(); + this.initPlayer(); + } + } else { + const playIndex = + statusStore.playSongMode === "shuffle" ? Math.floor(Math.random() * data.length) : 0; + statusStore.$patch({ playIndex, lyricIndex: -1 }); + // 清理并播放 + await this.resetStatus(); + this.initPlayer(); + } + // 更改播放歌单 + musicStore.playPlaylistId = pid ?? 0; + if (showTip) window.$message.success("已开始播放"); + } + /** + * 添加下一首歌曲 + * @param song 歌曲 + * @param play 是否立即播放 + */ + async addNextSong(song: SongType, play: boolean = false) { + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + // 关闭特殊模式 + if (statusStore.personalFmMode) statusStore.personalFmMode = false; + // 是否为当前播放歌曲 + if (musicStore.playSong.id === song.id) { + this.play(); + window.$message.success("已开始播放"); + return; + } + // 尝试添加 + const songIndex = await dataStore.setNextPlaySong(song, statusStore.playIndex); + // 播放歌曲 + if (!songIndex) return; + if (play) this.togglePlayIndex(songIndex); + else window.$message.success("已添加至下一首播放"); + } + /** + * 切换播放索引 + * @param index 播放索引 + */ + togglePlayIndex(index: number) { + const dataStore = useDataStore(); + const statusStore = useStatusStore(); + // 获取数据 + const { playList } = dataStore; + // 若超出播放列表 + if (index >= playList.length) return; + // 相同 + if (statusStore.playIndex === index) { + this.play(); + return; + } + // 更改状态 + this.setSeek(0); + statusStore.playIndex = index; + this.initPlayer(); + } + /** + * 移除指定歌曲 + * @param index 歌曲索引 + */ + removeSongIndex(index: number) { + const dataStore = useDataStore(); + const statusStore = useStatusStore(); + // 获取数据 + const { playList } = dataStore; + // 若超出播放列表 + if (index >= playList.length) return; + // 仅剩一首 + if (playList.length === 1) { + this.cleanPlayList(); + return; + } + // 深拷贝,防止影响原数据 + const newPlaylist = cloneDeep(playList); + // 若将移除最后一首 + if (index === playList.length - 1) { + statusStore.playIndex = 0; + } + // 若为当前播放之后 + else if (statusStore.playIndex > index) { + statusStore.playIndex--; + } + // 移除指定歌曲 + newPlaylist.splice(index, 1); + dataStore.setPlayList(newPlaylist); + // 若为当前播放 + if (statusStore.playIndex === index) { + this.initPlayer(statusStore.playStatus); + } + } + /** + * 清空播放列表 + */ + async cleanPlayList() { + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + // 停止播放 + await this.resetStatus(); + this.cleanPlayer(); + // 清空数据 + statusStore.$patch({ + playListShow: false, + showFullPlayer: false, + playHeartbeatMode: false, + personalFmMode: false, + }); + musicStore.resetMusicData(); + dataStore.setPlayList([]); + window.$message.success("已清空播放列表"); + } + /** + * 切换输出设备 + * @param deviceId 输出设备 + */ + toggleOutputDevice(deviceId?: string) { + try { + const settingStore = useSettingStore(); + // 输出设备 + const devices = deviceId ?? settingStore.playDevice; + if (!(this.player as any)?._sounds.length) return; + // 获取音频元素 + const audioDom = this.getAudioDom(); + // 设置输出设备 + if (devices && audioDom?.setSinkId) { + audioDom.setSinkId(devices); + } + } catch (error) { + console.error("Failed to change audio output device:", error); + } + } + /** + * 初始化音频可视化 + */ + initSpectrumData() { + try { + if (this.audioContext) return; + // AudioContext + this.audioContext = new (window.AudioContext || (window as any).webkitAudioContext)(); + // 获取音频元素 + const audioDom = this.getAudioDom(); + // 媒体元素源 + this.source = this.audioContext.createMediaElementSource(audioDom); + // AnalyserNode + this.analyser = this.audioContext.createAnalyser(); + // 频谱分析器 FFT + this.analyser.fftSize = 512; + // 连接源和分析节点 + this.source.connect(this.analyser); + // 连接分析节点到 AudioContext + this.analyser.connect(this.audioContext.destination); + // 配置 AnalyserNode + const bufferLength = this.analyser.frequencyBinCount; + this.dataArray = new Uint8Array(bufferLength); + // 更新频谱数据 + this.generateSpectrumData(); + console.log("🎼 Initialize music spectrum successfully"); + } catch (error) { + console.error("🎼 Initialize music spectrum failed:", error); + } + } + /** + * 切换桌面歌词 + */ + toggleDesktopLyric() { + const statusStore = useStatusStore(); + const show = !statusStore.showDesktopLyric; + statusStore.showDesktopLyric = show; + window.electron.ipcRenderer.send("change-desktop-lyric", show); + window.$message.success(`${show ? "已开启" : "已关闭"}桌面歌词`); + } + /** + * 切换心动模式 + * @param open 是否开启 + */ + async toggleHeartMode(open: boolean = true) { + try { + const dataStore = useDataStore(); + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + if (!open && statusStore.playHeartbeatMode) { + statusStore.playHeartbeatMode = false; + window.$message.success("已退出心动模式"); + return; + } + if (!isLogin()) { + openUserLogin(true); + return; + } + if (statusStore.playHeartbeatMode) { + window.$message.warning("已处于心动模式"); + this.play(); + return; + } + this.message?.destroy(); + this.message = window.$message.loading("心动模式开启中", { duration: 0 }); + // 获取所需数据 + const playSongData = this.getPlaySongData(); + const likeSongsList: any = await dataStore.getUserLikePlaylist(); + // if (!playSongData || !likeSongsList) { + // throw new Error("获取播放数据或喜欢列表失败"); + // } + const pid = + musicStore.playPlaylistId && musicStore.playPlaylistId !== 0 + ? musicStore.playPlaylistId + : likeSongsList?.detail?.id; + // 开启心动模式 + const result = await heartRateList(playSongData?.id || 0, pid); + if (result.code === 200) { + this.message?.destroy(); + const heartRatelists = formatSongsList(result.data); + // 更新播放列表 + await this.updatePlayList(heartRatelists, heartRatelists[0]); + // 更改模式 + statusStore.playHeartbeatMode = true; + } else { + this.message?.destroy(); + window.$message.error(result.message || "心动模式开启出错,请重试"); + } + } catch (error) { + console.error("Failed to toggle heart mode:", error); + this.message?.destroy(); + window.$message.error("心动模式开启出错,请重试"); + } finally { + this.message?.destroy(); + } + } + /** + * 听歌打卡 + */ + async scrobbleSong() { + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + try { + if (!isLogin()) return; + // 获取所需数据 + const playSongData = this.getPlaySongData(); + if (!playSongData) return; + const { id, name } = playSongData; + const sourceid = musicStore.playPlaylistId; + const time = statusStore.duration; + // 网易云打卡 + console.log("打卡:", id, name, sourceid, time); + await scrobble(id, sourceid, time); + } catch (error) { + console.error("Failed to scrobble song:", error); + } + } + /** + * 初始化私人FM + * @param playNext 是否播放下一首 + */ + async initPersonalFM(playNext: boolean = false) { + const musicStore = useMusicStore(); + const statusStore = useStatusStore(); + try { + // 获取并重置 + const getPersonalFmData = async () => { + const result = await personalFm(); + const songData = formatSongsList(result.data); + console.log(`🌐 personal FM:`, songData); + musicStore.personalFM.list = songData; + musicStore.personalFM.playIndex = 0; + }; + // 若为空 + if (musicStore.personalFM.list.length === 0) await getPersonalFmData(); + // 若需播放下一首 + if (playNext) { + statusStore.personalFmMode = true; + // 更改索引 + if (musicStore.personalFM.playIndex < musicStore.personalFM.list.length - 1) { + musicStore.personalFM.playIndex++; + } else { + await getPersonalFmData(); + } + // 清理并播放 + await this.resetStatus(); + this.initPlayer(); + } + } catch (error) { + console.error("Failed to initialize personal FM:", error); + } + } + /** + * 私人FM - 垃圾桶 + * @param id 歌曲id + */ + async personalFMTrash(id: number) { + try { + const statusStore = useStatusStore(); + if (!isLogin()) { + openUserLogin(true); + return; + } + // 更改模式 + statusStore.personalFmMode = true; + statusStore.playHeartbeatMode = false; + // 加入回收站 + const result = await personalFmToTrash(id); + if (result.code === 200) { + window.$message.success("已移至垃圾桶"); + this.nextOrPrev("next"); + } + } catch (error) { + console.error("Error adding to trash:", error); + window.$message.error("移至垃圾桶失败,请重试"); + } + } +} + +export default new Player(); diff --git a/src/utils/request.js b/src/utils/request.js deleted file mode 100644 index c591806..0000000 --- a/src/utils/request.js +++ /dev/null @@ -1,93 +0,0 @@ -import { checkPlatform } from "@/utils/helper"; -import { getCookie, isLogin } from "@/utils/auth"; -import { siteSettings } from "@/stores"; -import axios from "axios"; - -// 全局地址 -if (checkPlatform.electron()) { - axios.defaults.baseURL = "/api"; -} else { - axios.defaults.baseURL = import.meta.env["RENDERER_VITE_SERVER_URL"]; -} - -// 基础配置 -axios.defaults.timeout = 15000; -axios.defaults.withCredentials = true; - -// 请求拦截 -axios.interceptors.request.use( - (request) => { - const settings = siteSettings(); - if (!request.params) request.params = {}; - // 附加 cookie - if (!request.noCookie && (isLogin() || getCookie("MUSIC_U") !== null)) { - request.params.cookie = `MUSIC_U=${getCookie("MUSIC_U")};`; - } - // 去除 cookie - if (request.noCookie) { - request.params.noCookie = true; - } - // 附加 realIP - if (settings.useRealIP) { - request.params.realIP = settings.realIP || "116.25.146.177"; - } - // 附加代理 - const proxy = JSON.parse(localStorage.getItem("siteSettings")).proxyProtocol; - if (proxy !== "off") { - const server = JSON.parse(localStorage.getItem("siteSettings")).proxyServe; - const port = parseInt(localStorage.getItem("siteSettings").proxyPort); - if (server && port) { - request.params.proxy = `${proxy}://${server}:${port}`; - } - } - // 发送请求 - return request; - }, - (error) => { - console.error("请求失败,请稍后重试"); - return Promise.reject(error); - }, -); - -// 响应拦截 -axios.interceptors.response.use( - (response) => { - return response?.data; - }, - (error) => { - // 从错误对象中获取响应信息 - const response = error.response; - // 断网处理 - if (!response) $canNotConnect(error); - // 状态码处理 - switch (response?.status) { - case 400: - console.error("客户端错误:", response.status, response.statusText); - // 执行客户端错误的处理逻辑 - break; - case 401: - console.error("未授权:", response.status, response.statusText); - // 执行未授权的处理逻辑 - break; - case 403: - console.error("禁止访问:", response.status, response.statusText); - // 执行禁止访问的处理逻辑 - break; - case 404: - console.error("未找到资源:", response.status, response.statusText); - // 执行未找到资源的处理逻辑 - break; - case 500: - console.error("服务器错误:", response.status, response.statusText); - // 执行服务器错误的处理逻辑 - break; - default: - // 处理其他状态码或错误条件 - console.error("未处理的错误:", error.message); - } - // 继续传递错误 - return Promise.reject(error); - }, -); - -export default axios; diff --git a/src/utils/request.ts b/src/utils/request.ts new file mode 100644 index 0000000..cba3650 --- /dev/null +++ b/src/utils/request.ts @@ -0,0 +1,104 @@ +import axios, { AxiosInstance, AxiosRequestConfig, AxiosError, AxiosResponse } from "axios"; +import { isDev, isElectron } from "./helper"; +import { useSettingStore } from "@/stores"; +import { getCookie } from "./cookie"; +import { isLogin } from "./auth"; + +// 全局地址 +const baseURL: string = String(isDev ? "/api/netease" : import.meta.env["VITE_API_URL"]); + +// 基础配置 +const server: AxiosInstance = axios.create({ + baseURL, + // 允许跨域 + withCredentials: true, + // 超时时间 + timeout: 15000, +}); + +// 请求拦截器 +server.interceptors.request.use( + (request) => { + // pinia + const settingStore = useSettingStore(); + if (!request.params) request.params = {}; + // Cookie + if (!request.params.noCookie && (isLogin() || getCookie("MUSIC_U") !== null)) { + request.params.cookie = `MUSIC_U=${getCookie("MUSIC_U")};`; + } + // realIP + if (!isElectron && !request.url?.includes("/login")) { + request.params.realIP = "116.25.146.177"; + } + // 自定义 realIP + if (settingStore.useRealIP) { + request.params.realIP = settingStore.realIP || "116.25.146.177"; + } + // proxy + if (settingStore.proxyProtocol !== "off") { + const protocol = settingStore.proxyProtocol.toLowerCase(); + const server = settingStore.proxyServe; + const port = settingStore.proxyPort; + const proxy = `${protocol}://${server}:${port}`; + if (proxy) request.params.proxy = proxy; + } + // 发送请求 + return request; + }, + (error: AxiosError) => { + console.error("请求发送失败:", error); + return Promise.reject(error); + }, +); + +// 响应拦截器 +server.interceptors.response.use( + (response: AxiosResponse) => response, + (error: AxiosError) => { + const { response } = error; + // 状态码处理 + switch (response?.status) { + case 400: + console.error("客户端错误:", response.status, response.statusText); + // 执行客户端错误的处理逻辑 + break; + case 401: + console.error("未授权:", response.status, response.statusText); + // 执行未授权的处理逻辑 + break; + case 403: + console.error("禁止访问:", response.status, response.statusText); + // 执行禁止访问的处理逻辑 + break; + case 404: + console.error("未找到资源:", response.status, response.statusText); + // 执行未找到资源的处理逻辑 + break; + case 500: + console.error("服务器错误:", response.status, response.statusText); + // 执行服务器错误的处理逻辑 + break; + default: + // 处理其他状态码或错误条件 + console.error("未处理的错误:", error.message); + } + window.$notification.error({ + title: "请求错误", + description: `状态码: ${response?.status || ""}`, + content: (response && (response.data as { message?: string }).message) || error.message, + meta: "若持续发生,可尝试软件热重载", + duration: 5000, + }); + // 返回错误 + return Promise.reject(error); + }, +); + +// 请求 +const request = async (config: AxiosRequestConfig): Promise => { + // 返回请求数据 + const { data } = await server.request(config); + return data as any; +}; + +export default request; diff --git a/src/utils/rules.ts b/src/utils/rules.ts new file mode 100644 index 0000000..28217f5 --- /dev/null +++ b/src/utils/rules.ts @@ -0,0 +1,51 @@ +import type { FormItemRule } from "naive-ui"; + +// 普通文本 +export const textRule: FormItemRule = { + required: true, + message: "请填写必要信息", + trigger: ["blur"], +}; + +// 数字验证 +export const numberRule: FormItemRule = { + required: true, + type: "number", + message: "请输入数字", + trigger: ["input", "blur"], +}; + +// 邮箱验证 +export const emailRule: FormItemRule = { + required: true, + message: "请输入正确的邮箱", + trigger: ["input", "blur"], + validator: (_: FormItemRule, value: any) => { + if (!value) return new Error("请输入电子邮箱"); + else if ( + !/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test( + value, + ) + ) { + return new Error("请输入正确的电子邮箱"); + } + return true; + }, +}; + +// 手机号验证 +export const phoneRule: FormItemRule = { + required: true, + type: "number", + message: "请输入正确的手机号", + trigger: ["input", "blur"], + validator: (_: FormItemRule, value: any) => { + if (!value) return new Error("请输入手机号"); + else if ( + !/^1(3\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\d|9[0-35-9])\d{8}$/.test(value) + ) { + return new Error("请输入正确的手机号"); + } + return true; + }, +} diff --git a/src/utils/throttle.js b/src/utils/throttle.js deleted file mode 100644 index d07773b..0000000 --- a/src/utils/throttle.js +++ /dev/null @@ -1,25 +0,0 @@ -/** - * 节流函数 - * @param {Function} func - 要进行节流处理的函数 - * @param {number} delay - 延迟时间,单位毫秒 - * @param {string} errorMessage - 重复触发时的提醒消息 - * @returns {Function} - 返回一个新的函数,该函数在指定的时间间隔内最多只会执行一次 - */ -const throttle = (func, delay, errorMessage) => { - let isThrottled = false; - - // 返回一个新的函数 - return (...args) => { - if (!isThrottled) { - isThrottled = true; - func.apply(this, args); - setTimeout(() => { - isThrottled = false; - }, delay); - } else if (errorMessage) { - $message.warning(errorMessage); - } - }; -}; - -export default throttle; diff --git a/src/utils/time.ts b/src/utils/time.ts new file mode 100644 index 0000000..cbec5d2 --- /dev/null +++ b/src/utils/time.ts @@ -0,0 +1,129 @@ +import dayjs from "dayjs"; +import duration from "dayjs/plugin/duration"; +import relativeTime from "dayjs/plugin/relativeTime"; + +dayjs.extend(duration); +dayjs.extend(relativeTime); + +// 秒转为时间 +export const secondsToTime = (seconds: number) => { + if (seconds < 3600) { + return dayjs.duration(seconds, "seconds").format("m:ss"); + } else { + return dayjs.duration(seconds, "seconds").format("H:mm:ss"); + } +}; + +// 毫秒转为时间 +export const msToTime = (milliseconds: number) => { + const dur = dayjs.duration(milliseconds, "milliseconds"); + return milliseconds < 3600000 ? dur.format("mm:ss") : dur.format("H:mm:ss"); +}; + +// 毫秒转为秒 +export const msToS = (milliseconds: number, decimalPlaces: number = 2): number => { + return Number((milliseconds / 1000).toFixed(decimalPlaces)); +}; + +/** + * 格式化时间戳 + * @param {number|undefined} timestamp - 要格式化的时间戳(以毫秒为单位)。如果为 `null` 或 `0`,则返回空字符串。 + * @param {string} [format="YYYY-MM-DD"] - 可选的时间格式,默认格式为 "YYYY-MM-DD"。可传入任意 dayjs 支持的格式。 + * @returns {string} - 根据指定格式返回的日期字符串 + */ +export const formatTimestamp = ( + timestamp: number | undefined, + format: string = "YYYY-MM-DD", +): string => { + if (!timestamp) return ""; + const date = dayjs(timestamp); + const currentYear = dayjs().year(); + const year = date.year(); + // 如果年份相同 + if (year === currentYear) { + return date.format(format.replace("YYYY-", "")); + } + return date.format(format); +}; + +// 格式化评论时间戳 +export const formatCommentTime = (timestamp: number): string => { + const now = dayjs(); + const diff = now.diff(dayjs(timestamp), "minute"); + if (diff < 1) { + return "刚刚发布"; + } else if (diff < 60) { + return `${diff}分钟前`; + } else if (diff < 1440) { + // 1天 = 24小时 * 60分钟 + return `${Math.floor(diff / 60)}小时前`; + } else if (diff < 525600) { + // 1年约等于 525600分钟 + return dayjs(timestamp).format("MM-DD HH:mm"); + } else { + return dayjs(timestamp).format("YYYY-MM-DD HH:mm"); + } +}; + +/** + * 计算进度条移动的距离 + * @param {number} currentTime + * @param {number} duration + * @returns {number} 进度条移动的距离,精确到 0.01,最大为 100 + */ +export const calculateProgress = (currentTime: number, duration: number): number => { + if (duration === 0) return 0; + + const progress = (currentTime / duration) * 100; + return Math.min(Math.round(progress * 100) / 100, 100); +}; + +/** + * 根据进度和总时长反推当前时间 + * @param {number} progress 进度百分比,范围通常是0到100 + * @param {number} duration 总时长,单位为秒 + * @returns {number} 当前时间,单位为秒,精确到0.01秒 + */ +export const calculateCurrentTime = (progress: number, duration: number): number => { + // 确保在有效范围内 + progress = Math.min(Math.max(progress, 0), 100); + + const currentTime = (progress / 100) * duration; + return Math.round(currentTime * 100) / 100; +}; + +/** + * 获取当前时间段的问候语 + */ +export const getGreeting = () => { + const hour = dayjs().hour(); + if (hour < 6) { + return "凌晨好"; + } else if (hour < 9) { + return "早上好"; + } else if (hour < 12) { + return "上午好"; + } else if (hour < 14) { + return "中午好"; + } else if (hour < 17) { + return "下午好"; + } else if (hour < 19) { + return "傍晚好"; + } else if (hour < 22) { + return "晚上好"; + } else { + return "夜深了"; + } +}; + +/** + * 是否为当天的6点之前 + * @param timestamp 当前时间戳 + */ +export const isBeforeSixAM = (timestamp: number) => { + // 当天的早上 6 点 + const sixAM = dayjs().startOf('day').add(6, 'hour'); + // 判断输入时间是否在六点之前 + const inputTime = dayjs(timestamp); + return inputTime.isBefore(sixAM); +}; diff --git a/src/utils/timeTools.js b/src/utils/timeTools.js deleted file mode 100644 index ed4aee8..0000000 --- a/src/utils/timeTools.js +++ /dev/null @@ -1,136 +0,0 @@ -/** - * 获取根据当前时间的问候语 - * @returns {string} 当前时间对应的问候语 - */ -export const getGreetings = () => { - const hour = new Date().getHours(); - let hello; - if (hour < 6) { - hello = "凌晨好"; - } else if (hour < 9) { - hello = "早上好"; - } else if (hour < 12) { - hello = "上午好"; - } else if (hour < 14) { - hello = "中午好"; - } else if (hour < 17) { - hello = "下午好"; - } else if (hour < 19) { - hello = "傍晚好"; - } else if (hour < 22) { - hello = "晚上好"; - } else { - hello = "夜深了"; - } - return hello; -}; - -/** - * 歌曲时长时间戳转换 - * @param {number} mss 毫秒数 - * @returns {string} 格式为 "mm:ss" 的字符串 - */ -export const getSongTime = (mss) => { - const minutes = Math.floor(mss / (1000 * 60)); - let seconds = Math.floor((mss % (1000 * 60)) / 1000); - if (seconds < 10) { - seconds = `0${seconds}`; - } - return `${minutes}:${seconds}`; -}; - -/** - * 获取时间戳对应的日期 - * @param {number} mss - 时间戳 - * @returns {string} - 日期字符串 - */ -export const getTimestampTime = (mss, showYear = true) => { - const date = new Date(parseInt(mss)); - const y = date.getFullYear(); - const m = `0${date.getMonth() + 1}`.slice(-2); - const d = `0${date.getDate()}`.slice(-2); - return showYear ? `${y}-${m}-${d}` : `${m}-${d}`; -}; - -/** - * 歌曲播放时间转换 - * @param {number} num 歌曲播放时间,单位为秒 - * @returns {string} 格式为 "mm:ss" 的字符串 - */ -export const getSongPlayTime = (num) => { - const minutes = String(Math.floor(num / 60)).padStart(2, "0"); - const seconds = String(Math.floor(num % 60)).padStart(2, "0"); - return `${minutes}:${seconds}`; -}; - -/** - * 将评论时间戳转化为对应的时间格式 - * @param {number} t - 时间戳,单位为毫秒 - * @returns {string} - 转换后的时间字符串 - */ -export const getCommentTime = (t) => { - // 获取当前 Unix 时间戳 - const nowDate = new Date(); - // 获取今天 23:59:59.999 时间戳 - const todayLast = new Date( - nowDate.getFullYear(), - nowDate.getMonth(), - nowDate.getDate(), - 23, - 59, - 59, - 999, - ).getTime(); - // 将传入的时间戳转换为 Date 对象 - const userDate = new Date(Number(t)); - // 获取评论时间的小时和分钟数,并进行补零处理 - const UH = userDate.getHours() < 10 ? `0${userDate.getHours()}` : userDate.getHours(); - const Um = userDate.getMinutes() < 10 ? `0${userDate.getMinutes()}` : userDate.getMinutes(); - // 判断时间差 - if (nowDate - t <= 60000) { - return "刚刚发布"; - } else if (nowDate - t > 60000 && nowDate - t <= 3600000) { - const pastTimeUnix = nowDate - t; - const pastTime = new Date(Number(pastTimeUnix)); - return `${pastTime.getMinutes()} 分钟前`; - } else if (todayLast - t > 3600000 && todayLast - t <= 86400000) { - return `${UH}:${Um}`; - } else if (nowDate.getFullYear() === userDate.getFullYear()) { - // 如果在今年,不显示年份 - return `${userDate.getMonth() + 1}月${userDate.getDate()}日 ${UH}:${Um}`; - } else if (todayLast - t <= 172800000) { - return `昨天 ${UH}:${Um}`; - } else { - return `${userDate.getFullYear()}年${ - userDate.getMonth() + 1 - }月${userDate.getDate()}日 ${UH}:${Um}`; - } -}; - -/** - * 电台时间戳格式化 - * @param {number} timestamp - 要格式化的时间戳(毫秒) - * @returns {string} - 格式化后的日期描述 - */ -export const djFormatDate = (timestamp) => { - const now = new Date(); - const targetDate = new Date(timestamp); - const timeDiff = now - targetDate; - const oneDay = 24 * 60 * 60 * 1000; // 一天的毫秒数 - const daysDiff = Math.floor(timeDiff / oneDay); - // 数字补零 - const formatNumber = (num) => { - return num < 10 ? `0${num}` : num; - }; - if (daysDiff === 0) { - return "今日"; - } else if (daysDiff === 1) { - return "昨日"; - } else if (daysDiff <= 7) { - return `${daysDiff}天前`; - } else if (targetDate.getFullYear() === now.getFullYear() - 1) { - return `${targetDate.getFullYear()}-${formatNumber(targetDate.getMonth() + 1)}`; - } else { - return `${formatNumber(targetDate.getMonth() + 1)}-${formatNumber(targetDate.getDate())}`; - } -}; diff --git a/src/utils/userSignIn.js b/src/utils/userSignIn.js deleted file mode 100644 index e46b951..0000000 --- a/src/utils/userSignIn.js +++ /dev/null @@ -1,47 +0,0 @@ -import { userDailySignin } from "@/api/user"; -import { siteSettings } from "@/stores"; -import { isLogin } from "@/utils/auth"; - -/** - * 用户签到 - * https://github.com/Binaryify/NeteaseCloudMusicApi/issues/1387 - * 云贝签到本质上就是 Android 客户端每日签到 - */ -const userSignIn = async () => { - const settings = siteSettings(); - try { - if (!isLogin()) return false; - const today = new Date().toLocaleDateString(); - const lastSignInDate = sessionStorage.getItem("lastSignInDate"); - if (lastSignInDate !== today) { - const result = await userDailySignin(1); - console.log("签到结果:", result); - sessionStorage.setItem("lastSignInDate", today); - if (result.status === 400) { - return console.log("重复签到"); - } - $notification["success"]({ - content: "签到通知", - meta: "🎉 每日签到成功", - duration: 3000, - }); - } else { - console.log("今日已签到"); - } - } catch (error) { - if (error.request.status === 400) { - console.log("重复签到"); - sessionStorage.setItem("lastSignInDate", new Date().toLocaleDateString()); - return false; - } - settings.autoSignIn = false; - console.error("签到过程中发生错误:", error); - $notification["error"]({ - content: "签到通知", - meta: "签到过程中发生错误,已关闭自动签到,详细信息可查看控制台输出,请及时向开发者报告", - duration: 8000, - }); - } -}; - -export default userSignIn; diff --git a/src/views/Artist/albums.vue b/src/views/Artist/albums.vue index 16f46e5..abd0d21 100644 --- a/src/views/Artist/albums.vue +++ b/src/views/Artist/albums.vue @@ -1,92 +1,57 @@ - diff --git a/src/views/Artist/hot.vue b/src/views/Artist/hot.vue deleted file mode 100644 index b92a612..0000000 --- a/src/views/Artist/hot.vue +++ /dev/null @@ -1,84 +0,0 @@ - - - - - diff --git a/src/views/Artist/index.vue b/src/views/Artist/index.vue deleted file mode 100644 index 86f5824..0000000 --- a/src/views/Artist/index.vue +++ /dev/null @@ -1,370 +0,0 @@ - - - - - diff --git a/src/views/Artist/layout.vue b/src/views/Artist/layout.vue new file mode 100644 index 0000000..7396f2f --- /dev/null +++ b/src/views/Artist/layout.vue @@ -0,0 +1,422 @@ + + + + + diff --git a/src/views/Artist/songs.vue b/src/views/Artist/songs.vue index 302dd60..7fd6f7e 100644 --- a/src/views/Artist/songs.vue +++ b/src/views/Artist/songs.vue @@ -1,94 +1,74 @@ - diff --git a/src/views/Artist/videos.vue b/src/views/Artist/videos.vue index 8e65de4..ffeb18f 100644 --- a/src/views/Artist/videos.vue +++ b/src/views/Artist/videos.vue @@ -1,99 +1,58 @@ - diff --git a/src/views/Cloud.vue b/src/views/Cloud.vue index 08cd310..4f4a8fd 100644 --- a/src/views/Cloud.vue +++ b/src/views/Cloud.vue @@ -1,234 +1,272 @@ - diff --git a/src/views/Discover/index.vue b/src/views/Discover/index.vue deleted file mode 100644 index 44ac536..0000000 --- a/src/views/Discover/index.vue +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - diff --git a/src/views/Discover/layout.vue b/src/views/Discover/layout.vue new file mode 100644 index 0000000..b52e363 --- /dev/null +++ b/src/views/Discover/layout.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/views/Discover/new.vue b/src/views/Discover/new.vue index dae78ff..21deb3e 100644 --- a/src/views/Discover/new.vue +++ b/src/views/Discover/new.vue @@ -1,16 +1,14 @@ - - diff --git a/src/views/Discover/playlists.vue b/src/views/Discover/playlists.vue index 80f3738..87b66c3 100644 --- a/src/views/Discover/playlists.vue +++ b/src/views/Discover/playlists.vue @@ -1,11 +1,9 @@ -