mirror of
https://github.com/setube/ogame-vue-ts.git
synced 2026-05-12 07:55:11 +08:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cfcde0b024 | ||
|
|
053bd24855 | ||
|
|
7d1f36046d | ||
|
|
22ae07de90 | ||
|
|
a76909a2c7 | ||
|
|
8144f305e2 | ||
|
|
04721e2450 | ||
|
|
85ab19fb4a | ||
|
|
03f76b6497 | ||
|
|
9a571da4b1 | ||
|
|
797cc815f6 | ||
|
|
30aceb2a76 | ||
|
|
4340450d78 | ||
|
|
2bac87cd39 | ||
|
|
1aac97dfee | ||
|
|
84b090d51d | ||
|
|
a592713623 | ||
|
|
ec6b9cee07 | ||
|
|
b6fcad0a65 | ||
|
|
5273520305 | ||
|
|
751cb1e341 | ||
|
|
add90c5603 | ||
|
|
3410eeda19 | ||
|
|
c690323803 | ||
|
|
59dd7bfd05 | ||
|
|
9b9fda0400 | ||
|
|
3fa716e515 | ||
|
|
9aa240e335 | ||
|
|
44580909a3 | ||
|
|
88fa8aa2ee | ||
|
|
2601f1b776 | ||
|
|
763dfdde04 |
1
.github/workflows/build.yml
vendored
1
.github/workflows/build.yml
vendored
@@ -77,7 +77,6 @@ jobs:
|
||||
- name: Build Electron
|
||||
run: |
|
||||
pnpm install
|
||||
pnpm run build
|
||||
pnpm run build:electron --${{ matrix.platform }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
45
.github/workflows/github-pages.yml
vendored
Normal file
45
.github/workflows/github-pages.yml
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
name: 构建 Github Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ] # 如果你的主分支叫 master,请改为 master
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
build-and-deploy:
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: 检出代码
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 安装 Nodejs
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 20 # 建议使用 LTS 版本
|
||||
|
||||
- name: 安装 pnpm 并构建前端
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
run_install: true
|
||||
|
||||
- name: 构建前端项目
|
||||
run: pnpm run build
|
||||
|
||||
# 关键步骤:告诉 GitHub Actions 跳过 Jekyll 检查
|
||||
- name: 配置 Github Pages
|
||||
uses: actions/configure-pages@v5
|
||||
|
||||
- name: 上传构建版
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
path: './docs'
|
||||
|
||||
- name: 部署到 GitHub Pages
|
||||
uses: actions/deploy-pages@v4
|
||||
1
.github/workflows/ogame-vue-ts.yml
vendored
1
.github/workflows/ogame-vue-ts.yml
vendored
@@ -57,3 +57,4 @@ jobs:
|
||||
${{ vars.DOCKERHUB_USERNAME != '' && format('docker.io/{0}/ogame-vue-ts:{1}', vars.DOCKERHUB_USERNAME, github.sha) || '' }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
outputs: type=image,name=target,annotation-index.org.opencontainers.image.description=OGame Vue
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -11,8 +11,9 @@ CLAUDE.md
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
dist-electron
|
||||
docs
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.claude/*
|
||||
@@ -25,3 +26,5 @@ docs
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
/docs
|
||||
/docs/assets
|
||||
|
||||
16
README-EN.md
16
README-EN.md
@@ -53,23 +53,23 @@ OGame Vue TS is a single-player, browser-based space strategy game inspired by t
|
||||
|
||||
#### Server version
|
||||
|
||||
[Windows](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-windows-amd64.exe)
|
||||
[Windows](/releases/latest/download/ogame-windows-amd64.exe)
|
||||
|
||||
[Linux amd64](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-linux-amd64)
|
||||
[Linux amd64](/releases/latest/download/ogame-linux-amd64)
|
||||
|
||||
[Linux arm64](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-linux-arm64)
|
||||
[Linux arm64](/releases/latest/download/ogame-linux-arm64)
|
||||
|
||||
[MacOS Intel](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-macos-amd64)
|
||||
[MacOS Intel](/releases/latest/download/ogame-macos-amd64)
|
||||
|
||||
[MacOS](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-macos-arm64)
|
||||
[MacOS](/releases/latest/download/ogame-macos-arm64)
|
||||
|
||||
#### Desktop version
|
||||
|
||||
[Windows](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/OGame.Setup.exe)
|
||||
[Windows](/releases/latest/download/OGame.Setup.exe)
|
||||
|
||||
[Ubuntu](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/OGame.AppImage)
|
||||
[Ubuntu](/releases/latest/download/OGame.AppImage)
|
||||
|
||||
[MacOS](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/OGame-mac.dmg)
|
||||
[MacOS](/releases/latest/download/OGame-mac.dmg)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
|
||||
16
README.md
16
README.md
@@ -53,23 +53,23 @@ OGame Vue TS 是一款受经典 OGame 游戏启发的单机版、基于浏览器
|
||||
|
||||
#### 服务端
|
||||
|
||||
[Windows](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-windows-amd64.exe)
|
||||
[Windows](/releases/latest/download/ogame-windows-amd64.exe)
|
||||
|
||||
[Linux amd64](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-linux-amd64)
|
||||
[Linux amd64](/releases/latest/download/ogame-linux-amd64)
|
||||
|
||||
[Linux arm64](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-linux-arm64)
|
||||
[Linux arm64](/releases/latest/download/ogame-linux-arm64)
|
||||
|
||||
[MacOS Intel](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-macos-amd64)
|
||||
[MacOS Intel](/releases/latest/download/ogame-macos-amd64)
|
||||
|
||||
[MacOS](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/ogame-macos-arm64)
|
||||
[MacOS](/releases/latest/download/ogame-macos-arm64)
|
||||
|
||||
#### 桌面版
|
||||
|
||||
[Windows](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/OGame.Setup.exe)
|
||||
[Windows](/releases/latest/download/OGame.Setup.exe)
|
||||
|
||||
[Ubuntu](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/OGame.AppImage)
|
||||
[Ubuntu](/releases/latest/download/OGame.AppImage)
|
||||
|
||||
[MacOS](https://github.com/coolxitech/ogame-vue-ts/releases/latest/download/OGame-mac.dmg)
|
||||
[MacOS](/releases/latest/download/OGame-mac.dmg)
|
||||
|
||||
### 环境要求
|
||||
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
import { app, BrowserWindow } from 'electron'
|
||||
// @ts-ignore
|
||||
import path from "node:path";
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { dirname } from 'node:path'
|
||||
import pkg from '../package.json'
|
||||
|
||||
app.whenReady().then(() => {
|
||||
// @ts-ignore
|
||||
const __filename = fileURLToPath(import.meta.url)
|
||||
const __dirname = dirname(__filename)
|
||||
const win = new BrowserWindow({
|
||||
title: 'OGame',
|
||||
title: pkg.title,
|
||||
icon: path.join(__dirname, '../public/favicon.ico'),
|
||||
width: 1200,
|
||||
height: 800,
|
||||
height: 800
|
||||
})
|
||||
win.setMenu(null);
|
||||
win.setMenu(null)
|
||||
|
||||
// You can use `process.env.VITE_DEV_SERVER_URL` when the vite command is called `serve`
|
||||
if (process.env.VITE_DEV_SERVER_URL) {
|
||||
win.loadURL(process.env.VITE_DEV_SERVER_URL)
|
||||
} else {
|
||||
// Load your file
|
||||
win.loadFile('docs/index.html');
|
||||
win.loadFile('docs/index.html')
|
||||
}
|
||||
})
|
||||
8190
package-lock.json
generated
Normal file
8190
package-lock.json
generated
Normal file
@@ -0,0 +1,8190 @@
|
||||
{
|
||||
"name": "ogame-vue-ts",
|
||||
"version": "1.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "ogame-vue-ts",
|
||||
"version": "1.1.0",
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.17",
|
||||
"@tanstack/vue-table": "^8.21.3",
|
||||
"@vueuse/core": "^14.1.0",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"file-saver": "^2.0.5",
|
||||
"finalhandler": "^2.1.1",
|
||||
"lucide-vue-next": "^0.556.0",
|
||||
"pinia": "^3.0.4",
|
||||
"pinia-plugin-persistedstate": "^4.7.1",
|
||||
"reka-ui": "^2.6.1",
|
||||
"serve-static": "^2.2.0",
|
||||
"tailwind-merge": "^3.4.0",
|
||||
"tailwindcss": "^4.1.17",
|
||||
"vue": "^3.5.24",
|
||||
"vue-router": "4",
|
||||
"vue-sonner": "^2.0.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/file-saver": "^2.0.7",
|
||||
"@types/node": "^24.10.2",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"electron": "^30.0.0",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron-vite": "^5.0.0",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"typescript": "~5.9.3",
|
||||
"vite": "npm:rolldown-vite@7.2.5",
|
||||
"vite-plugin-electron": "^0.29.0",
|
||||
"vite-plugin-electron-renderer": "^0.14.6",
|
||||
"vue-tsc": "^3.1.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"js-tokens": "^4.0.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/compat-data": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.28.5.tgz",
|
||||
"integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/core": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.28.5.tgz",
|
||||
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/helper-compilation-targets": "^7.27.2",
|
||||
"@babel/helper-module-transforms": "^7.28.3",
|
||||
"@babel/helpers": "^7.28.4",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/traverse": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@jridgewell/remapping": "^2.3.5",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.2",
|
||||
"json5": "^2.2.3",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/babel"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.28.5.tgz",
|
||||
"integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/types": "^7.28.5",
|
||||
"@jridgewell/gen-mapping": "^0.3.12",
|
||||
"@jridgewell/trace-mapping": "^0.3.28",
|
||||
"jsesc": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
|
||||
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.27.2",
|
||||
"@babel/helper-validator-option": "^7.27.1",
|
||||
"browserslist": "^4.24.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-globals": {
|
||||
"version": "7.28.0",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
|
||||
"integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-imports": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
|
||||
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/traverse": "^7.27.1",
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-transforms": {
|
||||
"version": "7.28.3",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
|
||||
"integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-module-imports": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.27.1",
|
||||
"@babel/traverse": "^7.28.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-plugin-utils": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz",
|
||||
"integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
|
||||
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
|
||||
"integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-option": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
|
||||
"integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.28.4.tgz",
|
||||
"integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.28.5.tgz",
|
||||
"integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.28.5"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-arrow-functions": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz",
|
||||
"integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/template": {
|
||||
"version": "7.27.2",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.27.2.tgz",
|
||||
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/parser": "^7.27.2",
|
||||
"@babel/types": "^7.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.28.5.tgz",
|
||||
"integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.27.1",
|
||||
"@babel/generator": "^7.28.5",
|
||||
"@babel/helper-globals": "^7.28.0",
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@babel/template": "^7.27.2",
|
||||
"@babel/types": "^7.28.5",
|
||||
"debug": "^4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.28.5",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.5.tgz",
|
||||
"integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.27.1",
|
||||
"@babel/helper-validator-identifier": "^7.28.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@develar/schema-utils": {
|
||||
"version": "2.6.5",
|
||||
"resolved": "https://registry.npmmirror.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz",
|
||||
"integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.0",
|
||||
"ajv-keywords": "^3.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/asar": {
|
||||
"version": "3.2.18",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/asar/-/asar-3.2.18.tgz",
|
||||
"integrity": "sha512-2XyvMe3N3Nrs8cV39IKELRHTYUWFKrmqqSY1U+GMlc0jvqjIVnoxhNd2H4JolWQncbJi1DCvb5TNxZuI2fEjWg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"commander": "^5.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"minimatch": "^3.0.4"
|
||||
},
|
||||
"bin": {
|
||||
"asar": "bin/asar.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/asar/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/fuses": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/fuses/-/fuses-1.8.0.tgz",
|
||||
"integrity": "sha512-zx0EIq78WlY/lBb1uXlziZmDZI4ubcCXIMJ4uGjXzZW0nS19TjSPeXPAjzzTmKQlJUZm0SbmZhPKP7tuQ1SsEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"minimist": "^1.2.5"
|
||||
},
|
||||
"bin": {
|
||||
"electron-fuses": "dist/bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/fuses/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/fuses/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/fuses/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/get": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/get/-/get-2.0.3.tgz",
|
||||
"integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"env-paths": "^2.2.0",
|
||||
"fs-extra": "^8.1.0",
|
||||
"got": "^11.8.5",
|
||||
"progress": "^2.0.3",
|
||||
"semver": "^6.2.0",
|
||||
"sumchecker": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"global-agent": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/node-gyp": {
|
||||
"version": "10.2.0-electron.1",
|
||||
"resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2",
|
||||
"integrity": "sha512-4MSBTT8y07YUDqf69/vSh80Hh791epYqGtWHO3zSKhYFwQg+gx9wi1PqbqP6YqC4WMsNxZ5l9oDmnWdK5pfCKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"env-paths": "^2.2.0",
|
||||
"exponential-backoff": "^3.1.1",
|
||||
"glob": "^8.1.0",
|
||||
"graceful-fs": "^4.2.6",
|
||||
"make-fetch-happen": "^10.2.1",
|
||||
"nopt": "^6.0.0",
|
||||
"proc-log": "^2.0.1",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.2.1",
|
||||
"which": "^2.0.2"
|
||||
},
|
||||
"bin": {
|
||||
"node-gyp": "bin/node-gyp.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/node-gyp/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/node-gyp/node_modules/glob": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz",
|
||||
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^5.0.1",
|
||||
"once": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/node-gyp/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/node-gyp/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/notarize": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/notarize/-/notarize-2.5.0.tgz",
|
||||
"integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"promise-retry": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/notarize/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/notarize/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/notarize/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/osx-sign": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/osx-sign/-/osx-sign-1.3.1.tgz",
|
||||
"integrity": "sha512-BAfviURMHpmb1Yb50YbCxnOY0wfwaLXH5KJ4+80zS0gUkzDX3ec23naTlEqKsN+PwYn+a1cCzM7BJ4Wcd3sGzw==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"compare-version": "^0.1.2",
|
||||
"debug": "^4.3.4",
|
||||
"fs-extra": "^10.0.0",
|
||||
"isbinaryfile": "^4.0.8",
|
||||
"minimist": "^1.2.6",
|
||||
"plist": "^3.0.5"
|
||||
},
|
||||
"bin": {
|
||||
"electron-osx-flat": "bin/electron-osx-flat.js",
|
||||
"electron-osx-sign": "bin/electron-osx-sign.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/osx-sign/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/osx-sign/node_modules/isbinaryfile": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz",
|
||||
"integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/gjtorikian/"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/osx-sign/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/osx-sign/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/rebuild": {
|
||||
"version": "3.7.0",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/rebuild/-/rebuild-3.7.0.tgz",
|
||||
"integrity": "sha512-VW++CNSlZwMYP7MyXEbrKjpzEwhB5kDNbzGtiPEjwYysqyTCF+YbNJ210Dj3AjWsGSV4iEEwNkmJN9yGZmVvmw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2",
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
"chalk": "^4.0.0",
|
||||
"debug": "^4.1.1",
|
||||
"detect-libc": "^2.0.1",
|
||||
"fs-extra": "^10.0.0",
|
||||
"got": "^11.7.0",
|
||||
"node-abi": "^3.45.0",
|
||||
"node-api-version": "^0.2.0",
|
||||
"ora": "^5.1.0",
|
||||
"read-binary-file-arch": "^1.0.6",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.0.5",
|
||||
"yargs": "^17.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"electron-rebuild": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/rebuild/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/rebuild/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/rebuild/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/rebuild/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/universal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/universal/-/universal-2.0.1.tgz",
|
||||
"integrity": "sha512-fKpv9kg4SPmt+hY7SVBnIYULE9QJl8L3sCfcBsnqbJwwBwAeTLokJ9TRt9y7bK0JAzIW2y78TVVjvnQEms/yyA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/asar": "^3.2.7",
|
||||
"@malept/cross-spawn-promise": "^2.0.0",
|
||||
"debug": "^4.3.1",
|
||||
"dir-compare": "^4.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"minimatch": "^9.0.3",
|
||||
"plist": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/universal/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/universal/node_modules/fs-extra": {
|
||||
"version": "11.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.2.tgz",
|
||||
"integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/universal/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/universal/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/universal/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/windows-sign": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/@electron/windows-sign/-/windows-sign-1.2.2.tgz",
|
||||
"integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cross-dirname": "^0.1.0",
|
||||
"debug": "^4.3.4",
|
||||
"fs-extra": "^11.1.1",
|
||||
"minimist": "^1.2.8",
|
||||
"postject": "^1.0.0-alpha.6"
|
||||
},
|
||||
"bin": {
|
||||
"electron-windows-sign": "bin/electron-windows-sign.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/windows-sign/node_modules/fs-extra": {
|
||||
"version": "11.3.2",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.2.tgz",
|
||||
"integrity": "sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/windows-sign/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@electron/windows-sign/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/core": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmmirror.com/@emnapi/core/-/core-1.7.1.tgz",
|
||||
"integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/wasi-threads": "1.1.0",
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/runtime": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmmirror.com/@emnapi/runtime/-/runtime-1.7.1.tgz",
|
||||
"integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@emnapi/wasi-threads": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz",
|
||||
"integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz",
|
||||
"integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"aix"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.25.12.tgz",
|
||||
"integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz",
|
||||
"integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz",
|
||||
"integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz",
|
||||
"integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz",
|
||||
"integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz",
|
||||
"integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz",
|
||||
"integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz",
|
||||
"integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openharmony-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz",
|
||||
"integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz",
|
||||
"integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz",
|
||||
"integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/core": {
|
||||
"version": "1.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.7.3.tgz",
|
||||
"integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/dom": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.7.4.tgz",
|
||||
"integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/core": "^1.7.3",
|
||||
"@floating-ui/utils": "^0.2.10"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/utils": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.10.tgz",
|
||||
"integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@floating-ui/vue": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmmirror.com/@floating-ui/vue/-/vue-1.1.9.tgz",
|
||||
"integrity": "sha512-BfNqNW6KA83Nexspgb9DZuz578R7HT8MZw1CfK9I6Ah4QReNWEJsXWHN+SdmOVLNGmTPDi+fDT535Df5PzMLbQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.7.4",
|
||||
"@floating-ui/utils": "^0.2.10",
|
||||
"vue-demi": ">=0.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@floating-ui/vue/node_modules/vue-demi": {
|
||||
"version": "0.14.10",
|
||||
"resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
|
||||
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"vue-demi-fix": "bin/vue-demi-fix.js",
|
||||
"vue-demi-switch": "bin/vue-demi-switch.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vue/composition-api": "^1.0.0-rc.1",
|
||||
"vue": "^3.0.0-0 || ^2.6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vue/composition-api": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@gar/promisify": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/@gar/promisify/-/promisify-1.1.3.tgz",
|
||||
"integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@internationalized/date": {
|
||||
"version": "3.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/@internationalized/date/-/date-3.10.0.tgz",
|
||||
"integrity": "sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/helpers": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@internationalized/number": {
|
||||
"version": "3.6.5",
|
||||
"resolved": "https://registry.npmmirror.com/@internationalized/number/-/number-3.6.5.tgz",
|
||||
"integrity": "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/helpers": "^0.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/balanced-match": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz",
|
||||
"integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/brace-expansion": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz",
|
||||
"integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@isaacs/balanced-match": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^5.1.2",
|
||||
"string-width-cjs": "npm:string-width@^4.2.0",
|
||||
"strip-ansi": "^7.0.1",
|
||||
"strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
|
||||
"wrap-ansi": "^8.1.0",
|
||||
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz",
|
||||
"integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-regex?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/ansi-styles": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz",
|
||||
"integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/string-width": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-5.1.2.tgz",
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"eastasianwidth": "^0.2.0",
|
||||
"emoji-regex": "^9.2.2",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/strip-ansi": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.1.2.tgz",
|
||||
"integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^6.1.0",
|
||||
"string-width": "^5.0.1",
|
||||
"strip-ansi": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/remapping": {
|
||||
"version": "2.3.5",
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/remapping/-/remapping-2.3.5.tgz",
|
||||
"integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.31",
|
||||
"resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@malept/cross-spawn-promise": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz",
|
||||
"integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/malept"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund"
|
||||
}
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@malept/flatpak-bundler": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz",
|
||||
"integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"fs-extra": "^9.0.0",
|
||||
"lodash": "^4.17.15",
|
||||
"tmp-promise": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@malept/flatpak-bundler/node_modules/fs-extra": {
|
||||
"version": "9.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz",
|
||||
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"at-least-node": "^1.0.0",
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@malept/flatpak-bundler/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@malept/flatpak-bundler/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.0.tgz",
|
||||
"integrity": "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1",
|
||||
"@tybys/wasm-util": "^0.10.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@npmcli/fs": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/@npmcli/fs/-/fs-2.1.2.tgz",
|
||||
"integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@gar/promisify": "^1.1.3",
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@npmcli/fs/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@npmcli/move-file": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/@npmcli/move-file/-/move-file-2.0.1.tgz",
|
||||
"integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
|
||||
"deprecated": "This functionality has been moved to @npmcli/fs",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mkdirp": "^1.0.4",
|
||||
"rimraf": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/runtime": {
|
||||
"version": "0.97.0",
|
||||
"resolved": "https://registry.npmmirror.com/@oxc-project/runtime/-/runtime-0.97.0.tgz",
|
||||
"integrity": "sha512-yH0zw7z+jEws4dZ4IUKoix5Lh3yhqIJWF9Dc8PWvhpo7U7O+lJrv7ZZL4BeRO0la8LBQFwcCewtLBnVV7hPe/w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@oxc-project/types": {
|
||||
"version": "0.97.0",
|
||||
"resolved": "https://registry.npmmirror.com/@oxc-project/types/-/types-0.97.0.tgz",
|
||||
"integrity": "sha512-lxmZK4xFrdvU0yZiDwgVQTCvh2gHWBJCBk5ALsrtsBWhs0uDIi+FTOnXRQeQfs304imdvTdaakT/lqwQ8hkOXQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Boshen"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmmirror.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-android-arm64": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-XlEkrOIHLyGT3avOgzfTFSjG+f+dZMw+/qd+Y3HLN86wlndrB/gSimrJCk4gOhr1XtRtEKfszpadI3Md4Z4/Ag==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-arm64": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-+JRqKJhoFlt5r9q+DecAGPLZ5PxeLva+wCMtAuoFMWPoZzgcYrr599KQ+Ix0jwll4B4HGP43avu9My8KtSOR+w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-darwin-x64": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-fFXDjXnuX7/gQZQm/1FoivVtRcyAzdjSik7Eo+9iwPQ9EgtA5/nB2+jmbzaKtMGG3q+BnZbdKHCtOacmNrkIDA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-freebsd-x64": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-F1b6vARy49tjmT/hbloplzgJS7GIvwWZqt+tAHEstCh0JIh9sa8FAMVqEmYxDviqKBaAI8iVvUREm/Kh/PD26Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm-gnueabihf": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-U6cR76N8T8M6lHj7EZrQ3xunLPxSvYYxA8vJsBKZiFZkT8YV4kjgCO3KwMJL0NOjQCPGKyiXO07U+KmJzdPGRw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-gnu": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-ONgyjofCrrE3bnh5GZb8EINSFyR/hmwTzZ7oVuyUB170lboza1VMCnb8jgE6MsyyRgHYmN8Lb59i3NKGrxrYjw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-arm64-musl": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-L0zRdH2oDPkmB+wvuTl+dJbXCsx62SkqcEqdM+79LOcB+PxbAxxjzHU14BuZIQdXcAVDzfpMfaHWzZuwhhBTcw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-gnu": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-gyoI8o/TGpQd3OzkJnh1M2kxy1Bisg8qJ5Gci0sXm9yLFzEXIFdtc4EAzepxGvrT2ri99ar5rdsmNG0zP0SbIg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-linux-x64-musl": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-zti8A7M+xFDpKlghpcCAzyOi+e5nfUl3QhU023ce5NCgUxRG5zGP2GR9LTydQ1rnIPwZUVBWd4o7NjZDaQxaXA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-openharmony-arm64": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-eZUssog7qljrrRU9Mi0eqYEPm3Ch0UwB+qlWPMKSUXHNqhm3TvDZarJQdTevGEfu3EHAXJvBIe0YFYr0TPVaMA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-wasm32-wasi": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-nmCN0nIdeUnmgeDXiQ+2HU6FT162o+rxnF7WMkBm4M5Ds8qTU7Dzv2Wrf22bo4ftnlrb2hKK6FSwAJSAe2FWLg==",
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@napi-rs/wasm-runtime": "^1.0.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-arm64-msvc": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-7kcNLi7Ua59JTTLvbe1dYb028QEPaJPJQHqkmSZ5q3tJueUeb6yjRtx8mw4uIqgWZcnQHAR3PrLN4XRJxvgIkA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-ia32-msvc": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-lL70VTNvSCdSZkDPPVMwWn/M2yQiYvSoXw9hTLgdIWdUfC3g72UaruezusR6ceRuwHCY1Ayu2LtKqXkBO5LIwg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/binding-win32-x64-msvc": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-4qU4x5DXWB4JPjyTne/wBNPqkbQU8J45bl21geERBKtEittleonioACBL1R0PsBu0Aq21SwMK5a9zdBkWSlQtQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-beta.53",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
|
||||
"integrity": "sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/@sindresorhus/is/-/is-4.6.0.tgz",
|
||||
"integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/is?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.17",
|
||||
"resolved": "https://registry.npmmirror.com/@swc/helpers/-/helpers-0.5.17.tgz",
|
||||
"integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"tslib": "^2.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@szmarczak/http-timer": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
|
||||
"integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"defer-to-connect": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/node": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/node/-/node-4.1.18.tgz",
|
||||
"integrity": "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/remapping": "^2.3.4",
|
||||
"enhanced-resolve": "^5.18.3",
|
||||
"jiti": "^2.6.1",
|
||||
"lightningcss": "1.30.2",
|
||||
"magic-string": "^0.30.21",
|
||||
"source-map-js": "^1.2.1",
|
||||
"tailwindcss": "4.1.18"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide/-/oxide-4.1.18.tgz",
|
||||
"integrity": "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@tailwindcss/oxide-android-arm64": "4.1.18",
|
||||
"@tailwindcss/oxide-darwin-arm64": "4.1.18",
|
||||
"@tailwindcss/oxide-darwin-x64": "4.1.18",
|
||||
"@tailwindcss/oxide-freebsd-x64": "4.1.18",
|
||||
"@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18",
|
||||
"@tailwindcss/oxide-linux-arm64-gnu": "4.1.18",
|
||||
"@tailwindcss/oxide-linux-arm64-musl": "4.1.18",
|
||||
"@tailwindcss/oxide-linux-x64-gnu": "4.1.18",
|
||||
"@tailwindcss/oxide-linux-x64-musl": "4.1.18",
|
||||
"@tailwindcss/oxide-wasm32-wasi": "4.1.18",
|
||||
"@tailwindcss/oxide-win32-arm64-msvc": "4.1.18",
|
||||
"@tailwindcss/oxide-win32-x64-msvc": "4.1.18"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-android-arm64": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.18.tgz",
|
||||
"integrity": "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-darwin-arm64": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.18.tgz",
|
||||
"integrity": "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-darwin-x64": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.18.tgz",
|
||||
"integrity": "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-freebsd-x64": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.18.tgz",
|
||||
"integrity": "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.18.tgz",
|
||||
"integrity": "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.18.tgz",
|
||||
"integrity": "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-arm64-musl": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.18.tgz",
|
||||
"integrity": "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-x64-gnu": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.18.tgz",
|
||||
"integrity": "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-linux-x64-musl": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.18.tgz",
|
||||
"integrity": "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-wasm32-wasi": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.18.tgz",
|
||||
"integrity": "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA==",
|
||||
"bundleDependencies": [
|
||||
"@napi-rs/wasm-runtime",
|
||||
"@emnapi/core",
|
||||
"@emnapi/runtime",
|
||||
"@tybys/wasm-util",
|
||||
"@emnapi/wasi-threads",
|
||||
"tslib"
|
||||
],
|
||||
"cpu": [
|
||||
"wasm32"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@emnapi/core": "^1.7.1",
|
||||
"@emnapi/runtime": "^1.7.1",
|
||||
"@emnapi/wasi-threads": "^1.1.0",
|
||||
"@napi-rs/wasm-runtime": "^1.1.0",
|
||||
"@tybys/wasm-util": "^0.10.1",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.18.tgz",
|
||||
"integrity": "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/oxide-win32-x64-msvc": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.18.tgz",
|
||||
"integrity": "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/vite": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/@tailwindcss/vite/-/vite-4.1.18.tgz",
|
||||
"integrity": "sha512-jVA+/UpKL1vRLg6Hkao5jldawNmRo7mQYrZtNHMIVpLfLhDml5nMRUo/8MwoX2vNXvnaXNNMedrMfMugAVX1nA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tailwindcss/node": "4.1.18",
|
||||
"@tailwindcss/oxide": "4.1.18",
|
||||
"tailwindcss": "4.1.18"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^5.2.0 || ^6 || ^7"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/table-core": {
|
||||
"version": "8.21.3",
|
||||
"resolved": "https://registry.npmmirror.com/@tanstack/table-core/-/table-core-8.21.3.tgz",
|
||||
"integrity": "sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/virtual-core": {
|
||||
"version": "3.13.13",
|
||||
"resolved": "https://registry.npmmirror.com/@tanstack/virtual-core/-/virtual-core-3.13.13.tgz",
|
||||
"integrity": "sha512-uQFoSdKKf5S8k51W5t7b2qpfkyIbdHMzAn+AMQvHPxKUPeo1SsGaA4JRISQT87jm28b7z8OEqPcg1IOZagQHcA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/vue-table": {
|
||||
"version": "8.21.3",
|
||||
"resolved": "https://registry.npmmirror.com/@tanstack/vue-table/-/vue-table-8.21.3.tgz",
|
||||
"integrity": "sha512-rusRyd77c5tDPloPskctMyPLFEQUeBzxdQ+2Eow4F7gDPlPOB1UnnhzfpdvqZ8ZyX2rRNGmqNnQWm87OI2OQPw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/table-core": "8.21.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">=3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@tanstack/vue-virtual": {
|
||||
"version": "3.13.13",
|
||||
"resolved": "https://registry.npmmirror.com/@tanstack/vue-virtual/-/vue-virtual-3.13.13.tgz",
|
||||
"integrity": "sha512-Cf2xIEE8nWAfsX0N5nihkPYMeQRT+pHt4NEkuP8rNCn6lVnLDiV8rC8IeIxbKmQC0yPnj4SIBLwXYVf86xxKTQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tanstack/virtual-core": "3.13.13"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/tannerlinsley"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^2.7.0 || ^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/@tootallnate/once/-/once-2.0.0.tgz",
|
||||
"integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/@tybys/wasm-util": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
|
||||
"integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cacheable-request": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
|
||||
"integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/http-cache-semantics": "*",
|
||||
"@types/keyv": "^3.1.4",
|
||||
"@types/node": "*",
|
||||
"@types/responselike": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/crypto-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/@types/crypto-js/-/crypto-js-4.2.2.tgz",
|
||||
"integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/debug": {
|
||||
"version": "4.1.12",
|
||||
"resolved": "https://registry.npmmirror.com/@types/debug/-/debug-4.1.12.tgz",
|
||||
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/file-saver": {
|
||||
"version": "2.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/@types/file-saver/-/file-saver-2.0.7.tgz",
|
||||
"integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/fs-extra": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmmirror.com/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/http-cache-semantics": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
|
||||
"integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/keyv": {
|
||||
"version": "3.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/@types/keyv/-/keyv-3.1.4.tgz",
|
||||
"integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@types/ms/-/ms-2.1.0.tgz",
|
||||
"integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "24.10.4",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-24.10.4.tgz",
|
||||
"integrity": "sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==",
|
||||
"devOptional": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/plist": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/@types/plist/-/plist-3.0.5.tgz",
|
||||
"integrity": "sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"xmlbuilder": ">=11.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/responselike": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/@types/responselike/-/responselike-1.0.3.tgz",
|
||||
"integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/verror": {
|
||||
"version": "1.10.11",
|
||||
"resolved": "https://registry.npmmirror.com/@types/verror/-/verror-1.10.11.tgz",
|
||||
"integrity": "sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/web-bluetooth": {
|
||||
"version": "0.0.21",
|
||||
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
|
||||
"integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/yauzl": {
|
||||
"version": "2.10.3",
|
||||
"resolved": "https://registry.npmmirror.com/@types/yauzl/-/yauzl-2.10.3.tgz",
|
||||
"integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-6.0.3.tgz",
|
||||
"integrity": "sha512-TlGPkLFLVOY3T7fZrwdvKpjprR3s4fxRln0ORDo1VQ7HHyxJwTlrjKU3kpVWTlaAjIEuCTokmjkZnr8Tpc925w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rolldown/pluginutils": "1.0.0-beta.53"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0",
|
||||
"vue": "^3.2.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/language-core": {
|
||||
"version": "2.4.26",
|
||||
"resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.26.tgz",
|
||||
"integrity": "sha512-hH0SMitMxnB43OZpyF1IFPS9bgb2I3bpCh76m2WEK7BE0A0EzpYsRp0CCH2xNKshr7kacU5TQBLYn4zj7CG60A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/source-map": "2.4.26"
|
||||
}
|
||||
},
|
||||
"node_modules/@volar/source-map": {
|
||||
"version": "2.4.26",
|
||||
"resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.26.tgz",
|
||||
"integrity": "sha512-JJw0Tt/kSFsIRmgTQF4JSt81AUSI1aEye5Zl65EeZ8H35JHnTvFGmpDOBn5iOxd48fyGE+ZvZBp5FcgAy/1Qhw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@volar/typescript": {
|
||||
"version": "2.4.26",
|
||||
"resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.26.tgz",
|
||||
"integrity": "sha512-N87ecLD48Sp6zV9zID/5yuS1+5foj0DfuYGdQ6KHj/IbKvyKv1zNX6VCmnKYwtmHadEO6mFc2EKISiu3RDPAvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/language-core": "2.4.26",
|
||||
"path-browserify": "^1.0.1",
|
||||
"vscode-uri": "^3.0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.25.tgz",
|
||||
"integrity": "sha512-vay5/oQJdsNHmliWoZfHPoVZZRmnSWhug0BYT34njkYTPqClh3DNWLkZNJBVSjsNMrg0CCrBfoKkjZQPM/QVUw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@vue/shared": "3.5.25",
|
||||
"entities": "^4.5.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.25.tgz",
|
||||
"integrity": "sha512-4We0OAcMZsKgYoGlMjzYvaoErltdFI2/25wqanuTu+S4gismOTRTBPi4IASOjxWdzIwrYSjnqONfKvuqkXzE2Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-core": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.25.tgz",
|
||||
"integrity": "sha512-PUgKp2rn8fFsI++lF2sO7gwO2d9Yj57Utr5yEsDf3GNaQcowCLKL7sf+LvVFvtJDXUp/03+dC6f2+LCv5aK1ag==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.28.5",
|
||||
"@vue/compiler-core": "3.5.25",
|
||||
"@vue/compiler-dom": "3.5.25",
|
||||
"@vue/compiler-ssr": "3.5.25",
|
||||
"@vue/shared": "3.5.25",
|
||||
"estree-walker": "^2.0.2",
|
||||
"magic-string": "^0.30.21",
|
||||
"postcss": "^8.5.6",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.25.tgz",
|
||||
"integrity": "sha512-ritPSKLBcParnsKYi+GNtbdbrIE1mtuFEJ4U1sWeuOMlIziK5GtOL85t5RhsNy4uWIXPgk+OUdpnXiTdzn8o3A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-api": {
|
||||
"version": "7.7.9",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-7.7.9.tgz",
|
||||
"integrity": "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-kit": "^7.7.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-kit": {
|
||||
"version": "7.7.9",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz",
|
||||
"integrity": "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-shared": "^7.7.9",
|
||||
"birpc": "^2.3.0",
|
||||
"hookable": "^5.5.3",
|
||||
"mitt": "^3.0.1",
|
||||
"perfect-debounce": "^1.0.0",
|
||||
"speakingurl": "^14.0.1",
|
||||
"superjson": "^2.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/devtools-shared": {
|
||||
"version": "7.7.9",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz",
|
||||
"integrity": "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"rfdc": "^1.4.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/language-core": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-3.1.8.tgz",
|
||||
"integrity": "sha512-PfwAW7BLopqaJbneChNL6cUOTL3GL+0l8paYP5shhgY5toBNidWnMXWM+qDwL7MC9+zDtzCF2enT8r6VPu64iw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/language-core": "2.4.26",
|
||||
"@vue/compiler-dom": "^3.5.0",
|
||||
"@vue/shared": "^3.5.0",
|
||||
"alien-signals": "^3.0.0",
|
||||
"muggle-string": "^0.4.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/reactivity": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.25.tgz",
|
||||
"integrity": "sha512-5xfAypCQepv4Jog1U4zn8cZIcbKKFka3AgWHEFQeK65OW+Ys4XybP6z2kKgws4YB43KGpqp5D/K3go2UPPunLA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-core": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.25.tgz",
|
||||
"integrity": "sha512-Z751v203YWwYzy460bzsYQISDfPjHTl+6Zzwo/a3CsAf+0ccEjQ8c+0CdX1WsumRTHeywvyUFtW6KvNukT/smA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/runtime-dom": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.25.tgz",
|
||||
"integrity": "sha512-a4WrkYFbb19i9pjkz38zJBg8wa/rboNERq3+hRRb0dHiJh13c+6kAbgqCPfMaJ2gg4weWD3APZswASOfmKwamA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/reactivity": "3.5.25",
|
||||
"@vue/runtime-core": "3.5.25",
|
||||
"@vue/shared": "3.5.25",
|
||||
"csstype": "^3.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/server-renderer": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.25.tgz",
|
||||
"integrity": "sha512-UJaXR54vMG61i8XNIzTSf2Q7MOqZHpp8+x3XLGtE3+fL+nQd+k7O5+X3D/uWrnQXOdMw5VPih+Uremcw+u1woQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-ssr": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.5.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/shared": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.25.tgz",
|
||||
"integrity": "sha512-AbOPdQQnAnzs58H2FrrDxYj/TJfmeS2jdfEEhgiKINy+bnOANmVizIEgq1r+C5zsbs6l1CCQxtcj71rwNQ4jWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/tsconfig": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.8.1.tgz",
|
||||
"integrity": "sha512-aK7feIWPXFSUhsCP9PFqPyFOcz4ENkb8hZ2pneL6m2UjCkccvaOhC/5KCKluuBufvp2KzkbdA2W2pk20vLzu3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"typescript": "5.x",
|
||||
"vue": "^3.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
},
|
||||
"vue": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/core": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-14.1.0.tgz",
|
||||
"integrity": "sha512-rgBinKs07hAYyPF834mDTigH7BtPqvZ3Pryuzt1SD/lg5wEcWqvwzXXYGEDb2/cP0Sj5zSvHl3WkmMELr5kfWw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/web-bluetooth": "^0.0.21",
|
||||
"@vueuse/metadata": "14.1.0",
|
||||
"@vueuse/shared": "14.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/metadata": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-14.1.0.tgz",
|
||||
"integrity": "sha512-7hK4g015rWn2PhKcZ99NyT+ZD9sbwm7SGvp7k+k+rKGWnLjS/oQozoIZzWfCewSUeBmnJkIb+CNr7Zc/EyRnnA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/shared": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-14.1.0.tgz",
|
||||
"integrity": "sha512-EcKxtYvn6gx1F8z9J5/rsg3+lTQnvOruQd8fUecW99DCK04BkWD7z5KQ/wTAx+DazyoEE9dJt/zV8OIEQbM6kw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.8.11",
|
||||
"resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.11.tgz",
|
||||
"integrity": "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/7zip-bin": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/7zip-bin/-/7zip-bin-5.2.0.tgz",
|
||||
"integrity": "sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/abbrev/-/abbrev-1.1.1.tgz",
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz",
|
||||
"integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/agentkeepalive": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
|
||||
"integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"humanize-ms": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/aggregate-error": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clean-stack": "^2.0.0",
|
||||
"indent-string": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv-keywords": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"ajv": "^6.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/alien-signals": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-3.1.1.tgz",
|
||||
"integrity": "sha512-ogkIWbVrLwKtHY6oOAXaYkAxP+cTH7V5FZ5+Tm4NZFd8VDZ6uNMDrfzqctTZ42eTMCSR3ne3otpcxmqSnFfPYA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ansi-regex": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-convert": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/app-builder-bin": {
|
||||
"version": "5.0.0-alpha.12",
|
||||
"resolved": "https://registry.npmmirror.com/app-builder-bin/-/app-builder-bin-5.0.0-alpha.12.tgz",
|
||||
"integrity": "sha512-j87o0j6LqPL3QRr8yid6c+Tt5gC7xNfYo6uQIQkorAC6MpeayVMZrEDzKmJJ/Hlv7EnOQpaRm53k6ktDYZyB6w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/app-builder-lib": {
|
||||
"version": "26.0.12",
|
||||
"resolved": "https://registry.npmmirror.com/app-builder-lib/-/app-builder-lib-26.0.12.tgz",
|
||||
"integrity": "sha512-+/CEPH1fVKf6HowBUs6LcAIoRcjeqgvAeoSE+cl7Y7LndyQ9ViGPYibNk7wmhMHzNgHIuIbw4nWADPO+4mjgWw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@develar/schema-utils": "~2.6.5",
|
||||
"@electron/asar": "3.2.18",
|
||||
"@electron/fuses": "^1.8.0",
|
||||
"@electron/notarize": "2.5.0",
|
||||
"@electron/osx-sign": "1.3.1",
|
||||
"@electron/rebuild": "3.7.0",
|
||||
"@electron/universal": "2.0.1",
|
||||
"@malept/flatpak-bundler": "^0.4.0",
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"async-exit-hook": "^2.0.1",
|
||||
"builder-util": "26.0.11",
|
||||
"builder-util-runtime": "9.3.1",
|
||||
"chromium-pickle-js": "^0.2.0",
|
||||
"config-file-ts": "0.2.8-rc1",
|
||||
"debug": "^4.3.4",
|
||||
"dotenv": "^16.4.5",
|
||||
"dotenv-expand": "^11.0.6",
|
||||
"ejs": "^3.1.8",
|
||||
"electron-publish": "26.0.11",
|
||||
"fs-extra": "^10.1.0",
|
||||
"hosted-git-info": "^4.1.0",
|
||||
"is-ci": "^3.0.0",
|
||||
"isbinaryfile": "^5.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"json5": "^2.2.3",
|
||||
"lazy-val": "^1.0.5",
|
||||
"minimatch": "^10.0.0",
|
||||
"plist": "3.1.0",
|
||||
"resedit": "^1.7.0",
|
||||
"semver": "^7.3.8",
|
||||
"tar": "^6.1.12",
|
||||
"temp-file": "^3.4.0",
|
||||
"tiny-async-pool": "1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"dmg-builder": "26.0.12",
|
||||
"electron-builder-squirrel-windows": "26.0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/app-builder-lib/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/app-builder-lib/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/app-builder-lib/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/app-builder-lib/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true,
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmmirror.com/aria-hidden/-/aria-hidden-1.2.6.tgz",
|
||||
"integrity": "sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/astral-regex": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/astral-regex/-/astral-regex-2.0.0.tgz",
|
||||
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmmirror.com/async/-/async-3.2.6.tgz",
|
||||
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/async-exit-hook": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/async-exit-hook/-/async-exit-hook-2.0.1.tgz",
|
||||
"integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/at-least-node": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
|
||||
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/base64-js": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
|
||||
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.9.7",
|
||||
"resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.7.tgz",
|
||||
"integrity": "sha512-k9xFKplee6KIio3IDbwj+uaCLpqzOwakOgmqzPezM0sFJlFKcg30vk2wOiAJtkTSfx0SSQDSe8q+mWA/fSH5Zg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"baseline-browser-mapping": "dist/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/birpc": {
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmmirror.com/birpc/-/birpc-2.9.0.tgz",
|
||||
"integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/bl": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz",
|
||||
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer": "^5.5.0",
|
||||
"inherits": "^2.0.4",
|
||||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/boolean": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/boolean/-/boolean-3.2.0.tgz",
|
||||
"integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==",
|
||||
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.12.tgz",
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.28.1",
|
||||
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz",
|
||||
"integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
"electron-to-chromium": "^1.5.263",
|
||||
"node-releases": "^2.0.27",
|
||||
"update-browserslist-db": "^1.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
"version": "5.7.1",
|
||||
"resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz",
|
||||
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.1",
|
||||
"ieee754": "^1.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-crc32": {
|
||||
"version": "0.2.13",
|
||||
"resolved": "https://registry.npmmirror.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
|
||||
"integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/builder-util": {
|
||||
"version": "26.0.11",
|
||||
"resolved": "https://registry.npmmirror.com/builder-util/-/builder-util-26.0.11.tgz",
|
||||
"integrity": "sha512-xNjXfsldUEe153h1DraD0XvDOpqGR0L5eKFkdReB7eFW5HqysDZFfly4rckda6y9dF39N3pkPlOblcfHKGw+uA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/debug": "^4.1.6",
|
||||
"7zip-bin": "~5.2.0",
|
||||
"app-builder-bin": "5.0.0-alpha.12",
|
||||
"builder-util-runtime": "9.3.1",
|
||||
"chalk": "^4.1.2",
|
||||
"cross-spawn": "^7.0.6",
|
||||
"debug": "^4.3.4",
|
||||
"fs-extra": "^10.1.0",
|
||||
"http-proxy-agent": "^7.0.0",
|
||||
"https-proxy-agent": "^7.0.0",
|
||||
"is-ci": "^3.0.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"sanitize-filename": "^1.6.3",
|
||||
"source-map-support": "^0.5.19",
|
||||
"stat-mode": "^1.0.0",
|
||||
"temp-file": "^3.4.0",
|
||||
"tiny-async-pool": "1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/builder-util-runtime": {
|
||||
"version": "9.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/builder-util-runtime/-/builder-util-runtime-9.3.1.tgz",
|
||||
"integrity": "sha512-2/egrNDDnRaxVwK3A+cJq6UOlqOdedGA7JPqCeJjN2Zjk1/QB/6QUi3b714ScIGS7HafFXTyzJEOr5b44I3kvQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"sax": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/builder-util/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/builder-util/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/builder-util/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cac": {
|
||||
"version": "6.7.14",
|
||||
"resolved": "https://registry.npmmirror.com/cac/-/cac-6.7.14.tgz",
|
||||
"integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cacache": {
|
||||
"version": "16.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/cacache/-/cacache-16.1.3.tgz",
|
||||
"integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@npmcli/fs": "^2.1.0",
|
||||
"@npmcli/move-file": "^2.0.0",
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.1.0",
|
||||
"glob": "^8.0.1",
|
||||
"infer-owner": "^1.0.4",
|
||||
"lru-cache": "^7.7.1",
|
||||
"minipass": "^3.1.6",
|
||||
"minipass-collect": "^1.0.2",
|
||||
"minipass-flush": "^1.0.5",
|
||||
"minipass-pipeline": "^1.2.4",
|
||||
"mkdirp": "^1.0.4",
|
||||
"p-map": "^4.0.0",
|
||||
"promise-inflight": "^1.0.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"ssri": "^9.0.0",
|
||||
"tar": "^6.1.11",
|
||||
"unique-filename": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cacache/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cacache/node_modules/glob": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/glob/-/glob-8.1.0.tgz",
|
||||
"integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^5.0.1",
|
||||
"once": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/cacache/node_modules/lru-cache": {
|
||||
"version": "7.18.3",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.18.3.tgz",
|
||||
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/cacache/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-lookup": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
|
||||
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cacheable-request": {
|
||||
"version": "7.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/cacheable-request/-/cacheable-request-7.0.4.tgz",
|
||||
"integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clone-response": "^1.0.2",
|
||||
"get-stream": "^5.1.0",
|
||||
"http-cache-semantics": "^4.0.0",
|
||||
"keyv": "^4.0.0",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"normalize-url": "^6.0.1",
|
||||
"responselike": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/call-bind-apply-helpers": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
|
||||
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001760",
|
||||
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001760.tgz",
|
||||
"integrity": "sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.1.0",
|
||||
"supports-color": "^7.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/chromium-pickle-js": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
|
||||
"integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ci-info": {
|
||||
"version": "3.9.0",
|
||||
"resolved": "https://registry.npmmirror.com/ci-info/-/ci-info-3.9.0.tgz",
|
||||
"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/sibiraj-s"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/class-variance-authority": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmmirror.com/class-variance-authority/-/class-variance-authority-0.7.1.tgz",
|
||||
"integrity": "sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://polar.sh/cva"
|
||||
}
|
||||
},
|
||||
"node_modules/clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"restore-cursor": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-spinners": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.9.2.tgz",
|
||||
"integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-truncate": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/cli-truncate/-/cli-truncate-2.1.0.tgz",
|
||||
"integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"slice-ansi": "^3.0.0",
|
||||
"string-width": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/cliui": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz",
|
||||
"integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"string-width": "^4.2.0",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"wrap-ansi": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/clone": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/clone/-/clone-1.0.4.tgz",
|
||||
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/clone-response": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/clone-response/-/clone-response-1.0.3.tgz",
|
||||
"integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mimic-response": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/clsx/-/clsx-2.1.1.tgz",
|
||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/color-convert": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"color-name": "~1.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/color-name": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/commander/-/commander-5.1.0.tgz",
|
||||
"integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/compare-version": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/compare-version/-/compare-version-0.1.2.tgz",
|
||||
"integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/config-file-ts": {
|
||||
"version": "0.2.8-rc1",
|
||||
"resolved": "https://registry.npmmirror.com/config-file-ts/-/config-file-ts-0.2.8-rc1.tgz",
|
||||
"integrity": "sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"glob": "^10.3.12",
|
||||
"typescript": "^5.4.3"
|
||||
}
|
||||
},
|
||||
"node_modules/config-file-ts/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/config-file-ts/node_modules/glob": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/glob/-/glob-10.5.0.tgz",
|
||||
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.1.0",
|
||||
"jackspeak": "^3.1.2",
|
||||
"minimatch": "^9.0.4",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^1.11.1"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/config-file-ts/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/config-file-ts/node_modules/minipass": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz",
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/copy-anything": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-4.0.5.tgz",
|
||||
"integrity": "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-what": "^5.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mesqueeb"
|
||||
}
|
||||
},
|
||||
"node_modules/core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/crc": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmmirror.com/crc/-/crc-3.8.0.tgz",
|
||||
"integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cross-dirname": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/cross-dirname/-/cross-dirname-0.1.0.tgz",
|
||||
"integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/crypto-js": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
|
||||
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz",
|
||||
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mimic-response": "^3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/decompress-response/node_modules/mimic-response": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz",
|
||||
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/defaults": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/defaults/-/defaults-1.0.4.tgz",
|
||||
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clone": "^1.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/defer-to-connect": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/define-properties": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.2.1.tgz",
|
||||
"integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0",
|
||||
"object-keys": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/defu": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/defu/-/defu-6.1.4.tgz",
|
||||
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/depd/-/depd-2.0.0.tgz",
|
||||
"integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
"integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-node": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/detect-node/-/detect-node-2.1.0.tgz",
|
||||
"integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/dir-compare": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/dir-compare/-/dir-compare-4.2.0.tgz",
|
||||
"integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minimatch": "^3.0.5",
|
||||
"p-limit": "^3.1.0 "
|
||||
}
|
||||
},
|
||||
"node_modules/dir-compare/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/dmg-builder": {
|
||||
"version": "26.0.12",
|
||||
"resolved": "https://registry.npmmirror.com/dmg-builder/-/dmg-builder-26.0.12.tgz",
|
||||
"integrity": "sha512-59CAAjAhTaIMCN8y9kD573vDkxbs1uhDcrFLHSgutYdPcGOU35Rf95725snvzEOy4BFB7+eLJ8djCNPmGwG67w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"app-builder-lib": "26.0.12",
|
||||
"builder-util": "26.0.11",
|
||||
"builder-util-runtime": "9.3.1",
|
||||
"fs-extra": "^10.1.0",
|
||||
"iconv-lite": "^0.6.2",
|
||||
"js-yaml": "^4.1.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"dmg-license": "^1.0.11"
|
||||
}
|
||||
},
|
||||
"node_modules/dmg-builder/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/dmg-builder/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/dmg-builder/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dmg-license": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmmirror.com/dmg-license/-/dmg-license-1.0.11.tgz",
|
||||
"integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/plist": "^3.0.1",
|
||||
"@types/verror": "^1.10.3",
|
||||
"ajv": "^6.10.0",
|
||||
"crc": "^3.8.0",
|
||||
"iconv-corefoundation": "^1.1.7",
|
||||
"plist": "^3.0.4",
|
||||
"smart-buffer": "^4.0.2",
|
||||
"verror": "^1.10.0"
|
||||
},
|
||||
"bin": {
|
||||
"dmg-license": "bin/dmg-license.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/dotenv/-/dotenv-16.6.1.tgz",
|
||||
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv-expand": {
|
||||
"version": "11.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/dotenv-expand/-/dotenv-expand-11.0.7.tgz",
|
||||
"integrity": "sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"dotenv": "^16.4.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ejs": {
|
||||
"version": "3.1.10",
|
||||
"resolved": "https://registry.npmmirror.com/ejs/-/ejs-3.1.10.tgz",
|
||||
"integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"jake": "^10.8.5"
|
||||
},
|
||||
"bin": {
|
||||
"ejs": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron": {
|
||||
"version": "30.5.1",
|
||||
"resolved": "https://registry.npmmirror.com/electron/-/electron-30.5.1.tgz",
|
||||
"integrity": "sha512-AhL7+mZ8Lg14iaNfoYTkXQ2qee8mmsQyllKdqxlpv/zrKgfxz6jNVtcRRbQtLxtF8yzcImWdfTQROpYiPumdbw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@electron/get": "^2.0.0",
|
||||
"@types/node": "^20.9.0",
|
||||
"extract-zip": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"electron": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.20.55"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-builder": {
|
||||
"version": "26.0.12",
|
||||
"resolved": "https://registry.npmmirror.com/electron-builder/-/electron-builder-26.0.12.tgz",
|
||||
"integrity": "sha512-cD1kz5g2sgPTMFHjLxfMjUK5JABq3//J4jPswi93tOPFz6btzXYtK5NrDt717NRbukCUDOrrvmYVOWERlqoiXA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"app-builder-lib": "26.0.12",
|
||||
"builder-util": "26.0.11",
|
||||
"builder-util-runtime": "9.3.1",
|
||||
"chalk": "^4.1.2",
|
||||
"dmg-builder": "26.0.12",
|
||||
"fs-extra": "^10.1.0",
|
||||
"is-ci": "^3.0.0",
|
||||
"lazy-val": "^1.0.5",
|
||||
"simple-update-notifier": "2.0.0",
|
||||
"yargs": "^17.6.2"
|
||||
},
|
||||
"bin": {
|
||||
"electron-builder": "cli.js",
|
||||
"install-app-deps": "install-app-deps.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-builder-squirrel-windows": {
|
||||
"version": "26.0.12",
|
||||
"resolved": "https://registry.npmmirror.com/electron-builder-squirrel-windows/-/electron-builder-squirrel-windows-26.0.12.tgz",
|
||||
"integrity": "sha512-kpwXM7c/ayRUbYVErQbsZ0nQZX4aLHQrPEG9C4h9vuJCXylwFH8a7Jgi2VpKIObzCXO7LKHiCw4KdioFLFOgqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"app-builder-lib": "26.0.12",
|
||||
"builder-util": "26.0.11",
|
||||
"electron-winstaller": "5.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-builder/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-builder/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-builder/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-publish": {
|
||||
"version": "26.0.11",
|
||||
"resolved": "https://registry.npmmirror.com/electron-publish/-/electron-publish-26.0.11.tgz",
|
||||
"integrity": "sha512-a8QRH0rAPIWH9WyyS5LbNvW9Ark6qe63/LqDB7vu2JXYpi0Gma5Q60Dh4tmTqhOBQt0xsrzD8qE7C+D7j+B24A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/fs-extra": "^9.0.11",
|
||||
"builder-util": "26.0.11",
|
||||
"builder-util-runtime": "9.3.1",
|
||||
"chalk": "^4.1.2",
|
||||
"form-data": "^4.0.0",
|
||||
"fs-extra": "^10.1.0",
|
||||
"lazy-val": "^1.0.5",
|
||||
"mime": "^2.5.2"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-publish/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-publish/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-publish/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.267",
|
||||
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz",
|
||||
"integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/electron-vite": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/electron-vite/-/electron-vite-5.0.0.tgz",
|
||||
"integrity": "sha512-OHp/vjdlubNlhNkPkL/+3JD34ii5ov7M0GpuXEVdQeqdQ3ulvVR7Dg/rNBLfS5XPIFwgoBLDf9sjjrL+CuDyRQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.28.4",
|
||||
"@babel/plugin-transform-arrow-functions": "^7.27.1",
|
||||
"cac": "^6.7.14",
|
||||
"esbuild": "^0.25.11",
|
||||
"magic-string": "^0.30.19",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"electron-vite": "bin/electron-vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/core": "^1.0.0",
|
||||
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/core": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/electron-winstaller": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/electron-winstaller/-/electron-winstaller-5.4.0.tgz",
|
||||
"integrity": "sha512-bO3y10YikuUwUuDUQRM4KfwNkKhnpVO7IPdbsrejwN9/AABJzzTQ4GeHwyzNSrVO+tEH3/Np255a3sVZpZDjvg==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@electron/asar": "^3.2.1",
|
||||
"debug": "^4.1.1",
|
||||
"fs-extra": "^7.0.1",
|
||||
"lodash": "^4.17.21",
|
||||
"temp": "^0.9.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@electron/windows-sign": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-winstaller/node_modules/fs-extra": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-7.0.1.tgz",
|
||||
"integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
}
|
||||
},
|
||||
"node_modules/electron/node_modules/@types/node": {
|
||||
"version": "20.19.27",
|
||||
"resolved": "https://registry.npmmirror.com/@types/node/-/node-20.19.27.tgz",
|
||||
"integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron/node_modules/undici-types": {
|
||||
"version": "6.21.0",
|
||||
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.21.0.tgz",
|
||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/encodeurl/-/encodeurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/encoding": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmmirror.com/encoding/-/encoding-0.1.13.tgz",
|
||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.5",
|
||||
"resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.5.tgz",
|
||||
"integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.18.4",
|
||||
"resolved": "https://registry.npmmirror.com/enhanced-resolve/-/enhanced-resolve-5.18.4.tgz",
|
||||
"integrity": "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/env-paths": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/env-paths/-/env-paths-2.2.1.tgz",
|
||||
"integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/err-code": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/err-code/-/err-code-2.0.3.tgz",
|
||||
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-object-atoms": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
|
||||
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
|
||||
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.6",
|
||||
"has-tostringtag": "^1.0.2",
|
||||
"hasown": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es6-error": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/es6-error/-/es6-error-4.1.1.tgz",
|
||||
"integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.25.12.tgz",
|
||||
"integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==",
|
||||
"devOptional": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.25.12",
|
||||
"@esbuild/android-arm": "0.25.12",
|
||||
"@esbuild/android-arm64": "0.25.12",
|
||||
"@esbuild/android-x64": "0.25.12",
|
||||
"@esbuild/darwin-arm64": "0.25.12",
|
||||
"@esbuild/darwin-x64": "0.25.12",
|
||||
"@esbuild/freebsd-arm64": "0.25.12",
|
||||
"@esbuild/freebsd-x64": "0.25.12",
|
||||
"@esbuild/linux-arm": "0.25.12",
|
||||
"@esbuild/linux-arm64": "0.25.12",
|
||||
"@esbuild/linux-ia32": "0.25.12",
|
||||
"@esbuild/linux-loong64": "0.25.12",
|
||||
"@esbuild/linux-mips64el": "0.25.12",
|
||||
"@esbuild/linux-ppc64": "0.25.12",
|
||||
"@esbuild/linux-riscv64": "0.25.12",
|
||||
"@esbuild/linux-s390x": "0.25.12",
|
||||
"@esbuild/linux-x64": "0.25.12",
|
||||
"@esbuild/netbsd-arm64": "0.25.12",
|
||||
"@esbuild/netbsd-x64": "0.25.12",
|
||||
"@esbuild/openbsd-arm64": "0.25.12",
|
||||
"@esbuild/openbsd-x64": "0.25.12",
|
||||
"@esbuild/openharmony-arm64": "0.25.12",
|
||||
"@esbuild/sunos-x64": "0.25.12",
|
||||
"@esbuild/win32-arm64": "0.25.12",
|
||||
"@esbuild/win32-ia32": "0.25.12",
|
||||
"@esbuild/win32-x64": "0.25.12"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmmirror.com/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/exponential-backoff": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz",
|
||||
"integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/extract-zip": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/extract-zip/-/extract-zip-2.0.1.tgz",
|
||||
"integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.1",
|
||||
"get-stream": "^5.1.0",
|
||||
"yauzl": "^2.10.0"
|
||||
},
|
||||
"bin": {
|
||||
"extract-zip": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.17.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@types/yauzl": "^2.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/extsprintf": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/extsprintf/-/extsprintf-1.4.1.tgz",
|
||||
"integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==",
|
||||
"dev": true,
|
||||
"engines": [
|
||||
"node >=0.6.0"
|
||||
],
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-json-stable-stringify": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fd-slicer": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fd-slicer/-/fd-slicer-1.1.0.tgz",
|
||||
"integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pend": "~1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz",
|
||||
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"picomatch": "^3 || ^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"picomatch": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/file-saver": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/file-saver/-/file-saver-2.0.5.tgz",
|
||||
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/filelist": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/filelist/-/filelist-1.0.4.tgz",
|
||||
"integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"minimatch": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/brace-expansion": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filelist/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-2.1.1.tgz",
|
||||
"integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.4.0",
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"on-finished": "^2.4.1",
|
||||
"parseurl": "^1.3.3",
|
||||
"statuses": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz",
|
||||
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.6",
|
||||
"signal-exit": "^4.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/foreground-child/node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.5.tgz",
|
||||
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"es-set-tostringtag": "^2.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/fresh": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/fresh/-/fresh-2.0.0.tgz",
|
||||
"integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-extra": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-8.1.0.tgz",
|
||||
"integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6 <7 || >=8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "6.* || 8.* || >= 10.*"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
|
||||
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind-apply-helpers": "^1.0.2",
|
||||
"es-define-property": "^1.0.1",
|
||||
"es-errors": "^1.3.0",
|
||||
"es-object-atoms": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-proto": "^1.0.1",
|
||||
"gopd": "^1.2.0",
|
||||
"has-symbols": "^1.1.0",
|
||||
"hasown": "^2.0.2",
|
||||
"math-intrinsics": "^1.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz",
|
||||
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"dunder-proto": "^1.0.1",
|
||||
"es-object-atoms": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/glob/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/global-agent": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/global-agent/-/global-agent-3.0.0.tgz",
|
||||
"integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"boolean": "^3.0.1",
|
||||
"es6-error": "^4.1.1",
|
||||
"matcher": "^3.0.0",
|
||||
"roarr": "^2.15.3",
|
||||
"semver": "^7.3.2",
|
||||
"serialize-error": "^7.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/global-agent/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/globalthis": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/globalthis/-/globalthis-1.0.4.tgz",
|
||||
"integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"define-properties": "^1.2.1",
|
||||
"gopd": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.2.0.tgz",
|
||||
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/got": {
|
||||
"version": "11.8.6",
|
||||
"resolved": "https://registry.npmmirror.com/got/-/got-11.8.6.tgz",
|
||||
"integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@sindresorhus/is": "^4.0.0",
|
||||
"@szmarczak/http-timer": "^4.0.5",
|
||||
"@types/cacheable-request": "^6.0.1",
|
||||
"@types/responselike": "^1.0.0",
|
||||
"cacheable-lookup": "^5.0.3",
|
||||
"cacheable-request": "^7.0.2",
|
||||
"decompress-response": "^6.0.0",
|
||||
"http2-wrapper": "^1.0.0-beta.5.2",
|
||||
"lowercase-keys": "^2.0.0",
|
||||
"p-cancelable": "^2.0.0",
|
||||
"responselike": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.19.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/got?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/has-flag": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.1.0.tgz",
|
||||
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-tostringtag": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
|
||||
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-symbols": "^1.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/hookable": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz",
|
||||
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
|
||||
"integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/hosted-git-info/node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/hosted-git-info/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/http-cache-semantics": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz",
|
||||
"integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause"
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-2.0.1.tgz",
|
||||
"integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"depd": "~2.0.0",
|
||||
"inherits": "~2.0.4",
|
||||
"setprototypeof": "~1.2.0",
|
||||
"statuses": "~2.0.2",
|
||||
"toidentifier": "~1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/http-proxy-agent": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
||||
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/http2-wrapper": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
|
||||
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"quick-lru": "^5.1.1",
|
||||
"resolve-alpn": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.19.0"
|
||||
}
|
||||
},
|
||||
"node_modules/https-proxy-agent": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "^7.1.2",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/humanize-ms": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
||||
"integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-corefoundation": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmmirror.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz",
|
||||
"integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"dependencies": {
|
||||
"cli-truncate": "^2.1.0",
|
||||
"node-addon-api": "^1.6.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^8.11.2 || >=10"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ieee754": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz",
|
||||
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/imurmurhash": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmmirror.com/imurmurhash/-/imurmurhash-0.1.4.tgz",
|
||||
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/indent-string/-/indent-string-4.0.0.tgz",
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/infer-owner": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/infer-owner/-/infer-owner-1.0.4.tgz",
|
||||
"integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
|
||||
"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.",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/ip-address": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-10.1.0.tgz",
|
||||
"integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/is-ci": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/is-ci/-/is-ci-3.0.1.tgz",
|
||||
"integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ci-info": "^3.2.0"
|
||||
},
|
||||
"bin": {
|
||||
"is-ci": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-interactive": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-interactive/-/is-interactive-1.0.0.tgz",
|
||||
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-lambda": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/is-lambda/-/is-lambda-1.0.1.tgz",
|
||||
"integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/is-unicode-supported": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
|
||||
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-what": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/is-what/-/is-what-5.5.0.tgz",
|
||||
"integrity": "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/mesqueeb"
|
||||
}
|
||||
},
|
||||
"node_modules/isbinaryfile": {
|
||||
"version": "5.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/isbinaryfile/-/isbinaryfile-5.0.7.tgz",
|
||||
"integrity": "sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 18.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/gjtorikian/"
|
||||
}
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/jackspeak/-/jackspeak-3.4.3.tgz",
|
||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@pkgjs/parseargs": "^0.11.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jake": {
|
||||
"version": "10.9.4",
|
||||
"resolved": "https://registry.npmmirror.com/jake/-/jake-10.9.4.tgz",
|
||||
"integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"async": "^3.2.6",
|
||||
"filelist": "^1.0.4",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"jake": "bin/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/jiti/-/jiti-2.6.1.tgz",
|
||||
"integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.1.tgz",
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
"bin": {
|
||||
"js-yaml": "bin/js-yaml.js"
|
||||
}
|
||||
},
|
||||
"node_modules/jsesc": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz",
|
||||
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jsesc": "bin/jsesc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/json-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.1.tgz",
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/json5": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
|
||||
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"json5": "lib/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/keyv": {
|
||||
"version": "4.5.4",
|
||||
"resolved": "https://registry.npmmirror.com/keyv/-/keyv-4.5.4.tgz",
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"json-buffer": "3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/lazy-val": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/lazy-val/-/lazy-val-1.0.5.tgz",
|
||||
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lightningcss": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss/-/lightningcss-1.30.2.tgz",
|
||||
"integrity": "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==",
|
||||
"license": "MPL-2.0",
|
||||
"dependencies": {
|
||||
"detect-libc": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"lightningcss-android-arm64": "1.30.2",
|
||||
"lightningcss-darwin-arm64": "1.30.2",
|
||||
"lightningcss-darwin-x64": "1.30.2",
|
||||
"lightningcss-freebsd-x64": "1.30.2",
|
||||
"lightningcss-linux-arm-gnueabihf": "1.30.2",
|
||||
"lightningcss-linux-arm64-gnu": "1.30.2",
|
||||
"lightningcss-linux-arm64-musl": "1.30.2",
|
||||
"lightningcss-linux-x64-gnu": "1.30.2",
|
||||
"lightningcss-linux-x64-musl": "1.30.2",
|
||||
"lightningcss-win32-arm64-msvc": "1.30.2",
|
||||
"lightningcss-win32-x64-msvc": "1.30.2"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-android-arm64": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.30.2.tgz",
|
||||
"integrity": "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-darwin-arm64": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.2.tgz",
|
||||
"integrity": "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-darwin-x64": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.2.tgz",
|
||||
"integrity": "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-freebsd-x64": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.2.tgz",
|
||||
"integrity": "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm-gnueabihf": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.2.tgz",
|
||||
"integrity": "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm64-gnu": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.2.tgz",
|
||||
"integrity": "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-arm64-musl": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.2.tgz",
|
||||
"integrity": "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-x64-gnu": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.2.tgz",
|
||||
"integrity": "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-linux-x64-musl": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.2.tgz",
|
||||
"integrity": "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-win32-arm64-msvc": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.2.tgz",
|
||||
"integrity": "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lightningcss-win32-x64-msvc": {
|
||||
"version": "1.30.2",
|
||||
"resolved": "https://registry.npmmirror.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.2.tgz",
|
||||
"integrity": "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "MPL-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">= 12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/parcel"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/log-symbols": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.0",
|
||||
"is-unicode-supported": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lowercase-keys": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
|
||||
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/lucide-vue-next": {
|
||||
"version": "0.556.0",
|
||||
"resolved": "https://registry.npmmirror.com/lucide-vue-next/-/lucide-vue-next-0.556.0.tgz",
|
||||
"integrity": "sha512-JvdCM2smkWrMDhkfD/FpZiWekkbWD6MZLstIFx/FOVZgULrnMr5hegCB9LlTdgllEFnQYQs8hhHC1WYcAV9HTA==",
|
||||
"license": "ISC",
|
||||
"peerDependencies": {
|
||||
"vue": ">=3.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.21.tgz",
|
||||
"integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/sourcemap-codec": "^1.5.5"
|
||||
}
|
||||
},
|
||||
"node_modules/make-fetch-happen": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
|
||||
"integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"agentkeepalive": "^4.2.1",
|
||||
"cacache": "^16.1.0",
|
||||
"http-cache-semantics": "^4.1.0",
|
||||
"http-proxy-agent": "^5.0.0",
|
||||
"https-proxy-agent": "^5.0.0",
|
||||
"is-lambda": "^1.0.1",
|
||||
"lru-cache": "^7.7.1",
|
||||
"minipass": "^3.1.6",
|
||||
"minipass-collect": "^1.0.2",
|
||||
"minipass-fetch": "^2.0.3",
|
||||
"minipass-flush": "^1.0.5",
|
||||
"minipass-pipeline": "^1.2.4",
|
||||
"negotiator": "^0.6.3",
|
||||
"promise-retry": "^2.0.1",
|
||||
"socks-proxy-agent": "^7.0.0",
|
||||
"ssri": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/make-fetch-happen/node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/make-fetch-happen/node_modules/http-proxy-agent": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
|
||||
"integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tootallnate/once": "2",
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/make-fetch-happen/node_modules/https-proxy-agent": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
|
||||
"integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "6",
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/make-fetch-happen/node_modules/lru-cache": {
|
||||
"version": "7.18.3",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.18.3.tgz",
|
||||
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/matcher": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/matcher/-/matcher-3.0.0.tgz",
|
||||
"integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"escape-string-regexp": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/math-intrinsics": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
|
||||
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime/-/mime-2.6.0.tgz",
|
||||
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mime": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-fn": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/mimic-response/-/mimic-response-1.0.1.tgz",
|
||||
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-10.1.1.tgz",
|
||||
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/brace-expansion": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/minimist": {
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmmirror.com/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass-collect": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/minipass-collect/-/minipass-collect-1.0.2.tgz",
|
||||
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass-fetch": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
|
||||
"integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minipass": "^3.1.6",
|
||||
"minipass-sized": "^1.0.3",
|
||||
"minizlib": "^2.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"encoding": "^0.1.13"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass-flush": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/minipass-flush/-/minipass-flush-1.0.5.tgz",
|
||||
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass-pipeline": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmmirror.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
|
||||
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass-sized": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/minipass-sized/-/minipass-sized-1.0.3.tgz",
|
||||
"integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/minipass/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/minizlib": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/minizlib/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/muggle-string": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz",
|
||||
"integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.4",
|
||||
"resolved": "https://registry.npmmirror.com/negotiator/-/negotiator-0.6.4.tgz",
|
||||
"integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi": {
|
||||
"version": "3.85.0",
|
||||
"resolved": "https://registry.npmmirror.com/node-abi/-/node-abi-3.85.0.tgz",
|
||||
"integrity": "sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-abi/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-addon-api": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-1.7.2.tgz",
|
||||
"integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/node-api-version": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/node-api-version/-/node-api-version-0.2.1.tgz",
|
||||
"integrity": "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.3.5"
|
||||
}
|
||||
},
|
||||
"node_modules/node-api-version/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.27",
|
||||
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz",
|
||||
"integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nopt": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/nopt/-/nopt-6.0.0.tgz",
|
||||
"integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"abbrev": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"nopt": "bin/nopt.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/normalize-url": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/normalize-url/-/normalize-url-6.1.0.tgz",
|
||||
"integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz",
|
||||
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/ohash": {
|
||||
"version": "2.0.11",
|
||||
"resolved": "https://registry.npmmirror.com/ohash/-/ohash-2.0.11.tgz",
|
||||
"integrity": "sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/on-finished": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/on-finished/-/on-finished-2.4.1.tgz",
|
||||
"integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"node_modules/onetime": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/ora": {
|
||||
"version": "5.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/ora/-/ora-5.4.1.tgz",
|
||||
"integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bl": "^4.1.0",
|
||||
"chalk": "^4.1.0",
|
||||
"cli-cursor": "^3.1.0",
|
||||
"cli-spinners": "^2.5.0",
|
||||
"is-interactive": "^1.0.0",
|
||||
"is-unicode-supported": "^0.1.0",
|
||||
"log-symbols": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0",
|
||||
"wcwidth": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-cancelable": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/p-cancelable/-/p-cancelable-2.1.1.tgz",
|
||||
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/p-limit": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-limit/-/p-limit-3.1.0.tgz",
|
||||
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"yocto-queue": "^0.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/p-map": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/p-map/-/p-map-4.0.0.tgz",
|
||||
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/package-json-from-dist": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
|
||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmmirror.com/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-browserify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz",
|
||||
"integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-scurry": {
|
||||
"version": "1.11.1",
|
||||
"resolved": "https://registry.npmmirror.com/path-scurry/-/path-scurry-1.11.1.tgz",
|
||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"lru-cache": "^10.2.0",
|
||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/path-scurry/node_modules/lru-cache": {
|
||||
"version": "10.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-10.4.3.tgz",
|
||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/path-scurry/node_modules/minipass": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/minipass/-/minipass-7.1.2.tgz",
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/pe-library": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/pe-library/-/pe-library-0.4.1.tgz",
|
||||
"integrity": "sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jet2jet"
|
||||
}
|
||||
},
|
||||
"node_modules/pend": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/pend/-/pend-1.2.0.tgz",
|
||||
"integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/perfect-debounce": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
|
||||
"integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmmirror.com/pinia/-/pinia-3.0.4.tgz",
|
||||
"integrity": "sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^7.7.7"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.5.0",
|
||||
"vue": "^3.5.11"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/pinia-plugin-persistedstate": {
|
||||
"version": "4.7.1",
|
||||
"resolved": "https://registry.npmmirror.com/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-4.7.1.tgz",
|
||||
"integrity": "sha512-WHOqh2esDlR3eAaknPbqXrkkj0D24h8shrDPqysgCFR6ghqP/fpFfJmMPJp0gETHsvrh9YNNg6dQfo2OEtDnIQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"defu": "^6.1.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nuxt/kit": ">=3.0.0",
|
||||
"@pinia/nuxt": ">=0.10.0",
|
||||
"pinia": ">=3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@nuxt/kit": {
|
||||
"optional": true
|
||||
},
|
||||
"@pinia/nuxt": {
|
||||
"optional": true
|
||||
},
|
||||
"pinia": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/plist": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/plist/-/plist-3.1.0.tgz",
|
||||
"integrity": "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@xmldom/xmldom": "^0.8.8",
|
||||
"base64-js": "^1.5.1",
|
||||
"xmlbuilder": "^15.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
|
||||
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/postject": {
|
||||
"version": "1.0.0-alpha.6",
|
||||
"resolved": "https://registry.npmmirror.com/postject/-/postject-1.0.0-alpha.6.tgz",
|
||||
"integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"commander": "^9.4.0"
|
||||
},
|
||||
"bin": {
|
||||
"postject": "dist/cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/postject/node_modules/commander": {
|
||||
"version": "9.5.0",
|
||||
"resolved": "https://registry.npmmirror.com/commander/-/commander-9.5.0.tgz",
|
||||
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/proc-log": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/proc-log/-/proc-log-2.0.1.tgz",
|
||||
"integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/progress": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/progress/-/progress-2.0.3.tgz",
|
||||
"integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/promise-inflight": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/promise-inflight/-/promise-inflight-1.0.1.tgz",
|
||||
"integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/promise-retry": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/promise-retry/-/promise-retry-2.0.1.tgz",
|
||||
"integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"err-code": "^2.0.2",
|
||||
"retry": "^0.12.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/pump": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.3.tgz",
|
||||
"integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"end-of-stream": "^1.1.0",
|
||||
"once": "^1.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/quick-lru": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/quick-lru/-/quick-lru-5.1.1.tgz",
|
||||
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/read-binary-file-arch": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmmirror.com/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz",
|
||||
"integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"bin": {
|
||||
"read-binary-file-arch": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz",
|
||||
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/reka-ui": {
|
||||
"version": "2.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/reka-ui/-/reka-ui-2.6.1.tgz",
|
||||
"integrity": "sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@floating-ui/dom": "^1.6.13",
|
||||
"@floating-ui/vue": "^1.1.6",
|
||||
"@internationalized/date": "^3.5.0",
|
||||
"@internationalized/number": "^3.5.0",
|
||||
"@tanstack/vue-virtual": "^3.12.0",
|
||||
"@vueuse/core": "^12.5.0",
|
||||
"@vueuse/shared": "^12.5.0",
|
||||
"aria-hidden": "^1.2.4",
|
||||
"defu": "^6.1.4",
|
||||
"ohash": "^2.0.11"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">= 3.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reka-ui/node_modules/@vueuse/core": {
|
||||
"version": "12.8.2",
|
||||
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-12.8.2.tgz",
|
||||
"integrity": "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/web-bluetooth": "^0.0.21",
|
||||
"@vueuse/metadata": "12.8.2",
|
||||
"@vueuse/shared": "12.8.2",
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/reka-ui/node_modules/@vueuse/metadata": {
|
||||
"version": "12.8.2",
|
||||
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-12.8.2.tgz",
|
||||
"integrity": "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/reka-ui/node_modules/@vueuse/shared": {
|
||||
"version": "12.8.2",
|
||||
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-12.8.2.tgz",
|
||||
"integrity": "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"vue": "^3.5.13"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/require-directory": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
|
||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resedit": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/resedit/-/resedit-1.7.2.tgz",
|
||||
"integrity": "sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pe-library": "^0.4.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/jet2jet"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-alpn": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
|
||||
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/responselike": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/responselike/-/responselike-2.0.1.tgz",
|
||||
"integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lowercase-keys": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/restore-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-3.1.0.tgz",
|
||||
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"onetime": "^5.1.0",
|
||||
"signal-exit": "^3.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/retry": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmmirror.com/retry/-/retry-0.12.0.tgz",
|
||||
"integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/rfdc": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz",
|
||||
"integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/roarr": {
|
||||
"version": "2.15.4",
|
||||
"resolved": "https://registry.npmmirror.com/roarr/-/roarr-2.15.4.tgz",
|
||||
"integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"boolean": "^3.0.1",
|
||||
"detect-node": "^2.0.4",
|
||||
"globalthis": "^1.0.1",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"semver-compare": "^1.0.0",
|
||||
"sprintf-js": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/rolldown/-/rolldown-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-JFULvCNl/anKn99eKjOSEubi0lLmNqQDAjyEMME2T4CwezUDL0i6t1O9xZsu2OMehPnV2caNefWpGF+8TnzB6A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@oxc-project/types": "=0.97.0",
|
||||
"@rolldown/pluginutils": "1.0.0-beta.50"
|
||||
},
|
||||
"bin": {
|
||||
"rolldown": "bin/cli.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rolldown/binding-android-arm64": "1.0.0-beta.50",
|
||||
"@rolldown/binding-darwin-arm64": "1.0.0-beta.50",
|
||||
"@rolldown/binding-darwin-x64": "1.0.0-beta.50",
|
||||
"@rolldown/binding-freebsd-x64": "1.0.0-beta.50",
|
||||
"@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.50",
|
||||
"@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.50",
|
||||
"@rolldown/binding-linux-arm64-musl": "1.0.0-beta.50",
|
||||
"@rolldown/binding-linux-x64-gnu": "1.0.0-beta.50",
|
||||
"@rolldown/binding-linux-x64-musl": "1.0.0-beta.50",
|
||||
"@rolldown/binding-openharmony-arm64": "1.0.0-beta.50",
|
||||
"@rolldown/binding-wasm32-wasi": "1.0.0-beta.50",
|
||||
"@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.50",
|
||||
"@rolldown/binding-win32-ia32-msvc": "1.0.0-beta.50",
|
||||
"@rolldown/binding-win32-x64-msvc": "1.0.0-beta.50"
|
||||
}
|
||||
},
|
||||
"node_modules/rolldown/node_modules/@rolldown/pluginutils": {
|
||||
"version": "1.0.0-beta.50",
|
||||
"resolved": "https://registry.npmmirror.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.50.tgz",
|
||||
"integrity": "sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sanitize-filename": {
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmmirror.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
|
||||
"integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
|
||||
"dev": true,
|
||||
"license": "WTFPL OR ISC",
|
||||
"dependencies": {
|
||||
"truncate-utf8-bytes": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.3.tgz",
|
||||
"integrity": "sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/semver-compare": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/semver-compare/-/semver-compare-1.0.0.tgz",
|
||||
"integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/send": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/send/-/send-1.2.0.tgz",
|
||||
"integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.5",
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"etag": "^1.8.1",
|
||||
"fresh": "^2.0.0",
|
||||
"http-errors": "^2.0.0",
|
||||
"mime-types": "^3.0.1",
|
||||
"ms": "^2.1.3",
|
||||
"on-finished": "^2.4.1",
|
||||
"range-parser": "^1.2.1",
|
||||
"statuses": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/send/node_modules/mime-db": {
|
||||
"version": "1.54.0",
|
||||
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.54.0.tgz",
|
||||
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/send/node_modules/mime-types": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-3.0.2.tgz",
|
||||
"integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mime-db": "^1.54.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/express"
|
||||
}
|
||||
},
|
||||
"node_modules/serialize-error": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/serialize-error/-/serialize-error-7.0.1.tgz",
|
||||
"integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-2.2.0.tgz",
|
||||
"integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"encodeurl": "^2.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"parseurl": "^1.3.3",
|
||||
"send": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/simple-update-notifier": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
|
||||
"integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^7.5.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/simple-update-notifier/node_modules/semver": {
|
||||
"version": "7.7.3",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.7.3.tgz",
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/slice-ansi": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-3.0.0.tgz",
|
||||
"integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"astral-regex": "^2.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/smart-buffer": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/smart-buffer/-/smart-buffer-4.2.0.tgz",
|
||||
"integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socks": {
|
||||
"version": "2.8.7",
|
||||
"resolved": "https://registry.npmmirror.com/socks/-/socks-2.8.7.tgz",
|
||||
"integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ip-address": "^10.0.1",
|
||||
"smart-buffer": "^4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/socks-proxy-agent": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
|
||||
"integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"agent-base": "^6.0.2",
|
||||
"debug": "^4.3.3",
|
||||
"socks": "^2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/socks-proxy-agent/node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/agent-base/-/agent-base-6.0.2.tgz",
|
||||
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmmirror.com/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/speakingurl": {
|
||||
"version": "14.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz",
|
||||
"integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sprintf-js": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/sprintf-js/-/sprintf-js-1.1.3.tgz",
|
||||
"integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/ssri": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/ssri/-/ssri-9.0.1.tgz",
|
||||
"integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"minipass": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stat-mode": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/stat-mode/-/stat-mode-1.0.0.tgz",
|
||||
"integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/statuses/-/statuses-2.0.2.tgz",
|
||||
"integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/string_decoder": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz",
|
||||
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"safe-buffer": "~5.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width-cjs": {
|
||||
"name": "string-width",
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz",
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"emoji-regex": "^8.0.0",
|
||||
"is-fullwidth-code-point": "^3.0.0",
|
||||
"strip-ansi": "^6.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-ansi-cjs": {
|
||||
"name": "strip-ansi",
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/sumchecker": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/sumchecker/-/sumchecker-3.0.1.tgz",
|
||||
"integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"debug": "^4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/superjson": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.6.tgz",
|
||||
"integrity": "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"copy-anything": "^4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/supports-color": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has-flag": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwind-merge": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/tailwind-merge/-/tailwind-merge-3.4.0.tgz",
|
||||
"integrity": "sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/dcastil"
|
||||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "4.1.18",
|
||||
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-4.1.18.tgz",
|
||||
"integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tapable": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/tapable/-/tapable-2.3.0.tgz",
|
||||
"integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmmirror.com/tar/-/tar-6.2.1.tgz",
|
||||
"integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^5.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/tar/node_modules/minipass": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/minipass/-/minipass-5.0.0.tgz",
|
||||
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/tar/node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/temp": {
|
||||
"version": "0.9.4",
|
||||
"resolved": "https://registry.npmmirror.com/temp/-/temp-0.9.4.tgz",
|
||||
"integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"mkdirp": "^0.5.1",
|
||||
"rimraf": "~2.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/temp-file": {
|
||||
"version": "3.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/temp-file/-/temp-file-3.4.0.tgz",
|
||||
"integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"async-exit-hook": "^2.0.1",
|
||||
"fs-extra": "^10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/temp-file/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/temp-file/node_modules/jsonfile": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.2.0.tgz",
|
||||
"integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"graceful-fs": "^4.1.6"
|
||||
}
|
||||
},
|
||||
"node_modules/temp-file/node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/temp/node_modules/mkdirp": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||
"integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"minimist": "^1.2.6"
|
||||
},
|
||||
"bin": {
|
||||
"mkdirp": "bin/cmd.js"
|
||||
}
|
||||
},
|
||||
"node_modules/temp/node_modules/rimraf": {
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-2.6.3.tgz",
|
||||
"integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-async-pool": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmmirror.com/tiny-async-pool/-/tiny-async-pool-1.3.0.tgz",
|
||||
"integrity": "sha512-01EAw5EDrcVrdgyCLgoSPvqznC0sVxDSVeiOz09FUpjh71G79VCqneOr+xvt7T1r76CF6ZZfPjHorN2+d+3mqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"semver": "^5.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-async-pool/node_modules/semver": {
|
||||
"version": "5.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
|
||||
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.15",
|
||||
"resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
||||
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fdir": "^6.5.0",
|
||||
"picomatch": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/tmp": {
|
||||
"version": "0.2.5",
|
||||
"resolved": "https://registry.npmmirror.com/tmp/-/tmp-0.2.5.tgz",
|
||||
"integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14.14"
|
||||
}
|
||||
},
|
||||
"node_modules/tmp-promise": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmmirror.com/tmp-promise/-/tmp-promise-3.0.3.tgz",
|
||||
"integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tmp": "^0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/toidentifier/-/toidentifier-1.0.1.tgz",
|
||||
"integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/truncate-utf8-bytes": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
|
||||
"integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
|
||||
"dev": true,
|
||||
"license": "WTFPL",
|
||||
"dependencies": {
|
||||
"utf8-byte-length": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
|
||||
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||
"license": "0BSD"
|
||||
},
|
||||
"node_modules/tw-animate-css": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmmirror.com/tw-animate-css/-/tw-animate-css-1.4.0.tgz",
|
||||
"integrity": "sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/Wombosvideo"
|
||||
}
|
||||
},
|
||||
"node_modules/type-fest": {
|
||||
"version": "0.13.1",
|
||||
"resolved": "https://registry.npmmirror.com/type-fest/-/type-fest-0.13.1.tgz",
|
||||
"integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==",
|
||||
"dev": true,
|
||||
"license": "(MIT OR CC0-1.0)",
|
||||
"optional": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "7.16.0",
|
||||
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-7.16.0.tgz",
|
||||
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
||||
"devOptional": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unique-filename": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/unique-filename/-/unique-filename-2.0.1.tgz",
|
||||
"integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"unique-slug": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unique-slug": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/unique-slug/-/unique-slug-3.0.0.tgz",
|
||||
"integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"imurmurhash": "^0.1.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.13.0 || ^14.15.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz",
|
||||
"integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.2.tgz",
|
||||
"integrity": "sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"escalade": "^3.2.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"update-browserslist-db": "cli.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"browserslist": ">= 4.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uri-js": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/utf8-byte-length": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmmirror.com/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
|
||||
"integrity": "sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==",
|
||||
"dev": true,
|
||||
"license": "(WTFPL OR MIT)"
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/verror": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmmirror.com/verror/-/verror-1.10.1.tgz",
|
||||
"integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"name": "rolldown-vite",
|
||||
"version": "7.2.5",
|
||||
"resolved": "https://registry.npmmirror.com/rolldown-vite/-/rolldown-vite-7.2.5.tgz",
|
||||
"integrity": "sha512-u09tdk/huMiN8xwoiBbig197jKdCamQTtOruSalOzbqGje3jdHiV0njQlAW0YvzoahkirFePNQ4RYlfnRQpXZA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@oxc-project/runtime": "0.97.0",
|
||||
"fdir": "^6.5.0",
|
||||
"lightningcss": "^1.30.2",
|
||||
"picomatch": "^4.0.3",
|
||||
"postcss": "^8.5.6",
|
||||
"rolldown": "1.0.0-beta.50",
|
||||
"tinyglobby": "^0.2.15"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || >=22.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/vitejs/vite?sponsor=1"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": "^20.19.0 || >=22.12.0",
|
||||
"esbuild": "^0.25.0",
|
||||
"jiti": ">=1.21.0",
|
||||
"less": "^4.0.0",
|
||||
"sass": "^1.70.0",
|
||||
"sass-embedded": "^1.70.0",
|
||||
"stylus": ">=0.54.8",
|
||||
"sugarss": "^5.0.0",
|
||||
"terser": "^5.16.0",
|
||||
"tsx": "^4.8.1",
|
||||
"yaml": "^2.4.2"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"esbuild": {
|
||||
"optional": true
|
||||
},
|
||||
"jiti": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"terser": {
|
||||
"optional": true
|
||||
},
|
||||
"tsx": {
|
||||
"optional": true
|
||||
},
|
||||
"yaml": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-electron": {
|
||||
"version": "0.29.0",
|
||||
"resolved": "https://registry.npmmirror.com/vite-plugin-electron/-/vite-plugin-electron-0.29.0.tgz",
|
||||
"integrity": "sha512-HP0DI9Shg41hzt55IKYVnbrChWXHX95QtsEQfM+szQBpWjVhVGMlqRjVco6ebfQjWNr+Ga+PeoBjMIl8zMaufw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"vite-plugin-electron-renderer": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vite-plugin-electron-renderer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-electron-renderer": {
|
||||
"version": "0.14.6",
|
||||
"resolved": "https://registry.npmmirror.com/vite-plugin-electron-renderer/-/vite-plugin-electron-renderer-0.14.6.tgz",
|
||||
"integrity": "sha512-oqkWFa7kQIkvHXG7+Mnl1RTroA4sP0yesKatmAy0gjZC4VwUqlvF9IvOpHd1fpLWsqYX/eZlVxlhULNtaQ78Jw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vscode-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue": {
|
||||
"version": "3.5.25",
|
||||
"resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.25.tgz",
|
||||
"integrity": "sha512-YLVdgv2K13WJ6n+kD5owehKtEXwdwXuj2TTyJMsO7pSeKw2bfRNZGjhB7YzrpbMYj5b5QsUebHpOqR3R3ziy/g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.25",
|
||||
"@vue/compiler-sfc": "3.5.25",
|
||||
"@vue/runtime-dom": "3.5.25",
|
||||
"@vue/server-renderer": "3.5.25",
|
||||
"@vue/shared": "3.5.25"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"typescript": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router": {
|
||||
"version": "4.6.4",
|
||||
"resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.6.4.tgz",
|
||||
"integrity": "sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^6.6.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/posva"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-router/node_modules/@vue/devtools-api": {
|
||||
"version": "6.6.4",
|
||||
"resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
|
||||
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue-sonner": {
|
||||
"version": "2.0.9",
|
||||
"resolved": "https://registry.npmmirror.com/vue-sonner/-/vue-sonner-2.0.9.tgz",
|
||||
"integrity": "sha512-i6BokNlNDL93fpzNxN/LZSn6D6MzlO+i3qXt6iVZne3x1k7R46d5HlFB4P8tYydhgqOrRbIZEsnRd3kG7qGXyw==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"@nuxt/kit": "^4.0.3",
|
||||
"@nuxt/schema": "^4.0.3",
|
||||
"nuxt": "^4.0.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@nuxt/kit": {
|
||||
"optional": true
|
||||
},
|
||||
"@nuxt/schema": {
|
||||
"optional": true
|
||||
},
|
||||
"nuxt": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vue-tsc": {
|
||||
"version": "3.1.8",
|
||||
"resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-3.1.8.tgz",
|
||||
"integrity": "sha512-deKgwx6exIHeZwF601P1ktZKNF0bepaSN4jBU3AsbldPx9gylUc1JDxYppl82yxgkAgaz0Y0LCLOi+cXe9HMYA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@volar/typescript": "2.4.26",
|
||||
"@vue/language-core": "3.1.8"
|
||||
},
|
||||
"bin": {
|
||||
"vue-tsc": "bin/vue-tsc.js"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=5.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wcwidth": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/wcwidth/-/wcwidth-1.0.1.tgz",
|
||||
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"defaults": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs": {
|
||||
"name": "wrap-ansi",
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-styles": "^4.0.0",
|
||||
"string-width": "^4.1.0",
|
||||
"strip-ansi": "^6.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/xmlbuilder": {
|
||||
"version": "15.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz",
|
||||
"integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/y18n": {
|
||||
"version": "5.0.8",
|
||||
"resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz",
|
||||
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
"version": "17.7.2",
|
||||
"resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz",
|
||||
"integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cliui": "^8.0.1",
|
||||
"escalade": "^3.1.1",
|
||||
"get-caller-file": "^2.0.5",
|
||||
"require-directory": "^2.1.1",
|
||||
"string-width": "^4.2.3",
|
||||
"y18n": "^5.0.5",
|
||||
"yargs-parser": "^21.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/yauzl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmmirror.com/yauzl/-/yauzl-2.10.0.tgz",
|
||||
"integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-crc32": "~0.2.3",
|
||||
"fd-slicer": "~1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yocto-queue": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/yocto-queue/-/yocto-queue-0.1.0.tgz",
|
||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
package.json
22
package.json
@@ -8,8 +8,8 @@
|
||||
"email": "1962257451@qq.com"
|
||||
},
|
||||
"private": true,
|
||||
"version": "1.1.0",
|
||||
"buildDate": "2025/12/14 13:13:07",
|
||||
"version": "1.3.0",
|
||||
"buildDate": "2025/12/17 21:05:49",
|
||||
"main": "dist-electron/main.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
@@ -17,7 +17,7 @@
|
||||
"build": "vue-tsc -b && vite build && node update-build-date.js",
|
||||
"preview": "vite preview",
|
||||
"build:server": "pnpm run build && go build",
|
||||
"build:electron": "pnpm run build && electron-builder"
|
||||
"build:electron": "cross-env ELECTRON_BUILD=1 pnpm run build && electron-builder"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/vite": "^4.1.17",
|
||||
@@ -29,6 +29,7 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"finalhandler": "^2.1.1",
|
||||
"lucide-vue-next": "^0.556.0",
|
||||
"marked": "^17.0.1",
|
||||
"pinia": "^3.0.4",
|
||||
"pinia-plugin-persistedstate": "^4.7.1",
|
||||
"reka-ui": "^2.6.1",
|
||||
@@ -45,6 +46,7 @@
|
||||
"@types/node": "^24.10.2",
|
||||
"@vitejs/plugin-vue": "^6.0.1",
|
||||
"@vue/tsconfig": "^0.8.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"electron": "^39.2.7",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron-vite": "^5.0.0",
|
||||
@@ -53,6 +55,7 @@
|
||||
"vite": "npm:rolldown-vite@7.2.5",
|
||||
"vite-plugin-electron": "^0.29.0",
|
||||
"vite-plugin-electron-renderer": "^0.14.6",
|
||||
"vite-plugin-pwa": "^1.2.0",
|
||||
"vue-tsc": "^3.1.4"
|
||||
},
|
||||
"pnpm": {
|
||||
@@ -63,6 +66,9 @@
|
||||
"electron-winstaller",
|
||||
"esbuild",
|
||||
"vue-demi"
|
||||
],
|
||||
"ignoredBuiltDependencies": [
|
||||
"electron"
|
||||
]
|
||||
},
|
||||
"packageManager": "pnpm@10.13.1+sha512.37ebf1a5c7a30d5fabe0c5df44ee8da4c965ca0c5af3dbab28c3a1681b70a256218d05c81c9c0dcf767ef6b8551eb5b960042b9ed4300c59242336377e01cfad",
|
||||
@@ -79,11 +85,17 @@
|
||||
"artifactName": "${productName}-Setup.${ext}"
|
||||
},
|
||||
"mac": {
|
||||
"target": ["dmg", "zip"],
|
||||
"target": [
|
||||
"dmg",
|
||||
"zip"
|
||||
],
|
||||
"artifactName": "${productName}-mac.${ext}"
|
||||
},
|
||||
"linux": {
|
||||
"target": ["AppImage", "deb"],
|
||||
"target": [
|
||||
"AppImage",
|
||||
"deb"
|
||||
],
|
||||
"artifactName": "${productName}-linux.${ext}"
|
||||
}
|
||||
}
|
||||
|
||||
2898
pnpm-lock.yaml
generated
2898
pnpm-lock.yaml
generated
@@ -38,6 +38,9 @@ importers:
|
||||
lucide-vue-next:
|
||||
specifier: ^0.556.0
|
||||
version: 0.556.0(vue@3.5.25(typescript@5.9.3))
|
||||
marked:
|
||||
specifier: ^17.0.1
|
||||
version: 17.0.1
|
||||
pinia:
|
||||
specifier: ^3.0.4
|
||||
version: 3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))
|
||||
@@ -81,6 +84,9 @@ importers:
|
||||
'@vue/tsconfig':
|
||||
specifier: ^0.8.1
|
||||
version: 0.8.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))
|
||||
cross-env:
|
||||
specifier: ^7.0.3
|
||||
version: 7.0.3
|
||||
electron:
|
||||
specifier: ^39.2.7
|
||||
version: 39.2.7
|
||||
@@ -105,6 +111,9 @@ importers:
|
||||
vite-plugin-electron-renderer:
|
||||
specifier: ^0.14.6
|
||||
version: 0.14.6
|
||||
vite-plugin-pwa:
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(@vite-pwa/assets-generator@1.0.2)(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))(workbox-build@7.4.0)(workbox-window@7.4.0)
|
||||
vue-tsc:
|
||||
specifier: ^3.1.4
|
||||
version: 3.1.8(typescript@5.9.3)
|
||||
@@ -114,6 +123,12 @@ packages:
|
||||
7zip-bin@5.2.0:
|
||||
resolution: {integrity: sha512-ukTPVhqG4jNzMro2qA9HSCSSVJN3aN7tlb+hfqYCt3ER0yWroeA2VR38MNrOHLQ/cVj+DaIMad0kFCtWWowh/A==}
|
||||
|
||||
'@apideck/better-ajv-errors@0.3.6':
|
||||
resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
ajv: '>=8'
|
||||
|
||||
'@babel/code-frame@7.27.1':
|
||||
resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -130,14 +145,39 @@ packages:
|
||||
resolution: {integrity: sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-annotate-as-pure@7.27.3':
|
||||
resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-compilation-targets@7.27.2':
|
||||
resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-create-class-features-plugin@7.28.5':
|
||||
resolution: {integrity: sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/helper-create-regexp-features-plugin@7.28.5':
|
||||
resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/helper-define-polyfill-provider@0.6.5':
|
||||
resolution: {integrity: sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||
|
||||
'@babel/helper-globals@7.28.0':
|
||||
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-member-expression-to-functions@7.28.5':
|
||||
resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-module-imports@7.27.1':
|
||||
resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -148,10 +188,30 @@ packages:
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/helper-optimise-call-expression@7.27.1':
|
||||
resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-plugin-utils@7.27.1':
|
||||
resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-remap-async-to-generator@7.27.1':
|
||||
resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/helper-replace-supers@7.27.1':
|
||||
resolution: {integrity: sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/helper-skip-transparent-expression-wrappers@7.27.1':
|
||||
resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-string-parser@7.27.1':
|
||||
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -164,6 +224,10 @@ packages:
|
||||
resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helper-wrap-function@7.28.3':
|
||||
resolution: {integrity: sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/helpers@7.28.4':
|
||||
resolution: {integrity: sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -173,12 +237,381 @@ packages:
|
||||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5':
|
||||
resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1':
|
||||
resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1':
|
||||
resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1':
|
||||
resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.13.0
|
||||
|
||||
'@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3':
|
||||
resolution: {integrity: sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2':
|
||||
resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-syntax-import-assertions@7.27.1':
|
||||
resolution: {integrity: sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-syntax-import-attributes@7.27.1':
|
||||
resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-syntax-unicode-sets-regex@7.18.6':
|
||||
resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-transform-arrow-functions@7.27.1':
|
||||
resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-async-generator-functions@7.28.0':
|
||||
resolution: {integrity: sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-async-to-generator@7.27.1':
|
||||
resolution: {integrity: sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-block-scoped-functions@7.27.1':
|
||||
resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-block-scoping@7.28.5':
|
||||
resolution: {integrity: sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-class-properties@7.27.1':
|
||||
resolution: {integrity: sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-class-static-block@7.28.3':
|
||||
resolution: {integrity: sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.12.0
|
||||
|
||||
'@babel/plugin-transform-classes@7.28.4':
|
||||
resolution: {integrity: sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-computed-properties@7.27.1':
|
||||
resolution: {integrity: sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-destructuring@7.28.5':
|
||||
resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-dotall-regex@7.27.1':
|
||||
resolution: {integrity: sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-duplicate-keys@7.27.1':
|
||||
resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1':
|
||||
resolution: {integrity: sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-transform-dynamic-import@7.27.1':
|
||||
resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-explicit-resource-management@7.28.0':
|
||||
resolution: {integrity: sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-exponentiation-operator@7.28.5':
|
||||
resolution: {integrity: sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-export-namespace-from@7.27.1':
|
||||
resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-for-of@7.27.1':
|
||||
resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-function-name@7.27.1':
|
||||
resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-json-strings@7.27.1':
|
||||
resolution: {integrity: sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-literals@7.27.1':
|
||||
resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-logical-assignment-operators@7.28.5':
|
||||
resolution: {integrity: sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-member-expression-literals@7.27.1':
|
||||
resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-modules-amd@7.27.1':
|
||||
resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-modules-commonjs@7.27.1':
|
||||
resolution: {integrity: sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-modules-systemjs@7.28.5':
|
||||
resolution: {integrity: sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-modules-umd@7.27.1':
|
||||
resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-named-capturing-groups-regex@7.27.1':
|
||||
resolution: {integrity: sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-transform-new-target@7.27.1':
|
||||
resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-nullish-coalescing-operator@7.27.1':
|
||||
resolution: {integrity: sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-numeric-separator@7.27.1':
|
||||
resolution: {integrity: sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-object-rest-spread@7.28.4':
|
||||
resolution: {integrity: sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-object-super@7.27.1':
|
||||
resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-optional-catch-binding@7.27.1':
|
||||
resolution: {integrity: sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-optional-chaining@7.28.5':
|
||||
resolution: {integrity: sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-parameters@7.27.7':
|
||||
resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-private-methods@7.27.1':
|
||||
resolution: {integrity: sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-private-property-in-object@7.27.1':
|
||||
resolution: {integrity: sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-property-literals@7.27.1':
|
||||
resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-regenerator@7.28.4':
|
||||
resolution: {integrity: sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-regexp-modifiers@7.27.1':
|
||||
resolution: {integrity: sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/plugin-transform-reserved-words@7.27.1':
|
||||
resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-shorthand-properties@7.27.1':
|
||||
resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-spread@7.27.1':
|
||||
resolution: {integrity: sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-sticky-regex@7.27.1':
|
||||
resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-template-literals@7.27.1':
|
||||
resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-typeof-symbol@7.27.1':
|
||||
resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-unicode-escapes@7.27.1':
|
||||
resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-unicode-property-regex@7.27.1':
|
||||
resolution: {integrity: sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-unicode-regex@7.27.1':
|
||||
resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/plugin-transform-unicode-sets-regex@7.27.1':
|
||||
resolution: {integrity: sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
|
||||
'@babel/preset-env@7.28.5':
|
||||
resolution: {integrity: sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0-0
|
||||
|
||||
'@babel/preset-modules@0.1.6-no-external-plugins':
|
||||
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
|
||||
|
||||
'@babel/runtime@7.28.4':
|
||||
resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -191,6 +624,9 @@ packages:
|
||||
resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@canvas/image-data@1.1.0':
|
||||
resolution: {integrity: sha512-QdObRRjRbcXGmM1tmJ+MrHcaz1MftF2+W7YI+MsphnsCrmtyfS0d5qJbk0MeSbUeyM/jCb0hmnkXPsy026L7dA==}
|
||||
|
||||
'@develar/schema-utils@2.6.5':
|
||||
resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==}
|
||||
engines: {node: '>= 8.9.0'}
|
||||
@@ -422,6 +858,123 @@ packages:
|
||||
'@gar/promisify@1.1.3':
|
||||
resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-darwin-x64@0.33.5':
|
||||
resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.0.4':
|
||||
resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||
resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||
resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||
resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||
resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||
resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-arm@0.33.5':
|
||||
resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.5':
|
||||
resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linux-x64@0.33.5':
|
||||
resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||
resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||
resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@img/sharp-wasm32@0.33.5':
|
||||
resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [wasm32]
|
||||
|
||||
'@img/sharp-win32-ia32@0.33.5':
|
||||
resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
|
||||
'@img/sharp-win32-x64@0.33.5':
|
||||
resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@internationalized/date@3.10.0':
|
||||
resolution: {integrity: sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw==}
|
||||
|
||||
@@ -490,6 +1043,9 @@ packages:
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@quansync/fs@1.0.0':
|
||||
resolution: {integrity: sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==}
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.50':
|
||||
resolution: {integrity: sha512-XlEkrOIHLyGT3avOgzfTFSjG+f+dZMw+/qd+Y3HLN86wlndrB/gSimrJCk4gOhr1XtRtEKfszpadI3Md4Z4/Ag==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -580,10 +1136,62 @@ packages:
|
||||
'@rolldown/pluginutils@1.0.0-beta.50':
|
||||
resolution: {integrity: sha512-5e76wQiQVeL1ICOZVUg4LSOVYg9jyhGCin+icYozhsUzM+fHE7kddi1bdiE0jwVqTfkjba3jUFbEkoC9WkdvyA==}
|
||||
|
||||
'@rollup/plugin-babel@5.3.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
|
||||
|
||||
'@rollup/plugin-node-resolve@15.3.1':
|
||||
resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^2.78.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/plugin-replace@2.4.2':
|
||||
resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0 || ^2.0.0
|
||||
|
||||
'@rollup/plugin-terser@0.4.4':
|
||||
resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^2.0.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@rollup/pluginutils@3.1.0':
|
||||
resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0
|
||||
|
||||
'@rollup/pluginutils@5.3.0':
|
||||
resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
|
||||
peerDependenciesMeta:
|
||||
rollup:
|
||||
optional: true
|
||||
|
||||
'@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==}
|
||||
|
||||
'@swc/helpers@0.5.17':
|
||||
resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==}
|
||||
|
||||
@@ -719,6 +1327,12 @@ packages:
|
||||
'@types/debug@4.1.12':
|
||||
resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
|
||||
|
||||
'@types/estree@0.0.39':
|
||||
resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==}
|
||||
|
||||
'@types/estree@1.0.8':
|
||||
resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
|
||||
|
||||
'@types/file-saver@2.0.7':
|
||||
resolution: {integrity: sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==}
|
||||
|
||||
@@ -743,9 +1357,15 @@ packages:
|
||||
'@types/plist@3.0.5':
|
||||
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
|
||||
|
||||
'@types/resolve@1.20.2':
|
||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||
|
||||
'@types/responselike@1.0.3':
|
||||
resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
|
||||
|
||||
'@types/trusted-types@2.0.7':
|
||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||
|
||||
'@types/verror@1.10.11':
|
||||
resolution: {integrity: sha512-RlDm9K7+o5stv0Co8i8ZRGxDbrTxhJtgjqjFyVh/tXQyl/rYtTKlnTvZ88oSTeYREWurwx20Js4kTuKCsFkUtg==}
|
||||
|
||||
@@ -755,6 +1375,11 @@ packages:
|
||||
'@types/yauzl@2.10.3':
|
||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||
|
||||
'@vite-pwa/assets-generator@1.0.2':
|
||||
resolution: {integrity: sha512-MCbrb508JZHqe7bUibmZj/lyojdhLRnfkmyXnkrCM2zVrjTgL89U8UEfInpKTvPeTnxsw2hmyZxnhsdNR6yhwg==}
|
||||
engines: {node: '>=16.14.0'}
|
||||
hasBin: true
|
||||
|
||||
'@vitejs/plugin-vue@6.0.2':
|
||||
resolution: {integrity: sha512-iHmwV3QcVGGvSC1BG5bZ4z6iwa1SOpAPWmnjOErd4Ske+lZua5K9TtAVdx0gMBClJ28DViCbSmZitjWZsWO3LA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
@@ -889,6 +1514,9 @@ packages:
|
||||
ajv@6.12.6:
|
||||
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
|
||||
|
||||
ajv@8.17.1:
|
||||
resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
|
||||
|
||||
alien-signals@3.1.1:
|
||||
resolution: {integrity: sha512-ogkIWbVrLwKtHY6oOAXaYkAxP+cTH7V5FZ5+Tm4NZFd8VDZ6uNMDrfzqctTZ42eTMCSR3ne3otpcxmqSnFfPYA==}
|
||||
|
||||
@@ -925,6 +1553,14 @@ packages:
|
||||
resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
array-buffer-byte-length@1.0.2:
|
||||
resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
arraybuffer.prototype.slice@1.0.4:
|
||||
resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
assert-plus@1.0.0:
|
||||
resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==}
|
||||
engines: {node: '>=0.8'}
|
||||
@@ -937,6 +1573,10 @@ packages:
|
||||
resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
|
||||
async-function@1.0.0:
|
||||
resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
async@3.2.6:
|
||||
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
|
||||
|
||||
@@ -947,6 +1587,25 @@ packages:
|
||||
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
|
||||
available-typed-arrays@1.0.7:
|
||||
resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
babel-plugin-polyfill-corejs2@0.4.14:
|
||||
resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||
|
||||
babel-plugin-polyfill-corejs3@0.13.0:
|
||||
resolution: {integrity: sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||
|
||||
babel-plugin-polyfill-regenerator@0.6.5:
|
||||
resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
|
||||
|
||||
@@ -1014,6 +1673,14 @@ packages:
|
||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
call-bind@1.0.8:
|
||||
resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
call-bound@1.0.4:
|
||||
resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
caniuse-lite@1.0.30001760:
|
||||
resolution: {integrity: sha512-7AAMPcueWELt1p3mi13HR/LHH0TJLT11cnwDJEs3xA4+CK/PLKeO9Kl1oru24htkyUKtkGCvAx4ohB0Ttry8Dw==}
|
||||
|
||||
@@ -1073,6 +1740,16 @@ packages:
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
color-string@1.9.1:
|
||||
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
|
||||
|
||||
color@4.2.3:
|
||||
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
|
||||
engines: {node: '>=12.5.0'}
|
||||
|
||||
colorette@2.0.20:
|
||||
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@@ -1088,6 +1765,10 @@ packages:
|
||||
resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==}
|
||||
engines: {node: ^12.20.0 || >=14}
|
||||
|
||||
common-tags@1.8.2:
|
||||
resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
compare-version@0.1.2:
|
||||
resolution: {integrity: sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -1098,6 +1779,10 @@ packages:
|
||||
config-file-ts@0.2.8-rc1:
|
||||
resolution: {integrity: sha512-GtNECbVI82bT4RiDIzBSVuTKoSHufnU7Ce7/42bkWZJZFLjmDF2WBpVsvRkhKCfKBnTBb3qZrBwPpFBU/Myvhg==}
|
||||
|
||||
consola@3.4.2:
|
||||
resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
|
||||
engines: {node: ^14.18.0 || >=16.10.0}
|
||||
|
||||
convert-source-map@2.0.0:
|
||||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
|
||||
@@ -1105,6 +1790,9 @@ packages:
|
||||
resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
core-js-compat@3.47.0:
|
||||
resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==}
|
||||
|
||||
core-util-is@1.0.2:
|
||||
resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==}
|
||||
|
||||
@@ -1114,6 +1802,11 @@ packages:
|
||||
cross-dirname@0.1.0:
|
||||
resolution: {integrity: sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==}
|
||||
|
||||
cross-env@7.0.3:
|
||||
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
|
||||
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
|
||||
hasBin: true
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -1121,9 +1814,25 @@ packages:
|
||||
crypto-js@4.2.0:
|
||||
resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==}
|
||||
|
||||
crypto-random-string@2.0.0:
|
||||
resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
csstype@3.2.3:
|
||||
resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==}
|
||||
|
||||
data-view-buffer@1.0.2:
|
||||
resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
data-view-byte-length@1.0.2:
|
||||
resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
data-view-byte-offset@1.0.1:
|
||||
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
debug@4.4.3:
|
||||
resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
|
||||
engines: {node: '>=6.0'}
|
||||
@@ -1133,10 +1842,22 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decode-bmp@0.2.1:
|
||||
resolution: {integrity: sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA==}
|
||||
engines: {node: '>=8.6.0'}
|
||||
|
||||
decode-ico@0.4.1:
|
||||
resolution: {integrity: sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
decompress-response@6.0.0:
|
||||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
deepmerge@4.3.1:
|
||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
defaults@1.0.4:
|
||||
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
|
||||
|
||||
@@ -1270,6 +1991,10 @@ packages:
|
||||
err-code@2.0.3:
|
||||
resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==}
|
||||
|
||||
es-abstract@1.24.1:
|
||||
resolution: {integrity: sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1286,6 +2011,10 @@ packages:
|
||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-to-primitive@1.3.0:
|
||||
resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es6-error@4.1.1:
|
||||
resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==}
|
||||
|
||||
@@ -1305,9 +2034,16 @@ packages:
|
||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
estree-walker@1.0.1:
|
||||
resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==}
|
||||
|
||||
estree-walker@2.0.2:
|
||||
resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
|
||||
|
||||
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'}
|
||||
@@ -1330,6 +2066,9 @@ packages:
|
||||
fast-json-stable-stringify@2.1.0:
|
||||
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
|
||||
|
||||
fast-uri@3.1.0:
|
||||
resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==}
|
||||
|
||||
fd-slicer@1.1.0:
|
||||
resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==}
|
||||
|
||||
@@ -1352,6 +2091,10 @@ packages:
|
||||
resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
|
||||
engines: {node: '>= 18.0.0'}
|
||||
|
||||
for-each@0.3.5:
|
||||
resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -1399,6 +2142,17 @@ packages:
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
function.prototype.name@1.1.8:
|
||||
resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
functions-have-names@1.2.3:
|
||||
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
|
||||
|
||||
generator-function@2.0.1:
|
||||
resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
@@ -1411,6 +2165,9 @@ packages:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-own-enumerable-property-symbols@3.0.2:
|
||||
resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==}
|
||||
|
||||
get-proto@1.0.1:
|
||||
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1419,10 +2176,19 @@ packages:
|
||||
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
get-symbol-description@1.1.0:
|
||||
resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
glob@10.5.0:
|
||||
resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==}
|
||||
hasBin: true
|
||||
|
||||
glob@11.1.0:
|
||||
resolution: {integrity: sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==}
|
||||
engines: {node: 20 || >=22}
|
||||
hasBin: true
|
||||
|
||||
glob@7.2.3:
|
||||
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
|
||||
deprecated: Glob versions prior to v9 are no longer supported
|
||||
@@ -1451,6 +2217,10 @@ packages:
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||
|
||||
has-bigints@1.1.0:
|
||||
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1458,6 +2228,10 @@ packages:
|
||||
has-property-descriptors@1.0.2:
|
||||
resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
|
||||
|
||||
has-proto@1.2.0:
|
||||
resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1507,6 +2281,9 @@ packages:
|
||||
humanize-ms@1.2.1:
|
||||
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
|
||||
|
||||
ico-endec@0.1.6:
|
||||
resolution: {integrity: sha512-ZdLU38ZoED3g1j3iEyzcQj+wAkY2xfWNkymszfJPoxucIUhK7NayQ+/C4Kv0nDFMIsbtbEHldv3V8PU494/ueQ==}
|
||||
|
||||
iconv-corefoundation@1.1.7:
|
||||
resolution: {integrity: sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==}
|
||||
engines: {node: ^8.11.2 || >=10}
|
||||
@@ -1516,6 +2293,9 @@ packages:
|
||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
idb@7.1.1:
|
||||
resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==}
|
||||
|
||||
ieee754@1.2.1:
|
||||
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||
|
||||
@@ -1537,18 +2317,65 @@ packages:
|
||||
inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
|
||||
internal-slot@1.1.0:
|
||||
resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
ip-address@10.1.0:
|
||||
resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
is-array-buffer@3.0.5:
|
||||
resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-arrayish@0.3.4:
|
||||
resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==}
|
||||
|
||||
is-async-function@2.1.1:
|
||||
resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-bigint@1.1.0:
|
||||
resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-boolean-object@1.2.2:
|
||||
resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-callable@1.2.7:
|
||||
resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-ci@3.0.1:
|
||||
resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==}
|
||||
hasBin: true
|
||||
|
||||
is-core-module@2.16.1:
|
||||
resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-data-view@1.0.2:
|
||||
resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-date-object@1.1.0:
|
||||
resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-finalizationregistry@1.1.1:
|
||||
resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-generator-function@1.1.2:
|
||||
resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-interactive@1.0.0:
|
||||
resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1556,14 +2383,80 @@ packages:
|
||||
is-lambda@1.0.1:
|
||||
resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==}
|
||||
|
||||
is-map@2.0.3:
|
||||
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-module@1.0.0:
|
||||
resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==}
|
||||
|
||||
is-negative-zero@2.0.3:
|
||||
resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-number-object@1.1.1:
|
||||
resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-obj@1.0.1:
|
||||
resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-regex@1.2.1:
|
||||
resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-regexp@1.0.0:
|
||||
resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
is-set@2.0.3:
|
||||
resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-shared-array-buffer@1.0.4:
|
||||
resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-stream@2.0.1:
|
||||
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-string@1.1.1:
|
||||
resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-symbol@1.1.1:
|
||||
resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-typed-array@1.1.15:
|
||||
resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-unicode-supported@0.1.0:
|
||||
resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
is-weakmap@2.0.2:
|
||||
resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-weakref@1.1.1:
|
||||
resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-weakset@2.0.4:
|
||||
resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
is-what@5.5.0:
|
||||
resolution: {integrity: sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
isarray@2.0.5:
|
||||
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
|
||||
|
||||
isbinaryfile@4.0.10:
|
||||
resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==}
|
||||
engines: {node: '>= 8.0.0'}
|
||||
@@ -1578,6 +2471,10 @@ packages:
|
||||
jackspeak@3.4.3:
|
||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||
|
||||
jackspeak@4.1.1:
|
||||
resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
jake@10.9.4:
|
||||
resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -1605,6 +2502,12 @@ packages:
|
||||
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@0.4.0:
|
||||
resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==}
|
||||
|
||||
json-stringify-safe@5.0.1:
|
||||
resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==}
|
||||
|
||||
@@ -1619,12 +2522,20 @@ packages:
|
||||
jsonfile@6.2.0:
|
||||
resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==}
|
||||
|
||||
jsonpointer@5.0.1:
|
||||
resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
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==}
|
||||
|
||||
leven@3.1.0:
|
||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
lightningcss-android-arm64@1.30.2:
|
||||
resolution: {integrity: sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
@@ -1699,6 +2610,12 @@ packages:
|
||||
resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
|
||||
lodash.debounce@4.0.8:
|
||||
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
|
||||
|
||||
lodash.sortby@4.7.0:
|
||||
resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==}
|
||||
|
||||
lodash@4.17.21:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
|
||||
@@ -1713,6 +2630,10 @@ packages:
|
||||
lru-cache@10.4.3:
|
||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||
|
||||
lru-cache@11.2.4:
|
||||
resolution: {integrity: sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
lru-cache@5.1.1:
|
||||
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
|
||||
|
||||
@@ -1729,6 +2650,9 @@ packages:
|
||||
peerDependencies:
|
||||
vue: '>=3.0.1'
|
||||
|
||||
magic-string@0.25.9:
|
||||
resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==}
|
||||
|
||||
magic-string@0.30.21:
|
||||
resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
|
||||
|
||||
@@ -1736,6 +2660,11 @@ packages:
|
||||
resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
|
||||
marked@17.0.1:
|
||||
resolution: {integrity: sha512-boeBdiS0ghpWcSwoNm/jJBwdpFaMnZWRzjA6SkUMYb40SVaN1x7mmfGKp0jvexGcx+7y2La5zRZsYFZI6Qpypg==}
|
||||
engines: {node: '>= 20'}
|
||||
hasBin: true
|
||||
|
||||
matcher@3.0.0:
|
||||
resolution: {integrity: sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -1880,10 +2809,18 @@ packages:
|
||||
resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
object-inspect@1.13.4:
|
||||
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
object-keys@1.1.1:
|
||||
resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
object.assign@4.1.7:
|
||||
resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
ohash@2.0.11:
|
||||
resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==}
|
||||
|
||||
@@ -1902,6 +2839,10 @@ packages:
|
||||
resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
own-keys@1.0.1:
|
||||
resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
p-cancelable@2.1.1:
|
||||
resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -1932,10 +2873,17 @@ packages:
|
||||
resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-parse@1.0.7:
|
||||
resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
|
||||
engines: {node: '>=16 || 14 >=14.18'}
|
||||
|
||||
path-scurry@2.0.1:
|
||||
resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
pe-library@0.4.1:
|
||||
resolution: {integrity: sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw==}
|
||||
engines: {node: '>=12', npm: '>=6'}
|
||||
@@ -1949,6 +2897,10 @@ packages:
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
picomatch@2.3.1:
|
||||
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
picomatch@4.0.3:
|
||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1980,6 +2932,10 @@ packages:
|
||||
resolution: {integrity: sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ==}
|
||||
engines: {node: '>=10.4.0'}
|
||||
|
||||
possible-typed-array-names@1.1.0:
|
||||
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
postcss@8.5.6:
|
||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
@@ -1989,6 +2945,14 @@ packages:
|
||||
engines: {node: '>=14.0.0'}
|
||||
hasBin: true
|
||||
|
||||
pretty-bytes@5.6.0:
|
||||
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
pretty-bytes@6.1.1:
|
||||
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
|
||||
engines: {node: ^14.13.1 || >=16.0.0}
|
||||
|
||||
proc-log@2.0.1:
|
||||
resolution: {integrity: sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
@@ -2016,10 +2980,16 @@ packages:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
quansync@1.0.0:
|
||||
resolution: {integrity: sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==}
|
||||
|
||||
quick-lru@5.1.1:
|
||||
resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
randombytes@2.1.0:
|
||||
resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
|
||||
|
||||
range-parser@1.2.1:
|
||||
resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -2032,6 +3002,32 @@ packages:
|
||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
reflect.getprototypeof@1.0.10:
|
||||
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
regenerate-unicode-properties@10.2.2:
|
||||
resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
regenerate@1.4.2:
|
||||
resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==}
|
||||
|
||||
regexp.prototype.flags@1.5.4:
|
||||
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
regexpu-core@6.4.0:
|
||||
resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
regjsgen@0.8.0:
|
||||
resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==}
|
||||
|
||||
regjsparser@0.13.0:
|
||||
resolution: {integrity: sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q==}
|
||||
hasBin: true
|
||||
|
||||
reka-ui@2.6.1:
|
||||
resolution: {integrity: sha512-XK7cJDQoNuGXfCNzBBo/81Yg/OgjPwvbabnlzXG2VsdSgNsT6iIkuPBPr+C0Shs+3bb0x0lbPvgQAhMSCKm5Ww==}
|
||||
peerDependencies:
|
||||
@@ -2041,6 +3037,10 @@ packages:
|
||||
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'}
|
||||
|
||||
resedit@1.7.2:
|
||||
resolution: {integrity: sha512-vHjcY2MlAITJhC0eRD/Vv8Vlgmu9Sd3LX9zZvtGzU5ZImdTN3+d6e/4mnTyV8vEbyf1sgNIrWxhWlrys52OkEA==}
|
||||
engines: {node: '>=12', npm: '>=6'}
|
||||
@@ -2048,6 +3048,11 @@ packages:
|
||||
resolve-alpn@1.2.1:
|
||||
resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==}
|
||||
|
||||
resolve@1.22.11:
|
||||
resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
hasBin: true
|
||||
|
||||
responselike@2.0.1:
|
||||
resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==}
|
||||
|
||||
@@ -2121,9 +3126,26 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
hasBin: true
|
||||
|
||||
rollup@2.79.2:
|
||||
resolution: {integrity: sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
|
||||
safe-array-concat@1.1.3:
|
||||
resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
|
||||
safe-push-apply@1.0.0:
|
||||
resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
safe-regex-test@1.1.0:
|
||||
resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
safer-buffer@2.1.2:
|
||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||
|
||||
@@ -2157,13 +3179,35 @@ packages:
|
||||
resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
serialize-javascript@6.0.2:
|
||||
resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
|
||||
|
||||
serve-static@2.2.0:
|
||||
resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
set-function-length@1.2.2:
|
||||
resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
set-function-name@2.0.2:
|
||||
resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
set-proto@1.0.0:
|
||||
resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||
|
||||
sharp-ico@0.1.5:
|
||||
resolution: {integrity: sha512-a3jODQl82NPp1d5OYb0wY+oFaPk7AvyxipIowCHk7pBsZCWgbe0yAkU2OOXdoH0ENyANhyOQbs9xkAiRHcF02Q==}
|
||||
|
||||
sharp@0.33.5:
|
||||
resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
|
||||
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -2172,6 +3216,22 @@ packages:
|
||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
side-channel-list@1.0.0:
|
||||
resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
side-channel-map@1.0.1:
|
||||
resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
side-channel-weakmap@1.0.2:
|
||||
resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
side-channel@1.1.0:
|
||||
resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
signal-exit@3.0.7:
|
||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||
|
||||
@@ -2179,6 +3239,9 @@ packages:
|
||||
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
simple-swizzle@0.2.4:
|
||||
resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==}
|
||||
|
||||
simple-update-notifier@2.0.0:
|
||||
resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2191,6 +3254,9 @@ packages:
|
||||
resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==}
|
||||
engines: {node: '>= 6.0.0', npm: '>= 3.0.0'}
|
||||
|
||||
smob@1.5.0:
|
||||
resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==}
|
||||
|
||||
socks-proxy-agent@7.0.0:
|
||||
resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==}
|
||||
engines: {node: '>= 10'}
|
||||
@@ -2210,6 +3276,15 @@ packages:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
source-map@0.8.0-beta.0:
|
||||
resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==}
|
||||
engines: {node: '>= 8'}
|
||||
deprecated: The work that was done in this beta branch won't be included in future versions
|
||||
|
||||
sourcemap-codec@1.4.8:
|
||||
resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==}
|
||||
deprecated: Please use @jridgewell/sourcemap-codec instead
|
||||
|
||||
speakingurl@14.0.1:
|
||||
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -2229,6 +3304,10 @@ packages:
|
||||
resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
stop-iteration-iterator@1.1.0:
|
||||
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -2237,9 +3316,29 @@ packages:
|
||||
resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
string.prototype.matchall@4.0.12:
|
||||
resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
string.prototype.trim@1.2.10:
|
||||
resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
string.prototype.trimend@1.0.9:
|
||||
resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
string.prototype.trimstart@1.0.8:
|
||||
resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
string_decoder@1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
|
||||
stringify-object@3.3.0:
|
||||
resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -2248,6 +3347,10 @@ packages:
|
||||
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
strip-comments@2.0.1:
|
||||
resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
sumchecker@3.0.1:
|
||||
resolution: {integrity: sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==}
|
||||
engines: {node: '>= 8.0'}
|
||||
@@ -2260,6 +3363,10 @@ packages:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
tailwind-merge@3.4.0:
|
||||
resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==}
|
||||
|
||||
@@ -2274,6 +3381,10 @@ packages:
|
||||
resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
temp-dir@2.0.0:
|
||||
resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
temp-file@3.4.0:
|
||||
resolution: {integrity: sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==}
|
||||
|
||||
@@ -2281,6 +3392,10 @@ packages:
|
||||
resolution: {integrity: sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
tempy@0.6.0:
|
||||
resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
terser@5.44.1:
|
||||
resolution: {integrity: sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2300,10 +3415,16 @@ packages:
|
||||
resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==}
|
||||
engines: {node: '>=14.14'}
|
||||
|
||||
to-data-view@1.1.0:
|
||||
resolution: {integrity: sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==}
|
||||
|
||||
toidentifier@1.0.1:
|
||||
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
tr46@1.0.1:
|
||||
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
|
||||
|
||||
truncate-utf8-bytes@1.0.2:
|
||||
resolution: {integrity: sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==}
|
||||
|
||||
@@ -2317,17 +3438,63 @@ packages:
|
||||
resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
type-fest@0.16.0:
|
||||
resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
typed-array-buffer@1.0.3:
|
||||
resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typed-array-byte-length@1.0.3:
|
||||
resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typed-array-byte-offset@1.0.4:
|
||||
resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typed-array-length@1.0.7:
|
||||
resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
typescript@5.9.3:
|
||||
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
|
||||
engines: {node: '>=14.17'}
|
||||
hasBin: true
|
||||
|
||||
unbox-primitive@1.1.0:
|
||||
resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
unconfig-core@7.4.2:
|
||||
resolution: {integrity: sha512-VgPCvLWugINbXvMQDf8Jh0mlbvNjNC6eSUziHsBCMpxR05OPrNrvDnyatdMjRgcHaaNsCqz+wjNXxNw1kRLHUg==}
|
||||
|
||||
unconfig@7.4.2:
|
||||
resolution: {integrity: sha512-nrMlWRQ1xdTjSnSUqvYqJzbTBFugoqHobQj58B2bc8qxHKBBHMNNsWQFP3Cd3/JZK907voM2geYPWqD4VK3MPQ==}
|
||||
|
||||
undici-types@6.21.0:
|
||||
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
|
||||
|
||||
undici-types@7.16.0:
|
||||
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
|
||||
|
||||
unicode-canonical-property-names-ecmascript@2.0.1:
|
||||
resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
unicode-match-property-ecmascript@2.0.0:
|
||||
resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
unicode-match-property-value-ecmascript@2.2.1:
|
||||
resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
unicode-property-aliases-ecmascript@2.2.0:
|
||||
resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
unique-filename@2.0.1:
|
||||
resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
@@ -2336,6 +3503,10 @@ packages:
|
||||
resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==}
|
||||
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
|
||||
|
||||
unique-string@2.0.0:
|
||||
resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
universalify@0.1.2:
|
||||
resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==}
|
||||
engines: {node: '>= 4.0.0'}
|
||||
@@ -2344,6 +3515,10 @@ packages:
|
||||
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
|
||||
upath@1.2.0:
|
||||
resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
update-browserslist-db@1.2.2:
|
||||
resolution: {integrity: sha512-E85pfNzMQ9jpKkA7+TJAi4TJN+tBCuWh5rUcS/sv6cFi+1q9LYDwDI5dpUL0u/73EElyQ8d3TEaeW4sPedBqYA==}
|
||||
hasBin: true
|
||||
@@ -2374,6 +3549,18 @@ packages:
|
||||
vite-plugin-electron-renderer:
|
||||
optional: true
|
||||
|
||||
vite-plugin-pwa@1.2.0:
|
||||
resolution: {integrity: sha512-a2xld+SJshT9Lgcv8Ji4+srFJL4k/1bVbd1x06JIkvecpQkwkvCncD1+gSzcdm3s+owWLpMJerG3aN5jupJEVw==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
peerDependencies:
|
||||
'@vite-pwa/assets-generator': ^1.0.0
|
||||
vite: ^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0
|
||||
workbox-build: ^7.4.0
|
||||
workbox-window: ^7.4.0
|
||||
peerDependenciesMeta:
|
||||
'@vite-pwa/assets-generator':
|
||||
optional: true
|
||||
|
||||
vscode-uri@3.1.0:
|
||||
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
||||
|
||||
@@ -2424,11 +3611,82 @@ packages:
|
||||
wcwidth@1.0.1:
|
||||
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
|
||||
|
||||
webidl-conversions@4.0.2:
|
||||
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
|
||||
|
||||
whatwg-url@7.1.0:
|
||||
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
|
||||
|
||||
which-boxed-primitive@1.1.1:
|
||||
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
which-builtin-type@1.2.1:
|
||||
resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
which-collection@1.0.2:
|
||||
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
which-typed-array@1.1.19:
|
||||
resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
hasBin: true
|
||||
|
||||
workbox-background-sync@7.4.0:
|
||||
resolution: {integrity: sha512-8CB9OxKAgKZKyNMwfGZ1XESx89GryWTfI+V5yEj8sHjFH8MFelUwYXEyldEK6M6oKMmn807GoJFUEA1sC4XS9w==}
|
||||
|
||||
workbox-broadcast-update@7.4.0:
|
||||
resolution: {integrity: sha512-+eZQwoktlvo62cI0b+QBr40v5XjighxPq3Fzo9AWMiAosmpG5gxRHgTbGGhaJv/q/MFVxwFNGh/UwHZ/8K88lA==}
|
||||
|
||||
workbox-build@7.4.0:
|
||||
resolution: {integrity: sha512-Ntk1pWb0caOFIvwz/hfgrov/OJ45wPEhI5PbTywQcYjyZiVhT3UrwwUPl6TRYbTm4moaFYithYnl1lvZ8UjxcA==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
|
||||
workbox-cacheable-response@7.4.0:
|
||||
resolution: {integrity: sha512-0Fb8795zg/x23ISFkAc7lbWes6vbw34DGFIMw31cwuHPgDEC/5EYm6m/ZkylLX0EnEbbOyOCLjKgFS/Z5g0HeQ==}
|
||||
|
||||
workbox-core@7.4.0:
|
||||
resolution: {integrity: sha512-6BMfd8tYEnN4baG4emG9U0hdXM4gGuDU3ectXuVHnj71vwxTFI7WOpQJC4siTOlVtGqCUtj0ZQNsrvi6kZZTAQ==}
|
||||
|
||||
workbox-expiration@7.4.0:
|
||||
resolution: {integrity: sha512-V50p4BxYhtA80eOvulu8xVfPBgZbkxJ1Jr8UUn0rvqjGhLDqKNtfrDfjJKnLz2U8fO2xGQJTx/SKXNTzHOjnHw==}
|
||||
|
||||
workbox-google-analytics@7.4.0:
|
||||
resolution: {integrity: sha512-MVPXQslRF6YHkzGoFw1A4GIB8GrKym/A5+jYDUSL+AeJw4ytQGrozYdiZqUW1TPQHW8isBCBtyFJergUXyNoWQ==}
|
||||
|
||||
workbox-navigation-preload@7.4.0:
|
||||
resolution: {integrity: sha512-etzftSgdQfjMcfPgbfaZCfM2QuR1P+4o8uCA2s4rf3chtKTq/Om7g/qvEOcZkG6v7JZOSOxVYQiOu6PbAZgU6w==}
|
||||
|
||||
workbox-precaching@7.4.0:
|
||||
resolution: {integrity: sha512-VQs37T6jDqf1rTxUJZXRl3yjZMf5JX/vDPhmx2CPgDDKXATzEoqyRqhYnRoxl6Kr0rqaQlp32i9rtG5zTzIlNg==}
|
||||
|
||||
workbox-range-requests@7.4.0:
|
||||
resolution: {integrity: sha512-3Vq854ZNuP6Y0KZOQWLaLC9FfM7ZaE+iuQl4VhADXybwzr4z/sMmnLgTeUZLq5PaDlcJBxYXQ3U91V7dwAIfvw==}
|
||||
|
||||
workbox-recipes@7.4.0:
|
||||
resolution: {integrity: sha512-kOkWvsAn4H8GvAkwfJTbwINdv4voFoiE9hbezgB1sb/0NLyTG4rE7l6LvS8lLk5QIRIto+DjXLuAuG3Vmt3cxQ==}
|
||||
|
||||
workbox-routing@7.4.0:
|
||||
resolution: {integrity: sha512-C/ooj5uBWYAhAqwmU8HYQJdOjjDKBp9MzTQ+otpMmd+q0eF59K+NuXUek34wbL0RFrIXe/KKT+tUWcZcBqxbHQ==}
|
||||
|
||||
workbox-strategies@7.4.0:
|
||||
resolution: {integrity: sha512-T4hVqIi5A4mHi92+5EppMX3cLaVywDp8nsyUgJhOZxcfSV/eQofcOA6/EMo5rnTNmNTpw0rUgjAI6LaVullPpg==}
|
||||
|
||||
workbox-streams@7.4.0:
|
||||
resolution: {integrity: sha512-QHPBQrey7hQbnTs5GrEVoWz7RhHJXnPT+12qqWM378orDMo5VMJLCkCM1cnCk+8Eq92lccx/VgRZ7WAzZWbSLg==}
|
||||
|
||||
workbox-sw@7.4.0:
|
||||
resolution: {integrity: sha512-ltU+Kr3qWR6BtbdlMnCjobZKzeV1hN+S6UvDywBrwM19TTyqA03X66dzw1tEIdJvQ4lYKkBFox6IAEhoSEZ8Xw==}
|
||||
|
||||
workbox-window@7.4.0:
|
||||
resolution: {integrity: sha512-/bIYdBLAVsNR3v7gYGaV4pQW3M3kEPx5E8vDxGvxo6khTrGtSSCS7QiFKv9ogzBgZiy0OXLP9zO28U/1nF1mfw==}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -2473,6 +3731,13 @@ snapshots:
|
||||
|
||||
7zip-bin@5.2.0: {}
|
||||
|
||||
'@apideck/better-ajv-errors@0.3.6(ajv@8.17.1)':
|
||||
dependencies:
|
||||
ajv: 8.17.1
|
||||
json-schema: 0.4.0
|
||||
jsonpointer: 5.0.1
|
||||
leven: 3.1.0
|
||||
|
||||
'@babel/code-frame@7.27.1':
|
||||
dependencies:
|
||||
'@babel/helper-validator-identifier': 7.28.5
|
||||
@@ -2509,6 +3774,10 @@ snapshots:
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
jsesc: 3.1.0
|
||||
|
||||
'@babel/helper-annotate-as-pure@7.27.3':
|
||||
dependencies:
|
||||
'@babel/types': 7.28.5
|
||||
|
||||
'@babel/helper-compilation-targets@7.27.2':
|
||||
dependencies:
|
||||
'@babel/compat-data': 7.28.5
|
||||
@@ -2517,8 +3786,46 @@ snapshots:
|
||||
lru-cache: 5.1.1
|
||||
semver: 6.3.1
|
||||
|
||||
'@babel/helper-create-class-features-plugin@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-annotate-as-pure': 7.27.3
|
||||
'@babel/helper-member-expression-to-functions': 7.28.5
|
||||
'@babel/helper-optimise-call-expression': 7.27.1
|
||||
'@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||
'@babel/traverse': 7.28.5
|
||||
semver: 6.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-annotate-as-pure': 7.27.3
|
||||
regexpu-core: 6.4.0
|
||||
semver: 6.3.1
|
||||
|
||||
'@babel/helper-define-polyfill-provider@0.6.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
debug: 4.4.3
|
||||
lodash.debounce: 4.0.8
|
||||
resolve: 1.22.11
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-globals@7.28.0': {}
|
||||
|
||||
'@babel/helper-member-expression-to-functions@7.28.5':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.28.5
|
||||
'@babel/types': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-module-imports@7.27.1':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.28.5
|
||||
@@ -2535,14 +3842,51 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-optimise-call-expression@7.27.1':
|
||||
dependencies:
|
||||
'@babel/types': 7.28.5
|
||||
|
||||
'@babel/helper-plugin-utils@7.27.1': {}
|
||||
|
||||
'@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-annotate-as-pure': 7.27.3
|
||||
'@babel/helper-wrap-function': 7.28.3
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-replace-supers@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-member-expression-to-functions': 7.28.5
|
||||
'@babel/helper-optimise-call-expression': 7.27.1
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-skip-transparent-expression-wrappers@7.27.1':
|
||||
dependencies:
|
||||
'@babel/traverse': 7.28.5
|
||||
'@babel/types': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helper-string-parser@7.27.1': {}
|
||||
|
||||
'@babel/helper-validator-identifier@7.28.5': {}
|
||||
|
||||
'@babel/helper-validator-option@7.27.1': {}
|
||||
|
||||
'@babel/helper-wrap-function@7.28.3':
|
||||
dependencies:
|
||||
'@babel/template': 7.27.2
|
||||
'@babel/traverse': 7.28.5
|
||||
'@babel/types': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/helpers@7.28.4':
|
||||
dependencies:
|
||||
'@babel/template': 7.27.2
|
||||
@@ -2552,11 +3896,479 @@ snapshots:
|
||||
dependencies:
|
||||
'@babel/types': 7.28.5
|
||||
|
||||
'@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||
'@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.3(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
|
||||
'@babel/plugin-syntax-import-assertions@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-async-generator-functions@7.28.0(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-async-to-generator@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-module-imports': 7.27.1
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.5)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-block-scoping@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-class-properties@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-class-static-block@7.28.3(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-classes@7.28.4(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-annotate-as-pure': 7.27.3
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-globals': 7.28.0
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-computed-properties@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/template': 7.27.2
|
||||
|
||||
'@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-dotall-regex@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-explicit-resource-management@7.28.0(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-exponentiation-operator@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-function-name@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-json-strings@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-logical-assignment-operators@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-modules-systemjs@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-validator-identifier': 7.28.5
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-module-transforms': 7.28.3(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-named-capturing-groups-regex@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-nullish-coalescing-operator@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-numeric-separator@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-object-rest-spread@7.28.4(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5)
|
||||
'@babel/traverse': 7.28.5
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.5)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-optional-catch-binding@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-optional-chaining@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-private-methods@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-private-property-in-object@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-annotate-as-pure': 7.27.3
|
||||
'@babel/helper-create-class-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-regenerator@7.28.4(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-regexp-modifiers@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-spread@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-skip-transparent-expression-wrappers': 7.27.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-unicode-property-regex@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/plugin-transform-unicode-sets-regex@7.27.1(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
|
||||
'@babel/preset-env@7.28.5(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/compat-data': 7.28.5
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-compilation-targets': 7.27.2
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/helper-validator-option': 7.27.1
|
||||
'@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.3(@babel/core@7.28.5)
|
||||
'@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.5)
|
||||
'@babel/plugin-syntax-import-assertions': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-async-generator-functions': 7.28.0(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-async-to-generator': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-block-scoping': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-class-static-block': 7.28.3(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-classes': 7.28.4(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-computed-properties': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-dotall-regex': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-explicit-resource-management': 7.28.0(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-exponentiation-operator': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-json-strings': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-literals': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-logical-assignment-operators': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-modules-systemjs': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-named-capturing-groups-regex': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-nullish-coalescing-operator': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-numeric-separator': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-object-rest-spread': 7.28.4(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-optional-catch-binding': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-optional-chaining': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-private-methods': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-private-property-in-object': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-regenerator': 7.28.4(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-regexp-modifiers': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-spread': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-unicode-property-regex': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/plugin-transform-unicode-sets-regex': 7.27.1(@babel/core@7.28.5)
|
||||
'@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.5)
|
||||
babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.5)
|
||||
babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.5)
|
||||
babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.5)
|
||||
core-js-compat: 3.47.0
|
||||
semver: 6.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.28.5)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-plugin-utils': 7.27.1
|
||||
'@babel/types': 7.28.5
|
||||
esutils: 2.0.3
|
||||
|
||||
'@babel/runtime@7.28.4': {}
|
||||
|
||||
'@babel/template@7.27.2':
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.27.1
|
||||
@@ -2580,6 +4392,9 @@ snapshots:
|
||||
'@babel/helper-string-parser': 7.27.1
|
||||
'@babel/helper-validator-identifier': 7.28.5
|
||||
|
||||
'@canvas/image-data@1.1.0':
|
||||
optional: true
|
||||
|
||||
'@develar/schema-utils@2.6.5':
|
||||
dependencies:
|
||||
ajv: 6.12.6
|
||||
@@ -2811,6 +4626,81 @@ snapshots:
|
||||
|
||||
'@gar/promisify@1.1.3': {}
|
||||
|
||||
'@img/sharp-darwin-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-darwin-x64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-arm64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-darwin-x64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-arm@1.0.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-s390x@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linux-x64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-arm64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-libvips-linuxmusl-x64@1.0.4':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-arm@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-arm': 1.0.5
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-s390x@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linux-x64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linux-x64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-arm64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-linuxmusl-x64@0.33.5':
|
||||
optionalDependencies:
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
||||
optional: true
|
||||
|
||||
'@img/sharp-wasm32@0.33.5':
|
||||
dependencies:
|
||||
'@emnapi/runtime': 1.7.1
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-ia32@0.33.5':
|
||||
optional: true
|
||||
|
||||
'@img/sharp-win32-x64@0.33.5':
|
||||
optional: true
|
||||
|
||||
'@internationalized/date@3.10.0':
|
||||
dependencies:
|
||||
'@swc/helpers': 0.5.17
|
||||
@@ -2850,7 +4740,6 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/gen-mapping': 0.3.13
|
||||
'@jridgewell/trace-mapping': 0.3.31
|
||||
optional: true
|
||||
|
||||
'@jridgewell/sourcemap-codec@1.5.5': {}
|
||||
|
||||
@@ -2896,6 +4785,11 @@ snapshots:
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@quansync/fs@1.0.0':
|
||||
dependencies:
|
||||
quansync: 1.0.0
|
||||
optional: true
|
||||
|
||||
'@rolldown/binding-android-arm64@1.0.0-beta.50':
|
||||
optional: true
|
||||
|
||||
@@ -2942,8 +4836,63 @@ snapshots:
|
||||
|
||||
'@rolldown/pluginutils@1.0.0-beta.50': {}
|
||||
|
||||
'@rollup/plugin-babel@5.3.1(@babel/core@7.28.5)(rollup@2.79.2)':
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-module-imports': 7.27.1
|
||||
'@rollup/pluginutils': 3.1.0(rollup@2.79.2)
|
||||
rollup: 2.79.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@rollup/plugin-node-resolve@15.3.1(rollup@2.79.2)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.3.0(rollup@2.79.2)
|
||||
'@types/resolve': 1.20.2
|
||||
deepmerge: 4.3.1
|
||||
is-module: 1.0.0
|
||||
resolve: 1.22.11
|
||||
optionalDependencies:
|
||||
rollup: 2.79.2
|
||||
|
||||
'@rollup/plugin-replace@2.4.2(rollup@2.79.2)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0(rollup@2.79.2)
|
||||
magic-string: 0.25.9
|
||||
rollup: 2.79.2
|
||||
|
||||
'@rollup/plugin-terser@0.4.4(rollup@2.79.2)':
|
||||
dependencies:
|
||||
serialize-javascript: 6.0.2
|
||||
smob: 1.5.0
|
||||
terser: 5.44.1
|
||||
optionalDependencies:
|
||||
rollup: 2.79.2
|
||||
|
||||
'@rollup/pluginutils@3.1.0(rollup@2.79.2)':
|
||||
dependencies:
|
||||
'@types/estree': 0.0.39
|
||||
estree-walker: 1.0.1
|
||||
picomatch: 2.3.1
|
||||
rollup: 2.79.2
|
||||
|
||||
'@rollup/pluginutils@5.3.0(rollup@2.79.2)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.8
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 4.0.3
|
||||
optionalDependencies:
|
||||
rollup: 2.79.2
|
||||
|
||||
'@sindresorhus/is@4.6.0': {}
|
||||
|
||||
'@surma/rollup-plugin-off-main-thread@2.2.3':
|
||||
dependencies:
|
||||
ejs: 3.1.10
|
||||
json5: 2.2.3
|
||||
magic-string: 0.25.9
|
||||
string.prototype.matchall: 4.0.12
|
||||
|
||||
'@swc/helpers@0.5.17':
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
@@ -3054,6 +5003,10 @@ snapshots:
|
||||
dependencies:
|
||||
'@types/ms': 2.1.0
|
||||
|
||||
'@types/estree@0.0.39': {}
|
||||
|
||||
'@types/estree@1.0.8': {}
|
||||
|
||||
'@types/file-saver@2.0.7': {}
|
||||
|
||||
'@types/fs-extra@9.0.13':
|
||||
@@ -3082,10 +5035,14 @@ snapshots:
|
||||
xmlbuilder: 15.1.1
|
||||
optional: true
|
||||
|
||||
'@types/resolve@1.20.2': {}
|
||||
|
||||
'@types/responselike@1.0.3':
|
||||
dependencies:
|
||||
'@types/node': 24.10.2
|
||||
|
||||
'@types/trusted-types@2.0.7': {}
|
||||
|
||||
'@types/verror@1.10.11':
|
||||
optional: true
|
||||
|
||||
@@ -3096,6 +5053,16 @@ snapshots:
|
||||
'@types/node': 24.10.2
|
||||
optional: true
|
||||
|
||||
'@vite-pwa/assets-generator@1.0.2':
|
||||
dependencies:
|
||||
cac: 6.7.14
|
||||
colorette: 2.0.20
|
||||
consola: 3.4.2
|
||||
sharp: 0.33.5
|
||||
sharp-ico: 0.1.5
|
||||
unconfig: 7.4.2
|
||||
optional: true
|
||||
|
||||
'@vitejs/plugin-vue@6.0.2(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))(vue@3.5.25(typescript@5.9.3))':
|
||||
dependencies:
|
||||
'@rolldown/pluginutils': 1.0.0-beta.50
|
||||
@@ -3239,8 +5206,7 @@ snapshots:
|
||||
|
||||
abbrev@1.1.1: {}
|
||||
|
||||
acorn@8.15.0:
|
||||
optional: true
|
||||
acorn@8.15.0: {}
|
||||
|
||||
agent-base@6.0.2:
|
||||
dependencies:
|
||||
@@ -3270,6 +5236,13 @@ snapshots:
|
||||
json-schema-traverse: 0.4.1
|
||||
uri-js: 4.4.1
|
||||
|
||||
ajv@8.17.1:
|
||||
dependencies:
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-uri: 3.1.0
|
||||
json-schema-traverse: 1.0.0
|
||||
require-from-string: 2.0.2
|
||||
|
||||
alien-signals@3.1.1: {}
|
||||
|
||||
ansi-regex@5.0.1: {}
|
||||
@@ -3331,6 +5304,21 @@ snapshots:
|
||||
dependencies:
|
||||
tslib: 2.8.1
|
||||
|
||||
array-buffer-byte-length@1.0.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
is-array-buffer: 3.0.5
|
||||
|
||||
arraybuffer.prototype.slice@1.0.4:
|
||||
dependencies:
|
||||
array-buffer-byte-length: 1.0.2
|
||||
call-bind: 1.0.8
|
||||
define-properties: 1.2.1
|
||||
es-abstract: 1.24.1
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
is-array-buffer: 3.0.5
|
||||
|
||||
assert-plus@1.0.0:
|
||||
optional: true
|
||||
|
||||
@@ -3339,12 +5327,42 @@ snapshots:
|
||||
|
||||
async-exit-hook@2.0.1: {}
|
||||
|
||||
async-function@1.0.0: {}
|
||||
|
||||
async@3.2.6: {}
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
at-least-node@1.0.0: {}
|
||||
|
||||
available-typed-arrays@1.0.7:
|
||||
dependencies:
|
||||
possible-typed-array-names: 1.1.0
|
||||
|
||||
babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.5):
|
||||
dependencies:
|
||||
'@babel/compat-data': 7.28.5
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5)
|
||||
semver: 6.3.1
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.28.5):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5)
|
||||
core-js-compat: 3.47.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.5):
|
||||
dependencies:
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.5)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
base64-js@1.5.1: {}
|
||||
@@ -3459,6 +5477,18 @@ snapshots:
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
|
||||
call-bind@1.0.8:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-define-property: 1.0.1
|
||||
get-intrinsic: 1.3.0
|
||||
set-function-length: 1.2.2
|
||||
|
||||
call-bound@1.0.4:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
get-intrinsic: 1.3.0
|
||||
|
||||
caniuse-lite@1.0.30001760: {}
|
||||
|
||||
chalk@4.1.2:
|
||||
@@ -3510,18 +5540,34 @@ snapshots:
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
color-string@1.9.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
simple-swizzle: 0.2.4
|
||||
optional: true
|
||||
|
||||
color@4.2.3:
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
color-string: 1.9.1
|
||||
optional: true
|
||||
|
||||
colorette@2.0.20:
|
||||
optional: true
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
commander@2.20.3:
|
||||
optional: true
|
||||
commander@2.20.3: {}
|
||||
|
||||
commander@5.1.0: {}
|
||||
|
||||
commander@9.5.0:
|
||||
optional: true
|
||||
|
||||
common-tags@1.8.2: {}
|
||||
|
||||
compare-version@0.1.2: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
@@ -3531,12 +5577,19 @@ snapshots:
|
||||
glob: 10.5.0
|
||||
typescript: 5.9.3
|
||||
|
||||
consola@3.4.2:
|
||||
optional: true
|
||||
|
||||
convert-source-map@2.0.0: {}
|
||||
|
||||
copy-anything@4.0.5:
|
||||
dependencies:
|
||||
is-what: 5.5.0
|
||||
|
||||
core-js-compat@3.47.0:
|
||||
dependencies:
|
||||
browserslist: 4.28.1
|
||||
|
||||
core-util-is@1.0.2:
|
||||
optional: true
|
||||
|
||||
@@ -3548,6 +5601,10 @@ snapshots:
|
||||
cross-dirname@0.1.0:
|
||||
optional: true
|
||||
|
||||
cross-env@7.0.3:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
|
||||
cross-spawn@7.0.6:
|
||||
dependencies:
|
||||
path-key: 3.1.1
|
||||
@@ -3556,16 +5613,51 @@ snapshots:
|
||||
|
||||
crypto-js@4.2.0: {}
|
||||
|
||||
crypto-random-string@2.0.0: {}
|
||||
|
||||
csstype@3.2.3: {}
|
||||
|
||||
data-view-buffer@1.0.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
is-data-view: 1.0.2
|
||||
|
||||
data-view-byte-length@1.0.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
is-data-view: 1.0.2
|
||||
|
||||
data-view-byte-offset@1.0.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
is-data-view: 1.0.2
|
||||
|
||||
debug@4.4.3:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
decode-bmp@0.2.1:
|
||||
dependencies:
|
||||
'@canvas/image-data': 1.1.0
|
||||
to-data-view: 1.1.0
|
||||
optional: true
|
||||
|
||||
decode-ico@0.4.1:
|
||||
dependencies:
|
||||
'@canvas/image-data': 1.1.0
|
||||
decode-bmp: 0.2.1
|
||||
to-data-view: 1.1.0
|
||||
optional: true
|
||||
|
||||
decompress-response@6.0.0:
|
||||
dependencies:
|
||||
mimic-response: 3.1.0
|
||||
|
||||
deepmerge@4.3.1: {}
|
||||
|
||||
defaults@1.0.4:
|
||||
dependencies:
|
||||
clone: 1.0.4
|
||||
@@ -3577,14 +5669,12 @@ snapshots:
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
optional: true
|
||||
|
||||
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
|
||||
|
||||
defu@6.1.4: {}
|
||||
|
||||
@@ -3749,6 +5839,63 @@ snapshots:
|
||||
|
||||
err-code@2.0.3: {}
|
||||
|
||||
es-abstract@1.24.1:
|
||||
dependencies:
|
||||
array-buffer-byte-length: 1.0.2
|
||||
arraybuffer.prototype.slice: 1.0.4
|
||||
available-typed-arrays: 1.0.7
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
data-view-buffer: 1.0.2
|
||||
data-view-byte-length: 1.0.2
|
||||
data-view-byte-offset: 1.0.1
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
es-set-tostringtag: 2.1.0
|
||||
es-to-primitive: 1.3.0
|
||||
function.prototype.name: 1.1.8
|
||||
get-intrinsic: 1.3.0
|
||||
get-proto: 1.0.1
|
||||
get-symbol-description: 1.1.0
|
||||
globalthis: 1.0.4
|
||||
gopd: 1.2.0
|
||||
has-property-descriptors: 1.0.2
|
||||
has-proto: 1.2.0
|
||||
has-symbols: 1.1.0
|
||||
hasown: 2.0.2
|
||||
internal-slot: 1.1.0
|
||||
is-array-buffer: 3.0.5
|
||||
is-callable: 1.2.7
|
||||
is-data-view: 1.0.2
|
||||
is-negative-zero: 2.0.3
|
||||
is-regex: 1.2.1
|
||||
is-set: 2.0.3
|
||||
is-shared-array-buffer: 1.0.4
|
||||
is-string: 1.1.1
|
||||
is-typed-array: 1.1.15
|
||||
is-weakref: 1.1.1
|
||||
math-intrinsics: 1.1.0
|
||||
object-inspect: 1.13.4
|
||||
object-keys: 1.1.1
|
||||
object.assign: 4.1.7
|
||||
own-keys: 1.0.1
|
||||
regexp.prototype.flags: 1.5.4
|
||||
safe-array-concat: 1.1.3
|
||||
safe-push-apply: 1.0.0
|
||||
safe-regex-test: 1.1.0
|
||||
set-proto: 1.0.0
|
||||
stop-iteration-iterator: 1.1.0
|
||||
string.prototype.trim: 1.2.10
|
||||
string.prototype.trimend: 1.0.9
|
||||
string.prototype.trimstart: 1.0.8
|
||||
typed-array-buffer: 1.0.3
|
||||
typed-array-byte-length: 1.0.3
|
||||
typed-array-byte-offset: 1.0.4
|
||||
typed-array-length: 1.0.7
|
||||
unbox-primitive: 1.1.0
|
||||
which-typed-array: 1.1.19
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
@@ -3764,6 +5911,12 @@ snapshots:
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
es-to-primitive@1.3.0:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
is-date-object: 1.1.0
|
||||
is-symbol: 1.1.1
|
||||
|
||||
es6-error@4.1.1:
|
||||
optional: true
|
||||
|
||||
@@ -3803,8 +5956,12 @@ snapshots:
|
||||
escape-string-regexp@4.0.0:
|
||||
optional: true
|
||||
|
||||
estree-walker@1.0.1: {}
|
||||
|
||||
estree-walker@2.0.2: {}
|
||||
|
||||
esutils@2.0.3: {}
|
||||
|
||||
etag@1.8.1: {}
|
||||
|
||||
exponential-backoff@3.1.3: {}
|
||||
@@ -3826,6 +5983,8 @@ snapshots:
|
||||
|
||||
fast-json-stable-stringify@2.1.0: {}
|
||||
|
||||
fast-uri@3.1.0: {}
|
||||
|
||||
fd-slicer@1.1.0:
|
||||
dependencies:
|
||||
pend: 1.2.0
|
||||
@@ -3851,6 +6010,10 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
for-each@0.3.5:
|
||||
dependencies:
|
||||
is-callable: 1.2.7
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
@@ -3908,6 +6071,19 @@ snapshots:
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
function.prototype.name@1.1.8:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
define-properties: 1.2.1
|
||||
functions-have-names: 1.2.3
|
||||
hasown: 2.0.2
|
||||
is-callable: 1.2.7
|
||||
|
||||
functions-have-names@1.2.3: {}
|
||||
|
||||
generator-function@2.0.1: {}
|
||||
|
||||
gensync@1.0.0-beta.2: {}
|
||||
|
||||
get-caller-file@2.0.5: {}
|
||||
@@ -3925,6 +6101,8 @@ snapshots:
|
||||
hasown: 2.0.2
|
||||
math-intrinsics: 1.1.0
|
||||
|
||||
get-own-enumerable-property-symbols@3.0.2: {}
|
||||
|
||||
get-proto@1.0.1:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
@@ -3934,6 +6112,12 @@ snapshots:
|
||||
dependencies:
|
||||
pump: 3.0.3
|
||||
|
||||
get-symbol-description@1.1.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
|
||||
glob@10.5.0:
|
||||
dependencies:
|
||||
foreground-child: 3.3.1
|
||||
@@ -3943,6 +6127,15 @@ snapshots:
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 1.11.1
|
||||
|
||||
glob@11.1.0:
|
||||
dependencies:
|
||||
foreground-child: 3.3.1
|
||||
jackspeak: 4.1.1
|
||||
minimatch: 10.1.1
|
||||
minipass: 7.1.2
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 2.0.1
|
||||
|
||||
glob@7.2.3:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
@@ -3974,7 +6167,6 @@ snapshots:
|
||||
dependencies:
|
||||
define-properties: 1.2.1
|
||||
gopd: 1.2.0
|
||||
optional: true
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
@@ -3994,12 +6186,17 @@ snapshots:
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
has-bigints@1.1.0: {}
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
has-property-descriptors@1.0.2:
|
||||
dependencies:
|
||||
es-define-property: 1.0.1
|
||||
optional: true
|
||||
|
||||
has-proto@1.2.0:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
@@ -4065,6 +6262,9 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
ico-endec@0.1.6:
|
||||
optional: true
|
||||
|
||||
iconv-corefoundation@1.1.7:
|
||||
dependencies:
|
||||
cli-truncate: 2.1.0
|
||||
@@ -4075,6 +6275,8 @@ snapshots:
|
||||
dependencies:
|
||||
safer-buffer: 2.1.2
|
||||
|
||||
idb@7.1.1: {}
|
||||
|
||||
ieee754@1.2.1: {}
|
||||
|
||||
imurmurhash@0.1.4: {}
|
||||
@@ -4090,22 +6292,141 @@ snapshots:
|
||||
|
||||
inherits@2.0.4: {}
|
||||
|
||||
internal-slot@1.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
hasown: 2.0.2
|
||||
side-channel: 1.1.0
|
||||
|
||||
ip-address@10.1.0: {}
|
||||
|
||||
is-array-buffer@3.0.5:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
get-intrinsic: 1.3.0
|
||||
|
||||
is-arrayish@0.3.4:
|
||||
optional: true
|
||||
|
||||
is-async-function@2.1.1:
|
||||
dependencies:
|
||||
async-function: 1.0.0
|
||||
call-bound: 1.0.4
|
||||
get-proto: 1.0.1
|
||||
has-tostringtag: 1.0.2
|
||||
safe-regex-test: 1.1.0
|
||||
|
||||
is-bigint@1.1.0:
|
||||
dependencies:
|
||||
has-bigints: 1.1.0
|
||||
|
||||
is-boolean-object@1.2.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
is-callable@1.2.7: {}
|
||||
|
||||
is-ci@3.0.1:
|
||||
dependencies:
|
||||
ci-info: 3.9.0
|
||||
|
||||
is-core-module@2.16.1:
|
||||
dependencies:
|
||||
hasown: 2.0.2
|
||||
|
||||
is-data-view@1.0.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
get-intrinsic: 1.3.0
|
||||
is-typed-array: 1.1.15
|
||||
|
||||
is-date-object@1.1.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
is-finalizationregistry@1.1.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
is-generator-function@1.1.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
generator-function: 2.0.1
|
||||
get-proto: 1.0.1
|
||||
has-tostringtag: 1.0.2
|
||||
safe-regex-test: 1.1.0
|
||||
|
||||
is-interactive@1.0.0: {}
|
||||
|
||||
is-lambda@1.0.1: {}
|
||||
|
||||
is-map@2.0.3: {}
|
||||
|
||||
is-module@1.0.0: {}
|
||||
|
||||
is-negative-zero@2.0.3: {}
|
||||
|
||||
is-number-object@1.1.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
is-obj@1.0.1: {}
|
||||
|
||||
is-regex@1.2.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
gopd: 1.2.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
is-regexp@1.0.0: {}
|
||||
|
||||
is-set@2.0.3: {}
|
||||
|
||||
is-shared-array-buffer@1.0.4:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
|
||||
is-stream@2.0.1: {}
|
||||
|
||||
is-string@1.1.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
is-symbol@1.1.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
has-symbols: 1.1.0
|
||||
safe-regex-test: 1.1.0
|
||||
|
||||
is-typed-array@1.1.15:
|
||||
dependencies:
|
||||
which-typed-array: 1.1.19
|
||||
|
||||
is-unicode-supported@0.1.0: {}
|
||||
|
||||
is-weakmap@2.0.2: {}
|
||||
|
||||
is-weakref@1.1.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
|
||||
is-weakset@2.0.4:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
get-intrinsic: 1.3.0
|
||||
|
||||
is-what@5.5.0: {}
|
||||
|
||||
isarray@2.0.5: {}
|
||||
|
||||
isbinaryfile@4.0.10: {}
|
||||
|
||||
isbinaryfile@5.0.7: {}
|
||||
@@ -4118,6 +6439,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
'@pkgjs/parseargs': 0.11.0
|
||||
|
||||
jackspeak@4.1.1:
|
||||
dependencies:
|
||||
'@isaacs/cliui': 8.0.2
|
||||
|
||||
jake@10.9.4:
|
||||
dependencies:
|
||||
async: 3.2.6
|
||||
@@ -4138,6 +6463,10 @@ snapshots:
|
||||
|
||||
json-schema-traverse@0.4.1: {}
|
||||
|
||||
json-schema-traverse@1.0.0: {}
|
||||
|
||||
json-schema@0.4.0: {}
|
||||
|
||||
json-stringify-safe@5.0.1:
|
||||
optional: true
|
||||
|
||||
@@ -4153,12 +6482,16 @@ snapshots:
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.11
|
||||
|
||||
jsonpointer@5.0.1: {}
|
||||
|
||||
keyv@4.5.4:
|
||||
dependencies:
|
||||
json-buffer: 3.0.1
|
||||
|
||||
lazy-val@1.0.5: {}
|
||||
|
||||
leven@3.1.0: {}
|
||||
|
||||
lightningcss-android-arm64@1.30.2:
|
||||
optional: true
|
||||
|
||||
@@ -4208,6 +6541,10 @@ snapshots:
|
||||
lightningcss-win32-arm64-msvc: 1.30.2
|
||||
lightningcss-win32-x64-msvc: 1.30.2
|
||||
|
||||
lodash.debounce@4.0.8: {}
|
||||
|
||||
lodash.sortby@4.7.0: {}
|
||||
|
||||
lodash@4.17.21: {}
|
||||
|
||||
log-symbols@4.1.0:
|
||||
@@ -4219,6 +6556,8 @@ snapshots:
|
||||
|
||||
lru-cache@10.4.3: {}
|
||||
|
||||
lru-cache@11.2.4: {}
|
||||
|
||||
lru-cache@5.1.1:
|
||||
dependencies:
|
||||
yallist: 3.1.1
|
||||
@@ -4233,6 +6572,10 @@ snapshots:
|
||||
dependencies:
|
||||
vue: 3.5.25(typescript@5.9.3)
|
||||
|
||||
magic-string@0.25.9:
|
||||
dependencies:
|
||||
sourcemap-codec: 1.4.8
|
||||
|
||||
magic-string@0.30.21:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.5
|
||||
@@ -4259,6 +6602,8 @@ snapshots:
|
||||
- bluebird
|
||||
- supports-color
|
||||
|
||||
marked@17.0.1: {}
|
||||
|
||||
matcher@3.0.0:
|
||||
dependencies:
|
||||
escape-string-regexp: 4.0.0
|
||||
@@ -4376,8 +6721,18 @@ snapshots:
|
||||
|
||||
normalize-url@6.1.0: {}
|
||||
|
||||
object-keys@1.1.1:
|
||||
optional: true
|
||||
object-inspect@1.13.4: {}
|
||||
|
||||
object-keys@1.1.1: {}
|
||||
|
||||
object.assign@4.1.7:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
define-properties: 1.2.1
|
||||
es-object-atoms: 1.1.1
|
||||
has-symbols: 1.1.0
|
||||
object-keys: 1.1.1
|
||||
|
||||
ohash@2.0.11: {}
|
||||
|
||||
@@ -4405,6 +6760,12 @@ snapshots:
|
||||
strip-ansi: 6.0.1
|
||||
wcwidth: 1.0.1
|
||||
|
||||
own-keys@1.0.1:
|
||||
dependencies:
|
||||
get-intrinsic: 1.3.0
|
||||
object-keys: 1.1.1
|
||||
safe-push-apply: 1.0.0
|
||||
|
||||
p-cancelable@2.1.1: {}
|
||||
|
||||
p-limit@3.1.0:
|
||||
@@ -4425,11 +6786,18 @@ snapshots:
|
||||
|
||||
path-key@3.1.1: {}
|
||||
|
||||
path-parse@1.0.7: {}
|
||||
|
||||
path-scurry@1.11.1:
|
||||
dependencies:
|
||||
lru-cache: 10.4.3
|
||||
minipass: 7.1.2
|
||||
|
||||
path-scurry@2.0.1:
|
||||
dependencies:
|
||||
lru-cache: 11.2.4
|
||||
minipass: 7.1.2
|
||||
|
||||
pe-library@0.4.1: {}
|
||||
|
||||
pend@1.2.0: {}
|
||||
@@ -4438,6 +6806,8 @@ snapshots:
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
|
||||
picomatch@4.0.3: {}
|
||||
|
||||
pinia-plugin-persistedstate@4.7.1(pinia@3.0.4(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))):
|
||||
@@ -4459,6 +6829,8 @@ snapshots:
|
||||
base64-js: 1.5.1
|
||||
xmlbuilder: 15.1.1
|
||||
|
||||
possible-typed-array-names@1.1.0: {}
|
||||
|
||||
postcss@8.5.6:
|
||||
dependencies:
|
||||
nanoid: 3.3.11
|
||||
@@ -4470,6 +6842,10 @@ snapshots:
|
||||
commander: 9.5.0
|
||||
optional: true
|
||||
|
||||
pretty-bytes@5.6.0: {}
|
||||
|
||||
pretty-bytes@6.1.1: {}
|
||||
|
||||
proc-log@2.0.1: {}
|
||||
|
||||
progress@2.0.3: {}
|
||||
@@ -4488,8 +6864,15 @@ snapshots:
|
||||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
quansync@1.0.0:
|
||||
optional: true
|
||||
|
||||
quick-lru@5.1.1: {}
|
||||
|
||||
randombytes@2.1.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
range-parser@1.2.1: {}
|
||||
|
||||
read-binary-file-arch@1.0.6:
|
||||
@@ -4504,6 +6887,47 @@ snapshots:
|
||||
string_decoder: 1.3.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
reflect.getprototypeof@1.0.10:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
define-properties: 1.2.1
|
||||
es-abstract: 1.24.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
get-intrinsic: 1.3.0
|
||||
get-proto: 1.0.1
|
||||
which-builtin-type: 1.2.1
|
||||
|
||||
regenerate-unicode-properties@10.2.2:
|
||||
dependencies:
|
||||
regenerate: 1.4.2
|
||||
|
||||
regenerate@1.4.2: {}
|
||||
|
||||
regexp.prototype.flags@1.5.4:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
define-properties: 1.2.1
|
||||
es-errors: 1.3.0
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
set-function-name: 2.0.2
|
||||
|
||||
regexpu-core@6.4.0:
|
||||
dependencies:
|
||||
regenerate: 1.4.2
|
||||
regenerate-unicode-properties: 10.2.2
|
||||
regjsgen: 0.8.0
|
||||
regjsparser: 0.13.0
|
||||
unicode-match-property-ecmascript: 2.0.0
|
||||
unicode-match-property-value-ecmascript: 2.2.1
|
||||
|
||||
regjsgen@0.8.0: {}
|
||||
|
||||
regjsparser@0.13.0:
|
||||
dependencies:
|
||||
jsesc: 3.1.0
|
||||
|
||||
reka-ui@2.6.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)):
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.7.4
|
||||
@@ -4523,12 +6947,20 @@ snapshots:
|
||||
|
||||
require-directory@2.1.1: {}
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
resedit@1.7.2:
|
||||
dependencies:
|
||||
pe-library: 0.4.1
|
||||
|
||||
resolve-alpn@1.2.1: {}
|
||||
|
||||
resolve@1.22.11:
|
||||
dependencies:
|
||||
is-core-module: 2.16.1
|
||||
path-parse: 1.0.7
|
||||
supports-preserve-symlinks-flag: 1.0.0
|
||||
|
||||
responselike@2.0.1:
|
||||
dependencies:
|
||||
lowercase-keys: 2.0.0
|
||||
@@ -4596,8 +7028,31 @@ snapshots:
|
||||
'@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.50
|
||||
'@rolldown/binding-win32-x64-msvc': 1.0.0-beta.50
|
||||
|
||||
rollup@2.79.2:
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
safe-array-concat@1.1.3:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
get-intrinsic: 1.3.0
|
||||
has-symbols: 1.1.0
|
||||
isarray: 2.0.5
|
||||
|
||||
safe-buffer@5.2.1: {}
|
||||
|
||||
safe-push-apply@1.0.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
isarray: 2.0.5
|
||||
|
||||
safe-regex-test@1.1.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
is-regex: 1.2.1
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
|
||||
sanitize-filename@1.6.3:
|
||||
@@ -4636,6 +7091,10 @@ snapshots:
|
||||
type-fest: 0.13.1
|
||||
optional: true
|
||||
|
||||
serialize-javascript@6.0.2:
|
||||
dependencies:
|
||||
randombytes: 2.1.0
|
||||
|
||||
serve-static@2.2.0:
|
||||
dependencies:
|
||||
encodeurl: 2.0.0
|
||||
@@ -4645,18 +7104,107 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
set-function-length@1.2.2:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
get-intrinsic: 1.3.0
|
||||
gopd: 1.2.0
|
||||
has-property-descriptors: 1.0.2
|
||||
|
||||
set-function-name@2.0.2:
|
||||
dependencies:
|
||||
define-data-property: 1.1.4
|
||||
es-errors: 1.3.0
|
||||
functions-have-names: 1.2.3
|
||||
has-property-descriptors: 1.0.2
|
||||
|
||||
set-proto@1.0.0:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
setprototypeof@1.2.0: {}
|
||||
|
||||
sharp-ico@0.1.5:
|
||||
dependencies:
|
||||
decode-ico: 0.4.1
|
||||
ico-endec: 0.1.6
|
||||
sharp: 0.33.5
|
||||
optional: true
|
||||
|
||||
sharp@0.33.5:
|
||||
dependencies:
|
||||
color: 4.2.3
|
||||
detect-libc: 2.1.2
|
||||
semver: 7.7.3
|
||||
optionalDependencies:
|
||||
'@img/sharp-darwin-arm64': 0.33.5
|
||||
'@img/sharp-darwin-x64': 0.33.5
|
||||
'@img/sharp-libvips-darwin-arm64': 1.0.4
|
||||
'@img/sharp-libvips-darwin-x64': 1.0.4
|
||||
'@img/sharp-libvips-linux-arm': 1.0.5
|
||||
'@img/sharp-libvips-linux-arm64': 1.0.4
|
||||
'@img/sharp-libvips-linux-s390x': 1.0.4
|
||||
'@img/sharp-libvips-linux-x64': 1.0.4
|
||||
'@img/sharp-libvips-linuxmusl-arm64': 1.0.4
|
||||
'@img/sharp-libvips-linuxmusl-x64': 1.0.4
|
||||
'@img/sharp-linux-arm': 0.33.5
|
||||
'@img/sharp-linux-arm64': 0.33.5
|
||||
'@img/sharp-linux-s390x': 0.33.5
|
||||
'@img/sharp-linux-x64': 0.33.5
|
||||
'@img/sharp-linuxmusl-arm64': 0.33.5
|
||||
'@img/sharp-linuxmusl-x64': 0.33.5
|
||||
'@img/sharp-wasm32': 0.33.5
|
||||
'@img/sharp-win32-ia32': 0.33.5
|
||||
'@img/sharp-win32-x64': 0.33.5
|
||||
optional: true
|
||||
|
||||
shebang-command@2.0.0:
|
||||
dependencies:
|
||||
shebang-regex: 3.0.0
|
||||
|
||||
shebang-regex@3.0.0: {}
|
||||
|
||||
side-channel-list@1.0.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
object-inspect: 1.13.4
|
||||
|
||||
side-channel-map@1.0.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
object-inspect: 1.13.4
|
||||
|
||||
side-channel-weakmap@1.0.2:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
object-inspect: 1.13.4
|
||||
side-channel-map: 1.0.1
|
||||
|
||||
side-channel@1.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
object-inspect: 1.13.4
|
||||
side-channel-list: 1.0.0
|
||||
side-channel-map: 1.0.1
|
||||
side-channel-weakmap: 1.0.2
|
||||
|
||||
signal-exit@3.0.7: {}
|
||||
|
||||
signal-exit@4.1.0: {}
|
||||
|
||||
simple-swizzle@0.2.4:
|
||||
dependencies:
|
||||
is-arrayish: 0.3.4
|
||||
optional: true
|
||||
|
||||
simple-update-notifier@2.0.0:
|
||||
dependencies:
|
||||
semver: 7.7.3
|
||||
@@ -4670,6 +7218,8 @@ snapshots:
|
||||
|
||||
smart-buffer@4.2.0: {}
|
||||
|
||||
smob@1.5.0: {}
|
||||
|
||||
socks-proxy-agent@7.0.0:
|
||||
dependencies:
|
||||
agent-base: 6.0.2
|
||||
@@ -4692,6 +7242,12 @@ snapshots:
|
||||
|
||||
source-map@0.6.1: {}
|
||||
|
||||
source-map@0.8.0-beta.0:
|
||||
dependencies:
|
||||
whatwg-url: 7.1.0
|
||||
|
||||
sourcemap-codec@1.4.8: {}
|
||||
|
||||
speakingurl@14.0.1: {}
|
||||
|
||||
sprintf-js@1.1.3:
|
||||
@@ -4705,6 +7261,11 @@ snapshots:
|
||||
|
||||
statuses@2.0.2: {}
|
||||
|
||||
stop-iteration-iterator@1.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
internal-slot: 1.1.0
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
@@ -4717,10 +7278,55 @@ snapshots:
|
||||
emoji-regex: 9.2.2
|
||||
strip-ansi: 7.1.2
|
||||
|
||||
string.prototype.matchall@4.0.12:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
define-properties: 1.2.1
|
||||
es-abstract: 1.24.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
get-intrinsic: 1.3.0
|
||||
gopd: 1.2.0
|
||||
has-symbols: 1.1.0
|
||||
internal-slot: 1.1.0
|
||||
regexp.prototype.flags: 1.5.4
|
||||
set-function-name: 2.0.2
|
||||
side-channel: 1.1.0
|
||||
|
||||
string.prototype.trim@1.2.10:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
define-data-property: 1.1.4
|
||||
define-properties: 1.2.1
|
||||
es-abstract: 1.24.1
|
||||
es-object-atoms: 1.1.1
|
||||
has-property-descriptors: 1.0.2
|
||||
|
||||
string.prototype.trimend@1.0.9:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
define-properties: 1.2.1
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
string.prototype.trimstart@1.0.8:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
define-properties: 1.2.1
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
string_decoder@1.3.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
stringify-object@3.3.0:
|
||||
dependencies:
|
||||
get-own-enumerable-property-symbols: 3.0.2
|
||||
is-obj: 1.0.1
|
||||
is-regexp: 1.0.0
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
@@ -4729,6 +7335,8 @@ snapshots:
|
||||
dependencies:
|
||||
ansi-regex: 6.2.2
|
||||
|
||||
strip-comments@2.0.1: {}
|
||||
|
||||
sumchecker@3.0.1:
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
@@ -4743,6 +7351,8 @@ snapshots:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
tailwind-merge@3.4.0: {}
|
||||
|
||||
tailwindcss@4.1.17: {}
|
||||
@@ -4758,6 +7368,8 @@ snapshots:
|
||||
mkdirp: 1.0.4
|
||||
yallist: 4.0.0
|
||||
|
||||
temp-dir@2.0.0: {}
|
||||
|
||||
temp-file@3.4.0:
|
||||
dependencies:
|
||||
async-exit-hook: 2.0.1
|
||||
@@ -4768,13 +7380,19 @@ snapshots:
|
||||
mkdirp: 0.5.6
|
||||
rimraf: 2.6.3
|
||||
|
||||
tempy@0.6.0:
|
||||
dependencies:
|
||||
is-stream: 2.0.1
|
||||
temp-dir: 2.0.0
|
||||
type-fest: 0.16.0
|
||||
unique-string: 2.0.0
|
||||
|
||||
terser@5.44.1:
|
||||
dependencies:
|
||||
'@jridgewell/source-map': 0.3.11
|
||||
acorn: 8.15.0
|
||||
commander: 2.20.3
|
||||
source-map-support: 0.5.21
|
||||
optional: true
|
||||
|
||||
tiny-async-pool@1.3.0:
|
||||
dependencies:
|
||||
@@ -4791,8 +7409,15 @@ snapshots:
|
||||
|
||||
tmp@0.2.5: {}
|
||||
|
||||
to-data-view@1.1.0:
|
||||
optional: true
|
||||
|
||||
toidentifier@1.0.1: {}
|
||||
|
||||
tr46@1.0.1:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
truncate-utf8-bytes@1.0.2:
|
||||
dependencies:
|
||||
utf8-byte-length: 1.0.5
|
||||
@@ -4804,12 +7429,80 @@ snapshots:
|
||||
type-fest@0.13.1:
|
||||
optional: true
|
||||
|
||||
type-fest@0.16.0: {}
|
||||
|
||||
typed-array-buffer@1.0.3:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
es-errors: 1.3.0
|
||||
is-typed-array: 1.1.15
|
||||
|
||||
typed-array-byte-length@1.0.3:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
for-each: 0.3.5
|
||||
gopd: 1.2.0
|
||||
has-proto: 1.2.0
|
||||
is-typed-array: 1.1.15
|
||||
|
||||
typed-array-byte-offset@1.0.4:
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.7
|
||||
call-bind: 1.0.8
|
||||
for-each: 0.3.5
|
||||
gopd: 1.2.0
|
||||
has-proto: 1.2.0
|
||||
is-typed-array: 1.1.15
|
||||
reflect.getprototypeof: 1.0.10
|
||||
|
||||
typed-array-length@1.0.7:
|
||||
dependencies:
|
||||
call-bind: 1.0.8
|
||||
for-each: 0.3.5
|
||||
gopd: 1.2.0
|
||||
is-typed-array: 1.1.15
|
||||
possible-typed-array-names: 1.1.0
|
||||
reflect.getprototypeof: 1.0.10
|
||||
|
||||
typescript@5.9.3: {}
|
||||
|
||||
unbox-primitive@1.1.0:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
has-bigints: 1.1.0
|
||||
has-symbols: 1.1.0
|
||||
which-boxed-primitive: 1.1.1
|
||||
|
||||
unconfig-core@7.4.2:
|
||||
dependencies:
|
||||
'@quansync/fs': 1.0.0
|
||||
quansync: 1.0.0
|
||||
optional: true
|
||||
|
||||
unconfig@7.4.2:
|
||||
dependencies:
|
||||
'@quansync/fs': 1.0.0
|
||||
defu: 6.1.4
|
||||
jiti: 2.6.1
|
||||
quansync: 1.0.0
|
||||
unconfig-core: 7.4.2
|
||||
optional: true
|
||||
|
||||
undici-types@6.21.0: {}
|
||||
|
||||
undici-types@7.16.0: {}
|
||||
|
||||
unicode-canonical-property-names-ecmascript@2.0.1: {}
|
||||
|
||||
unicode-match-property-ecmascript@2.0.0:
|
||||
dependencies:
|
||||
unicode-canonical-property-names-ecmascript: 2.0.1
|
||||
unicode-property-aliases-ecmascript: 2.2.0
|
||||
|
||||
unicode-match-property-value-ecmascript@2.2.1: {}
|
||||
|
||||
unicode-property-aliases-ecmascript@2.2.0: {}
|
||||
|
||||
unique-filename@2.0.1:
|
||||
dependencies:
|
||||
unique-slug: 3.0.0
|
||||
@@ -4818,10 +7511,16 @@ snapshots:
|
||||
dependencies:
|
||||
imurmurhash: 0.1.4
|
||||
|
||||
unique-string@2.0.0:
|
||||
dependencies:
|
||||
crypto-random-string: 2.0.0
|
||||
|
||||
universalify@0.1.2: {}
|
||||
|
||||
universalify@2.0.1: {}
|
||||
|
||||
upath@1.2.0: {}
|
||||
|
||||
update-browserslist-db@1.2.2(browserslist@4.28.1):
|
||||
dependencies:
|
||||
browserslist: 4.28.1
|
||||
@@ -4849,6 +7548,19 @@ snapshots:
|
||||
optionalDependencies:
|
||||
vite-plugin-electron-renderer: 0.14.6
|
||||
|
||||
vite-plugin-pwa@1.2.0(@vite-pwa/assets-generator@1.0.2)(rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1))(workbox-build@7.4.0)(workbox-window@7.4.0):
|
||||
dependencies:
|
||||
debug: 4.4.3
|
||||
pretty-bytes: 6.1.1
|
||||
tinyglobby: 0.2.15
|
||||
vite: rolldown-vite@7.2.5(@types/node@24.10.2)(esbuild@0.25.12)(jiti@2.6.1)(terser@5.44.1)
|
||||
workbox-build: 7.4.0
|
||||
workbox-window: 7.4.0
|
||||
optionalDependencies:
|
||||
'@vite-pwa/assets-generator': 1.0.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vscode-uri@3.1.0: {}
|
||||
|
||||
vue-demi@0.14.10(vue@3.5.25(typescript@5.9.3)):
|
||||
@@ -4882,10 +7594,172 @@ snapshots:
|
||||
dependencies:
|
||||
defaults: 1.0.4
|
||||
|
||||
webidl-conversions@4.0.2: {}
|
||||
|
||||
whatwg-url@7.1.0:
|
||||
dependencies:
|
||||
lodash.sortby: 4.7.0
|
||||
tr46: 1.0.1
|
||||
webidl-conversions: 4.0.2
|
||||
|
||||
which-boxed-primitive@1.1.1:
|
||||
dependencies:
|
||||
is-bigint: 1.1.0
|
||||
is-boolean-object: 1.2.2
|
||||
is-number-object: 1.1.1
|
||||
is-string: 1.1.1
|
||||
is-symbol: 1.1.1
|
||||
|
||||
which-builtin-type@1.2.1:
|
||||
dependencies:
|
||||
call-bound: 1.0.4
|
||||
function.prototype.name: 1.1.8
|
||||
has-tostringtag: 1.0.2
|
||||
is-async-function: 2.1.1
|
||||
is-date-object: 1.1.0
|
||||
is-finalizationregistry: 1.1.1
|
||||
is-generator-function: 1.1.2
|
||||
is-regex: 1.2.1
|
||||
is-weakref: 1.1.1
|
||||
isarray: 2.0.5
|
||||
which-boxed-primitive: 1.1.1
|
||||
which-collection: 1.0.2
|
||||
which-typed-array: 1.1.19
|
||||
|
||||
which-collection@1.0.2:
|
||||
dependencies:
|
||||
is-map: 2.0.3
|
||||
is-set: 2.0.3
|
||||
is-weakmap: 2.0.2
|
||||
is-weakset: 2.0.4
|
||||
|
||||
which-typed-array@1.1.19:
|
||||
dependencies:
|
||||
available-typed-arrays: 1.0.7
|
||||
call-bind: 1.0.8
|
||||
call-bound: 1.0.4
|
||||
for-each: 0.3.5
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
has-tostringtag: 1.0.2
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
workbox-background-sync@7.4.0:
|
||||
dependencies:
|
||||
idb: 7.1.1
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-broadcast-update@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-build@7.4.0:
|
||||
dependencies:
|
||||
'@apideck/better-ajv-errors': 0.3.6(ajv@8.17.1)
|
||||
'@babel/core': 7.28.5
|
||||
'@babel/preset-env': 7.28.5(@babel/core@7.28.5)
|
||||
'@babel/runtime': 7.28.4
|
||||
'@rollup/plugin-babel': 5.3.1(@babel/core@7.28.5)(rollup@2.79.2)
|
||||
'@rollup/plugin-node-resolve': 15.3.1(rollup@2.79.2)
|
||||
'@rollup/plugin-replace': 2.4.2(rollup@2.79.2)
|
||||
'@rollup/plugin-terser': 0.4.4(rollup@2.79.2)
|
||||
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
||||
ajv: 8.17.1
|
||||
common-tags: 1.8.2
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
fs-extra: 9.1.0
|
||||
glob: 11.1.0
|
||||
lodash: 4.17.21
|
||||
pretty-bytes: 5.6.0
|
||||
rollup: 2.79.2
|
||||
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.4.0
|
||||
workbox-broadcast-update: 7.4.0
|
||||
workbox-cacheable-response: 7.4.0
|
||||
workbox-core: 7.4.0
|
||||
workbox-expiration: 7.4.0
|
||||
workbox-google-analytics: 7.4.0
|
||||
workbox-navigation-preload: 7.4.0
|
||||
workbox-precaching: 7.4.0
|
||||
workbox-range-requests: 7.4.0
|
||||
workbox-recipes: 7.4.0
|
||||
workbox-routing: 7.4.0
|
||||
workbox-strategies: 7.4.0
|
||||
workbox-streams: 7.4.0
|
||||
workbox-sw: 7.4.0
|
||||
workbox-window: 7.4.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/babel__core'
|
||||
- supports-color
|
||||
|
||||
workbox-cacheable-response@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-core@7.4.0: {}
|
||||
|
||||
workbox-expiration@7.4.0:
|
||||
dependencies:
|
||||
idb: 7.1.1
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-google-analytics@7.4.0:
|
||||
dependencies:
|
||||
workbox-background-sync: 7.4.0
|
||||
workbox-core: 7.4.0
|
||||
workbox-routing: 7.4.0
|
||||
workbox-strategies: 7.4.0
|
||||
|
||||
workbox-navigation-preload@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-precaching@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
workbox-routing: 7.4.0
|
||||
workbox-strategies: 7.4.0
|
||||
|
||||
workbox-range-requests@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-recipes@7.4.0:
|
||||
dependencies:
|
||||
workbox-cacheable-response: 7.4.0
|
||||
workbox-core: 7.4.0
|
||||
workbox-expiration: 7.4.0
|
||||
workbox-precaching: 7.4.0
|
||||
workbox-routing: 7.4.0
|
||||
workbox-strategies: 7.4.0
|
||||
|
||||
workbox-routing@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-strategies@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
|
||||
workbox-streams@7.4.0:
|
||||
dependencies:
|
||||
workbox-core: 7.4.0
|
||||
workbox-routing: 7.4.0
|
||||
|
||||
workbox-sw@7.4.0: {}
|
||||
|
||||
workbox-window@7.4.0:
|
||||
dependencies:
|
||||
'@types/trusted-types': 2.0.7
|
||||
workbox-core: 7.4.0
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
|
||||
1240
src/App.vue
1240
src/App.vue
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<SidebarProvider :open="sidebarOpen" @update:open="sidebarOpen = $event">
|
||||
<SidebarProvider :open="sidebarOpen" @update:open="handleSidebarOpenChange">
|
||||
<Sidebar collapsible="icon">
|
||||
<!-- Logo -->
|
||||
<SidebarHeader class="border-b">
|
||||
@@ -13,15 +13,68 @@
|
||||
<!-- 星球信息 -->
|
||||
<SidebarGroup v-if="planet" class="border-b group-data-[collapsible=icon]:hidden">
|
||||
<div class="px-4 py-3 space-y-2 text-sm">
|
||||
<div>
|
||||
<p class="font-semibold mb-1">
|
||||
{{ planet.name }}
|
||||
<Badge v-if="planet.isMoon" variant="secondary" class="ml-1 text-xs">{{ t('planet.moon') }}</Badge>
|
||||
</p>
|
||||
<p class="text-muted-foreground text-xs">
|
||||
[{{ planet.position.galaxy }}:{{ planet.position.system }}:{{ planet.position.position }}]
|
||||
</p>
|
||||
<!-- 星球切换器 -->
|
||||
<Popover>
|
||||
<PopoverTrigger as-child>
|
||||
<Button
|
||||
data-tutorial="planet-selector"
|
||||
variant="outline"
|
||||
class="w-full justify-between h-auto px-3 py-2.5 border-2 hover:bg-accent hover:border-primary transition-colors"
|
||||
>
|
||||
<div class="flex items-start gap-2.5 flex-1 min-w-0">
|
||||
<Globe class="h-5 w-5 flex-shrink-0 mt-0.5 text-primary" />
|
||||
<div class="flex-1 min-w-0 text-left">
|
||||
<div class="text-[10px] text-muted-foreground uppercase tracking-wider mb-0.5">
|
||||
{{ t('planet.currentPlanet') }}
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 mb-0.5">
|
||||
<span class="truncate font-semibold text-sm">{{ planet.name }}</span>
|
||||
<Badge v-if="planet.isMoon" variant="secondary" class="text-[10px] px-1 py-0 h-4">
|
||||
{{ t('planet.moon') }}
|
||||
</Badge>
|
||||
</div>
|
||||
<div class="text-[11px] text-muted-foreground">
|
||||
[{{ planet.position.galaxy }}:{{ planet.position.system }}:{{ planet.position.position }}]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ChevronsUpDown class="h-4 w-4 flex-shrink-0 text-muted-foreground ml-2" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-72 p-0" side="bottom" align="start">
|
||||
<div class="p-2">
|
||||
<div class="px-2 py-1.5 mb-1 text-xs font-semibold text-muted-foreground">
|
||||
{{ t('planet.switchPlanet') }}
|
||||
</div>
|
||||
<div class="space-y-0.5 max-h-80 overflow-y-auto">
|
||||
<Button
|
||||
v-for="p in gameStore.player.planets"
|
||||
:key="p.id"
|
||||
@click="switchToPlanet(p.id)"
|
||||
:variant="p.id === planet.id ? 'secondary' : 'ghost'"
|
||||
class="w-full justify-start h-auto py-2 px-2"
|
||||
size="sm"
|
||||
>
|
||||
<div class="flex items-start gap-2 w-full min-w-0">
|
||||
<Globe class="h-4 w-4 flex-shrink-0 mt-0.5" :class="p.id === planet.id ? 'text-primary' : ''" />
|
||||
<div class="flex-1 min-w-0 text-left">
|
||||
<div class="flex items-center gap-1.5 mb-0.5">
|
||||
<span class="truncate font-medium text-sm">{{ p.name }}</span>
|
||||
<Badge v-if="p.isMoon" variant="outline" class="text-[10px] px-1 py-0 h-4">
|
||||
{{ t('planet.moon') }}
|
||||
</Badge>
|
||||
</div>
|
||||
<div class="text-[11px] text-muted-foreground">
|
||||
[{{ p.position.galaxy }}:{{ p.position.system }}:{{ p.position.position }}]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
<!-- 玩家积分显示 -->
|
||||
<div class="bg-muted/50 rounded-lg p-2">
|
||||
<div class="flex items-center justify-between">
|
||||
@@ -42,18 +95,35 @@
|
||||
</SidebarGroup>
|
||||
|
||||
<!-- 导航菜单 -->
|
||||
<SidebarGroup>
|
||||
<SidebarGroup data-tutorial="navigation">
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem v-for="item in navItems" :key="item.path">
|
||||
<SidebarMenuButton as-child :is-active="$route.path === item.path" :tooltip="item.name.value">
|
||||
<RouterLink :to="item.path">
|
||||
<SidebarMenuButton
|
||||
:data-nav-path="item.path"
|
||||
:is-active="$route.path === item.path"
|
||||
:tooltip="item.name.value"
|
||||
@click="handleNavClick(item.path, $event)"
|
||||
>
|
||||
<component :is="item.icon" />
|
||||
<span>{{ item.name.value }}</span>
|
||||
<!-- 未读消息数量 -->
|
||||
<SidebarMenuBadge v-if="item.path === '/messages' && unreadMessagesCount > 0">
|
||||
<SidebarMenuBadge
|
||||
v-if="item.path === '/messages' && unreadMessagesCount > 0"
|
||||
class="bg-destructive text-destructive-foreground"
|
||||
>
|
||||
{{ unreadMessagesCount }}
|
||||
</SidebarMenuBadge>
|
||||
</RouterLink>
|
||||
<!-- 正在执行的舰队任务数量 -->
|
||||
<SidebarMenuBadge v-if="item.path === '/fleet' && activeFleetMissionsCount > 0" class="bg-primary text-primary-foreground">
|
||||
{{ activeFleetMissionsCount }}
|
||||
</SidebarMenuBadge>
|
||||
<!-- 未读外交报告数量 -->
|
||||
<SidebarMenuBadge
|
||||
v-if="item.path === '/diplomacy' && unreadDiplomaticReportsCount > 0"
|
||||
class="bg-destructive text-destructive-foreground"
|
||||
>
|
||||
{{ unreadDiplomaticReportsCount }}
|
||||
</SidebarMenuBadge>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
@@ -72,7 +142,11 @@
|
||||
<span>{{ localeNames[gameStore.locale] }}</span>
|
||||
</SidebarMenuButton>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-48 p-2" side="right" align="end">
|
||||
<PopoverContent
|
||||
class="w-48 p-2"
|
||||
:side="sidebarOpen || innerWidth < 768 ? 'top' : 'right'"
|
||||
:align="sidebarOpen || innerWidth < 768 ? 'center' : 'end'"
|
||||
>
|
||||
<div class="space-y-1">
|
||||
<Button
|
||||
v-for="locale in locales"
|
||||
@@ -111,21 +185,43 @@
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<SidebarInset>
|
||||
<div class="flex flex-col h-full overflow-hidden">
|
||||
<!-- 顶部资源栏 -->
|
||||
<header v-if="planet" class="bg-card border-b px-4 sm:px-6 py-6.5 shadow-md">
|
||||
<div class="flex items-center justify-between gap-3 sm:gap-6">
|
||||
<!-- 汉堡菜单(移动端)- 左侧占位 -->
|
||||
<div class="lg:flex-1">
|
||||
<SidebarTrigger class="lg:hidden" />
|
||||
<div class="flex flex-col h-full overflow-hidden pt-[60px]">
|
||||
<!-- 顶部资源栏 - 固定定位 -->
|
||||
<header
|
||||
v-if="planet"
|
||||
class="fixed top-0 right-0 left-0 z-40 bg-card border-b px-4 sm:px-6 py-3 shadow-md"
|
||||
:class="sidebarOpen ? 'lg:left-[var(--sidebar-width)]' : 'lg:left-[var(--sidebar-width-icon)]'"
|
||||
>
|
||||
<div class="flex flex-col gap-3">
|
||||
<!-- 第一行:菜单、资源预览、状态 -->
|
||||
<div class="grid items-center gap-3 sm:gap-6" style="grid-template-columns: auto 1fr auto">
|
||||
<!-- 左侧:汉堡菜单(移动端)/ 占位(PC端) -->
|
||||
<div>
|
||||
<SidebarTrigger class="lg:hidden" data-tutorial="mobile-menu" />
|
||||
</div>
|
||||
|
||||
<!-- 资源显示 - PC端居中 -->
|
||||
<div class="flex items-center gap-3 sm:gap-6 flex-1 lg:flex-none overflow-x-auto lg:justify-center">
|
||||
<!-- 资源显示 - PC端居中,移动端可折叠 -->
|
||||
<div
|
||||
class="resource-bar flex items-center gap-3 sm:gap-6 justify-center"
|
||||
:class="resourceBarExpanded ? 'hidden' : 'overflow-x-auto'"
|
||||
>
|
||||
<div v-for="resourceType in resourceTypes" :key="resourceType.key" class="flex items-center gap-1.5 sm:gap-2 flex-shrink-0">
|
||||
<ResourceIcon :type="resourceType.key" size="md" />
|
||||
<div class="min-w-0">
|
||||
<!-- 所有资源统一显示:当前值/容量 -->
|
||||
<!-- 电力显示净产量和效率 -->
|
||||
<template v-if="resourceType.key === 'energy'">
|
||||
<p
|
||||
class="text-xs sm:text-sm font-medium truncate"
|
||||
:class="netEnergy >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'"
|
||||
>
|
||||
{{ netEnergy >= 0 ? '+' : '' }}{{ formatNumber(netEnergy) }}
|
||||
</p>
|
||||
<p class="text-[10px] sm:text-xs text-muted-foreground truncate">
|
||||
{{ formatNumber(production?.energy || 0) }} / {{ formatNumber(energyConsumption) }}
|
||||
</p>
|
||||
</template>
|
||||
<!-- 其他资源统一显示:当前值/容量 -->
|
||||
<template v-else>
|
||||
<p
|
||||
class="text-xs sm:text-sm font-medium truncate"
|
||||
:class="getResourceColor(planet.resources[resourceType.key], capacity?.[resourceType.key] || Infinity)"
|
||||
@@ -135,88 +231,91 @@
|
||||
<p class="text-[10px] sm:text-xs text-muted-foreground truncate">
|
||||
+{{ formatNumber(Math.round((production?.[resourceType.key] || 0) / 60)) }}/{{ t('resources.perMinute') }}
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧状态 - 右侧占位 -->
|
||||
<div class="flex items-center gap-2 sm:gap-4 flex-shrink-0 lg:flex-1 lg:justify-end">
|
||||
<!-- 建造队列状态 -->
|
||||
<div v-if="planet.buildQueue.length > 0" class="flex items-center gap-1.5 sm:gap-2 text-xs sm:text-sm">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500 animate-pulse" />
|
||||
<span class="text-muted-foreground hidden sm:inline">{{ t('queue.building') }}</span>
|
||||
</div>
|
||||
<div v-if="gameStore.player.researchQueue.length > 0" class="flex items-center gap-1.5 sm:gap-2 text-xs sm:text-sm">
|
||||
<div class="h-2 w-2 rounded-full bg-blue-500 animate-pulse" />
|
||||
<span class="text-muted-foreground hidden sm:inline">{{ t('queue.researching') }}</span>
|
||||
<!-- 右侧:展开按钮(仅移动端) + 状态 -->
|
||||
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0 justify-end">
|
||||
<!-- 移动端展开按钮 -->
|
||||
<Button @click="resourceBarExpanded = !resourceBarExpanded" variant="ghost" size="sm" class="lg:hidden h-8 w-8 p-0">
|
||||
<ChevronDown v-if="!resourceBarExpanded" class="h-4 w-4" />
|
||||
<ChevronUp v-else class="h-4 w-4" />
|
||||
</Button>
|
||||
|
||||
<!-- 外交通知 -->
|
||||
<DiplomaticNotifications />
|
||||
|
||||
<!-- 队列通知 -->
|
||||
<QueueNotifications />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 建造队列 -->
|
||||
<!-- 展开的资源详情(仅移动端且展开时显示) - absolute定位覆盖在内容上,带过渡动画 -->
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-300 ease-out"
|
||||
enter-from-class="opacity-0 -translate-y-2"
|
||||
enter-to-class="opacity-100 translate-y-0"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 translate-y-0"
|
||||
leave-to-class="opacity-0 -translate-y-2"
|
||||
>
|
||||
<div
|
||||
v-if="planet && (planet.buildQueue.length > 0 || gameStore.player.researchQueue.length > 0)"
|
||||
class="bg-card border-b px-4 sm:px-6 py-4.5"
|
||||
v-if="planet && resourceBarExpanded"
|
||||
class="fixed top-[60px] right-0 left-0 z-30 bg-card border-b px-4 py-3 shadow-md lg:hidden"
|
||||
:class="sidebarOpen ? 'lg:left-[var(--sidebar-width)]' : 'lg:left-[var(--sidebar-width-icon)]'"
|
||||
>
|
||||
<div class="space-y-3">
|
||||
<!-- 建造队列 -->
|
||||
<div v-for="item in planet.buildQueue" :key="item.id" class="space-y-1.5">
|
||||
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
||||
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
||||
<div class="h-2 w-2 rounded-full bg-green-500 animate-pulse flex-shrink-0" />
|
||||
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
||||
<span class="text-muted-foreground hidden sm:inline flex-shrink-0 text-[10px] sm:text-xs">
|
||||
<template v-if="item.type === 'ship' || item.type === 'defense'">
|
||||
→ {{ t('queue.quantity') }} {{ item.quantity }}
|
||||
<div class="grid grid-cols-2 gap-3">
|
||||
<div v-for="resourceType in resourceTypes" :key="resourceType.key" class="bg-muted/50 rounded-lg p-2.5">
|
||||
<div class="flex items-center justify-center gap-2 mb-1.5">
|
||||
<ResourceIcon :type="resourceType.key" size="md" />
|
||||
<span class="text-xs font-medium text-muted-foreground">{{ t(`resources.${resourceType.key}`) }}</span>
|
||||
</div>
|
||||
<div class="space-y-0.5 text-center">
|
||||
<!-- 电力显示净产量和效率 -->
|
||||
<template v-if="resourceType.key === 'energy'">
|
||||
<p
|
||||
class="text-sm font-semibold"
|
||||
:class="netEnergy >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'"
|
||||
>
|
||||
{{ netEnergy >= 0 ? '+' : '' }}{{ formatNumber(netEnergy) }}
|
||||
</p>
|
||||
<p class="text-[10px] text-muted-foreground">
|
||||
{{ t('resources.production') }}: {{ formatNumber(production?.energy || 0) }} / {{ formatNumber(energyConsumption) }}
|
||||
</p>
|
||||
</template>
|
||||
<template v-else>→ {{ t('queue.level') }} {{ item.targetLevel }}</template>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
||||
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
||||
{{ formatTime(getRemainingTime(item)) }}
|
||||
</span>
|
||||
<Button
|
||||
@click="handleCancelBuild(item.id)"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs"
|
||||
<!-- 其他资源统一显示:当前值/容量 -->
|
||||
<template v-else>
|
||||
<p
|
||||
class="text-sm font-semibold"
|
||||
:class="getResourceColor(planet.resources[resourceType.key], capacity?.[resourceType.key] || Infinity)"
|
||||
>
|
||||
{{ t('queue.cancel') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
||||
</div>
|
||||
<!-- 研究队列 -->
|
||||
<div v-for="item in gameStore.player.researchQueue" :key="item.id" class="space-y-1.5">
|
||||
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
||||
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
||||
<div class="h-2 w-2 rounded-full bg-blue-500 animate-pulse flex-shrink-0" />
|
||||
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
||||
<span class="text-muted-foreground hidden sm:inline flex-shrink-0 text-[10px] sm:text-xs">
|
||||
→ {{ t('queue.level') }} {{ item.targetLevel }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
||||
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
||||
{{ formatTime(getRemainingTime(item)) }}
|
||||
</span>
|
||||
<Button
|
||||
@click="handleCancelResearch(item.id)"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs"
|
||||
>
|
||||
{{ t('queue.cancel') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
||||
{{ formatNumber(planet.resources[resourceType.key]) }}
|
||||
</p>
|
||||
<p class="text-[10px] text-muted-foreground">
|
||||
{{ t('resources.capacity') }}: {{ formatNumber(capacity?.[resourceType.key] || 0) }}
|
||||
</p>
|
||||
<p class="text-[10px] text-muted-foreground">
|
||||
{{ t('resources.production') }}: +{{ formatNumber(Math.round((production?.[resourceType.key] || 0) / 60)) }}/{{
|
||||
t('resources.perMinute')
|
||||
}}
|
||||
</p>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<!-- 即将到来的敌对舰队警告 -->
|
||||
<IncomingFleetAlerts
|
||||
v-if="gameStore.player.incomingFleetAlerts && gameStore.player.incomingFleetAlerts.length > 0"
|
||||
:alerts="gameStore.player.incomingFleetAlerts"
|
||||
@mark-as-read="removeIncomingFleetAlert"
|
||||
/>
|
||||
|
||||
<!-- 内容区域 -->
|
||||
<main class="flex-1 overflow-y-auto">
|
||||
@@ -228,28 +327,52 @@
|
||||
</SidebarInset>
|
||||
|
||||
<!-- 确认对话框 -->
|
||||
<ConfirmDialog ref="confirmDialog" />
|
||||
<AlertDialog :open="confirmDialogOpen" @update:open="confirmDialogOpen = $event">
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{{ confirmDialogTitle }}</AlertDialogTitle>
|
||||
<AlertDialogDescription class="whitespace-pre-line">
|
||||
{{ confirmDialogMessage }}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>{{ t('common.cancel') }}</AlertDialogCancel>
|
||||
<AlertDialogAction @click="handleConfirmDialogConfirm">{{ t('common.confirm') }}</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
|
||||
<!-- 详情弹窗 -->
|
||||
<DetailDialog />
|
||||
|
||||
<!-- 更新弹窗 -->
|
||||
<UpdateDialog v-model:open="showUpdateDialog" :version-info="updateInfo" />
|
||||
|
||||
<!-- 新手引导 -->
|
||||
<TutorialOverlay />
|
||||
|
||||
<!-- Toast 通知 -->
|
||||
<Sonner position="top-center" />
|
||||
</SidebarProvider>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, onUnmounted, computed, ref } from 'vue'
|
||||
import { RouterView, RouterLink } from 'vue-router'
|
||||
import { onMounted, onUnmounted, computed, ref, watch } from 'vue'
|
||||
import { RouterView, useRouter } from 'vue-router'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useUniverseStore } from '@/stores/universeStore'
|
||||
import { useNPCStore } from '@/stores/npcStore'
|
||||
import { useTheme } from '@/composables/useTheme'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { useGameConfig } from '@/composables/useGameConfig'
|
||||
import { useTutorial } from '@/composables/useTutorial'
|
||||
import { localeNames, detectBrowserLocale, type Locale } from '@/locales'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Progress } from '@/components/ui/progress'
|
||||
import { Popover, PopoverTrigger, PopoverContent } from '@/components/ui/popover'
|
||||
import IncomingFleetAlerts from '@/components/IncomingFleetAlerts.vue'
|
||||
import DiplomaticNotifications from '@/components/DiplomaticNotifications.vue'
|
||||
import QueueNotifications from '@/components/QueueNotifications.vue'
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
@@ -265,12 +388,25 @@
|
||||
SidebarTrigger
|
||||
} from '@/components/ui/sidebar'
|
||||
import ResourceIcon from '@/components/ResourceIcon.vue'
|
||||
import ConfirmDialog from '@/components/ConfirmDialog.vue'
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle
|
||||
} from '@/components/ui/alert-dialog'
|
||||
import DetailDialog from '@/components/DetailDialog.vue'
|
||||
import UpdateDialog from '@/components/UpdateDialog.vue'
|
||||
import TutorialOverlay from '@/components/TutorialOverlay.vue'
|
||||
import Sonner from '@/components/ui/sonner/Sonner.vue'
|
||||
import { MissionType } from '@/types/game'
|
||||
import type { BuildQueueItem, FleetMission } from '@/types/game'
|
||||
import { formatNumber, formatTime, getResourceColor } from '@/utils/format'
|
||||
import { MissionType, BuildingType, DiplomaticEventType } from '@/types/game'
|
||||
import type { FleetMission, NPC, IncomingFleetAlert, MissileAttack } from '@/types/game'
|
||||
import { DIPLOMATIC_CONFIG } from '@/config/gameConfig'
|
||||
import type { VersionInfo } from '@/utils/versionCheck'
|
||||
import { formatNumber, getResourceColor } from '@/utils/format'
|
||||
import {
|
||||
Moon,
|
||||
Sun,
|
||||
@@ -287,7 +423,11 @@
|
||||
Languages,
|
||||
Settings,
|
||||
Wrench,
|
||||
ChevronsLeft
|
||||
ChevronsLeft,
|
||||
ChevronsUpDown,
|
||||
ChevronDown,
|
||||
ChevronUp,
|
||||
Handshake
|
||||
} from 'lucide-vue-next'
|
||||
import * as gameLogic from '@/logic/gameLogic'
|
||||
import * as planetLogic from '@/logic/planetLogic'
|
||||
@@ -297,17 +437,43 @@
|
||||
import * as researchValidation from '@/logic/researchValidation'
|
||||
import * as fleetLogic from '@/logic/fleetLogic'
|
||||
import * as shipLogic from '@/logic/shipLogic'
|
||||
import * as npcGrowthLogic from '@/logic/npcGrowthLogic'
|
||||
import * as npcBehaviorLogic from '@/logic/npcBehaviorLogic'
|
||||
import * as diplomaticLogic from '@/logic/diplomaticLogic'
|
||||
import pkg from '../package.json'
|
||||
import { toast } from 'vue-sonner'
|
||||
import { migrateGameData } from '@/utils/migration'
|
||||
import { checkLatestVersion } from '@/utils/versionCheck'
|
||||
|
||||
// 执行数据迁移(在 store 初始化之前)
|
||||
migrateGameData()
|
||||
|
||||
const router = useRouter()
|
||||
const gameStore = useGameStore()
|
||||
const universeStore = useUniverseStore()
|
||||
const npcStore = useNPCStore()
|
||||
const { isDark } = useTheme()
|
||||
const { t } = useI18n()
|
||||
const confirmDialog = ref<InstanceType<typeof ConfirmDialog> | null>(null)
|
||||
const { BUILDINGS } = useGameConfig()
|
||||
const { startTutorial, tutorialState, currentStep } = useTutorial()
|
||||
|
||||
// ConfirmDialog 状态
|
||||
const confirmDialogOpen = ref(false)
|
||||
const confirmDialogTitle = ref('')
|
||||
const confirmDialogMessage = ref('')
|
||||
const innerWidth = computed(() => window.innerWidth)
|
||||
const confirmDialogAction = ref<(() => void) | null>(null)
|
||||
|
||||
// 更新弹窗状态
|
||||
const showUpdateDialog = ref(false)
|
||||
const updateInfo = ref<VersionInfo | null>(null)
|
||||
|
||||
const handleConfirmDialogConfirm = () => {
|
||||
if (confirmDialogAction.value) {
|
||||
confirmDialogAction.value()
|
||||
}
|
||||
confirmDialogOpen.value = false
|
||||
}
|
||||
|
||||
// 所有可用的语言选项
|
||||
const locales: Locale[] = ['zh-CN', 'zh-TW', 'en', 'de', 'ru', 'ko', 'ja']
|
||||
@@ -316,24 +482,32 @@
|
||||
// PC端(≥1024px)默认打开,移动端默认关闭
|
||||
const sidebarOpen = ref(window.innerWidth >= 1024)
|
||||
|
||||
// 移动端资源栏展开状态
|
||||
const resourceBarExpanded = ref(false)
|
||||
|
||||
const initGame = async () => {
|
||||
const shouldInit = gameLogic.shouldInitializeGame(gameStore.player.planets)
|
||||
if (!shouldInit) {
|
||||
const now = Date.now()
|
||||
|
||||
// 计算离线收益(直接同步计算)
|
||||
// 计算离线收益(直接同步计算,应用游戏速度)
|
||||
const bonuses = officerLogic.calculateActiveBonuses(gameStore.player.officers, now)
|
||||
gameStore.player.planets.forEach(planet => {
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses)
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses, gameStore.gameSpeed)
|
||||
})
|
||||
|
||||
// 只在没有NPC星球时才生成(首次加载已有玩家数据时)
|
||||
if (Object.keys(universeStore.planets).length === 0) {
|
||||
generateNPCPlanets()
|
||||
}
|
||||
return
|
||||
}
|
||||
gameStore.player = gameLogic.initializePlayer(gameStore.player.id, t('common.playerName'))
|
||||
const initialPlanet = planetLogic.createInitialPlanet(gameStore.player.id, t('planet.homePlanet'))
|
||||
gameStore.player.planets = [initialPlanet]
|
||||
gameStore.currentPlanetId = initialPlanet.id
|
||||
// 新玩家初始化时生成NPC星球
|
||||
generateNPCPlanets()
|
||||
}
|
||||
|
||||
const generateNPCPlanets = () => {
|
||||
@@ -347,14 +521,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
const updateGame = () => {
|
||||
if (gameStore.isPaused) return
|
||||
const updateGame = async () => {
|
||||
const now = Date.now()
|
||||
gameStore.gameTime = now
|
||||
if (gameStore.isPaused) return
|
||||
// 检查军官过期
|
||||
gameLogic.checkOfficersExpiration(gameStore.player.officers, now)
|
||||
// 处理游戏更新(建造队列、研究队列等)
|
||||
const result = gameLogic.processGameUpdate(gameStore.player, now)
|
||||
const result = gameLogic.processGameUpdate(gameStore.player, now, gameStore.gameSpeed)
|
||||
gameStore.player.researchQueue = result.updatedResearchQueue
|
||||
// 处理舰队任务
|
||||
gameStore.player.fleetMissions.forEach(mission => {
|
||||
@@ -364,6 +538,56 @@
|
||||
processMissionReturn(mission)
|
||||
}
|
||||
})
|
||||
|
||||
// 处理导弹攻击任务(使用反向循环以便安全删除)
|
||||
for (let i = gameStore.player.missileAttacks.length - 1; i >= 0; i--) {
|
||||
const missileAttack = gameStore.player.missileAttacks[i]
|
||||
if (missileAttack && missileAttack.status === 'flying' && now >= missileAttack.arrivalTime) {
|
||||
await processMissileAttackArrival(missileAttack)
|
||||
// 导弹攻击是单程的,到达后直接从数组中移除
|
||||
gameStore.player.missileAttacks.splice(i, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// 处理NPC舰队任务
|
||||
npcStore.npcs.forEach(npc => {
|
||||
if (npc.fleetMissions) {
|
||||
npc.fleetMissions.forEach(mission => {
|
||||
if (mission.status === 'outbound' && now >= mission.arrivalTime) {
|
||||
processNPCMissionArrival(npc, mission)
|
||||
} else if (mission.status === 'returning' && mission.returnTime && now >= mission.returnTime) {
|
||||
processNPCMissionReturn(npc, mission)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// NPC成长系统更新
|
||||
updateNPCGrowth(1)
|
||||
|
||||
// NPC行为系统更新(侦查和攻击决策)
|
||||
updateNPCBehavior(1)
|
||||
|
||||
// 检查并处理被消灭的NPC(所有星球都被摧毁的NPC)
|
||||
const eliminatedNpcIds = diplomaticLogic.checkAndHandleEliminatedNPCs(npcStore.npcs, gameStore.player, gameStore.locale)
|
||||
if (eliminatedNpcIds.length > 0) {
|
||||
// 从universeStore中移除被消灭NPC的星球数据
|
||||
eliminatedNpcIds.forEach(npcId => {
|
||||
const npc = npcStore.npcs.find(n => n.id === npcId)
|
||||
if (npc && npc.planets) {
|
||||
// 遍历NPC的所有星球,从universeStore中删除
|
||||
npc.planets.forEach(planet => {
|
||||
const planetKey = gameLogic.generatePositionKey(planet.position.galaxy, planet.position.system, planet.position.position)
|
||||
if (universeStore.planets[planetKey]) {
|
||||
delete universeStore.planets[planetKey]
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 从NPC列表中移除被消灭的NPC
|
||||
npcStore.npcs = npcStore.npcs.filter(npc => !eliminatedNpcIds.includes(npc.id))
|
||||
}
|
||||
}
|
||||
|
||||
const processMissionArrival = async (mission: FleetMission) => {
|
||||
@@ -382,12 +606,46 @@
|
||||
p.position.position === mission.targetPosition.position
|
||||
) || universeStore.planets[targetKey]
|
||||
|
||||
// 获取起始星球名称(用于报告)
|
||||
const originPlanet = gameStore.player.planets.find(p => p.id === mission.originPlanetId)
|
||||
const originPlanetName = originPlanet?.name || t('fleetView.unknownPlanet')
|
||||
|
||||
if (mission.missionType === MissionType.Transport) {
|
||||
fleetLogic.processTransportArrival(mission, targetPlanet)
|
||||
const result = fleetLogic.processTransportArrival(mission, targetPlanet, gameStore.player, npcStore.npcs)
|
||||
// 生成运输任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Transport,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: targetPlanet?.id,
|
||||
targetPlanetName:
|
||||
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
||||
success: result.success,
|
||||
message: result.success ? t('missionReports.transportSuccess') : t('missionReports.transportFailed'),
|
||||
details: {
|
||||
transportedResources: mission.cargo
|
||||
},
|
||||
read: false
|
||||
})
|
||||
} else if (mission.missionType === MissionType.Attack) {
|
||||
const attackResult = await fleetLogic.processAttackArrival(mission, targetPlanet, gameStore.player, null, gameStore.player.planets)
|
||||
if (attackResult) {
|
||||
gameStore.player.battleReports.push(attackResult.battleResult)
|
||||
|
||||
// 检查是否攻击了NPC星球,更新外交关系
|
||||
if (targetPlanet) {
|
||||
const targetNpc = npcStore.npcs.find(npc => npc.planets.some(p => p.id === targetPlanet.id))
|
||||
if (targetNpc) {
|
||||
diplomaticLogic.handleAttackReputation(gameStore.player, targetNpc, attackResult.battleResult, npcStore.npcs, gameStore.locale)
|
||||
}
|
||||
}
|
||||
|
||||
if (attackResult.moon) {
|
||||
gameStore.player.planets.push(attackResult.moon)
|
||||
}
|
||||
@@ -397,15 +655,59 @@
|
||||
}
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Colonize) {
|
||||
const newPlanet = fleetLogic.processColonizeArrival(mission, targetPlanet, gameStore.player.id, t('planet.colonyPrefix'))
|
||||
const newPlanet = fleetLogic.processColonizeArrival(mission, targetPlanet, gameStore.player, t('planet.colonyPrefix'))
|
||||
// 生成殖民任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Colonize,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: newPlanet?.id,
|
||||
targetPlanetName: newPlanet?.name,
|
||||
success: !!newPlanet,
|
||||
message: newPlanet ? t('missionReports.colonizeSuccess') : t('missionReports.colonizeFailed'),
|
||||
details: newPlanet
|
||||
? {
|
||||
newPlanetId: newPlanet.id,
|
||||
newPlanetName: newPlanet.name
|
||||
}
|
||||
: undefined,
|
||||
read: false
|
||||
})
|
||||
if (newPlanet) {
|
||||
gameStore.player.planets.push(newPlanet)
|
||||
}
|
||||
} else if (mission.missionType === MissionType.Spy) {
|
||||
const spyReport = fleetLogic.processSpyArrival(mission, targetPlanet, gameStore.player.id)
|
||||
const spyReport = fleetLogic.processSpyArrival(mission, targetPlanet, gameStore.player, null, npcStore.npcs)
|
||||
if (spyReport) gameStore.player.spyReports.push(spyReport)
|
||||
} else if (mission.missionType === MissionType.Deploy) {
|
||||
const deployed = fleetLogic.processDeployArrival(mission, targetPlanet, gameStore.player.id)
|
||||
// 生成部署任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Deploy,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: targetPlanet?.id,
|
||||
targetPlanetName:
|
||||
targetPlanet?.name || `[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`,
|
||||
success: deployed,
|
||||
message: deployed ? t('missionReports.deploySuccess') : t('missionReports.deployFailed'),
|
||||
details: {
|
||||
deployedFleet: mission.fleet
|
||||
},
|
||||
read: false
|
||||
})
|
||||
if (deployed) {
|
||||
const missionIndex = gameStore.player.fleetMissions.indexOf(mission)
|
||||
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
||||
@@ -416,6 +718,29 @@
|
||||
const debrisId = `debris_${mission.targetPosition.galaxy}_${mission.targetPosition.system}_${mission.targetPosition.position}`
|
||||
const debrisField = universeStore.debrisFields[debrisId]
|
||||
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
||||
|
||||
// 生成回收任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Recycle,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
success: !!recycleResult,
|
||||
message: recycleResult ? t('missionReports.recycleSuccess') : t('missionReports.recycleFailed'),
|
||||
details: recycleResult
|
||||
? {
|
||||
recycledResources: recycleResult.collectedResources,
|
||||
remainingDebris: recycleResult.remainingDebris || undefined
|
||||
}
|
||||
: undefined,
|
||||
read: false
|
||||
})
|
||||
|
||||
if (recycleResult && debrisField) {
|
||||
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
||||
// 更新残骸场
|
||||
@@ -434,8 +759,43 @@
|
||||
} else if (mission.missionType === MissionType.Destroy) {
|
||||
// 处理行星毁灭任务
|
||||
const destroyResult = fleetLogic.processDestroyArrival(mission, targetPlanet, gameStore.player)
|
||||
|
||||
// 生成毁灭任务报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `mission-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.Destroy,
|
||||
originPlanetId: mission.originPlanetId,
|
||||
originPlanetName,
|
||||
targetPosition: mission.targetPosition,
|
||||
targetPlanetId: targetPlanet?.id,
|
||||
targetPlanetName: targetPlanet?.name,
|
||||
success: destroyResult?.success || false,
|
||||
message: destroyResult?.success ? t('missionReports.destroySuccess') : t('missionReports.destroyFailed'),
|
||||
details: destroyResult?.success
|
||||
? {
|
||||
destroyedPlanetName:
|
||||
targetPlanet?.name ||
|
||||
`[${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}]`
|
||||
}
|
||||
: undefined,
|
||||
read: false
|
||||
})
|
||||
|
||||
if (destroyResult && destroyResult.success && destroyResult.planetId) {
|
||||
// 星球被摧毁
|
||||
|
||||
// 处理外交关系(如果目标是NPC星球)
|
||||
if (targetPlanet && targetPlanet.ownerId) {
|
||||
const planetOwner = npcStore.npcs.find(npc => npc.id === targetPlanet.ownerId)
|
||||
if (planetOwner) {
|
||||
diplomaticLogic.handlePlanetDestructionReputation(gameStore.player, targetPlanet, planetOwner, npcStore.npcs, gameStore.locale)
|
||||
}
|
||||
}
|
||||
|
||||
// 从玩家星球列表中移除(如果是玩家的星球)
|
||||
const planetIndex = gameStore.player.planets.findIndex(p => p.id === destroyResult.planetId)
|
||||
if (planetIndex > -1) {
|
||||
@@ -444,8 +804,6 @@
|
||||
// 不是玩家星球,从宇宙地图中移除
|
||||
delete universeStore.planets[targetKey]
|
||||
}
|
||||
|
||||
// TODO: 可以添加战斗报告或摧毁报告来通知玩家结果
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,13 +817,414 @@
|
||||
if (missionIndex > -1) gameStore.player.fleetMissions.splice(missionIndex, 1)
|
||||
}
|
||||
|
||||
// NPC任务处理
|
||||
const processNPCMissionArrival = (npc: NPC, mission: FleetMission) => {
|
||||
if (mission.missionType === MissionType.Recycle) {
|
||||
// NPC回收任务到达
|
||||
const debrisId = mission.debrisFieldId
|
||||
if (!debrisId) {
|
||||
console.warn('[NPC Mission] Recycle mission missing debrisFieldId')
|
||||
mission.status = 'returning'
|
||||
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
||||
return
|
||||
}
|
||||
|
||||
const debrisField = universeStore.debrisFields[debrisId]
|
||||
const recycleResult = fleetLogic.processRecycleArrival(mission, debrisField)
|
||||
|
||||
if (recycleResult && debrisField) {
|
||||
if (recycleResult.remainingDebris && (recycleResult.remainingDebris.metal > 0 || recycleResult.remainingDebris.crystal > 0)) {
|
||||
// 更新残骸场
|
||||
universeStore.debrisFields[debrisId] = {
|
||||
id: debrisField.id,
|
||||
position: debrisField.position,
|
||||
resources: recycleResult.remainingDebris,
|
||||
createdAt: debrisField.createdAt
|
||||
}
|
||||
} else {
|
||||
// 残骸已被完全回收,从宇宙中删除
|
||||
delete universeStore.debrisFields[debrisId]
|
||||
}
|
||||
}
|
||||
|
||||
// 移除即将到来的警告(回收任务已到达)
|
||||
removeIncomingFleetAlertById(mission.id)
|
||||
|
||||
// 设置返回时间
|
||||
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
||||
return
|
||||
}
|
||||
|
||||
// 找到目标星球
|
||||
const targetKey = gameLogic.generatePositionKey(
|
||||
mission.targetPosition.galaxy,
|
||||
mission.targetPosition.system,
|
||||
mission.targetPosition.position
|
||||
)
|
||||
const targetPlanet =
|
||||
gameStore.player.planets.find(
|
||||
p =>
|
||||
p.position.galaxy === mission.targetPosition.galaxy &&
|
||||
p.position.system === mission.targetPosition.system &&
|
||||
p.position.position === mission.targetPosition.position
|
||||
) || universeStore.planets[targetKey]
|
||||
|
||||
if (!targetPlanet) {
|
||||
console.warn('[NPC Mission] Target planet not found')
|
||||
return
|
||||
}
|
||||
|
||||
if (mission.missionType === MissionType.Spy) {
|
||||
// NPC侦查到达
|
||||
const { spiedNotification, spyReport } = npcBehaviorLogic.processNPCSpyArrival(npc, mission, targetPlanet, gameStore.player)
|
||||
|
||||
// 保存侦查报告到NPC(用于后续攻击决策)
|
||||
if (!npc.playerSpyReports) {
|
||||
npc.playerSpyReports = {}
|
||||
}
|
||||
npc.playerSpyReports[targetPlanet.id] = spyReport
|
||||
|
||||
// 添加被侦查通知给玩家
|
||||
if (!gameStore.player.spiedNotifications) {
|
||||
gameStore.player.spiedNotifications = []
|
||||
}
|
||||
gameStore.player.spiedNotifications.push(spiedNotification)
|
||||
|
||||
// 移除即将到来的警告(侦查已到达)
|
||||
removeIncomingFleetAlertById(mission.id)
|
||||
} else if (mission.missionType === MissionType.Attack) {
|
||||
// NPC攻击到达 - 使用专门的NPC攻击处理逻辑
|
||||
fleetLogic.processNPCAttackArrival(npc, mission, targetPlanet, gameStore.player, gameStore.player.planets).then(attackResult => {
|
||||
if (attackResult) {
|
||||
// 添加战斗报告给玩家
|
||||
gameStore.player.battleReports.push(attackResult.battleResult)
|
||||
|
||||
// 如果生成月球,添加到玩家星球列表
|
||||
if (attackResult.moon) {
|
||||
gameStore.player.planets.push(attackResult.moon)
|
||||
}
|
||||
|
||||
// 如果生成残骸场,添加到宇宙残骸场列表
|
||||
if (attackResult.debrisField) {
|
||||
universeStore.debrisFields[attackResult.debrisField.id] = attackResult.debrisField
|
||||
}
|
||||
}
|
||||
|
||||
// 移除即将到来的警告(攻击已到达)
|
||||
removeIncomingFleetAlertById(mission.id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const processNPCMissionReturn = (npc: NPC, mission: FleetMission) => {
|
||||
// 找到NPC的起始星球
|
||||
const originPlanet = npc.planets.find(p => p.id === mission.originPlanetId)
|
||||
if (!originPlanet) return
|
||||
|
||||
// 返还舰队
|
||||
shipLogic.addFleet(originPlanet.fleet, mission.fleet)
|
||||
|
||||
// 如果携带掠夺资源,给NPC添加资源
|
||||
if (mission.cargo) {
|
||||
originPlanet.resources.metal += mission.cargo.metal
|
||||
originPlanet.resources.crystal += mission.cargo.crystal
|
||||
originPlanet.resources.deuterium += mission.cargo.deuterium
|
||||
}
|
||||
|
||||
// 从NPC任务列表中移除
|
||||
if (npc.fleetMissions) {
|
||||
const missionIndex = npc.fleetMissions.indexOf(mission)
|
||||
if (missionIndex > -1) {
|
||||
npc.fleetMissions.splice(missionIndex, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理导弹攻击到达
|
||||
const processMissileAttackArrival = async (missileAttack: MissileAttack) => {
|
||||
// 动态导入导弹逻辑
|
||||
const missileLogic = await import('@/logic/missileLogic')
|
||||
|
||||
// 找到目标星球
|
||||
const targetKey = gameLogic.generatePositionKey(
|
||||
missileAttack.targetPosition.galaxy,
|
||||
missileAttack.targetPosition.system,
|
||||
missileAttack.targetPosition.position
|
||||
)
|
||||
const targetPlanet =
|
||||
gameStore.player.planets.find(
|
||||
p =>
|
||||
p.position.galaxy === missileAttack.targetPosition.galaxy &&
|
||||
p.position.system === missileAttack.targetPosition.system &&
|
||||
p.position.position === missileAttack.targetPosition.position
|
||||
) || universeStore.planets[targetKey]
|
||||
|
||||
// 如果目标星球不存在,导弹失败
|
||||
if (!targetPlanet) {
|
||||
missileAttack.status = 'arrived'
|
||||
// 生成失败报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
gameStore.player.missionReports.push({
|
||||
id: `missile-report-${missileAttack.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.MissileAttack,
|
||||
originPlanetId: missileAttack.originPlanetId,
|
||||
originPlanetName: gameStore.player.planets.find(p => p.id === missileAttack.originPlanetId)?.name || t('fleetView.unknownPlanet'),
|
||||
targetPosition: missileAttack.targetPosition,
|
||||
targetPlanetId: undefined,
|
||||
targetPlanetName: `[${missileAttack.targetPosition.galaxy}:${missileAttack.targetPosition.system}:${missileAttack.targetPosition.position}]`,
|
||||
success: false,
|
||||
message: t('missionReports.missileAttackFailed'),
|
||||
details: {
|
||||
missileCount: missileAttack.missileCount,
|
||||
missileHits: 0,
|
||||
missileIntercepted: 0,
|
||||
defenseLosses: {}
|
||||
},
|
||||
read: false
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 计算导弹攻击结果
|
||||
const impactResult = missileLogic.calculateMissileImpact(missileAttack.missileCount, targetPlanet)
|
||||
|
||||
// 应用损失到目标星球
|
||||
missileLogic.applyMissileAttackResult(targetPlanet, impactResult.defenseLosses)
|
||||
|
||||
// 如果目标是NPC的星球,扣除外交好感度
|
||||
if (targetPlanet.ownerId && targetPlanet.ownerId !== gameStore.player.id) {
|
||||
const targetNpc = npcStore.npcs.find(npc => npc.id === targetPlanet.ownerId)
|
||||
if (targetNpc) {
|
||||
// 导弹攻击扣除好感度
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
const reputationLoss = REPUTATION_CHANGES.ATTACK / 2 // 导弹攻击的好感度惩罚是普通攻击的一半
|
||||
|
||||
// 更新玩家对NPC的关系
|
||||
if (!gameStore.player.diplomaticRelations) {
|
||||
gameStore.player.diplomaticRelations = {}
|
||||
}
|
||||
const relation = diplomaticLogic.getOrCreateRelation(
|
||||
gameStore.player.diplomaticRelations,
|
||||
gameStore.player.id,
|
||||
targetNpc.id
|
||||
)
|
||||
gameStore.player.diplomaticRelations[targetNpc.id] = diplomaticLogic.updateReputation(
|
||||
relation,
|
||||
reputationLoss,
|
||||
DiplomaticEventType.Attack,
|
||||
t('diplomacy.reports.missileAttackNpc', { npcName: targetNpc.name })
|
||||
)
|
||||
|
||||
// 更新NPC对玩家的关系
|
||||
if (!targetNpc.relations) {
|
||||
targetNpc.relations = {}
|
||||
}
|
||||
const npcRelation = diplomaticLogic.getOrCreateRelation(targetNpc.relations, targetNpc.id, gameStore.player.id)
|
||||
targetNpc.relations[gameStore.player.id] = diplomaticLogic.updateReputation(
|
||||
npcRelation,
|
||||
reputationLoss,
|
||||
DiplomaticEventType.Attack,
|
||||
t('diplomacy.reports.wasAttackedByMissile')
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// 标记导弹攻击为已到达
|
||||
missileAttack.status = 'arrived'
|
||||
|
||||
// 生成导弹攻击报告
|
||||
if (!gameStore.player.missionReports) {
|
||||
gameStore.player.missionReports = []
|
||||
}
|
||||
const reportMessage =
|
||||
impactResult.missileHits > 0
|
||||
? `${t('missionReports.missileAttackSuccess')}: ${impactResult.missileHits} ${t('missionReports.hits')}`
|
||||
: t('missionReports.missileAttackIntercepted')
|
||||
|
||||
gameStore.player.missionReports.push({
|
||||
id: `missile-report-${missileAttack.id}`,
|
||||
timestamp: Date.now(),
|
||||
missionType: MissionType.MissileAttack,
|
||||
originPlanetId: missileAttack.originPlanetId,
|
||||
originPlanetName: gameStore.player.planets.find(p => p.id === missileAttack.originPlanetId)?.name || t('fleetView.unknownPlanet'),
|
||||
targetPosition: missileAttack.targetPosition,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
targetPlanetName: targetPlanet.name,
|
||||
success: true,
|
||||
message: reportMessage,
|
||||
details: {
|
||||
missileCount: missileAttack.missileCount,
|
||||
missileHits: impactResult.missileHits,
|
||||
missileIntercepted: impactResult.missileIntercepted,
|
||||
defenseLosses: impactResult.defenseLosses
|
||||
},
|
||||
read: false
|
||||
})
|
||||
}
|
||||
|
||||
// 移除即将到来的舰队警告
|
||||
const removeIncomingFleetAlert = (alert: IncomingFleetAlert) => {
|
||||
if (!gameStore.player.incomingFleetAlerts) return
|
||||
const index = gameStore.player.incomingFleetAlerts.indexOf(alert)
|
||||
if (index > -1) {
|
||||
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
const removeIncomingFleetAlertById = (missionId: string) => {
|
||||
if (!gameStore.player.incomingFleetAlerts) return
|
||||
const index = gameStore.player.incomingFleetAlerts.findIndex(a => a.id === missionId)
|
||||
if (index > -1) {
|
||||
gameStore.player.incomingFleetAlerts.splice(index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
// NPC成长系统更新函数
|
||||
let npcUpdateCounter = 0 // 累计秒数
|
||||
const NPC_UPDATE_INTERVAL = 1 // 每1秒更新一次NPC,确保发育速度与玩家相当
|
||||
|
||||
const updateNPCGrowth = (deltaSeconds: number) => {
|
||||
// 累积时间
|
||||
npcUpdateCounter += deltaSeconds
|
||||
|
||||
// 只在达到更新间隔时才执行
|
||||
if (npcUpdateCounter < NPC_UPDATE_INTERVAL) {
|
||||
return
|
||||
}
|
||||
|
||||
// 获取所有星球
|
||||
const allPlanets = Object.values(universeStore.planets)
|
||||
|
||||
// 如果NPC store为空,从星球数据中初始化NPC
|
||||
if (npcStore.npcs.length === 0) {
|
||||
const npcMap = new Map<string, any>()
|
||||
|
||||
allPlanets.forEach(planet => {
|
||||
// 跳过玩家的星球
|
||||
if (planet.ownerId === gameStore.player.id || !planet.ownerId) return
|
||||
|
||||
// 这是NPC的星球
|
||||
if (!npcMap.has(planet.ownerId)) {
|
||||
npcMap.set(planet.ownerId, {
|
||||
id: planet.ownerId,
|
||||
name: `NPC-${planet.ownerId.substring(0, 8)}`,
|
||||
planets: [],
|
||||
technologies: {}, // 初始化空科技树
|
||||
difficulty: 'medium' as const, // 默认中等难度
|
||||
relations: {}, // 外交关系
|
||||
allies: [], // 盟友列表
|
||||
enemies: [] // 敌人列表
|
||||
})
|
||||
}
|
||||
|
||||
npcMap.get(planet.ownerId)!.planets.push(planet)
|
||||
})
|
||||
|
||||
// 保存到store
|
||||
npcStore.npcs = Array.from(npcMap.values())
|
||||
|
||||
// 如果有NPC,基于玩家实力初始化NPC
|
||||
if (npcStore.npcs.length > 0) {
|
||||
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
||||
planets: allPlanets,
|
||||
player: gameStore.player,
|
||||
npcs: npcStore.npcs
|
||||
}
|
||||
|
||||
const playerPower = npcGrowthLogic.calculatePlayerAveragePower(gameState)
|
||||
|
||||
npcStore.npcs.forEach(npc => {
|
||||
npcGrowthLogic.initializeNPCStartingPower(npc, playerPower)
|
||||
})
|
||||
|
||||
// 初始化NPC之间的外交关系(盟友/敌人)
|
||||
npcGrowthLogic.initializeNPCDiplomacy(npcStore.npcs)
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没有NPC,直接返回
|
||||
if (npcStore.npcs.length === 0) {
|
||||
npcUpdateCounter = 0
|
||||
return
|
||||
}
|
||||
|
||||
// 构建游戏状态
|
||||
const gameState: npcGrowthLogic.NPCGrowthGameState = {
|
||||
planets: allPlanets,
|
||||
player: gameStore.player,
|
||||
npcs: npcStore.npcs
|
||||
}
|
||||
|
||||
// 使用累积的时间更新每个NPC
|
||||
npcStore.npcs.forEach(npc => {
|
||||
npcGrowthLogic.updateNPCGrowth(npc, gameState, npcUpdateCounter)
|
||||
})
|
||||
|
||||
// 重置计数器
|
||||
npcUpdateCounter = 0
|
||||
}
|
||||
|
||||
// NPC行为系统更新函数(侦查和攻击决策)
|
||||
let npcBehaviorCounter = 0
|
||||
const NPC_BEHAVIOR_INTERVAL = 5 // 每5秒检查一次NPC行为
|
||||
|
||||
const updateNPCBehavior = (deltaSeconds: number) => {
|
||||
// 累积时间
|
||||
npcBehaviorCounter += deltaSeconds
|
||||
|
||||
// 只在达到更新间隔时才执行
|
||||
if (npcBehaviorCounter < NPC_BEHAVIOR_INTERVAL) {
|
||||
return
|
||||
}
|
||||
|
||||
// 如果没有NPC,直接返回
|
||||
if (npcStore.npcs.length === 0) {
|
||||
npcBehaviorCounter = 0
|
||||
return
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
const allPlanets = Object.values(universeStore.planets)
|
||||
|
||||
// 更新每个NPC的行为
|
||||
npcStore.npcs.forEach(npc => {
|
||||
npcBehaviorLogic.updateNPCBehavior(npc, gameStore.player, allPlanets, universeStore.debrisFields, now)
|
||||
})
|
||||
|
||||
npcBehaviorCounter = 0
|
||||
}
|
||||
|
||||
// 游戏循环定时器
|
||||
let gameLoop: ReturnType<typeof setInterval> | null = null
|
||||
let konamiCleanup: (() => void) | null = null
|
||||
let versionCheckInterval: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
// 清理定时器
|
||||
onUnmounted(() => {
|
||||
if (gameLoop) clearInterval(gameLoop)
|
||||
})
|
||||
// 启动游戏循环
|
||||
const startGameLoop = () => {
|
||||
// 清理旧的定时器
|
||||
if (gameLoop) {
|
||||
clearInterval(gameLoop)
|
||||
}
|
||||
// 根据游戏速度计算间隔时间
|
||||
const interval = 1000 / (gameStore.gameSpeed || 1)
|
||||
// 启动新的游戏循环
|
||||
gameLoop = setInterval(() => {
|
||||
updateGame()
|
||||
}, interval)
|
||||
}
|
||||
|
||||
// 监听游戏速度变化,重新启动游戏循环
|
||||
watch(
|
||||
() => gameStore.gameSpeed,
|
||||
() => {
|
||||
if (gameLoop) {
|
||||
startGameLoop()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 初始化游戏
|
||||
onMounted(async () => {
|
||||
@@ -476,15 +1235,110 @@
|
||||
}
|
||||
await initGame()
|
||||
// 启动游戏循环
|
||||
gameLoop = setInterval(() => {
|
||||
updateGame()
|
||||
}, 1000) // 每1秒更新一次
|
||||
startGameLoop()
|
||||
// 启动科乐美秘籍监听
|
||||
konamiCleanup = setupKonamiCode()
|
||||
|
||||
// 启动新手引导(如果尚未完成)
|
||||
startTutorial()
|
||||
|
||||
// 添加队列取消事件监听
|
||||
window.addEventListener('cancel-build', handleCancelBuildEvent as EventListener)
|
||||
window.addEventListener('cancel-research', handleCancelResearchEvent as EventListener)
|
||||
|
||||
// 首次检查版本(被动检测)
|
||||
const versionInfo = await checkLatestVersion(gameStore.player.lastVersionCheckTime || 0, (time: number) => {
|
||||
gameStore.player.lastVersionCheckTime = time
|
||||
})
|
||||
if (versionInfo) {
|
||||
updateInfo.value = versionInfo
|
||||
toast.info(t('settings.newVersionAvailable', { version: versionInfo.version }), {
|
||||
duration: Infinity,
|
||||
dismissible: true,
|
||||
action: {
|
||||
label: t('settings.viewUpdate'),
|
||||
onClick: () => {
|
||||
showUpdateDialog.value = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 启动版本检查定时器(每5分钟被动检查一次)
|
||||
versionCheckInterval = setInterval(async () => {
|
||||
const versionInfo = await checkLatestVersion(gameStore.player.lastVersionCheckTime || 0, (time: number) => {
|
||||
gameStore.player.lastVersionCheckTime = time
|
||||
})
|
||||
if (versionInfo) {
|
||||
updateInfo.value = versionInfo
|
||||
toast.info(t('settings.newVersionAvailable', { version: versionInfo.version }), {
|
||||
duration: Infinity,
|
||||
dismissible: true,
|
||||
action: {
|
||||
label: t('settings.viewUpdate'),
|
||||
onClick: () => {
|
||||
showUpdateDialog.value = true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}, 5 * 60 * 1000)
|
||||
})
|
||||
|
||||
// 清理定时器
|
||||
onUnmounted(() => {
|
||||
if (gameLoop) clearInterval(gameLoop)
|
||||
if (konamiCleanup) konamiCleanup()
|
||||
if (versionCheckInterval) clearInterval(versionCheckInterval)
|
||||
// 移除队列取消事件监听
|
||||
window.removeEventListener('cancel-build', handleCancelBuildEvent as EventListener)
|
||||
window.removeEventListener('cancel-research', handleCancelResearchEvent as EventListener)
|
||||
})
|
||||
|
||||
// 处理取消建造事件
|
||||
const handleCancelBuildEvent = (event: CustomEvent) => {
|
||||
handleCancelBuild(event.detail)
|
||||
}
|
||||
|
||||
// 处理取消研究事件
|
||||
const handleCancelResearchEvent = (event: CustomEvent) => {
|
||||
handleCancelResearch(event.detail)
|
||||
}
|
||||
|
||||
// 科乐美秘籍:上上下下左左右右BA
|
||||
const setupKonamiCode = () => {
|
||||
const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowLeft', 'ArrowRight', 'ArrowRight', 'b', 'a']
|
||||
let konamiIndex = 0
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
// 如果已经激活GM模式,直接返回
|
||||
if (gameStore.player.isGMEnabled) return
|
||||
|
||||
const key = event.key.toLowerCase()
|
||||
// 检查是否匹配当前秘籍序列
|
||||
if (key === konamiCode[konamiIndex] || event.key === konamiCode[konamiIndex]) {
|
||||
konamiIndex++
|
||||
// 如果完成整个秘籍序列
|
||||
if (konamiIndex === konamiCode.length) {
|
||||
gameStore.player.isGMEnabled = true
|
||||
// 显示成功消息
|
||||
toast.success(t('common.gmModeActivated'))
|
||||
konamiIndex = 0
|
||||
}
|
||||
} else {
|
||||
// 如果按错了键,重置序列
|
||||
konamiIndex = 0
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
// 返回清理函数
|
||||
return () => {
|
||||
window.removeEventListener('keydown', handleKeyDown)
|
||||
}
|
||||
}
|
||||
|
||||
// 定义 planet computed(需要在 watch 之前定义)
|
||||
const planet = computed(() => gameStore.currentPlanet)
|
||||
|
||||
const navItems = [
|
||||
const navItems = computed(() => [
|
||||
{ name: computed(() => t('nav.overview')), path: '/', icon: Home },
|
||||
{ name: computed(() => t('nav.buildings')), path: '/buildings', icon: Building2 },
|
||||
{ name: computed(() => t('nav.research')), path: '/research', icon: FlaskConical },
|
||||
@@ -494,11 +1348,62 @@
|
||||
{ name: computed(() => t('nav.officers')), path: '/officers', icon: Users },
|
||||
{ name: computed(() => t('nav.simulator')), path: '/battle-simulator', icon: Swords },
|
||||
{ name: computed(() => t('nav.galaxy')), path: '/galaxy', icon: Globe },
|
||||
{ name: computed(() => t('nav.diplomacy')), path: '/diplomacy', icon: Handshake },
|
||||
{ name: computed(() => t('nav.messages')), path: '/messages', icon: Mail },
|
||||
{ name: computed(() => t('nav.settings')), path: '/settings', icon: Settings },
|
||||
// GM菜单仅在开发模式下显示
|
||||
...(import.meta.env.DEV ? [{ name: computed(() => t('nav.gm')), path: '/gm', icon: Wrench }] : [])
|
||||
]
|
||||
// GM菜单在启用GM模式时显示
|
||||
...(gameStore.player.isGMEnabled ? [{ name: computed(() => t('nav.gm')), path: '/gm', icon: Wrench }] : [])
|
||||
])
|
||||
|
||||
// 功能解锁要求配置
|
||||
const featureRequirements: Record<string, { building: BuildingType; level: number }> = {
|
||||
'/research': { building: BuildingType.ResearchLab, level: 1 },
|
||||
'/shipyard': { building: BuildingType.Shipyard, level: 1 },
|
||||
'/defense': { building: BuildingType.Shipyard, level: 1 },
|
||||
'/fleet': { building: BuildingType.Shipyard, level: 1 }
|
||||
}
|
||||
|
||||
// 检查功能是否解锁
|
||||
const checkFeatureUnlocked = (path: string): { unlocked: boolean; requirement?: { building: BuildingType; level: number } } => {
|
||||
const requirement = featureRequirements[path]
|
||||
if (!requirement) {
|
||||
return { unlocked: true }
|
||||
}
|
||||
|
||||
const currentLevel = planet.value?.buildings[requirement.building] || 0
|
||||
return {
|
||||
unlocked: currentLevel >= requirement.level,
|
||||
requirement
|
||||
}
|
||||
}
|
||||
|
||||
// 处理导航点击
|
||||
const handleNavClick = (path: string, event: Event) => {
|
||||
const { unlocked, requirement } = checkFeatureUnlocked(path)
|
||||
|
||||
if (!unlocked && requirement) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
const buildingName = BUILDINGS.value[requirement.building]?.name || requirement.building
|
||||
const currentLevel = planet.value?.buildings[requirement.building] || 0
|
||||
|
||||
toast.warning(t('common.featureLocked'), {
|
||||
description: `${t('common.requiredBuilding')}: ${buildingName} Lv ${requirement.level} (${t(
|
||||
'common.currentLevel'
|
||||
)}: Lv ${currentLevel})`,
|
||||
action: {
|
||||
label: t('common.goToBuildings'),
|
||||
onClick: () => router.push('/buildings')
|
||||
},
|
||||
duration: 3000
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 功能已解锁,正常导航
|
||||
router.push(path)
|
||||
}
|
||||
|
||||
// 使用直接计算,不再缓存
|
||||
const production = computed(() => {
|
||||
@@ -519,11 +1424,40 @@
|
||||
return resourceLogic.calculateResourceCapacity(planet.value, bonuses.storageCapacityBonus)
|
||||
})
|
||||
|
||||
// 电力消耗
|
||||
const energyConsumption = computed(() => {
|
||||
if (!planet.value) return 0
|
||||
return resourceLogic.calculateEnergyConsumption(planet.value)
|
||||
})
|
||||
|
||||
// 净电力(产量 - 消耗)
|
||||
const netEnergy = computed(() => {
|
||||
if (!planet.value || !production.value) return 0
|
||||
return production.value.energy - energyConsumption.value
|
||||
})
|
||||
|
||||
// 未读消息数量
|
||||
const unreadMessagesCount = computed(() => {
|
||||
const unreadBattles = gameStore.player.battleReports.filter(r => !r.read).length
|
||||
const unreadSpies = gameStore.player.spyReports.filter(r => !r.read).length
|
||||
return unreadBattles + unreadSpies
|
||||
const unreadSpied = gameStore.player.spiedNotifications?.filter(n => !n.read).length || 0
|
||||
const unreadMissions = gameStore.player.missionReports?.filter(r => !r.read).length || 0
|
||||
const unreadNPCActivity = gameStore.player.npcActivityNotifications?.filter(n => !n.read).length || 0
|
||||
const unreadGifts = gameStore.player.giftNotifications?.filter(n => !n.read).length || 0
|
||||
const unreadGiftRejected = gameStore.player.giftRejectedNotifications?.filter(n => !n.read).length || 0
|
||||
return unreadBattles + unreadSpies + unreadSpied + unreadMissions + unreadNPCActivity + unreadGifts + unreadGiftRejected
|
||||
})
|
||||
|
||||
// 正在执行的舰队任务数量(包括飞行中的导弹)
|
||||
const activeFleetMissionsCount = computed(() => {
|
||||
const fleetMissions = gameStore.player.fleetMissions.filter(m => m.status === 'outbound' || m.status === 'returning').length
|
||||
const flyingMissiles = gameStore.player.missileAttacks?.filter(m => m.status === 'flying').length || 0
|
||||
return fleetMissions + flyingMissiles
|
||||
})
|
||||
|
||||
// 未读外交报告数量
|
||||
const unreadDiplomaticReportsCount = computed(() => {
|
||||
return (gameStore.player.diplomaticReports || []).filter(r => !r.read).length
|
||||
})
|
||||
|
||||
// 资源类型配置
|
||||
@@ -556,46 +1490,39 @@
|
||||
}
|
||||
}
|
||||
|
||||
// 切换到指定星球
|
||||
const switchToPlanet = (planetId: string) => {
|
||||
gameStore.currentPlanetId = planetId
|
||||
}
|
||||
|
||||
// 切换侧边栏
|
||||
const toggleSidebar = () => {
|
||||
sidebarOpen.value = !sidebarOpen.value
|
||||
}
|
||||
|
||||
// 获取队列项的名称
|
||||
const getItemName = (item: BuildQueueItem): string => {
|
||||
if (item.type === 'building' || item.type === 'demolish') {
|
||||
const buildingName = t(`buildings.${item.itemType}`)
|
||||
return item.type === 'demolish' ? `${t('buildingsView.demolish')} - ${buildingName}` : buildingName
|
||||
} else if (item.type === 'technology') {
|
||||
return t(`technologies.${item.itemType}`)
|
||||
} else if (item.type === 'ship') {
|
||||
return t(`ships.${item.itemType}`)
|
||||
} else if (item.type === 'defense') {
|
||||
return t(`defenses.${item.itemType}`)
|
||||
// 处理侧边栏打开/关闭状态变化
|
||||
const handleSidebarOpenChange = (open: boolean) => {
|
||||
// 如果是移动端且在教程的菜单相关步骤,阻止关闭侧边栏
|
||||
if (window.innerWidth < 768 && tutorialState.value.isActive && currentStep.value) {
|
||||
// 只在第3步期间阻止关闭侧边栏,让玩家必须手动打开
|
||||
if (currentStep.value.id === 'menu_intro_mobile') {
|
||||
// 只允许打开,不允许关闭
|
||||
if (open) {
|
||||
sidebarOpen.value = true
|
||||
}
|
||||
return item.itemType
|
||||
// 如果试图关闭,忽略该操作,保持打开状态
|
||||
return
|
||||
}
|
||||
|
||||
// 获取剩余时间
|
||||
const getRemainingTime = (item: BuildQueueItem): number => {
|
||||
const now = Date.now()
|
||||
return Math.max(0, Math.floor((item.endTime - now) / 1000))
|
||||
}
|
||||
|
||||
// 获取队列进度
|
||||
const getQueueProgress = (item: BuildQueueItem): number => {
|
||||
const now = Date.now()
|
||||
const total = item.endTime - item.startTime
|
||||
const elapsed = now - item.startTime
|
||||
return Math.min(100, Math.max(0, (elapsed / total) * 100))
|
||||
// 其他情况正常更新
|
||||
sidebarOpen.value = open
|
||||
}
|
||||
|
||||
// 取消建造
|
||||
const handleCancelBuild = (queueId: string) => {
|
||||
confirmDialog.value?.show({
|
||||
title: t('queue.cancelBuild'),
|
||||
message: t('queue.confirmCancel'),
|
||||
onConfirm: () => {
|
||||
confirmDialogTitle.value = t('queue.cancelBuild')
|
||||
confirmDialogMessage.value = t('queue.confirmCancel')
|
||||
confirmDialogAction.value = () => {
|
||||
if (!gameStore.currentPlanet) return false
|
||||
const { item, index } = buildingValidation.findQueueItem(gameStore.currentPlanet.buildQueue, queueId)
|
||||
if (!item) return false
|
||||
@@ -606,15 +1533,14 @@
|
||||
gameStore.currentPlanet.buildQueue.splice(index, 1)
|
||||
return true
|
||||
}
|
||||
})
|
||||
confirmDialogOpen.value = true
|
||||
}
|
||||
|
||||
// 取消研究
|
||||
const handleCancelResearch = (queueId: string) => {
|
||||
confirmDialog.value?.show({
|
||||
title: t('queue.cancelResearch'),
|
||||
message: t('queue.confirmCancel'),
|
||||
onConfirm: () => {
|
||||
confirmDialogTitle.value = t('queue.cancelResearch')
|
||||
confirmDialogMessage.value = t('queue.confirmCancel')
|
||||
confirmDialogAction.value = () => {
|
||||
if (!gameStore.currentPlanet) return false
|
||||
const { item, index } = buildingValidation.findQueueItem(gameStore.player.researchQueue, queueId)
|
||||
if (!item) return false
|
||||
@@ -625,7 +1551,7 @@
|
||||
gameStore.player.researchQueue.splice(index, 1)
|
||||
return true
|
||||
}
|
||||
})
|
||||
confirmDialogOpen.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div v-if="isOpen" class="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div class="fixed inset-0 bg-black/50" @click="handleClose" />
|
||||
<div class="relative bg-card border rounded-lg shadow-lg p-6 max-w-md w-full mx-4 z-10">
|
||||
<h2 class="text-lg font-semibold mb-2">{{ dialogProps?.title }}</h2>
|
||||
<p class="text-sm text-muted-foreground mb-6 whitespace-pre-line">{{ dialogProps?.message }}</p>
|
||||
|
||||
<div class="flex justify-end gap-2">
|
||||
<Button v-if="dialogProps?.onConfirm" @click="handleClose" variant="outline">{{ t('common.cancel') }}</Button>
|
||||
<Button @click="handleConfirm" variant="default">{{ t('common.confirm') }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
interface AlertDialogProps {
|
||||
title: string
|
||||
message: string
|
||||
onConfirm?: () => void
|
||||
}
|
||||
|
||||
const isOpen = ref(false)
|
||||
const dialogProps = ref<AlertDialogProps | null>(null)
|
||||
|
||||
const show = (props: AlertDialogProps) => {
|
||||
dialogProps.value = props
|
||||
isOpen.value = true
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (dialogProps.value?.onConfirm) {
|
||||
dialogProps.value.onConfirm()
|
||||
}
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<Dialog v-model:open="isOpen">
|
||||
<DialogContent class="max-w-4xl max-h-[90vh] overflow-y-auto">
|
||||
<ScrollableDialogContent container-class="sm:max-w-4xl max-h-[90vh]">
|
||||
<template #header>
|
||||
<DialogHeader>
|
||||
<DialogTitle class="flex items-center gap-2">
|
||||
<Trophy class="h-5 w-5" />
|
||||
@@ -10,6 +11,8 @@
|
||||
{{ formatDate(report.timestamp) }}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
</template>
|
||||
|
||||
<div v-if="report" class="space-y-4">
|
||||
<!-- 战斗双方信息 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 text-sm">
|
||||
@@ -260,7 +263,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</ScrollableDialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
@@ -270,7 +273,7 @@
|
||||
import { useUniverseStore } from '@/stores/universeStore'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { useGameConfig } from '@/composables/useGameConfig'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Dialog, ScrollableDialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
|
||||
import ResourceIcon from '@/components/ResourceIcon.vue'
|
||||
|
||||
@@ -13,7 +13,19 @@
|
||||
</div>
|
||||
|
||||
<!-- 前置条件详情对话框 -->
|
||||
<AlertDialog ref="requirementsDialog" />
|
||||
<AlertDialog :open="requirementsDialogOpen" @update:open="requirementsDialogOpen = $event">
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>{{ requirementsDialogTitle }}</AlertDialogTitle>
|
||||
<AlertDialogDescription class="whitespace-pre-line">
|
||||
{{ requirementsDialogMessage }}
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogAction>{{ t('common.confirm') }}</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -25,7 +37,15 @@
|
||||
import { BuildingType, TechnologyType } from '@/types/game'
|
||||
import { Lock } from 'lucide-vue-next'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import AlertDialog from '@/components/AlertDialog.vue'
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle
|
||||
} from '@/components/ui/alert-dialog'
|
||||
import * as publicLogic from '@/logic/publicLogic'
|
||||
|
||||
interface Props {
|
||||
@@ -37,7 +57,11 @@
|
||||
const gameStore = useGameStore()
|
||||
const { t } = useI18n()
|
||||
const { BUILDINGS, TECHNOLOGIES } = useGameConfig()
|
||||
const requirementsDialog = ref<InstanceType<typeof AlertDialog> | null>(null)
|
||||
|
||||
// AlertDialog 状态
|
||||
const requirementsDialogOpen = ref(false)
|
||||
const requirementsDialogTitle = ref('')
|
||||
const requirementsDialogMessage = ref('')
|
||||
|
||||
const isUnlocked = computed(() => {
|
||||
// 如果已经建造过(level > 0),则认为已解锁,不显示遮罩
|
||||
@@ -72,9 +96,8 @@
|
||||
}
|
||||
|
||||
const showRequirements = () => {
|
||||
requirementsDialog.value?.show({
|
||||
title: t('common.requirementsNotMet'),
|
||||
message: getRequirementsList()
|
||||
})
|
||||
requirementsDialogTitle.value = t('common.requirementsNotMet')
|
||||
requirementsDialogMessage.value = getRequirementsList()
|
||||
requirementsDialogOpen.value = true
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div v-if="isOpen" class="fixed inset-0 z-50 flex items-center justify-center">
|
||||
<div class="fixed inset-0 bg-black/50" @click="handleCancel" />
|
||||
<div class="relative bg-card border rounded-lg shadow-lg p-6 max-w-md w-full mx-4 z-10">
|
||||
<h2 class="text-lg font-semibold mb-2">{{ dialogProps?.title }}</h2>
|
||||
<p class="text-sm text-muted-foreground mb-6">{{ dialogProps?.message }}</p>
|
||||
|
||||
<div class="flex justify-end gap-3">
|
||||
<Button @click="handleCancel" variant="outline">{{ t('common.cancel') }}</Button>
|
||||
<Button @click="handleConfirm" variant="default">{{ t('common.confirm') }}</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
interface ConfirmDialogProps {
|
||||
title: string
|
||||
message: string
|
||||
onConfirm: () => void
|
||||
}
|
||||
|
||||
const isOpen = ref(false)
|
||||
const dialogProps = ref<ConfirmDialogProps | null>(null)
|
||||
|
||||
const show = (props: ConfirmDialogProps) => {
|
||||
dialogProps.value = props
|
||||
isOpen.value = true
|
||||
}
|
||||
|
||||
const handleConfirm = () => {
|
||||
if (dialogProps.value) {
|
||||
dialogProps.value.onConfirm()
|
||||
}
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
@@ -1,81 +1,61 @@
|
||||
<template>
|
||||
<Dialog :open="dialogStore.isOpen" @update:open="handleClose">
|
||||
<DialogContent class="max-w-[calc(100%-1rem)] sm:max-w-[90vw] md:max-w-3xl lg:max-w-4xl max-h-[90vh] flex flex-col p-0">
|
||||
<!-- 建筑详情 -->
|
||||
<template v-if="dialogStore.type === 'building' && dialogStore.itemType">
|
||||
<DialogHeader class="px-6 pt-6 pb-4 shrink-0">
|
||||
<ScrollableDialogContent
|
||||
v-if="dialogStore.type && dialogStore.itemType"
|
||||
container-class="sm:max-w-[90vw] md:max-w-3xl lg:max-w-4xl max-h-[90vh]"
|
||||
>
|
||||
<template #header>
|
||||
<DialogHeader>
|
||||
<DialogTitle class="flex items-center gap-2">
|
||||
{{ t(`buildings.${dialogStore.itemType}`) }}
|
||||
<Badge variant="outline">{{ t('common.currentLevel') }} {{ dialogStore.currentLevel || 0 }}</Badge>
|
||||
{{ itemTitle }}
|
||||
<Badge v-if="dialogStore.currentLevel !== undefined" variant="outline">
|
||||
{{ t('common.currentLevel') }} {{ dialogStore.currentLevel }}
|
||||
</Badge>
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{{ t(`buildingDescriptions.${dialogStore.itemType}`) }}
|
||||
{{ itemDescription }}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div class="overflow-y-auto px-6 pb-6">
|
||||
<BuildingDetailView :buildingType="dialogStore.itemType as BuildingType" :currentLevel="dialogStore.currentLevel || 0" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 科技详情 -->
|
||||
<template v-else-if="dialogStore.type === 'technology' && dialogStore.itemType">
|
||||
<DialogHeader class="px-6 pt-6 pb-4 shrink-0">
|
||||
<DialogTitle class="flex items-center gap-2">
|
||||
{{ t(`technologies.${dialogStore.itemType}`) }}
|
||||
<Badge variant="outline">{{ t('common.currentLevel') }} {{ dialogStore.currentLevel || 0 }}</Badge>
|
||||
</DialogTitle>
|
||||
<DialogDescription>
|
||||
{{ t(`technologyDescriptions.${dialogStore.itemType}`) }}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div class="overflow-y-auto px-6 pb-6">
|
||||
<TechnologyDetailView :technologyType="dialogStore.itemType as TechnologyType" :currentLevel="dialogStore.currentLevel || 0" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 舰船详情 -->
|
||||
<template v-else-if="dialogStore.type === 'ship' && dialogStore.itemType">
|
||||
<DialogHeader class="px-6 pt-6 pb-4 shrink-0">
|
||||
<DialogTitle>{{ t(`ships.${dialogStore.itemType}`) }}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{{ t(`shipDescriptions.${dialogStore.itemType}`) }}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div class="overflow-y-auto px-6 pb-6">
|
||||
<ShipDetailView :shipType="dialogStore.itemType as ShipType" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 防御详情 -->
|
||||
<template v-else-if="dialogStore.type === 'defense' && dialogStore.itemType">
|
||||
<DialogHeader class="px-6 pt-6 pb-4 shrink-0">
|
||||
<DialogTitle>{{ t(`defenses.${dialogStore.itemType}`) }}</DialogTitle>
|
||||
<DialogDescription>
|
||||
{{ t(`defenseDescriptions.${dialogStore.itemType}`) }}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div class="overflow-y-auto px-6 pb-6">
|
||||
<DefenseDetailView :defenseType="dialogStore.itemType as DefenseType" />
|
||||
</div>
|
||||
</template>
|
||||
</DialogContent>
|
||||
<ItemDetailView :type="dialogStore.type" :itemType="dialogStore.itemType" :currentLevel="dialogStore.currentLevel" />
|
||||
</ScrollableDialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'
|
||||
import { computed } from 'vue'
|
||||
import { Dialog, ScrollableDialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { useDetailDialogStore } from '@/stores/detailDialogStore'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import type { BuildingType, TechnologyType, ShipType, DefenseType } from '@/types/game'
|
||||
import BuildingDetailView from './detail-views/BuildingDetailView.vue'
|
||||
import TechnologyDetailView from './detail-views/TechnologyDetailView.vue'
|
||||
import ShipDetailView from './detail-views/ShipDetailView.vue'
|
||||
import DefenseDetailView from './detail-views/DefenseDetailView.vue'
|
||||
import ItemDetailView from './ItemDetailView.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const dialogStore = useDetailDialogStore()
|
||||
|
||||
const itemTitle = computed(() => {
|
||||
if (!dialogStore.type || !dialogStore.itemType) return ''
|
||||
const typeMap = {
|
||||
building: 'buildings',
|
||||
technology: 'technologies',
|
||||
ship: 'ships',
|
||||
defense: 'defenses'
|
||||
}
|
||||
return t(`${typeMap[dialogStore.type]}.${dialogStore.itemType}`)
|
||||
})
|
||||
|
||||
const itemDescription = computed(() => {
|
||||
if (!dialogStore.type || !dialogStore.itemType) return ''
|
||||
const typeMap = {
|
||||
building: 'buildingDescriptions',
|
||||
technology: 'technologyDescriptions',
|
||||
ship: 'shipDescriptions',
|
||||
defense: 'defenseDescriptions'
|
||||
}
|
||||
return t(`${typeMap[dialogStore.type]}.${dialogStore.itemType}`)
|
||||
})
|
||||
|
||||
const handleClose = (open: boolean) => {
|
||||
if (!open) {
|
||||
dialogStore.close()
|
||||
|
||||
300
src/components/DiplomaticNotifications.vue
Normal file
300
src/components/DiplomaticNotifications.vue
Normal file
@@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<Popover v-model:open="isOpen">
|
||||
<PopoverTrigger as-child>
|
||||
<Button variant="outline" size="icon" class="relative">
|
||||
<ScrollText class="h-4 w-4" />
|
||||
<Badge
|
||||
v-if="unreadCount > 0"
|
||||
variant="destructive"
|
||||
class="absolute -top-1 -right-1 h-5 w-5 p-0 flex items-center justify-center text-xs"
|
||||
>
|
||||
{{ unreadCount > 9 ? '9+' : unreadCount }}
|
||||
</Badge>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-96 p-0" align="end">
|
||||
<div class="flex items-center justify-between p-4 border-b">
|
||||
<h3 class="font-semibold">{{ t('diplomacy.notifications') }}</h3>
|
||||
<Button v-if="unreadCount > 0" variant="ghost" size="sm" @click="markAllAsRead">
|
||||
{{ t('diplomacy.markAllRead') }}
|
||||
</Button>
|
||||
</div>
|
||||
<ScrollArea class="h-96">
|
||||
<div v-if="reports.length === 0" class="p-8 text-center text-muted-foreground">
|
||||
{{ t('diplomacy.noReports') }}
|
||||
</div>
|
||||
<div v-else class="divide-y">
|
||||
<div
|
||||
v-for="report in reports"
|
||||
:key="report.id"
|
||||
class="p-4 hover:bg-muted/50 cursor-pointer transition-colors"
|
||||
:class="{ 'bg-primary/5': !report.read }"
|
||||
@click="handleReportClick(report)"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="flex-shrink-0 mt-1">
|
||||
<component :is="getEventIcon(report.eventType)" class="h-4 w-4" :class="getEventIconColor(report.eventType)" />
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<span class="font-medium text-sm">{{ report.npcName }}</span>
|
||||
<Badge :variant="getStatusBadgeVariant(report.newStatus)" class="text-xs">
|
||||
{{ getStatusText(report.newStatus) }}
|
||||
</Badge>
|
||||
<span v-if="!report.read" class="ml-auto">
|
||||
<Badge variant="destructive" class="h-2 w-2 p-0 rounded-full" />
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-sm text-muted-foreground line-clamp-2">
|
||||
{{ report.messageKey && report.messageParams ? t(report.messageKey, report.messageParams) : report.message }}
|
||||
</p>
|
||||
<p class="text-xs text-muted-foreground mt-1">
|
||||
{{ formatRelativeTime((Date.now() - report.timestamp) / 1000, t) }}{{ t('diplomacy.ago') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
<div v-if="reports.length > 0" class="p-2 border-t">
|
||||
<Button variant="ghost" size="sm" class="w-full" @click="goToDiplomacy">
|
||||
{{ t('diplomacy.viewAll') }}
|
||||
</Button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
|
||||
<!-- 外交报告详情对话框 -->
|
||||
<Dialog :open="detailDialogOpen" @update:open="detailDialogOpen = $event">
|
||||
<DialogContent class="max-w-2xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle class="flex items-center gap-2">
|
||||
<component
|
||||
v-if="selectedReport"
|
||||
:is="getEventIcon(selectedReport.eventType)"
|
||||
class="h-5 w-5"
|
||||
:class="getEventIconColor(selectedReport.eventType)"
|
||||
/>
|
||||
{{ t('diplomacy.reportDetails') }}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
|
||||
<div v-if="selectedReport" class="space-y-4">
|
||||
<!-- NPC信息 -->
|
||||
<div class="flex items-center gap-3 p-4 bg-muted/50 rounded-lg">
|
||||
<div class="flex-1">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<h3 class="font-semibold text-lg">{{ selectedReport.npcName }}</h3>
|
||||
<Badge :variant="getStatusBadgeVariant(selectedReport.newStatus)">
|
||||
{{ getStatusText(selectedReport.newStatus) }}
|
||||
</Badge>
|
||||
</div>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ formatRelativeTime((Date.now() - selectedReport.timestamp) / 1000, t) }}{{ t('diplomacy.ago') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 事件描述 -->
|
||||
<div class="space-y-2">
|
||||
<h4 class="font-semibold text-sm">{{ t('diplomacy.eventDescription') }}</h4>
|
||||
<p class="text-sm p-3 bg-muted/30 rounded-md">
|
||||
{{
|
||||
selectedReport.messageKey && selectedReport.messageParams
|
||||
? t(selectedReport.messageKey, selectedReport.messageParams)
|
||||
: selectedReport.message
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 关系变化 -->
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<!-- 好感度变化 -->
|
||||
<div class="space-y-2">
|
||||
<h4 class="font-semibold text-sm">{{ t('diplomacy.reputationChange') }}</h4>
|
||||
<div class="p-3 bg-muted/30 rounded-md">
|
||||
<div class="flex items-center justify-between text-sm mb-2">
|
||||
<span class="text-muted-foreground">{{ t('diplomacy.before') }}</span>
|
||||
<span class="font-semibold" :class="getReputationColor(selectedReport.newReputation - selectedReport.reputationChange)">
|
||||
{{ selectedReport.newReputation - selectedReport.reputationChange > 0 ? '+' : ''
|
||||
}}{{ selectedReport.newReputation - selectedReport.reputationChange }}
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center justify-center text-lg font-bold my-1"
|
||||
:class="selectedReport.reputationChange >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'"
|
||||
>
|
||||
{{ selectedReport.reputationChange >= 0 ? '+' : '' }}{{ selectedReport.reputationChange }}
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm mt-2">
|
||||
<span class="text-muted-foreground">{{ t('diplomacy.after') }}</span>
|
||||
<span class="font-semibold" :class="getReputationColor(selectedReport.newReputation)">
|
||||
{{ selectedReport.newReputation > 0 ? '+' : '' }}{{ selectedReport.newReputation }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 关系状态变化 -->
|
||||
<div class="space-y-2">
|
||||
<h4 class="font-semibold text-sm">{{ t('diplomacy.statusChange') }}</h4>
|
||||
<div class="p-3 bg-muted/30 rounded-md">
|
||||
<div class="flex items-center justify-between text-sm mb-2">
|
||||
<span class="text-muted-foreground">{{ t('diplomacy.before') }}</span>
|
||||
<Badge :variant="getStatusBadgeVariant(selectedReport.oldStatus)" class="text-xs">
|
||||
{{ getStatusText(selectedReport.oldStatus) }}
|
||||
</Badge>
|
||||
</div>
|
||||
<div class="flex items-center justify-center my-3">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6 text-muted-foreground"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm mt-2">
|
||||
<span class="text-muted-foreground">{{ t('diplomacy.after') }}</span>
|
||||
<Badge :variant="getStatusBadgeVariant(selectedReport.newStatus)" class="text-xs">
|
||||
{{ getStatusText(selectedReport.newStatus) }}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<DialogFooter>
|
||||
<Button variant="outline" @click="detailDialogOpen = false">{{ t('common.close') }}</Button>
|
||||
<Button @click="goToDiplomacyFromDialog">{{ t('diplomacy.viewDiplomacy') }}</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from '@/components/ui/dialog'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { ScrollText, Gift, Sword, Eye, Trash2, Skull } from 'lucide-vue-next'
|
||||
import { RelationStatus, DiplomaticEventType } from '@/types/game'
|
||||
import type { DiplomaticReport } from '@/types/game'
|
||||
import { formatRelativeTime } from '@/utils/format'
|
||||
|
||||
const router = useRouter()
|
||||
const gameStore = useGameStore()
|
||||
const { t } = useI18n()
|
||||
const isOpen = ref(false)
|
||||
const detailDialogOpen = ref(false)
|
||||
const selectedReport = ref<DiplomaticReport | null>(null)
|
||||
|
||||
const reports = computed(() => {
|
||||
return (gameStore.player.diplomaticReports || []).slice().reverse().slice(0, 20) // 最近20条
|
||||
})
|
||||
|
||||
const unreadCount = computed(() => {
|
||||
return (gameStore.player.diplomaticReports || []).filter(r => !r.read).length
|
||||
})
|
||||
|
||||
const getEventIcon = (eventType: DiplomaticReport['eventType']) => {
|
||||
switch (eventType) {
|
||||
case DiplomaticEventType.GiftResources:
|
||||
return Gift
|
||||
case DiplomaticEventType.Attack:
|
||||
case DiplomaticEventType.AllyAttacked:
|
||||
return Sword
|
||||
case DiplomaticEventType.Spy:
|
||||
return Eye
|
||||
case DiplomaticEventType.StealDebris:
|
||||
return Trash2
|
||||
case DiplomaticEventType.DestroyPlanet:
|
||||
return Skull
|
||||
default:
|
||||
return ScrollText
|
||||
}
|
||||
}
|
||||
|
||||
const getEventIconColor = (eventType: DiplomaticReport['eventType']) => {
|
||||
switch (eventType) {
|
||||
case DiplomaticEventType.GiftResources:
|
||||
return 'text-green-500'
|
||||
case DiplomaticEventType.Attack:
|
||||
case DiplomaticEventType.DestroyPlanet:
|
||||
return 'text-red-500'
|
||||
case DiplomaticEventType.AllyAttacked:
|
||||
return 'text-orange-500'
|
||||
case DiplomaticEventType.Spy:
|
||||
return 'text-purple-500'
|
||||
case DiplomaticEventType.StealDebris:
|
||||
return 'text-yellow-500'
|
||||
default:
|
||||
return 'text-muted-foreground'
|
||||
}
|
||||
}
|
||||
|
||||
const getStatusBadgeVariant = (status: RelationStatus) => {
|
||||
switch (status) {
|
||||
case RelationStatus.Hostile:
|
||||
return 'destructive'
|
||||
case RelationStatus.Friendly:
|
||||
return 'default'
|
||||
case RelationStatus.Neutral:
|
||||
default:
|
||||
return 'secondary'
|
||||
}
|
||||
}
|
||||
|
||||
const getStatusText = (status: RelationStatus) => {
|
||||
switch (status) {
|
||||
case RelationStatus.Hostile:
|
||||
return t('diplomacy.status.hostile')
|
||||
case RelationStatus.Friendly:
|
||||
return t('diplomacy.status.friendly')
|
||||
case RelationStatus.Neutral:
|
||||
default:
|
||||
return t('diplomacy.status.neutral')
|
||||
}
|
||||
}
|
||||
|
||||
const getReputationColor = (reputation: number | null) => {
|
||||
if (reputation === null) return 'text-muted-foreground'
|
||||
if (reputation >= 20) return 'text-green-600 dark:text-green-400'
|
||||
if (reputation <= -20) return 'text-red-600 dark:text-red-400'
|
||||
return 'text-muted-foreground'
|
||||
}
|
||||
|
||||
const handleReportClick = (report: DiplomaticReport) => {
|
||||
// 标记为已读
|
||||
report.read = true
|
||||
// 设置选中的报告并打开详情对话框
|
||||
selectedReport.value = report
|
||||
detailDialogOpen.value = true
|
||||
// 关闭通知面板
|
||||
isOpen.value = false
|
||||
}
|
||||
|
||||
const markAllAsRead = () => {
|
||||
gameStore.player.diplomaticReports?.forEach(report => {
|
||||
report.read = true
|
||||
})
|
||||
}
|
||||
|
||||
const goToDiplomacy = () => {
|
||||
isOpen.value = false
|
||||
router.push('/diplomacy')
|
||||
}
|
||||
|
||||
const goToDiplomacyFromDialog = () => {
|
||||
detailDialogOpen.value = false
|
||||
router.push('/diplomacy')
|
||||
}
|
||||
</script>
|
||||
101
src/components/IncomingFleetAlerts.vue
Normal file
101
src/components/IncomingFleetAlerts.vue
Normal file
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div v-if="alerts.length > 0" class="bg-destructive/10 border-b border-destructive/20">
|
||||
<div class="px-4 sm:px-6 py-2 space-y-2">
|
||||
<div
|
||||
v-for="alert in alerts"
|
||||
:key="alert.id"
|
||||
class="flex items-center justify-between gap-3 bg-destructive/5 rounded-lg px-3 py-2 border border-destructive/20"
|
||||
>
|
||||
<!-- 警告图标和信息 -->
|
||||
<div class="flex items-center gap-2 flex-1 min-w-0">
|
||||
<AlertTriangle class="h-5 w-5 text-destructive flex-shrink-0 animate-pulse" />
|
||||
<div class="flex-1 min-w-0">
|
||||
<p class="text-sm font-semibold text-destructive truncate">
|
||||
<template v-if="alert.missionType === 'spy'">
|
||||
{{ t('alerts.npcSpyIncoming') }}
|
||||
</template>
|
||||
<template v-else-if="alert.missionType === 'attack'">
|
||||
{{ t('alerts.npcAttackIncoming') }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ t('alerts.npcFleetIncoming') }}
|
||||
</template>
|
||||
</p>
|
||||
<p class="text-xs text-muted-foreground truncate">
|
||||
{{ alert.npcName }} → {{ alert.targetPlanetName }}
|
||||
<template v-if="alert.missionType === 'attack'">({{ alert.fleetSize }} {{ t('alerts.ships') }})</template>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 倒计时 -->
|
||||
<div class="flex items-center gap-2 flex-shrink-0">
|
||||
<div class="text-right">
|
||||
<p class="text-xs font-mono text-destructive">
|
||||
{{ formatTimeRemaining(alert.arrivalTime) }}
|
||||
</p>
|
||||
<p class="text-[10px] text-muted-foreground">
|
||||
{{ formatTime(alert.arrivalTime) }}
|
||||
</p>
|
||||
</div>
|
||||
<Button @click="markAsRead(alert)" variant="ghost" size="sm" class="h-6 w-6 p-0">
|
||||
<X class="h-3 w-3" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted } from 'vue'
|
||||
import type { IncomingFleetAlert } from '@/types/game'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { AlertTriangle, X } from 'lucide-vue-next'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
|
||||
const props = defineProps<{
|
||||
alerts: IncomingFleetAlert[]
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'markAsRead', alert: IncomingFleetAlert): void
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
// 强制更新倒计时
|
||||
const now = ref(Date.now())
|
||||
let updateInterval: ReturnType<typeof setInterval> | null = null
|
||||
|
||||
onMounted(() => {
|
||||
updateInterval = setInterval(() => {
|
||||
now.value = Date.now()
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
if (updateInterval) clearInterval(updateInterval)
|
||||
})
|
||||
|
||||
const formatTimeRemaining = (arrivalTime: number): string => {
|
||||
const remaining = Math.max(0, arrivalTime - now.value)
|
||||
const seconds = Math.floor((remaining / 1000) % 60)
|
||||
const minutes = Math.floor((remaining / (1000 * 60)) % 60)
|
||||
const hours = Math.floor(remaining / (1000 * 60 * 60))
|
||||
|
||||
if (hours > 0) {
|
||||
return `${hours}:${String(minutes).padStart(2, '0')}:${String(seconds).padStart(2, '0')}`
|
||||
}
|
||||
return `${minutes}:${String(seconds).padStart(2, '0')}`
|
||||
}
|
||||
|
||||
const formatTime = (timestamp: number): string => {
|
||||
const date = new Date(timestamp)
|
||||
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
||||
}
|
||||
|
||||
const markAsRead = (alert: IncomingFleetAlert) => {
|
||||
emit('markAsRead', alert)
|
||||
}
|
||||
</script>
|
||||
837
src/components/ItemDetailView.vue
Normal file
837
src/components/ItemDetailView.vue
Normal file
@@ -0,0 +1,837 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<!-- 建筑/科技:等级范围表格 -->
|
||||
<div v-if="type === 'building' || type === 'technology'" class="border rounded-lg overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead class="w-20 text-center">{{ t(`${typeKey}.levelRange`) }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.metal') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.crystal') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.deuterium') }}</TableHead>
|
||||
<TableHead v-if="showDarkMatterColumn" class="text-center">{{ t('resources.darkMatter') }}</TableHead>
|
||||
<TableHead class="text-center">{{ type === 'building' ? t('buildings.buildTime') : t('research.researchTime') }}</TableHead>
|
||||
<!-- 建筑相关列 -->
|
||||
<TableHead v-if="type === 'building' && showProductionColumn" class="text-center">{{ t('buildings.production') }}</TableHead>
|
||||
<TableHead v-if="type === 'building' && showConsumptionColumn" class="text-center">{{ t('buildings.consumption') }}</TableHead>
|
||||
<TableHead v-if="type === 'building' && showCapacityColumn" class="text-center">{{ t('buildings.storageCapacity') }}</TableHead>
|
||||
<TableHead v-if="type === 'building' && showFleetStorageColumn" class="text-center">
|
||||
{{ t('buildings.fleetStorage') }}
|
||||
</TableHead>
|
||||
<TableHead v-if="type === 'building' && showBuildQueueColumn" class="text-center">
|
||||
{{ t('buildings.buildQueueBonus') }}
|
||||
</TableHead>
|
||||
<TableHead v-if="type === 'building' && showSpaceColumn" class="text-center">{{ t('buildings.spaceBonus') }}</TableHead>
|
||||
<TableHead v-if="type === 'building' && showMissileColumn" class="text-center">{{ t('buildings.missileCapacity') }}</TableHead>
|
||||
<TableHead v-if="type === 'building' && showBuildSpeedColumn" class="text-center">
|
||||
{{ t('buildings.buildSpeedBonus') }}
|
||||
</TableHead>
|
||||
<TableHead v-if="type === 'building' && showResearchSpeedColumn" class="text-center">
|
||||
{{ t('buildings.researchSpeedBonus') }}
|
||||
</TableHead>
|
||||
<!-- 科技相关列 -->
|
||||
<TableHead v-if="type === 'technology' && showAttackBonusColumn" class="text-center">{{ t('research.attackBonus') }}</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showShieldBonusColumn" class="text-center">{{ t('research.shieldBonus') }}</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showArmorBonusColumn" class="text-center">{{ t('research.armorBonus') }}</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showSpyLevelColumn" class="text-center">{{ t('research.spyLevel') }}</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showFleetStorageColumn" class="text-center">
|
||||
{{ t('buildings.fleetStorage') }}
|
||||
</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showResearchQueueColumn" class="text-center">
|
||||
{{ t('research.researchQueueBonus') }}
|
||||
</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showColonySlotsColumn" class="text-center">{{ t('research.colonySlots') }}</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showSpaceColumn" class="text-center">{{ t('buildings.spaceBonus') }}</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showSpeedBonusColumn" class="text-center">{{ t('research.speedBonus') }}</TableHead>
|
||||
<TableHead v-if="type === 'technology' && showResearchSpeedColumn" class="text-center">
|
||||
{{ t('buildings.researchSpeedBonus') }}
|
||||
</TableHead>
|
||||
<TableHead class="text-center">{{ t('player.points') }}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow v-for="level in levelRange" :key="level" :class="{ 'bg-muted/50': level === safeCurrentLevel }">
|
||||
<TableCell class="text-center font-medium">
|
||||
<Badge v-if="level === safeCurrentLevel" variant="default">{{ level }}</Badge>
|
||||
<span v-else>{{ level }}</span>
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.metal" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.crystal" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.deuterium" />
|
||||
</TableCell>
|
||||
<TableCell v-if="showDarkMatterColumn" class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.darkMatter" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">{{ formatTime(getLevelData(level).time) }}</TableCell>
|
||||
<!-- 建筑相关数据 -->
|
||||
<TableCell v-if="type === 'building' && showProductionColumn" class="text-center text-sm">
|
||||
<span v-if="getLevelData(level).production > 0" class="text-green-600 dark:text-green-400">
|
||||
+
|
||||
<NumberWithTooltip :value="getLevelData(level).production" />
|
||||
/{{ t('resources.perHour') }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showConsumptionColumn" class="text-center text-sm">
|
||||
<span v-if="getLevelData(level).consumption > 0" class="text-red-600 dark:text-red-400">
|
||||
-
|
||||
<NumberWithTooltip :value="getLevelData(level).consumption" />
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showCapacityColumn" class="text-center text-sm">
|
||||
<span v-if="getLevelData(level).capacity > 0" class="text-blue-600 dark:text-blue-400">
|
||||
<NumberWithTooltip :value="getLevelData(level).capacity" />
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showFleetStorageColumn" class="text-center text-sm">
|
||||
<span v-if="getLevelData(level).fleetStorage > 0" class="text-blue-600 dark:text-blue-400">
|
||||
+
|
||||
<NumberWithTooltip :value="getLevelData(level).fleetStorage" />
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showBuildQueueColumn" class="text-center text-sm">
|
||||
<span class="text-purple-600 dark:text-purple-400">+1</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showSpaceColumn" class="text-center text-sm">
|
||||
<span v-if="getLevelData(level).spaceBonus > 0" class="text-green-600 dark:text-green-400">
|
||||
+
|
||||
<NumberWithTooltip :value="getLevelData(level).spaceBonus" />
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showMissileColumn" class="text-center text-sm">
|
||||
<span class="text-orange-600 dark:text-orange-400">+10</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showBuildSpeedColumn" class="text-center text-sm">
|
||||
<span v-if="itemType === 'roboticsFactory'" class="text-cyan-600 dark:text-cyan-400">
|
||||
+{{ getLevelData(level).buildSpeedBonus * 100 }}%
|
||||
</span>
|
||||
<span v-else-if="itemType === 'naniteFactory'" class="text-cyan-600 dark:text-cyan-400">
|
||||
+{{ getLevelData(level).buildSpeedBonus * 100 }}%
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'building' && showResearchSpeedColumn" class="text-center text-sm">
|
||||
<span class="text-indigo-600 dark:text-indigo-400">+{{ (getLevelData(level).researchSpeedBonus - 1) * 100 }}%</span>
|
||||
</TableCell>
|
||||
<!-- 科技相关数据 -->
|
||||
<TableCell v-if="type === 'technology' && showAttackBonusColumn" class="text-center text-sm">
|
||||
<span class="text-red-600 dark:text-red-400">+{{ level * 10 }}%</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showShieldBonusColumn" class="text-center text-sm">
|
||||
<span class="text-blue-600 dark:text-blue-400">+{{ level * 10 }}%</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showArmorBonusColumn" class="text-center text-sm">
|
||||
<span class="text-gray-600 dark:text-gray-400">+{{ level * 10 }}%</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showSpyLevelColumn" class="text-center text-sm">
|
||||
<span class="text-purple-600 dark:text-purple-400">+{{ level }}</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showFleetStorageColumn" class="text-center text-sm">
|
||||
<span class="text-blue-600 dark:text-blue-400">
|
||||
+
|
||||
<NumberWithTooltip :value="level * 500" />
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showResearchQueueColumn" class="text-center text-sm">
|
||||
<span class="text-purple-600 dark:text-purple-400">+1</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showColonySlotsColumn" class="text-center text-sm">
|
||||
<span class="text-green-600 dark:text-green-400">+1</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showSpaceColumn" class="text-center text-sm">
|
||||
<span class="text-green-600 dark:text-green-400">+30 {{ t('research.forAllPlanets') }}</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showSpeedBonusColumn" class="text-center text-sm">
|
||||
<span class="text-yellow-600 dark:text-yellow-400">+{{ level * 10 }}%</span>
|
||||
</TableCell>
|
||||
<TableCell v-if="type === 'technology' && showResearchSpeedColumn" class="text-center text-sm">
|
||||
<span class="text-indigo-600 dark:text-indigo-400">+{{ getLevelData(level).researchSpeedBonus * 100 }}%</span>
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<span class="text-primary font-medium">
|
||||
+
|
||||
<NumberWithTooltip :value="getLevelData(level).points" />
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<!-- 建筑/科技:累积统计 -->
|
||||
<div v-if="type === 'building' || type === 'technology'" class="grid grid-cols-2 gap-4">
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm">{{ t(`${typeKey}.totalCost`) }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-2">
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm">{{ t(`${typeKey}.totalPoints`) }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-3xl font-bold text-primary">
|
||||
<NumberWithTooltip :value="totalStats.points" />
|
||||
</div>
|
||||
<p class="text-xs text-muted-foreground mt-1">
|
||||
{{ t(`${typeKey}.levelRange`) }}: {{ Math.max(0, safeCurrentLevel - 10) }} - {{ safeCurrentLevel + 10 }}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 舰船/防御:基础属性 -->
|
||||
<div v-if="type === 'ship' || type === 'defense'" class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Sword class="h-4 w-4" />
|
||||
{{ t(`${typeKey}.attack`) }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="combatUnitConfig?.attack || 0" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Shield class="h-4 w-4" />
|
||||
{{ t(`${typeKey}.shield`) }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="combatUnitConfig?.shield || 0" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<ShieldCheck class="h-4 w-4" />
|
||||
{{ t(`${typeKey}.armor`) }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="combatUnitConfig?.armor || 0" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<!-- 仅舰船显示 -->
|
||||
<Card v-if="type === 'ship'">
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Zap class="h-4 w-4" />
|
||||
{{ t('shipyard.speed') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="shipConfig?.speed || 0" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card v-if="type === 'ship'">
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Package class="h-4 w-4" />
|
||||
{{ t('shipyard.cargoCapacity') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="shipConfig?.cargoCapacity || 0" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card v-if="type === 'ship'">
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Fuel class="h-4 w-4" />
|
||||
{{ t('shipyard.fuelConsumption') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="shipConfig?.fuelConsumption || 0" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 舰船/防御:建造成本和时间 -->
|
||||
<div v-if="type === 'ship' || type === 'defense'" class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t(`${typeKey}.buildCost`) }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-2">
|
||||
<div
|
||||
v-for="resourceType in costResourceTypes"
|
||||
:key="resourceType.key"
|
||||
v-show="unitCost[resourceType.key] > 0"
|
||||
class="flex items-center justify-between text-sm"
|
||||
>
|
||||
<span class="text-muted-foreground">{{ t(`resources.${resourceType.key}`) }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="unitCost[resourceType.key]" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm pt-2 border-t">
|
||||
<span class="text-muted-foreground">{{ t('player.points') }}:</span>
|
||||
<span class="font-bold text-primary">
|
||||
<NumberWithTooltip :value="pointsPerUnit" />
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t(`${typeKey}.buildTime`) }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-3xl font-bold">{{ formatTime(unitBuildTime) }}</div>
|
||||
<p class="text-xs text-muted-foreground mt-2">{{ t(`${typeKey}.perUnit`) }}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 舰船/防御:批量建造计算器 -->
|
||||
<Card v-if="type === 'ship' || type === 'defense'">
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t(`${typeKey}.batchCalculator`) }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<Label class="w-20">{{ t(`${typeKey}.quantity`) }}:</Label>
|
||||
<Input v-model.number="quantity" type="number" min="1" class="flex-1" />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4 pt-4 border-t">
|
||||
<div class="space-y-2">
|
||||
<p class="text-sm text-muted-foreground">{{ t(`${typeKey}.totalCost`) }}:</p>
|
||||
<div class="space-y-1 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<p class="text-sm text-muted-foreground">{{ t(`${typeKey}.totalTime`) }}:</p>
|
||||
<div class="text-xl font-bold">{{ formatTime(unitBuildTime * quantity) }}</div>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ t('player.points') }}: +
|
||||
<NumberWithTooltip :value="batchPoints" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import type { BuildingType, TechnologyType, ShipType, DefenseType } from '@/types/game'
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import NumberWithTooltip from '@/components/NumberWithTooltip.vue'
|
||||
import { Sword, Shield, ShieldCheck, Zap, Package, Fuel } from 'lucide-vue-next'
|
||||
import * as buildingLogic from '@/logic/buildingLogic'
|
||||
import * as researchLogic from '@/logic/researchLogic'
|
||||
import * as pointsLogic from '@/logic/pointsLogic'
|
||||
import * as officerLogic from '@/logic/officerLogic'
|
||||
import * as shipLogic from '@/logic/shipLogic'
|
||||
import { SHIPS, DEFENSES } from '@/config/gameConfig'
|
||||
import { formatTime } from '@/utils/format'
|
||||
|
||||
const { t } = useI18n()
|
||||
const gameStore = useGameStore()
|
||||
|
||||
const props = defineProps<{
|
||||
type: 'building' | 'technology' | 'ship' | 'defense'
|
||||
itemType: BuildingType | TechnologyType | ShipType | DefenseType
|
||||
currentLevel?: number
|
||||
}>()
|
||||
|
||||
const quantity = ref(1)
|
||||
|
||||
// 资源类型配置(用于成本显示)
|
||||
const costResourceTypes = [{ key: 'metal' as const }, { key: 'crystal' as const }, { key: 'deuterium' as const }]
|
||||
|
||||
// 获取当前星球
|
||||
const currentPlanet = computed(() => gameStore.currentPlanet)
|
||||
|
||||
// 计算当前加成
|
||||
const activeBonuses = computed(() => {
|
||||
return officerLogic.calculateActiveBonuses(gameStore.player.officers, gameStore.gameTime)
|
||||
})
|
||||
|
||||
// 获取工厂等级(用于建造时间计算)
|
||||
const roboticsFactoryLevel = computed(() => {
|
||||
if (!currentPlanet.value) return 0
|
||||
return currentPlanet.value.buildings['roboticsFactory'] || 0
|
||||
})
|
||||
|
||||
const naniteFactoryLevel = computed(() => {
|
||||
if (!currentPlanet.value) return 0
|
||||
return currentPlanet.value.buildings['naniteFactory'] || 0
|
||||
})
|
||||
|
||||
// 获取研究所等级(用于研究时间计算)
|
||||
const researchLabLevel = computed(() => {
|
||||
if (!currentPlanet.value) return 0
|
||||
return currentPlanet.value.buildings['researchLab'] || 0
|
||||
})
|
||||
|
||||
// 翻译键(转换为复数形式)
|
||||
const typeKey = computed(() => {
|
||||
const typeMap = {
|
||||
building: 'buildings',
|
||||
technology: 'research',
|
||||
ship: 'shipyard',
|
||||
defense: 'defense'
|
||||
} as const
|
||||
return typeMap[props.type]
|
||||
})
|
||||
|
||||
// 控制建筑列显示
|
||||
const showDarkMatterColumn = computed(() => {
|
||||
if (props.type === 'building') {
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return buildingType === 'darkMatterCollector'
|
||||
} else if (props.type === 'technology') {
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'gravitonTechnology'
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
const showProductionColumn = computed(() => {
|
||||
if (props.type !== 'building') return false
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return ['metalMine', 'crystalMine', 'deuteriumSynthesizer', 'solarPlant', 'fusionReactor', 'darkMatterCollector'].includes(buildingType)
|
||||
})
|
||||
|
||||
const showConsumptionColumn = computed(() => {
|
||||
if (props.type !== 'building') return false
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return ['metalMine', 'crystalMine', 'deuteriumSynthesizer'].includes(buildingType)
|
||||
})
|
||||
|
||||
const showCapacityColumn = computed(() => {
|
||||
if (props.type !== 'building') return false
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return ['metalStorage', 'crystalStorage', 'deuteriumTank', 'darkMatterCollector', 'darkMatterTank'].includes(buildingType)
|
||||
})
|
||||
|
||||
const showFleetStorageColumn = computed(() => {
|
||||
if (props.type === 'building') {
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return buildingType === 'shipyard' || buildingType === 'hangar'
|
||||
} else if (props.type === 'technology') {
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'computerTechnology'
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
const showBuildQueueColumn = computed(() => {
|
||||
if (props.type !== 'building') return false
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return buildingType === 'naniteFactory'
|
||||
})
|
||||
|
||||
const showSpaceColumn = computed(() => {
|
||||
if (props.type === 'building') {
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return ['terraformer', 'lunarBase'].includes(buildingType)
|
||||
} else if (props.type === 'technology') {
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'terraformingTechnology'
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
const showMissileColumn = computed(() => {
|
||||
if (props.type !== 'building') return false
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return buildingType === 'missileSilo'
|
||||
})
|
||||
|
||||
const showBuildSpeedColumn = computed(() => {
|
||||
if (props.type !== 'building') return false
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return ['roboticsFactory', 'naniteFactory'].includes(buildingType)
|
||||
})
|
||||
|
||||
const showResearchSpeedColumn = computed(() => {
|
||||
if (props.type === 'building') {
|
||||
const buildingType = props.itemType as BuildingType
|
||||
return buildingType === 'researchLab'
|
||||
} else if (props.type === 'technology') {
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'energyTechnology'
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// 控制科技列显示
|
||||
const showAttackBonusColumn = computed(() => {
|
||||
if (props.type !== 'technology') return false
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'weaponsTechnology'
|
||||
})
|
||||
|
||||
const showShieldBonusColumn = computed(() => {
|
||||
if (props.type !== 'technology') return false
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'shieldingTechnology'
|
||||
})
|
||||
|
||||
const showArmorBonusColumn = computed(() => {
|
||||
if (props.type !== 'technology') return false
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'armourTechnology'
|
||||
})
|
||||
|
||||
const showSpyLevelColumn = computed(() => {
|
||||
if (props.type !== 'technology') return false
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'espionageTechnology'
|
||||
})
|
||||
|
||||
const showResearchQueueColumn = computed(() => {
|
||||
if (props.type !== 'technology') return false
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'computerTechnology'
|
||||
})
|
||||
|
||||
const showColonySlotsColumn = computed(() => {
|
||||
if (props.type !== 'technology') return false
|
||||
const techType = props.itemType as TechnologyType
|
||||
return techType === 'astrophysics'
|
||||
})
|
||||
|
||||
const showSpeedBonusColumn = computed(() => {
|
||||
if (props.type !== 'technology') return false
|
||||
const techType = props.itemType as TechnologyType
|
||||
return ['combustionDrive', 'impulseDrive', 'hyperspaceDrive'].includes(techType)
|
||||
})
|
||||
|
||||
// 安全的当前等级(防止undefined)
|
||||
const safeCurrentLevel = computed(() => props.currentLevel ?? 0)
|
||||
|
||||
// 类型安全:战斗单位配置(舰船/防御)
|
||||
const combatUnitConfig = computed(() => {
|
||||
if (props.type === 'ship') return SHIPS[props.itemType as ShipType]
|
||||
if (props.type === 'defense') return DEFENSES[props.itemType as DefenseType]
|
||||
return null
|
||||
})
|
||||
|
||||
// 类型安全:舰船配置
|
||||
const shipConfig = computed(() => {
|
||||
if (props.type === 'ship') return SHIPS[props.itemType as ShipType]
|
||||
return null
|
||||
})
|
||||
|
||||
// 类型安全:单位成本(处理cost vs baseCost差异)
|
||||
const unitCost = computed(() => {
|
||||
if (props.type === 'ship') return SHIPS[props.itemType as ShipType].cost
|
||||
if (props.type === 'defense') return DEFENSES[props.itemType as DefenseType].cost
|
||||
return { metal: 0, crystal: 0, deuterium: 0 }
|
||||
})
|
||||
|
||||
// 类型安全:单位建造时间(处理buildTime vs baseTime差异,应用加成)
|
||||
const unitBuildTime = computed(() => {
|
||||
if (props.type === 'ship') {
|
||||
return shipLogic.calculateShipBuildTime(
|
||||
props.itemType as ShipType,
|
||||
1, // 单个单位
|
||||
activeBonuses.value.buildingSpeedBonus,
|
||||
roboticsFactoryLevel.value,
|
||||
naniteFactoryLevel.value
|
||||
)
|
||||
}
|
||||
if (props.type === 'defense') {
|
||||
return shipLogic.calculateDefenseBuildTime(
|
||||
props.itemType as DefenseType,
|
||||
1, // 单个单位
|
||||
activeBonuses.value.buildingSpeedBonus,
|
||||
roboticsFactoryLevel.value,
|
||||
naniteFactoryLevel.value
|
||||
)
|
||||
}
|
||||
return 0
|
||||
})
|
||||
|
||||
// 建筑/科技:等级范围
|
||||
const levelRange = computed(() => {
|
||||
if (props.type !== 'building' && props.type !== 'technology') return []
|
||||
const current = props.currentLevel || 0
|
||||
const levels = []
|
||||
for (let i = current; i <= current + 10; i++) {
|
||||
levels.push(i)
|
||||
}
|
||||
return levels
|
||||
})
|
||||
|
||||
// 建筑/科技:获取某个等级的数据
|
||||
const getLevelData = (level: number) => {
|
||||
if (level === 0) {
|
||||
return {
|
||||
cost: { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0 },
|
||||
time: 0,
|
||||
production: 0,
|
||||
consumption: 0,
|
||||
points: 0,
|
||||
capacity: 0,
|
||||
fleetStorage: 0,
|
||||
spaceBonus: 0,
|
||||
buildSpeedBonus: 0,
|
||||
researchSpeedBonus: 0
|
||||
}
|
||||
}
|
||||
|
||||
if (props.type === 'building') {
|
||||
const buildingType = props.itemType as BuildingType
|
||||
const cost = buildingLogic.calculateBuildingCost(buildingType, level)
|
||||
|
||||
// 使用实际的工厂等级和加成计算建造时间
|
||||
const time = buildingLogic.calculateBuildingTime(
|
||||
buildingType,
|
||||
level,
|
||||
activeBonuses.value.buildingSpeedBonus,
|
||||
roboticsFactoryLevel.value,
|
||||
naniteFactoryLevel.value
|
||||
)
|
||||
|
||||
let production = 0
|
||||
let consumption = 0
|
||||
let capacity = 0
|
||||
let fleetStorage = 0
|
||||
let spaceBonus = 0
|
||||
let buildSpeedBonus = 0
|
||||
let researchSpeedBonus = 0
|
||||
|
||||
// 应用资源产量加成
|
||||
const resourceBonus = 1 + (activeBonuses.value.resourceProductionBonus || 0) / 100
|
||||
const energyBonus = 1 + (activeBonuses.value.energyProductionBonus || 0) / 100
|
||||
const storageBonus = 1 + (activeBonuses.value.storageCapacityBonus || 0) / 100
|
||||
const baseCapacity = 10000
|
||||
|
||||
// Building calculation configuration
|
||||
const buildingCalculations: Record<string, (level: number) => Partial<{
|
||||
production: number
|
||||
consumption: number
|
||||
capacity: number
|
||||
fleetStorage: number
|
||||
spaceBonus: number
|
||||
buildSpeedBonus: number
|
||||
researchSpeedBonus: number
|
||||
}>> = {
|
||||
metalMine: (lvl) => ({
|
||||
production: Math.floor(1500 * lvl * Math.pow(1.5, lvl) * resourceBonus),
|
||||
consumption: Math.floor(10 * lvl * Math.pow(1.1, lvl))
|
||||
}),
|
||||
crystalMine: (lvl) => ({
|
||||
production: Math.floor(1000 * lvl * Math.pow(1.5, lvl) * resourceBonus),
|
||||
consumption: Math.floor(10 * lvl * Math.pow(1.1, lvl))
|
||||
}),
|
||||
deuteriumSynthesizer: (lvl) => ({
|
||||
production: Math.floor(500 * lvl * Math.pow(1.5, lvl) * resourceBonus),
|
||||
consumption: Math.floor(10 * lvl * Math.pow(1.1, lvl))
|
||||
}),
|
||||
solarPlant: (lvl) => ({
|
||||
production: Math.floor(50 * lvl * Math.pow(1.1, lvl) * energyBonus)
|
||||
}),
|
||||
metalStorage: (lvl) => ({
|
||||
capacity: Math.floor(baseCapacity * Math.pow(2, lvl) * storageBonus)
|
||||
}),
|
||||
crystalStorage: (lvl) => ({
|
||||
capacity: Math.floor(baseCapacity * Math.pow(2, lvl) * storageBonus)
|
||||
}),
|
||||
deuteriumTank: (lvl) => ({
|
||||
capacity: Math.floor(baseCapacity * Math.pow(2, lvl) * storageBonus)
|
||||
}),
|
||||
darkMatterCollector: (lvl) => ({
|
||||
capacity: 1000 + lvl * 100,
|
||||
production: Math.floor(25 * lvl * Math.pow(1.5, lvl))
|
||||
}),
|
||||
darkMatterTank: (lvl) => ({
|
||||
capacity: Math.floor(1000 * Math.pow(2, lvl) * storageBonus)
|
||||
}),
|
||||
fusionReactor: (lvl) => ({
|
||||
production: Math.floor(150 * lvl * Math.pow(1.15, lvl))
|
||||
}),
|
||||
shipyard: (lvl) => ({
|
||||
fleetStorage: 1000 * lvl
|
||||
}),
|
||||
hangar: (lvl) => ({
|
||||
fleetStorage: 500 * lvl
|
||||
}),
|
||||
terraformer: () => ({
|
||||
spaceBonus: 30
|
||||
}),
|
||||
lunarBase: () => ({
|
||||
spaceBonus: 30
|
||||
}),
|
||||
roboticsFactory: (lvl) => ({
|
||||
buildSpeedBonus: lvl
|
||||
}),
|
||||
naniteFactory: (lvl) => ({
|
||||
buildSpeedBonus: lvl * 2
|
||||
}),
|
||||
researchLab: (lvl) => ({
|
||||
researchSpeedBonus: lvl
|
||||
})
|
||||
}
|
||||
|
||||
// Apply calculations if configuration exists
|
||||
const calc = buildingCalculations[buildingType]
|
||||
if (calc) {
|
||||
const result = calc(level)
|
||||
production = result.production ?? production
|
||||
consumption = result.consumption ?? consumption
|
||||
capacity = result.capacity ?? capacity
|
||||
fleetStorage = result.fleetStorage ?? fleetStorage
|
||||
spaceBonus = result.spaceBonus ?? spaceBonus
|
||||
buildSpeedBonus = result.buildSpeedBonus ?? buildSpeedBonus
|
||||
researchSpeedBonus = result.researchSpeedBonus ?? researchSpeedBonus
|
||||
}
|
||||
|
||||
const points = pointsLogic.calculateBuildingPoints(buildingType, level - 1, level)
|
||||
return { cost, time, production, consumption, points, capacity, fleetStorage, spaceBonus, buildSpeedBonus, researchSpeedBonus }
|
||||
} else {
|
||||
const techType = props.itemType as TechnologyType
|
||||
const cost = researchLogic.calculateTechnologyCost(techType, level)
|
||||
|
||||
// 使用实际的研究所等级和加成计算研究时间
|
||||
const time = researchLogic.calculateTechnologyTime(
|
||||
techType,
|
||||
level - 1,
|
||||
activeBonuses.value.researchSpeedBonus,
|
||||
researchLabLevel.value
|
||||
)
|
||||
|
||||
let researchSpeedBonus = 0
|
||||
if (techType === 'energyTechnology') {
|
||||
researchSpeedBonus = level
|
||||
}
|
||||
|
||||
const points = pointsLogic.calculateTechnologyPoints(techType, level - 1, level)
|
||||
return {
|
||||
cost,
|
||||
time,
|
||||
production: 0,
|
||||
consumption: 0,
|
||||
points,
|
||||
capacity: 0,
|
||||
fleetStorage: 0,
|
||||
spaceBonus: 0,
|
||||
buildSpeedBonus: 0,
|
||||
researchSpeedBonus
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 建筑/科技:累积统计
|
||||
const totalStats = computed(() => {
|
||||
if (props.type !== 'building' && props.type !== 'technology') {
|
||||
return { metal: 0, crystal: 0, deuterium: 0, points: 0 }
|
||||
}
|
||||
|
||||
let metal = 0,
|
||||
crystal = 0,
|
||||
deuterium = 0,
|
||||
points = 0
|
||||
for (const level of levelRange.value) {
|
||||
if (level === 0) continue
|
||||
const data = getLevelData(level)
|
||||
metal += data.cost.metal
|
||||
crystal += data.cost.crystal
|
||||
deuterium += data.cost.deuterium
|
||||
points += data.points
|
||||
}
|
||||
return { metal, crystal, deuterium, points }
|
||||
})
|
||||
|
||||
// 舰船/防御:单位积分
|
||||
const pointsPerUnit = computed(() => {
|
||||
if (props.type === 'ship') return pointsLogic.calculateShipPoints(props.itemType as ShipType, 1)
|
||||
if (props.type === 'defense') return pointsLogic.calculateDefensePoints(props.itemType as DefenseType, 1)
|
||||
return 0
|
||||
})
|
||||
|
||||
// 舰船/防御:批量成本
|
||||
const batchCost = computed(() => ({
|
||||
metal: unitCost.value.metal * quantity.value,
|
||||
crystal: unitCost.value.crystal * quantity.value,
|
||||
deuterium: unitCost.value.deuterium * quantity.value
|
||||
}))
|
||||
|
||||
// 舰船/防御:批量积分
|
||||
const batchPoints = computed(() => {
|
||||
if (props.type === 'ship') return pointsLogic.calculateShipPoints(props.itemType as ShipType, quantity.value)
|
||||
if (props.type === 'defense') return pointsLogic.calculateDefensePoints(props.itemType as DefenseType, quantity.value)
|
||||
return 0
|
||||
})
|
||||
</script>
|
||||
248
src/components/NpcRelationCard.vue
Normal file
248
src/components/NpcRelationCard.vue
Normal file
@@ -0,0 +1,248 @@
|
||||
<template>
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex-1">
|
||||
<CardTitle class="flex items-center gap-2">
|
||||
{{ npc.name }}
|
||||
<Badge :variant="statusBadgeVariant">
|
||||
{{ statusText }}
|
||||
</Badge>
|
||||
</CardTitle>
|
||||
<CardDescription class="mt-1">
|
||||
{{ npc.planets.length }} {{ t('diplomacy.planets') }}
|
||||
<span v-if="npc.allies && npc.allies.length > 0" class="ml-2">· {{ npc.allies.length }} {{ t('diplomacy.allies') }}</span>
|
||||
</CardDescription>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-4">
|
||||
<!-- 好感度进度条 -->
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('diplomacy.reputation') }}</span>
|
||||
<span class="font-semibold" :class="reputationColor">{{ reputation > 0 ? '+' : '' }}{{ reputation }}</span>
|
||||
</div>
|
||||
<div class="relative">
|
||||
<!-- 背景进度条 -->
|
||||
<div class="h-2 bg-muted rounded-full overflow-hidden">
|
||||
<!-- 负值部分(左侧,红色) -->
|
||||
<div
|
||||
v-if="reputation < 0"
|
||||
class="h-full bg-red-500 dark:bg-red-600 absolute right-1/2"
|
||||
:style="{ width: `${Math.abs(reputation) / 2}%` }"
|
||||
/>
|
||||
<!-- 正值部分(右侧,绿色) -->
|
||||
<div
|
||||
v-if="reputation > 0"
|
||||
class="h-full bg-green-500 dark:bg-green-600 absolute left-1/2"
|
||||
:style="{ width: `${reputation / 2}%` }"
|
||||
/>
|
||||
</div>
|
||||
<!-- 中心线 -->
|
||||
<div class="absolute left-1/2 top-0 bottom-0 w-px bg-border" />
|
||||
</div>
|
||||
<div class="flex justify-between text-xs text-muted-foreground">
|
||||
<span>-100</span>
|
||||
<span>0</span>
|
||||
<span>+100</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 盟友信息 -->
|
||||
<div v-if="npc.allies && npc.allies.length > 0" class="pt-2 border-t">
|
||||
<p class="text-sm text-muted-foreground mb-2">{{ t('diplomacy.alliedWith') }}:</p>
|
||||
<div class="flex flex-wrap gap-1">
|
||||
<Badge
|
||||
v-for="allyId in npc.allies.slice(0, 3)"
|
||||
:key="allyId"
|
||||
variant="outline"
|
||||
class="text-xs cursor-pointer hover:bg-accent transition-colors"
|
||||
@click="scrollToAlly(allyId)"
|
||||
>
|
||||
{{ getAllyName(allyId) }}
|
||||
</Badge>
|
||||
<Badge v-if="npc.allies.length > 3" variant="outline" class="text-xs">
|
||||
+{{ npc.allies.length - 3 }} {{ t('diplomacy.more') }}
|
||||
</Badge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="flex gap-2 pt-2">
|
||||
<Button size="sm" variant="outline" class="flex-1" @click="handleGiftResources">
|
||||
<Gift class="h-4 w-4 mr-2" />
|
||||
{{ t('diplomacy.actions.gift') }}
|
||||
</Button>
|
||||
<Button size="sm" variant="outline" class="flex-1" @click="handleViewPlanets">
|
||||
<Globe class="h-4 w-4 mr-2" />
|
||||
{{ t('diplomacy.actions.viewPlanets') }}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<!-- 最近活动 -->
|
||||
<div v-if="recentEvent" class="pt-2 border-t">
|
||||
<p class="text-xs text-muted-foreground mb-1">{{ t('diplomacy.lastEvent') }}:</p>
|
||||
<div class="flex items-center gap-2 text-xs">
|
||||
<component :is="getEventIcon(recentEvent.reason)" class="h-3 w-3" />
|
||||
<span>{{ getEventText(recentEvent.reason) }}</span>
|
||||
<span class="text-muted-foreground">
|
||||
{{ formatRelativeTime((Date.now() - recentEvent.timestamp) / 1000, t) }}{{ t('diplomacy.ago') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useNPCStore } from '@/stores/npcStore'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Gift, Globe, Sword, Eye, Trash2 } from 'lucide-vue-next'
|
||||
import { RelationStatus, DiplomaticEventType } from '@/types/game'
|
||||
import type { DiplomaticRelation, NPC } from '@/types/game'
|
||||
import { formatRelativeTime } from '@/utils/format'
|
||||
|
||||
const props = defineProps<{
|
||||
npc: NPC
|
||||
relation?: DiplomaticRelation
|
||||
}>()
|
||||
|
||||
const router = useRouter()
|
||||
const npcStore = useNPCStore()
|
||||
const { t } = useI18n()
|
||||
|
||||
// 好感度值
|
||||
const reputation = computed(() => props.relation?.reputation || 0)
|
||||
|
||||
// 关系状态
|
||||
const status = computed(() => props.relation?.status || RelationStatus.Neutral)
|
||||
|
||||
// 关系状态文本
|
||||
const statusText = computed(() => {
|
||||
switch (status.value) {
|
||||
case RelationStatus.Friendly:
|
||||
return t('diplomacy.status.friendly')
|
||||
case RelationStatus.Hostile:
|
||||
return t('diplomacy.status.hostile')
|
||||
default:
|
||||
return t('diplomacy.status.neutral')
|
||||
}
|
||||
})
|
||||
|
||||
// 关系状态Badge样式
|
||||
const statusBadgeVariant = computed(() => {
|
||||
switch (status.value) {
|
||||
case RelationStatus.Friendly:
|
||||
return 'default'
|
||||
case RelationStatus.Hostile:
|
||||
return 'destructive'
|
||||
default:
|
||||
return 'secondary'
|
||||
}
|
||||
})
|
||||
|
||||
// 好感度颜色
|
||||
const reputationColor = computed(() => {
|
||||
if (reputation.value >= 20) return 'text-green-600 dark:text-green-400'
|
||||
if (reputation.value <= -20) return 'text-red-600 dark:text-red-400'
|
||||
return 'text-muted-foreground'
|
||||
})
|
||||
|
||||
// 最近的外交事件
|
||||
const recentEvent = computed(() => {
|
||||
if (!props.relation?.history || props.relation.history.length === 0) return null
|
||||
return props.relation.history[props.relation.history.length - 1]
|
||||
})
|
||||
|
||||
// 获取盟友名称
|
||||
const getAllyName = (allyId: string) => {
|
||||
const ally = npcStore.npcs.find(n => n.id === allyId)
|
||||
return ally?.name || allyId.substring(0, 8)
|
||||
}
|
||||
|
||||
// 获取事件图标
|
||||
const getEventIcon = (eventType: string) => {
|
||||
switch (eventType) {
|
||||
case DiplomaticEventType.GiftResources:
|
||||
return Gift
|
||||
case DiplomaticEventType.Attack:
|
||||
case DiplomaticEventType.AllyAttacked:
|
||||
return Sword
|
||||
case DiplomaticEventType.Spy:
|
||||
return Eye
|
||||
case DiplomaticEventType.StealDebris:
|
||||
return Trash2
|
||||
default:
|
||||
return Gift
|
||||
}
|
||||
}
|
||||
|
||||
// 获取事件文本
|
||||
const getEventText = (eventType: string) => {
|
||||
switch (eventType) {
|
||||
case DiplomaticEventType.GiftResources:
|
||||
return t('diplomacy.events.gift')
|
||||
case DiplomaticEventType.Attack:
|
||||
return t('diplomacy.events.attack')
|
||||
case DiplomaticEventType.AllyAttacked:
|
||||
return t('diplomacy.events.allyAttacked')
|
||||
case DiplomaticEventType.Spy:
|
||||
return t('diplomacy.events.spy')
|
||||
case DiplomaticEventType.StealDebris:
|
||||
return t('diplomacy.events.stealDebris')
|
||||
default:
|
||||
return eventType
|
||||
}
|
||||
}
|
||||
|
||||
// 赠送资源
|
||||
const handleGiftResources = () => {
|
||||
// 跳转到舰队页面,自动选择第一个NPC星球
|
||||
if (props.npc.planets.length > 0) {
|
||||
const targetPlanet = props.npc.planets[0]
|
||||
if (!targetPlanet) return
|
||||
|
||||
router.push({
|
||||
path: '/fleet',
|
||||
query: {
|
||||
galaxy: targetPlanet.position.galaxy,
|
||||
system: targetPlanet.position.system,
|
||||
position: targetPlanet.position.position,
|
||||
gift: '1'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 查看星球
|
||||
const handleViewPlanets = () => {
|
||||
// 跳转到星系视图,定位到第一个NPC星球,并传递NPC ID用于高亮
|
||||
if (props.npc.planets.length > 0) {
|
||||
const targetPlanet = props.npc.planets[0]
|
||||
if (!targetPlanet) return
|
||||
|
||||
router.push({
|
||||
path: '/galaxy',
|
||||
query: {
|
||||
galaxy: targetPlanet.position.galaxy,
|
||||
system: targetPlanet.position.system,
|
||||
highlightNpc: props.npc.id
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动到盟友卡片
|
||||
const scrollToAlly = (allyId: string) => {
|
||||
// 触发父组件的滚动事件
|
||||
// 通过emit通知父组件滚动到指定的NPC卡片
|
||||
const event = new CustomEvent('scrollToNpc', { detail: { npcId: allyId }, bubbles: true })
|
||||
document.dispatchEvent(event)
|
||||
}
|
||||
</script>
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<Popover>
|
||||
<PopoverTrigger as-child>
|
||||
<span class="cursor-pointer underline decoration-dotted underline-offset-4 touch-manipulation">{{ abbreviatedValue }}</span>
|
||||
<span class="cursor-pointer underline decoration-dotted underline-offset-4 touch-manipulation">{{ formatNumber(value, 1) }}</span>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-auto p-2" side="top" align="center">
|
||||
<p class="font-mono text-sm">{{ formattedValue }}</p>
|
||||
@@ -12,6 +12,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import { formatNumber } from '@/utils/format'
|
||||
|
||||
const props = defineProps<{
|
||||
value: number
|
||||
@@ -21,30 +22,4 @@
|
||||
const formattedValue = computed(() => {
|
||||
return props.value.toLocaleString()
|
||||
})
|
||||
|
||||
// 缩写格式的数字
|
||||
const abbreviatedValue = computed(() => {
|
||||
const num = props.value
|
||||
|
||||
// 小于1000直接显示
|
||||
if (num < 1000) {
|
||||
return num.toString()
|
||||
}
|
||||
|
||||
// 1000 - 999,999: 使用 K (千)
|
||||
if (num < 1000000) {
|
||||
const k = num / 1000
|
||||
return k % 1 === 0 ? `${k}K` : `${k.toFixed(1)}K`
|
||||
}
|
||||
|
||||
// 1,000,000 - 999,999,999: 使用 M (百万)
|
||||
if (num < 1000000000) {
|
||||
const m = num / 1000000
|
||||
return m % 1 === 0 ? `${m}M` : `${m.toFixed(1)}M`
|
||||
}
|
||||
|
||||
// 1,000,000,000+: 使用 B (十亿)
|
||||
const b = num / 1000000000
|
||||
return b % 1 === 0 ? `${b}B` : `${b.toFixed(1)}B`
|
||||
})
|
||||
</script>
|
||||
|
||||
166
src/components/QueueNotifications.vue
Normal file
166
src/components/QueueNotifications.vue
Normal file
@@ -0,0 +1,166 @@
|
||||
<template>
|
||||
<Popover v-model:open="isOpen">
|
||||
<PopoverTrigger as-child>
|
||||
<Button data-tutorial="queue-button" variant="outline" size="icon" class="relative">
|
||||
<ListOrdered class="h-4 w-4" />
|
||||
<Badge
|
||||
v-if="totalQueueCount > 0"
|
||||
variant="default"
|
||||
class="absolute -top-1 -right-1 h-5 w-5 p-0 flex items-center justify-center text-xs"
|
||||
>
|
||||
{{ totalQueueCount > 9 ? '9+' : totalQueueCount }}
|
||||
</Badge>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="w-96 p-0" align="end">
|
||||
<div class="flex items-center justify-between p-4 border-b">
|
||||
<h3 class="font-semibold">{{ t('queue.title') }}</h3>
|
||||
</div>
|
||||
<ScrollArea class="max-h-96">
|
||||
<div v-if="totalQueueCount === 0" class="p-8 text-center text-muted-foreground">
|
||||
{{ t('queue.empty') }}
|
||||
</div>
|
||||
<div v-else class="divide-y p-4 space-y-3">
|
||||
<!-- 建造队列 -->
|
||||
<div v-for="item in buildQueue" :key="item.id" class="space-y-1.5">
|
||||
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
||||
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
||||
<div
|
||||
class="h-2 w-2 rounded-full animate-pulse flex-shrink-0"
|
||||
:class="item.type === 'demolish' ? 'bg-destructive' : 'bg-green-500'"
|
||||
/>
|
||||
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
||||
<span class="text-muted-foreground text-[10px] sm:text-xs">
|
||||
<template v-if="item.type === 'ship' || item.type === 'defense'">
|
||||
→ {{ t('queue.quantity') }} {{ item.quantity }}
|
||||
</template>
|
||||
<template v-else-if="item.type === 'demolish'">→ {{ t('queue.demolishing') }}</template>
|
||||
<template v-else>→ {{ t('queue.level') }} {{ item.targetLevel }}</template>
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
||||
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
||||
{{ formatTime(getRemainingTime(item)) }}
|
||||
</span>
|
||||
<Button @click="handleCancel(item)" variant="ghost" size="sm" class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs">
|
||||
{{ t('queue.cancel') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
||||
</div>
|
||||
|
||||
<!-- 研究队列 -->
|
||||
<div v-for="item in researchQueue" :key="item.id" class="space-y-1.5">
|
||||
<div class="flex items-center justify-between text-xs sm:text-sm gap-2">
|
||||
<div class="flex items-center gap-1.5 sm:gap-2 min-w-0 flex-1">
|
||||
<div class="h-2 w-2 rounded-full bg-blue-500 animate-pulse flex-shrink-0" />
|
||||
<span class="font-medium truncate">{{ getItemName(item) }}</span>
|
||||
<span class="text-muted-foreground text-[10px] sm:text-xs">→ {{ t('queue.level') }} {{ item.targetLevel }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2 sm:gap-3 flex-shrink-0">
|
||||
<span class="text-muted-foreground text-[10px] sm:text-xs whitespace-nowrap">
|
||||
{{ formatTime(getRemainingTime(item)) }}
|
||||
</span>
|
||||
<Button
|
||||
@click="handleCancelResearch(item.id)"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
class="h-5 sm:h-6 px-1.5 sm:px-2 text-[10px] sm:text-xs"
|
||||
>
|
||||
{{ t('queue.cancel') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<Progress :model-value="getQueueProgress(item)" class="h-1.5" />
|
||||
</div>
|
||||
</div>
|
||||
</ScrollArea>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { ListOrdered } from 'lucide-vue-next'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import { ScrollArea } from '@/components/ui/scroll-area'
|
||||
import { Progress } from '@/components/ui/progress'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useGameConfig } from '@/composables/useGameConfig'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { formatTime } from '@/utils/format'
|
||||
import type { BuildQueueItem, BuildingType, ShipType, DefenseType, TechnologyType } from '@/types/game'
|
||||
|
||||
const { t } = useI18n()
|
||||
const gameStore = useGameStore()
|
||||
const { BUILDINGS, SHIPS, DEFENSES, TECHNOLOGIES } = useGameConfig()
|
||||
|
||||
const isOpen = ref(false)
|
||||
|
||||
// 获取当前星球的建造队列
|
||||
const buildQueue = computed(() => {
|
||||
return gameStore.currentPlanet?.buildQueue || []
|
||||
})
|
||||
|
||||
// 获取研究队列
|
||||
const researchQueue = computed(() => {
|
||||
return gameStore.player.researchQueue || []
|
||||
})
|
||||
|
||||
// 总队列数量
|
||||
const totalQueueCount = computed(() => {
|
||||
return buildQueue.value.length + researchQueue.value.length
|
||||
})
|
||||
|
||||
// 获取队列项名称
|
||||
const getItemName = (item: BuildQueueItem): string => {
|
||||
if (item.type === 'building' || item.type === 'demolish') {
|
||||
return BUILDINGS.value[item.itemType as BuildingType].name
|
||||
} else if (item.type === 'ship') {
|
||||
return SHIPS.value[item.itemType as ShipType].name
|
||||
} else if (item.type === 'defense') {
|
||||
return DEFENSES.value[item.itemType as DefenseType].name
|
||||
} else if (item.type === 'technology') {
|
||||
return TECHNOLOGIES.value[item.itemType as TechnologyType].name
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
// 获取剩余时间
|
||||
const getRemainingTime = (item: BuildQueueItem): number => {
|
||||
const now = Date.now()
|
||||
return Math.max(0, Math.floor((item.endTime - now) / 1000))
|
||||
}
|
||||
|
||||
// 获取队列进度
|
||||
const getQueueProgress = (item: BuildQueueItem): number => {
|
||||
const now = Date.now()
|
||||
const elapsed = now - item.startTime
|
||||
const total = item.endTime - item.startTime
|
||||
return Math.min(100, (elapsed / total) * 100)
|
||||
}
|
||||
|
||||
// 统一的取消处理
|
||||
const handleCancel = (item: BuildQueueItem) => {
|
||||
let eventName: string
|
||||
if (item.type === 'building' || item.type === 'ship' || item.type === 'defense' || item.type === 'demolish') {
|
||||
eventName = 'cancel-build'
|
||||
} else if (item.type === 'technology') {
|
||||
eventName = 'cancel-research'
|
||||
} else {
|
||||
return
|
||||
}
|
||||
|
||||
const event = new CustomEvent(eventName, { detail: item.id })
|
||||
window.dispatchEvent(event)
|
||||
}
|
||||
|
||||
// 取消研究
|
||||
const handleCancelResearch = (queueId: string) => {
|
||||
const event = new CustomEvent('cancel-research', { detail: queueId })
|
||||
window.dispatchEvent(event)
|
||||
}
|
||||
</script>
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<Dialog v-model:open="isOpen">
|
||||
<DialogContent class="max-w-2xl max-h-[90vh] overflow-y-auto">
|
||||
<ScrollableDialogContent container-class="sm:max-w-2xl max-h-[90vh]">
|
||||
<template #header>
|
||||
<DialogHeader>
|
||||
<DialogTitle class="flex items-center gap-2">
|
||||
<Eye class="h-5 w-5" />
|
||||
@@ -10,16 +11,17 @@
|
||||
{{ formatDate(report.timestamp) }}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
</template>
|
||||
|
||||
<div v-if="report" class="space-y-4">
|
||||
<!-- 目标星球信息 -->
|
||||
<div class="p-3 bg-muted rounded-lg">
|
||||
<p class="text-sm font-medium mb-2">{{ t('messagesView.targetPlanet') }}</p>
|
||||
<p v-if="targetPlanet" class="text-xs text-muted-foreground">
|
||||
{{ targetPlanet.name }} [{{ targetPlanet.position.galaxy }}:{{ targetPlanet.position.system }}:{{
|
||||
targetPlanet.position.position
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ report.targetPlanetName }} [{{ report.targetPosition.galaxy }}:{{ report.targetPosition.system }}:{{
|
||||
report.targetPosition.position
|
||||
}}]
|
||||
</p>
|
||||
<p v-else class="text-xs text-muted-foreground">{{ report.targetPlanetId }}</p>
|
||||
</div>
|
||||
|
||||
<!-- 资源 -->
|
||||
@@ -80,17 +82,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</ScrollableDialogContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, computed } from 'vue'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import { useUniverseStore } from '@/stores/universeStore'
|
||||
import { ref, watch } from 'vue'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { useGameConfig } from '@/composables/useGameConfig'
|
||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Dialog, ScrollableDialogContent, DialogDescription, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import ResourceIcon from '@/components/ResourceIcon.vue'
|
||||
import { formatNumber, formatDate } from '@/utils/format'
|
||||
import { Eye } from 'lucide-vue-next'
|
||||
@@ -105,23 +105,11 @@
|
||||
(e: 'update:open', value: boolean): void
|
||||
}>()
|
||||
|
||||
const gameStore = useGameStore()
|
||||
const universeStore = useUniverseStore()
|
||||
const { t } = useI18n()
|
||||
const { SHIPS, DEFENSES, BUILDINGS } = useGameConfig()
|
||||
|
||||
const isOpen = ref(props.open)
|
||||
|
||||
// 获取目标星球信息
|
||||
const targetPlanet = computed(() => {
|
||||
if (!props.report) return null
|
||||
// 先从玩家星球中查找
|
||||
const playerPlanet = gameStore.player.planets.find(p => p.id === props.report!.targetPlanetId)
|
||||
if (playerPlanet) return playerPlanet
|
||||
// 再从宇宙星球地图中查找
|
||||
return Object.values(universeStore.planets).find(p => p.id === props.report!.targetPlanetId)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.open,
|
||||
newValue => {
|
||||
|
||||
438
src/components/TutorialOverlay.vue
Normal file
438
src/components/TutorialOverlay.vue
Normal file
@@ -0,0 +1,438 @@
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div v-if="tutorialState.isActive && currentStep" class="tutorial-overlay">
|
||||
<!-- Dark overlay parts (4 rectangles around the highlight) -->
|
||||
<template v-if="highlightRect && currentStep.target">
|
||||
<!-- Top overlay -->
|
||||
<div
|
||||
class="tutorial-backdrop-part"
|
||||
:style="{
|
||||
top: '0',
|
||||
left: '0',
|
||||
width: '100%',
|
||||
height: `${highlightRect.top}px`
|
||||
}"
|
||||
/>
|
||||
<!-- Bottom overlay -->
|
||||
<div
|
||||
class="tutorial-backdrop-part"
|
||||
:style="{
|
||||
top: `${highlightRect.bottom}px`,
|
||||
left: '0',
|
||||
width: '100%',
|
||||
height: `calc(100% - ${highlightRect.bottom}px)`
|
||||
}"
|
||||
/>
|
||||
<!-- Left overlay -->
|
||||
<div
|
||||
class="tutorial-backdrop-part"
|
||||
:style="{
|
||||
top: `${highlightRect.top}px`,
|
||||
left: '0',
|
||||
width: `${highlightRect.left}px`,
|
||||
height: `${highlightRect.height}px`
|
||||
}"
|
||||
/>
|
||||
<!-- Right overlay -->
|
||||
<div
|
||||
class="tutorial-backdrop-part"
|
||||
:style="{
|
||||
top: `${highlightRect.top}px`,
|
||||
left: `${highlightRect.right}px`,
|
||||
width: `calc(100% - ${highlightRect.right}px)`,
|
||||
height: `${highlightRect.height}px`
|
||||
}"
|
||||
/>
|
||||
<!-- Highlight border -->
|
||||
<div
|
||||
class="tutorial-highlight-border"
|
||||
:style="{
|
||||
top: `${highlightRect.top}px`,
|
||||
left: `${highlightRect.left}px`,
|
||||
width: `${highlightRect.width}px`,
|
||||
height: `${highlightRect.height}px`
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<!-- Full overlay for center placement (no target) -->
|
||||
<div v-else class="tutorial-backdrop-full" />
|
||||
|
||||
<!-- Tutorial tooltip -->
|
||||
<div
|
||||
v-if="tooltipPosition"
|
||||
class="tutorial-tooltip"
|
||||
:class="`tutorial-tooltip-${currentStep.placement || 'center'}`"
|
||||
:style="{
|
||||
top: tooltipPosition.top,
|
||||
left: tooltipPosition.left,
|
||||
transform: tooltipPosition.transform
|
||||
}"
|
||||
>
|
||||
<Card class="tutorial-card">
|
||||
<CardHeader class="pb-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<CardTitle class="text-lg">{{ t(currentStep.title) }}</CardTitle>
|
||||
<Button v-if="currentStep.canSkip" variant="ghost" size="icon" class="h-6 w-6" @click="skipTutorial">
|
||||
<XIcon :size="16" />
|
||||
</Button>
|
||||
</div>
|
||||
<CardDescription class="text-sm mt-2">
|
||||
{{ t(currentStep.content) }}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent class="pt-0 space-y-3">
|
||||
<!-- Progress bar -->
|
||||
<div class="space-y-1">
|
||||
<div class="flex justify-between text-xs text-muted-foreground">
|
||||
<span>{{ t('tutorial.progress') }}</span>
|
||||
<span>{{ tutorialState.currentStepIndex + 1 }} / {{ totalSteps }}</span>
|
||||
</div>
|
||||
<div class="w-full bg-secondary rounded-full h-1.5">
|
||||
<div class="bg-primary h-1.5 rounded-full transition-all duration-300" :style="{ width: `${progress}%` }" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation buttons -->
|
||||
<div class="flex gap-2">
|
||||
<Button v-if="tutorialState.currentStepIndex > 0" variant="outline" size="sm" @click="previousStep">
|
||||
<ChevronLeftIcon :size="16" class="mr-1" />
|
||||
{{ t('tutorial.previous') }}
|
||||
</Button>
|
||||
|
||||
<Button v-if="!isLastStep" class="ml-auto" size="sm" @click="handleNext" :disabled="!canProceed">
|
||||
{{ t('tutorial.next') }}
|
||||
<ChevronRightIcon :size="16" class="ml-1" />
|
||||
</Button>
|
||||
|
||||
<Button v-else class="ml-auto" size="sm" @click="completeTutorial">
|
||||
{{ t('tutorial.completeButton') }}
|
||||
<CheckIcon :size="16" class="ml-1" />
|
||||
</Button>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch, onMounted, onUnmounted } from 'vue'
|
||||
import { useTutorial, getTutorialSteps } from '@/composables/useTutorial'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { XIcon, ChevronLeftIcon, ChevronRightIcon, CheckIcon } from 'lucide-vue-next'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { tutorialState, currentStep, progress, isLastStep, nextStep, previousStep, skipTutorial, completeTutorial } = useTutorial()
|
||||
|
||||
const highlightRect = ref<DOMRect | null>(null)
|
||||
const tooltipPosition = ref<{ top: string; left: string; transform: string } | null>(null)
|
||||
const totalSteps = computed(() => getTutorialSteps().length)
|
||||
const isMobile = ref(false)
|
||||
|
||||
// Check if current step can proceed
|
||||
const canProceed = computed(() => {
|
||||
if (!currentStep.value) return false
|
||||
|
||||
// 所有步骤都允许手动点击下一步
|
||||
return true
|
||||
})
|
||||
|
||||
// 检测是否为移动端
|
||||
const checkMobile = () => {
|
||||
isMobile.value = window.innerWidth < 768
|
||||
}
|
||||
|
||||
// Calculate highlight and tooltip positions
|
||||
const updatePositions = () => {
|
||||
if (!currentStep.value) {
|
||||
highlightRect.value = null
|
||||
tooltipPosition.value = null
|
||||
return
|
||||
}
|
||||
|
||||
// 检测移动端
|
||||
checkMobile()
|
||||
|
||||
// For center placement, no target element needed
|
||||
if (!currentStep.value.target || currentStep.value.placement === 'center') {
|
||||
highlightRect.value = null
|
||||
tooltipPosition.value = {
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)'
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Find target element
|
||||
const targetElement = document.querySelector(currentStep.value.target)
|
||||
if (!targetElement) {
|
||||
// Fallback to center if target not found
|
||||
highlightRect.value = null
|
||||
tooltipPosition.value = {
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)'
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Auto-scroll target element into view
|
||||
targetElement.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center',
|
||||
inline: 'center'
|
||||
})
|
||||
|
||||
// Get target element rect
|
||||
const rect = targetElement.getBoundingClientRect()
|
||||
const padding = currentStep.value.highlightPadding || 8
|
||||
|
||||
// Set highlight rect with padding
|
||||
highlightRect.value = new DOMRect(rect.left - padding, rect.top - padding, rect.width + padding * 2, rect.height + padding * 2)
|
||||
|
||||
// 获取视口尺寸
|
||||
const viewportWidth = window.innerWidth
|
||||
const viewportHeight = window.innerHeight
|
||||
|
||||
// 气泡的预估尺寸(根据视口大小响应式调整)
|
||||
const tooltipWidth = isMobile.value ? Math.min(viewportWidth - 32, 360) : 480
|
||||
const tooltipHeight = isMobile.value ? 280 : 300 // 预估高度
|
||||
|
||||
// 计算各个方向的可用空间
|
||||
const spaceTop = rect.top
|
||||
const spaceBottom = viewportHeight - rect.bottom
|
||||
const spaceLeft = rect.left
|
||||
const spaceRight = viewportWidth - rect.right
|
||||
|
||||
const tooltipOffset = isMobile.value ? 8 : 16 // 移动端使用更小的间距
|
||||
const edgeMargin = isMobile.value ? 8 : 16 // 距离边缘的最小距离
|
||||
|
||||
// 根据优先级和可用空间自动选择最佳位置
|
||||
let placement = currentStep.value.placement || 'bottom'
|
||||
let finalPosition: { top: string; left: string; transform: string }
|
||||
|
||||
// 移动端优先使用 bottom 或 top 位置
|
||||
if (isMobile.value) {
|
||||
// 移动端强制使用 top/bottom,忽略 left/right
|
||||
if (placement === 'left' || placement === 'right') {
|
||||
placement = spaceBottom > spaceTop ? 'bottom' : 'top'
|
||||
}
|
||||
}
|
||||
|
||||
// 智能位置选择:如果指定位置空间不足,自动调整
|
||||
const canFitTop = spaceTop >= tooltipHeight + tooltipOffset + edgeMargin
|
||||
const canFitBottom = spaceBottom >= tooltipHeight + tooltipOffset + edgeMargin
|
||||
const canFitLeft = spaceLeft >= tooltipWidth + tooltipOffset + edgeMargin
|
||||
const canFitRight = spaceRight >= tooltipWidth + tooltipOffset + edgeMargin
|
||||
|
||||
// 自动调整位置
|
||||
if (placement === 'top' && !canFitTop && canFitBottom) {
|
||||
placement = 'bottom'
|
||||
} else if (placement === 'bottom' && !canFitBottom && canFitTop) {
|
||||
placement = 'top'
|
||||
} else if (placement === 'left' && !canFitLeft && canFitRight) {
|
||||
placement = 'right'
|
||||
} else if (placement === 'right' && !canFitRight && canFitLeft) {
|
||||
placement = 'left'
|
||||
}
|
||||
|
||||
// 计算位置
|
||||
switch (placement) {
|
||||
case 'top': {
|
||||
let left = rect.left + rect.width / 2
|
||||
// 确保不超出左右边界
|
||||
left = Math.max(tooltipWidth / 2 + edgeMargin, Math.min(left, viewportWidth - tooltipWidth / 2 - edgeMargin))
|
||||
finalPosition = {
|
||||
top: `${Math.max(edgeMargin, rect.top - tooltipOffset)}px`,
|
||||
left: `${left}px`,
|
||||
transform: 'translate(-50%, -100%)'
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'bottom': {
|
||||
let left = rect.left + rect.width / 2
|
||||
// 确保不超出左右边界
|
||||
left = Math.max(tooltipWidth / 2 + edgeMargin, Math.min(left, viewportWidth - tooltipWidth / 2 - edgeMargin))
|
||||
finalPosition = {
|
||||
top: `${Math.min(viewportHeight - tooltipHeight - edgeMargin, rect.bottom + tooltipOffset)}px`,
|
||||
left: `${left}px`,
|
||||
transform: 'translate(-50%, 0)'
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'left': {
|
||||
let top = rect.top + rect.height / 2
|
||||
// 确保不超出上下边界
|
||||
top = Math.max(tooltipHeight / 2 + edgeMargin, Math.min(top, viewportHeight - tooltipHeight / 2 - edgeMargin))
|
||||
finalPosition = {
|
||||
top: `${top}px`,
|
||||
left: `${Math.max(edgeMargin, rect.left - tooltipOffset)}px`,
|
||||
transform: 'translate(-100%, -50%)'
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'right': {
|
||||
let top = rect.top + rect.height / 2
|
||||
// 确保不超出上下边界
|
||||
top = Math.max(tooltipHeight / 2 + edgeMargin, Math.min(top, viewportHeight - tooltipHeight / 2 - edgeMargin))
|
||||
finalPosition = {
|
||||
top: `${top}px`,
|
||||
left: `${Math.min(viewportWidth - tooltipWidth - edgeMargin, rect.right + tooltipOffset)}px`,
|
||||
transform: 'translate(0, -50%)'
|
||||
}
|
||||
break
|
||||
}
|
||||
default:
|
||||
finalPosition = {
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)'
|
||||
}
|
||||
}
|
||||
|
||||
tooltipPosition.value = finalPosition
|
||||
}
|
||||
|
||||
// Handle next step
|
||||
const handleNext = () => {
|
||||
if (canProceed.value) {
|
||||
nextStep()
|
||||
}
|
||||
}
|
||||
|
||||
// Update positions when step changes
|
||||
watch(
|
||||
() => currentStep.value,
|
||||
() => {
|
||||
// Wait for DOM update and route change
|
||||
setTimeout(() => {
|
||||
updatePositions()
|
||||
}, 100)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
// Update positions on window resize or scroll
|
||||
const handleResize = () => {
|
||||
checkMobile()
|
||||
updatePositions()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
checkMobile()
|
||||
window.addEventListener('resize', handleResize)
|
||||
window.addEventListener('scroll', handleResize, true)
|
||||
updatePositions()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', handleResize)
|
||||
window.removeEventListener('scroll', handleResize, true)
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tutorial-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 9999;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tutorial-backdrop-part {
|
||||
position: fixed;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
pointer-events: auto;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.tutorial-backdrop-full {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, 0.7);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.tutorial-highlight-border {
|
||||
position: fixed;
|
||||
background: transparent;
|
||||
border: 4px solid rgba(59, 130, 246, 0.5);
|
||||
border-radius: 8px;
|
||||
pointer-events: none;
|
||||
transition: all 0.3s ease;
|
||||
z-index: 10000;
|
||||
}
|
||||
|
||||
.tutorial-tooltip {
|
||||
position: fixed;
|
||||
z-index: 10001;
|
||||
pointer-events: auto;
|
||||
max-width: 480px;
|
||||
min-width: 320px;
|
||||
}
|
||||
|
||||
/* 移动端样式调整 */
|
||||
@media (max-width: 767px) {
|
||||
.tutorial-tooltip {
|
||||
max-width: calc(100vw - 32px);
|
||||
min-width: calc(100vw - 32px);
|
||||
width: calc(100vw - 32px);
|
||||
}
|
||||
|
||||
.tutorial-tooltip-center {
|
||||
max-width: calc(100vw - 32px);
|
||||
}
|
||||
|
||||
.tutorial-card {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.tutorial-highlight-border {
|
||||
border-width: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.tutorial-tooltip-center {
|
||||
max-width: 560px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.tutorial-tooltip-center {
|
||||
max-width: calc(100vw - 32px);
|
||||
}
|
||||
}
|
||||
|
||||
.tutorial-card {
|
||||
animation: tutorial-fade-in 0.3s ease;
|
||||
}
|
||||
|
||||
@keyframes tutorial-fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0.95);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dark mode adjustments */
|
||||
.dark .tutorial-backdrop-part {
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.dark .tutorial-backdrop-full {
|
||||
background: rgba(0, 0, 0, 0.85);
|
||||
}
|
||||
|
||||
.dark .tutorial-highlight-border {
|
||||
border-color: rgba(59, 130, 246, 0.6);
|
||||
}
|
||||
</style>
|
||||
120
src/components/UpdateDialog.vue
Normal file
120
src/components/UpdateDialog.vue
Normal file
@@ -0,0 +1,120 @@
|
||||
<template>
|
||||
<Dialog :open="open" @update:open="$emit('update:open', $event)">
|
||||
<DialogScrollContent class="max-w-2xl max-h-[80vh] flex flex-col">
|
||||
<DialogHeader class="flex-shrink-0">
|
||||
<DialogTitle>{{ t('settings.newVersionAvailable', { version: versionInfo?.version || '' }) }}</DialogTitle>
|
||||
<DialogDescription>{{ t('settings.updateAvailable') }}</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div class="flex-1 overflow-y-auto min-h-0 mt-4 pr-2">
|
||||
<div class="prose prose-sm dark:prose-invert max-w-none" v-html="renderedMarkdown" />
|
||||
</div>
|
||||
|
||||
<DialogFooter class="flex gap-2 flex-shrink-0 mt-4">
|
||||
<Button variant="outline" @click="$emit('update:open', false)">
|
||||
{{ t('common.cancel') }}
|
||||
</Button>
|
||||
<Button @click="handleDownload">
|
||||
<Download class="mr-2 h-4 w-4" />
|
||||
{{ t('settings.download') }}
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogScrollContent>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { marked } from 'marked'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import { Dialog, DialogScrollContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Download } from 'lucide-vue-next'
|
||||
import type { VersionInfo } from '@/utils/versionCheck'
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean
|
||||
versionInfo: VersionInfo | null
|
||||
}>()
|
||||
|
||||
defineEmits<{
|
||||
'update:open': [value: boolean]
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const renderedMarkdown = computed(() => {
|
||||
if (!props.versionInfo?.releaseNotes) return ''
|
||||
return marked(props.versionInfo.releaseNotes)
|
||||
})
|
||||
|
||||
const handleDownload = () => {
|
||||
if (props.versionInfo?.downloadUrl) {
|
||||
window.open(props.versionInfo.downloadUrl, '_blank')
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
:deep(.prose) {
|
||||
color: hsl(var(--foreground));
|
||||
}
|
||||
|
||||
:deep(.prose h1) {
|
||||
font-size: 1.5em;
|
||||
font-weight: 700;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
:deep(.prose h2) {
|
||||
font-size: 1.25em;
|
||||
font-weight: 600;
|
||||
margin-top: 0.8em;
|
||||
margin-bottom: 0.4em;
|
||||
}
|
||||
|
||||
:deep(.prose h3) {
|
||||
font-size: 1.1em;
|
||||
font-weight: 600;
|
||||
margin-top: 0.6em;
|
||||
margin-bottom: 0.3em;
|
||||
}
|
||||
|
||||
:deep(.prose p) {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
:deep(.prose ul) {
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
padding-left: 1.5em;
|
||||
}
|
||||
|
||||
:deep(.prose li) {
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 0.25em;
|
||||
}
|
||||
|
||||
:deep(.prose code) {
|
||||
background: hsl(var(--muted));
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 0.25rem;
|
||||
font-size: 0.875em;
|
||||
}
|
||||
|
||||
:deep(.prose pre) {
|
||||
background: hsl(var(--muted));
|
||||
padding: 1em;
|
||||
border-radius: 0.5rem;
|
||||
overflow-x: auto;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
:deep(.prose a) {
|
||||
color: hsl(var(--primary));
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
@@ -1,202 +0,0 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<!-- 建筑等级范围表格 -->
|
||||
<div class="border rounded-lg overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead class="w-20 text-center">{{ t('buildings.levelRange') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.metal') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.crystal') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.deuterium') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('buildings.buildTime') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('buildings.production') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('buildings.consumption') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('player.points') }}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow v-for="level in levelRange" :key="level" :class="{ 'bg-muted/50': level === currentLevel }">
|
||||
<TableCell class="text-center font-medium">
|
||||
<Badge v-if="level === currentLevel" variant="default">{{ level }}</Badge>
|
||||
<span v-else>{{ level }}</span>
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.metal" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.crystal" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.deuterium" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">{{ formatTime(getLevelData(level).buildTime) }}</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<span v-if="getLevelData(level).production > 0" class="text-green-600 dark:text-green-400">
|
||||
+
|
||||
<NumberWithTooltip :value="getLevelData(level).production" />
|
||||
/{{ t('resources.perHour') }}
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<span v-if="getLevelData(level).consumption > 0" class="text-red-600 dark:text-red-400">
|
||||
-
|
||||
<NumberWithTooltip :value="getLevelData(level).consumption" />
|
||||
</span>
|
||||
<span v-else>-</span>
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<span class="text-primary font-medium">
|
||||
+
|
||||
<NumberWithTooltip :value="getLevelData(level).points" />
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<!-- 累积统计 -->
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm">{{ t('buildings.totalCost') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-2">
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm">{{ t('buildings.totalPoints') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-3xl font-bold text-primary">
|
||||
<NumberWithTooltip :value="totalStats.points" />
|
||||
</div>
|
||||
<p class="text-xs text-muted-foreground mt-1">
|
||||
{{ t('buildings.levelRange') }}: {{ Math.max(0, currentLevel - 10) }} - {{ Math.min(currentLevel + 10, currentLevel + 10) }}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import type { BuildingType } from '@/types/game'
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import NumberWithTooltip from '@/components/NumberWithTooltip.vue'
|
||||
import * as buildingLogic from '@/logic/buildingLogic'
|
||||
import * as pointsLogic from '@/logic/pointsLogic'
|
||||
import { formatTime } from '@/utils/format'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
buildingType: BuildingType
|
||||
currentLevel: number
|
||||
}>()
|
||||
|
||||
// 等级范围:当前等级 +10
|
||||
const levelRange = computed(() => {
|
||||
const end = props.currentLevel + 10
|
||||
const levels = []
|
||||
for (let i = props.currentLevel; i <= end; i++) {
|
||||
levels.push(i)
|
||||
}
|
||||
return levels
|
||||
})
|
||||
|
||||
// 获取某个等级的详细数据
|
||||
const getLevelData = (level: number) => {
|
||||
if (level === 0) {
|
||||
return {
|
||||
cost: { metal: 0, crystal: 0, deuterium: 0 },
|
||||
buildTime: 0,
|
||||
production: 0,
|
||||
consumption: 0,
|
||||
points: 0
|
||||
}
|
||||
}
|
||||
|
||||
const cost = buildingLogic.calculateBuildingCost(props.buildingType, level)
|
||||
const buildTime = buildingLogic.calculateBuildingTime(props.buildingType, level)
|
||||
|
||||
// 计算产量和消耗
|
||||
let production = 0
|
||||
let consumption = 0
|
||||
|
||||
// 资源矿产量(与 resourceLogic.ts 保持一致)
|
||||
if (props.buildingType === 'metalMine') {
|
||||
production = Math.floor(1500 * level * Math.pow(1.5, level))
|
||||
} else if (props.buildingType === 'crystalMine') {
|
||||
production = Math.floor(1000 * level * Math.pow(1.5, level))
|
||||
} else if (props.buildingType === 'deuteriumSynthesizer') {
|
||||
production = Math.floor(500 * level * Math.pow(1.5, level))
|
||||
}
|
||||
|
||||
// 能量产出(与 resourceLogic.ts 保持一致)
|
||||
if (props.buildingType === 'solarPlant') {
|
||||
production = Math.floor(50 * level * Math.pow(1.1, level))
|
||||
}
|
||||
|
||||
// 能量消耗(矿场和合成器)
|
||||
if (['metalMine', 'crystalMine', 'deuteriumSynthesizer'].includes(props.buildingType)) {
|
||||
consumption = Math.floor(10 * level * Math.pow(1.1, level))
|
||||
}
|
||||
|
||||
// 计算积分
|
||||
const points = pointsLogic.calculateBuildingPoints(props.buildingType, level - 1, level)
|
||||
|
||||
return {
|
||||
cost,
|
||||
buildTime,
|
||||
production,
|
||||
consumption,
|
||||
points
|
||||
}
|
||||
}
|
||||
|
||||
// 累积统计
|
||||
const totalStats = computed(() => {
|
||||
let metal = 0
|
||||
let crystal = 0
|
||||
let deuterium = 0
|
||||
let points = 0
|
||||
|
||||
for (const level of levelRange.value) {
|
||||
if (level === 0) continue
|
||||
const data = getLevelData(level)
|
||||
metal += data.cost.metal
|
||||
crystal += data.cost.crystal
|
||||
deuterium += data.cost.deuterium
|
||||
points += data.points
|
||||
}
|
||||
|
||||
return { metal, crystal, deuterium, points }
|
||||
})
|
||||
</script>
|
||||
@@ -1,179 +0,0 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<!-- 防御基础信息 -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Sword class="h-4 w-4" />
|
||||
{{ t('defense.attack') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.attack" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Shield class="h-4 w-4" />
|
||||
{{ t('defense.shield') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.shield" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<ShieldCheck class="h-4 w-4" />
|
||||
{{ t('defense.armor') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.armor" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 建造成本和时间 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t('defense.buildCost') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-2">
|
||||
<div v-if="config.cost.metal > 0" class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="config.cost.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="config.cost.crystal > 0" class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="config.cost.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="config.cost.deuterium > 0" class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="config.cost.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm pt-2 border-t">
|
||||
<span class="text-muted-foreground">{{ t('player.points') }}:</span>
|
||||
<span class="font-bold text-primary">
|
||||
<NumberWithTooltip :value="pointsPerUnit" />
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t('defense.buildTime') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-3xl font-bold">{{ formatTime(config.buildTime) }}</div>
|
||||
<p class="text-xs text-muted-foreground mt-2">{{ t('defense.perUnit') }}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 批量建造计算器 -->
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t('defense.batchCalculator') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<Label class="w-20">{{ t('defense.quantity') }}:</Label>
|
||||
<Input v-model.number="quantity" type="number" min="1" class="flex-1" />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4 pt-4 border-t">
|
||||
<div class="space-y-2">
|
||||
<p class="text-sm text-muted-foreground">{{ t('defense.totalCost') }}:</p>
|
||||
<div class="space-y-1 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<p class="text-sm text-muted-foreground">{{ t('defense.totalTime') }}:</p>
|
||||
<div class="text-xl font-bold">{{ formatTime(config.buildTime * quantity) }}</div>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ t('player.points') }}: +
|
||||
<NumberWithTooltip :value="batchPoints" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import type { DefenseType } from '@/types/game'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import NumberWithTooltip from '@/components/NumberWithTooltip.vue'
|
||||
import { Sword, Shield, ShieldCheck } from 'lucide-vue-next'
|
||||
import * as pointsLogic from '@/logic/pointsLogic'
|
||||
import { DEFENSES } from '@/config/gameConfig'
|
||||
import { formatTime } from '@/utils/format'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
defenseType: DefenseType
|
||||
}>()
|
||||
|
||||
const config = computed(() => DEFENSES[props.defenseType])
|
||||
const quantity = ref(1)
|
||||
|
||||
// 单个防御的积分
|
||||
const pointsPerUnit = computed(() => {
|
||||
return pointsLogic.calculateDefensePoints(props.defenseType, 1)
|
||||
})
|
||||
|
||||
// 批量建造成本
|
||||
const batchCost = computed(() => ({
|
||||
metal: config.value.cost.metal * quantity.value,
|
||||
crystal: config.value.cost.crystal * quantity.value,
|
||||
deuterium: config.value.cost.deuterium * quantity.value
|
||||
}))
|
||||
|
||||
// 批量建造积分
|
||||
const batchPoints = computed(() => {
|
||||
return pointsLogic.calculateDefensePoints(props.defenseType, quantity.value)
|
||||
})
|
||||
</script>
|
||||
@@ -1,221 +0,0 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<!-- 舰船基础信息 -->
|
||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Sword class="h-4 w-4" />
|
||||
{{ t('shipyard.attack') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.attack" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Shield class="h-4 w-4" />
|
||||
{{ t('shipyard.shield') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.shield" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<ShieldCheck class="h-4 w-4" />
|
||||
{{ t('shipyard.armor') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.armor" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Zap class="h-4 w-4" />
|
||||
{{ t('shipyard.speed') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.speed" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Package class="h-4 w-4" />
|
||||
{{ t('shipyard.cargoCapacity') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.cargoCapacity" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm flex items-center gap-2">
|
||||
<Fuel class="h-4 w-4" />
|
||||
{{ t('shipyard.fuelConsumption') }}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-2xl font-bold">
|
||||
<NumberWithTooltip :value="config.fuelConsumption" />
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 建造成本和时间 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t('shipyard.buildCost') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-2">
|
||||
<div v-if="config.cost.metal > 0" class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="config.cost.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="config.cost.crystal > 0" class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="config.cost.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="config.cost.deuterium > 0" class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="config.cost.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm pt-2 border-t">
|
||||
<span class="text-muted-foreground">{{ t('player.points') }}:</span>
|
||||
<span class="font-bold text-primary">
|
||||
<NumberWithTooltip :value="pointsPerUnit" />
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t('shipyard.buildTime') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-3xl font-bold">{{ formatTime(config.buildTime) }}</div>
|
||||
<p class="text-xs text-muted-foreground mt-2">{{ t('shipyard.perUnit') }}</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
<!-- 批量建造计算器 -->
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle class="text-sm">{{ t('shipyard.batchCalculator') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-4">
|
||||
<div class="flex items-center gap-4">
|
||||
<Label class="w-20">{{ t('shipyard.quantity') }}:</Label>
|
||||
<Input v-model.number="quantity" type="number" min="1" class="flex-1" />
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-4 pt-4 border-t">
|
||||
<div class="space-y-2">
|
||||
<p class="text-sm text-muted-foreground">{{ t('shipyard.totalCost') }}:</p>
|
||||
<div class="space-y-1 text-sm">
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex justify-between">
|
||||
<span>{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="batchCost.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<p class="text-sm text-muted-foreground">{{ t('shipyard.totalTime') }}:</p>
|
||||
<div class="text-xl font-bold">{{ formatTime(config.buildTime * quantity) }}</div>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
{{ t('player.points') }}: +
|
||||
<NumberWithTooltip :value="batchPoints" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import type { ShipType } from '@/types/game'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import NumberWithTooltip from '@/components/NumberWithTooltip.vue'
|
||||
import { Sword, Shield, ShieldCheck, Zap, Package, Fuel } from 'lucide-vue-next'
|
||||
import * as pointsLogic from '@/logic/pointsLogic'
|
||||
import { SHIPS } from '@/config/gameConfig'
|
||||
import { formatTime } from '@/utils/format'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
shipType: ShipType
|
||||
}>()
|
||||
|
||||
const config = computed(() => SHIPS[props.shipType])
|
||||
const quantity = ref(1)
|
||||
|
||||
// 单艘舰船的积分
|
||||
const pointsPerUnit = computed(() => {
|
||||
return pointsLogic.calculateShipPoints(props.shipType, 1)
|
||||
})
|
||||
|
||||
// 批量建造成本
|
||||
const batchCost = computed(() => ({
|
||||
metal: config.value.cost.metal * quantity.value,
|
||||
crystal: config.value.cost.crystal * quantity.value,
|
||||
deuterium: config.value.cost.deuterium * quantity.value
|
||||
}))
|
||||
|
||||
// 批量建造积分
|
||||
const batchPoints = computed(() => {
|
||||
return pointsLogic.calculateShipPoints(props.shipType, quantity.value)
|
||||
})
|
||||
</script>
|
||||
@@ -1,158 +0,0 @@
|
||||
<template>
|
||||
<div class="space-y-4">
|
||||
<!-- 科技等级范围表格 -->
|
||||
<div class="border rounded-lg overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead class="w-20 text-center">{{ t('research.levelRange') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.metal') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.crystal') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('resources.deuterium') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('research.researchTime') }}</TableHead>
|
||||
<TableHead class="text-center">{{ t('player.points') }}</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
<TableRow v-for="level in levelRange" :key="level" :class="{ 'bg-muted/50': level === currentLevel }">
|
||||
<TableCell class="text-center font-medium">
|
||||
<Badge v-if="level === currentLevel" variant="default">{{ level }}</Badge>
|
||||
<span v-else>{{ level }}</span>
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.metal" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.crystal" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<NumberWithTooltip :value="getLevelData(level).cost.deuterium" />
|
||||
</TableCell>
|
||||
<TableCell class="text-center text-sm">{{ formatTime(getLevelData(level).researchTime) }}</TableCell>
|
||||
<TableCell class="text-center text-sm">
|
||||
<span class="text-primary font-medium">
|
||||
+
|
||||
<NumberWithTooltip :value="getLevelData(level).points" />
|
||||
</span>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
<!-- 累积统计 -->
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm">{{ t('research.totalCost') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent class="space-y-2">
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.metal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.metal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.crystal') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.crystal" />
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center justify-between text-sm">
|
||||
<span class="text-muted-foreground">{{ t('resources.deuterium') }}:</span>
|
||||
<span class="font-medium">
|
||||
<NumberWithTooltip :value="totalStats.deuterium" />
|
||||
</span>
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
<Card>
|
||||
<CardHeader class="pb-3">
|
||||
<CardTitle class="text-sm">{{ t('research.totalPoints') }}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div class="text-3xl font-bold text-primary">
|
||||
<NumberWithTooltip :value="totalStats.points" />
|
||||
</div>
|
||||
<p class="text-xs text-muted-foreground mt-1">
|
||||
{{ t('research.levelRange') }}: {{ Math.max(0, currentLevel - 10) }} - {{ Math.min(currentLevel + 10, currentLevel + 10) }}
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '@/composables/useI18n'
|
||||
import type { TechnologyType } from '@/types/game'
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'
|
||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import NumberWithTooltip from '@/components/NumberWithTooltip.vue'
|
||||
import * as researchLogic from '@/logic/researchLogic'
|
||||
import * as pointsLogic from '@/logic/pointsLogic'
|
||||
import { formatTime } from '@/utils/format'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
technologyType: TechnologyType
|
||||
currentLevel: number
|
||||
}>()
|
||||
|
||||
// 等级范围:当前等级 +10
|
||||
const levelRange = computed(() => {
|
||||
const end = props.currentLevel + 10
|
||||
const levels = []
|
||||
for (let i = props.currentLevel; i <= end; i++) {
|
||||
levels.push(i)
|
||||
}
|
||||
return levels
|
||||
})
|
||||
|
||||
// 获取某个等级的详细数据
|
||||
const getLevelData = (level: number) => {
|
||||
if (level === 0) {
|
||||
return {
|
||||
cost: { metal: 0, crystal: 0, deuterium: 0 },
|
||||
researchTime: 0,
|
||||
points: 0
|
||||
}
|
||||
}
|
||||
|
||||
const cost = researchLogic.calculateTechnologyCost(props.technologyType, level)
|
||||
const researchTime = researchLogic.calculateTechnologyTime(props.technologyType, level - 1)
|
||||
|
||||
// 计算积分
|
||||
const points = pointsLogic.calculateTechnologyPoints(props.technologyType, level - 1, level)
|
||||
|
||||
return {
|
||||
cost,
|
||||
researchTime,
|
||||
points
|
||||
}
|
||||
}
|
||||
|
||||
// 累积统计
|
||||
const totalStats = computed(() => {
|
||||
let metal = 0
|
||||
let crystal = 0
|
||||
let deuterium = 0
|
||||
let points = 0
|
||||
|
||||
for (const level of levelRange.value) {
|
||||
if (level === 0) continue
|
||||
const data = getLevelData(level)
|
||||
metal += data.cost.metal
|
||||
crystal += data.cost.crystal
|
||||
deuterium += data.cost.deuterium
|
||||
points += data.points
|
||||
}
|
||||
|
||||
return { metal, crystal, deuterium, points }
|
||||
})
|
||||
</script>
|
||||
@@ -4,7 +4,7 @@ import { cva } from 'class-variance-authority'
|
||||
export { default as Badge } from './Badge.vue'
|
||||
|
||||
export const badgeVariants = cva(
|
||||
'inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
|
||||
'inline-flex items-center justify-center rounded-sm border h-5 min-w-5 px-1 text-xs font-medium tabular-nums select-none w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PrimitiveProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '.'
|
||||
import { Primitive } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { buttonVariants } from '.'
|
||||
import type { PrimitiveProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '.'
|
||||
import { Primitive } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { buttonVariants } from '.'
|
||||
|
||||
interface Props extends PrimitiveProps {
|
||||
interface Props extends PrimitiveProps {
|
||||
variant?: ButtonVariants['variant']
|
||||
size?: ButtonVariants['size']
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
as: 'button'
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
35
src/components/ui/checkbox/Checkbox.vue
Normal file
35
src/components/ui/checkbox/Checkbox.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<CheckboxRoot
|
||||
v-slot="slotProps"
|
||||
data-slot="checkbox"
|
||||
v-bind="forwarded"
|
||||
:class="
|
||||
cn(
|
||||
'peer border-input data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground data-[state=checked]:border-primary focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive size-4 shrink-0 rounded-[4px] border shadow-xs transition-shadow outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<CheckboxIndicator data-slot="checkbox-indicator" class="grid place-content-center text-current transition-none">
|
||||
<slot v-bind="slotProps">
|
||||
<Check class="size-3.5" />
|
||||
</slot>
|
||||
</CheckboxIndicator>
|
||||
</CheckboxRoot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { CheckboxRootEmits, CheckboxRootProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { Check } from 'lucide-vue-next'
|
||||
import { CheckboxIndicator, CheckboxRoot, useForwardPropsEmits } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<CheckboxRootProps & { class?: HTMLAttributes['class'] }>()
|
||||
const emits = defineEmits<CheckboxRootEmits>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
1
src/components/ui/checkbox/index.ts
Normal file
1
src/components/ui/checkbox/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default as Checkbox } from './Checkbox.vue'
|
||||
@@ -6,7 +6,7 @@
|
||||
v-bind="{ ...$attrs, ...forwarded }"
|
||||
:class="
|
||||
cn(
|
||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-lg',
|
||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 sm:max-w-2xl',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
|
||||
71
src/components/ui/dialog/ScrollableDialogContent.vue
Normal file
71
src/components/ui/dialog/ScrollableDialogContent.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<DialogPortal>
|
||||
<DialogOverlay />
|
||||
<DialogContent
|
||||
data-slot="scrollable-dialog-content"
|
||||
v-bind="{ ...$attrs, ...forwarded }"
|
||||
:class="
|
||||
cn(
|
||||
'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 fixed top-[50%] left-[50%] z-50 w-[calc(100vw-3rem)] translate-x-[-50%] translate-y-[-50%] rounded-lg border shadow-lg duration-200 sm:w-auto sm:min-w-[764px] flex flex-col p-0',
|
||||
containerClass
|
||||
)
|
||||
"
|
||||
>
|
||||
<!-- 固定的头部 -->
|
||||
<div class="shrink-0 px-4 pt-4 pb-3 sm:px-6 sm:pt-6 sm:pb-4 border-b">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
|
||||
<!-- 可滚动的内容区域 -->
|
||||
<div class="overflow-y-auto px-4 py-3 sm:px-6 sm:py-4">
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<!-- 可选的固定底部 -->
|
||||
<div v-if="$slots.footer" class="shrink-0 px-4 pb-4 pt-3 sm:px-6 sm:pb-6 sm:pt-4 border-t">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
|
||||
<!-- 关闭按钮 -->
|
||||
<DialogClose
|
||||
v-if="showCloseButton"
|
||||
data-slot="dialog-close"
|
||||
class="ring-offset-background focus:ring-ring data-[state=open]:bg-accent data-[state=open]:text-muted-foreground absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 z-10"
|
||||
>
|
||||
<X />
|
||||
<span class="sr-only">Close</span>
|
||||
</DialogClose>
|
||||
</DialogContent>
|
||||
</DialogPortal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { DialogContentEmits, DialogContentProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { X } from 'lucide-vue-next'
|
||||
import { DialogClose, DialogContent, DialogPortal, useForwardPropsEmits } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import DialogOverlay from './DialogOverlay.vue'
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false
|
||||
})
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
DialogContentProps & {
|
||||
containerClass?: HTMLAttributes['class']
|
||||
showCloseButton?: boolean
|
||||
}
|
||||
>(),
|
||||
{
|
||||
showCloseButton: true
|
||||
}
|
||||
)
|
||||
const emits = defineEmits<DialogContentEmits>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'containerClass')
|
||||
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
@@ -6,5 +6,6 @@ export { default as DialogFooter } from './DialogFooter.vue'
|
||||
export { default as DialogHeader } from './DialogHeader.vue'
|
||||
export { default as DialogOverlay } from './DialogOverlay.vue'
|
||||
export { default as DialogScrollContent } from './DialogScrollContent.vue'
|
||||
export { default as ScrollableDialogContent } from './ScrollableDialogContent.vue'
|
||||
export { default as DialogTitle } from './DialogTitle.vue'
|
||||
export { default as DialogTrigger } from './DialogTrigger.vue'
|
||||
|
||||
22
src/components/ui/empty/Empty.vue
Normal file
22
src/components/ui/empty/Empty.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<div
|
||||
data-slot="empty"
|
||||
:class="
|
||||
cn(
|
||||
'flex min-w-0 flex-1 flex-col items-center justify-center gap-6 text-balance rounded-lg border-dashed p-6 text-center md:p-12',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
14
src/components/ui/empty/EmptyContent.vue
Normal file
14
src/components/ui/empty/EmptyContent.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div data-slot="empty-content" :class="cn('flex w-full min-w-0 max-w-sm flex-col items-center gap-4 text-balance text-sm', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
19
src/components/ui/empty/EmptyDescription.vue
Normal file
19
src/components/ui/empty/EmptyDescription.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<p
|
||||
data-slot="empty-description"
|
||||
:class="
|
||||
cn('text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4', $attrs.class ?? '')
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
14
src/components/ui/empty/EmptyHeader.vue
Normal file
14
src/components/ui/empty/EmptyHeader.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div data-slot="empty-header" :class="cn('flex max-w-sm flex-col items-center gap-2 text-center', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
17
src/components/ui/empty/EmptyMedia.vue
Normal file
17
src/components/ui/empty/EmptyMedia.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div data-slot="empty-icon" :data-variant="variant" :class="cn(emptyMediaVariants({ variant }), props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { EmptyMediaVariants } from '.'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { emptyMediaVariants } from '.'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
variant?: EmptyMediaVariants['variant']
|
||||
}>()
|
||||
</script>
|
||||
14
src/components/ui/empty/EmptyTitle.vue
Normal file
14
src/components/ui/empty/EmptyTitle.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<div data-slot="empty-title" :class="cn('text-lg font-medium tracking-tight', props.class)">
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
</script>
|
||||
23
src/components/ui/empty/index.ts
Normal file
23
src/components/ui/empty/index.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import { cva } from 'class-variance-authority'
|
||||
|
||||
export { default as Empty } from './Empty.vue'
|
||||
export { default as EmptyContent } from './EmptyContent.vue'
|
||||
export { default as EmptyDescription } from './EmptyDescription.vue'
|
||||
export { default as EmptyHeader } from './EmptyHeader.vue'
|
||||
export { default as EmptyMedia } from './EmptyMedia.vue'
|
||||
export { default as EmptyTitle } from './EmptyTitle.vue'
|
||||
|
||||
export const emptyMediaVariants = cva('mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0', {
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-transparent',
|
||||
icon: "bg-muted text-foreground flex size-10 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-6"
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default'
|
||||
}
|
||||
})
|
||||
|
||||
export type EmptyMediaVariants = VariantProps<typeof emptyMediaVariants>
|
||||
28
src/components/ui/pagination/Pagination.vue
Normal file
28
src/components/ui/pagination/Pagination.vue
Normal file
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<PaginationRoot
|
||||
v-slot="slotProps"
|
||||
data-slot="pagination"
|
||||
v-bind="forwarded"
|
||||
:class="cn('mx-auto flex w-full justify-center', props.class)"
|
||||
>
|
||||
<slot v-bind="slotProps" />
|
||||
</PaginationRoot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationRootEmits, PaginationRootProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { PaginationRoot, useForwardPropsEmits } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<
|
||||
PaginationRootProps & {
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
>()
|
||||
const emits = defineEmits<PaginationRootEmits>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
22
src/components/ui/pagination/PaginationContent.vue
Normal file
22
src/components/ui/pagination/PaginationContent.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
<template>
|
||||
<PaginationList
|
||||
v-slot="slotProps"
|
||||
data-slot="pagination-content"
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('flex flex-row items-center gap-1', props.class)"
|
||||
>
|
||||
<slot v-bind="slotProps" />
|
||||
</PaginationList>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationListProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { PaginationList } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<PaginationListProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
25
src/components/ui/pagination/PaginationEllipsis.vue
Normal file
25
src/components/ui/pagination/PaginationEllipsis.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<PaginationEllipsis
|
||||
data-slot="pagination-ellipsis"
|
||||
v-bind="delegatedProps"
|
||||
:class="cn('flex size-9 items-center justify-center', props.class)"
|
||||
>
|
||||
<slot>
|
||||
<MoreHorizontal class="size-4" />
|
||||
<span class="sr-only">More pages</span>
|
||||
</slot>
|
||||
</PaginationEllipsis>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationEllipsisProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { MoreHorizontal } from 'lucide-vue-next'
|
||||
import { PaginationEllipsis } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<PaginationEllipsisProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
38
src/components/ui/pagination/PaginationFirst.vue
Normal file
38
src/components/ui/pagination/PaginationFirst.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<PaginationFirst
|
||||
data-slot="pagination-first"
|
||||
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||
v-bind="forwarded"
|
||||
>
|
||||
<slot>
|
||||
<ChevronLeftIcon />
|
||||
<span class="hidden sm:block">First</span>
|
||||
</slot>
|
||||
</PaginationFirst>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationFirstProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '@/components/ui/button'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { ChevronLeftIcon } from 'lucide-vue-next'
|
||||
import { PaginationFirst, useForwardProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
PaginationFirstProps & {
|
||||
size?: ButtonVariants['size']
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
>(),
|
||||
{
|
||||
size: 'default'
|
||||
}
|
||||
)
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size')
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
</script>
|
||||
42
src/components/ui/pagination/PaginationItem.vue
Normal file
42
src/components/ui/pagination/PaginationItem.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<PaginationListItem
|
||||
data-slot="pagination-item"
|
||||
v-bind="delegatedProps"
|
||||
:class="
|
||||
cn(
|
||||
buttonVariants({
|
||||
variant: isActive ? 'outline' : 'ghost',
|
||||
size
|
||||
}),
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</PaginationListItem>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationListItemProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '@/components/ui/button'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { PaginationListItem } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
PaginationListItemProps & {
|
||||
size?: ButtonVariants['size']
|
||||
class?: HTMLAttributes['class']
|
||||
isActive?: boolean
|
||||
}
|
||||
>(),
|
||||
{
|
||||
size: 'icon'
|
||||
}
|
||||
)
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size', 'isActive')
|
||||
</script>
|
||||
38
src/components/ui/pagination/PaginationLast.vue
Normal file
38
src/components/ui/pagination/PaginationLast.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<PaginationLast
|
||||
data-slot="pagination-last"
|
||||
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||
v-bind="forwarded"
|
||||
>
|
||||
<slot>
|
||||
<span class="hidden sm:block">Last</span>
|
||||
<ChevronRightIcon />
|
||||
</slot>
|
||||
</PaginationLast>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationLastProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '@/components/ui/button'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { ChevronRightIcon } from 'lucide-vue-next'
|
||||
import { PaginationLast, useForwardProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
PaginationLastProps & {
|
||||
size?: ButtonVariants['size']
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
>(),
|
||||
{
|
||||
size: 'default'
|
||||
}
|
||||
)
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size')
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
</script>
|
||||
38
src/components/ui/pagination/PaginationNext.vue
Normal file
38
src/components/ui/pagination/PaginationNext.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<PaginationNext
|
||||
data-slot="pagination-next"
|
||||
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||
v-bind="forwarded"
|
||||
>
|
||||
<slot>
|
||||
<span class="hidden sm:block">Next</span>
|
||||
<ChevronRightIcon />
|
||||
</slot>
|
||||
</PaginationNext>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationNextProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '@/components/ui/button'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { ChevronRightIcon } from 'lucide-vue-next'
|
||||
import { PaginationNext, useForwardProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
PaginationNextProps & {
|
||||
size?: ButtonVariants['size']
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
>(),
|
||||
{
|
||||
size: 'default'
|
||||
}
|
||||
)
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size')
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
</script>
|
||||
38
src/components/ui/pagination/PaginationPrevious.vue
Normal file
38
src/components/ui/pagination/PaginationPrevious.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<PaginationPrev
|
||||
data-slot="pagination-previous"
|
||||
:class="cn(buttonVariants({ variant: 'ghost', size }), 'gap-1 px-2.5 sm:pr-2.5', props.class)"
|
||||
v-bind="forwarded"
|
||||
>
|
||||
<slot>
|
||||
<ChevronLeftIcon />
|
||||
<span class="hidden sm:block">Previous</span>
|
||||
</slot>
|
||||
</PaginationPrev>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PaginationPrevProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import type { ButtonVariants } from '@/components/ui/button'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { ChevronLeftIcon } from 'lucide-vue-next'
|
||||
import { PaginationPrev, useForwardProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { buttonVariants } from '@/components/ui/button'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<
|
||||
PaginationPrevProps & {
|
||||
size?: ButtonVariants['size']
|
||||
class?: HTMLAttributes['class']
|
||||
}
|
||||
>(),
|
||||
{
|
||||
size: 'default'
|
||||
}
|
||||
)
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'size')
|
||||
const forwarded = useForwardProps(delegatedProps)
|
||||
</script>
|
||||
8
src/components/ui/pagination/index.ts
Normal file
8
src/components/ui/pagination/index.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export { default as Pagination } from './Pagination.vue'
|
||||
export { default as PaginationContent } from './PaginationContent.vue'
|
||||
export { default as PaginationEllipsis } from './PaginationEllipsis.vue'
|
||||
export { default as PaginationFirst } from './PaginationFirst.vue'
|
||||
export { default as PaginationItem } from './PaginationItem.vue'
|
||||
export { default as PaginationLast } from './PaginationLast.vue'
|
||||
export { default as PaginationNext } from './PaginationNext.vue'
|
||||
export { default as PaginationPrevious } from './PaginationPrevious.vue'
|
||||
25
src/components/ui/scroll-area/ScrollArea.vue
Normal file
25
src/components/ui/scroll-area/ScrollArea.vue
Normal file
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<ScrollAreaRoot data-slot="scroll-area" v-bind="delegatedProps" :class="cn('relative', props.class)">
|
||||
<ScrollAreaViewport
|
||||
data-slot="scroll-area-viewport"
|
||||
class="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
|
||||
>
|
||||
<slot />
|
||||
</ScrollAreaViewport>
|
||||
<ScrollBar />
|
||||
<ScrollAreaCorner />
|
||||
</ScrollAreaRoot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ScrollAreaRootProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { ScrollAreaCorner, ScrollAreaRoot, ScrollAreaViewport } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
import ScrollBar from './ScrollBar.vue'
|
||||
|
||||
const props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
30
src/components/ui/scroll-area/ScrollBar.vue
Normal file
30
src/components/ui/scroll-area/ScrollBar.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<template>
|
||||
<ScrollAreaScrollbar
|
||||
data-slot="scroll-area-scrollbar"
|
||||
v-bind="delegatedProps"
|
||||
:class="
|
||||
cn(
|
||||
'flex touch-none p-px transition-colors select-none',
|
||||
orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent',
|
||||
orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<ScrollAreaThumb data-slot="scroll-area-thumb" class="bg-border relative flex-1 rounded-full" />
|
||||
</ScrollAreaScrollbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { ScrollAreaScrollbarProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { ScrollAreaScrollbar, ScrollAreaThumb } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = withDefaults(defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes['class'] }>(), {
|
||||
orientation: 'vertical'
|
||||
})
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
2
src/components/ui/scroll-area/index.ts
Normal file
2
src/components/ui/scroll-area/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default as ScrollArea } from './ScrollArea.vue'
|
||||
export { default as ScrollBar } from './ScrollBar.vue'
|
||||
@@ -8,7 +8,7 @@
|
||||
<slot />
|
||||
</div>
|
||||
|
||||
<Sheet v-else-if="isMobile" :open="openMobile" v-bind="$attrs" @update:open="setOpenMobile">
|
||||
<Sheet v-else-if="isMobile" :open="openMobile" v-bind="$attrs" @update:open="handleOpenMobileChange">
|
||||
<SheetContent
|
||||
data-sidebar="sidebar"
|
||||
data-slot="sidebar"
|
||||
@@ -79,12 +79,15 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { SidebarProps } from '.'
|
||||
import { watch } from 'vue'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Sheet, SheetContent } from '@/components/ui/sheet'
|
||||
import SheetDescription from '@/components/ui/sheet/SheetDescription.vue'
|
||||
import SheetHeader from '@/components/ui/sheet/SheetHeader.vue'
|
||||
import SheetTitle from '@/components/ui/sheet/SheetTitle.vue'
|
||||
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'
|
||||
import { useTutorial } from '@/composables/useTutorial'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false
|
||||
@@ -96,5 +99,51 @@
|
||||
collapsible: 'offcanvas'
|
||||
})
|
||||
|
||||
const router = useRouter()
|
||||
const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
|
||||
const { tutorialState, currentStep, nextStep } = useTutorial()
|
||||
|
||||
// 包装setOpenMobile以拦截教程期间的关闭操作
|
||||
const handleOpenMobileChange = (open: boolean) => {
|
||||
// 如果是移动端且在教程的菜单相关步骤,阻止关闭侧边栏
|
||||
if (tutorialState.value.isActive && currentStep.value) {
|
||||
// 只在第3步期间阻止关闭侧边栏,让玩家必须手动打开
|
||||
if (currentStep.value.id === 'menu_intro_mobile') {
|
||||
// 只允许打开,不允许关闭
|
||||
if (open) {
|
||||
setOpenMobile(true)
|
||||
}
|
||||
// 如果试图关闭,忽略该操作,保持打开状态
|
||||
return
|
||||
}
|
||||
}
|
||||
// 其他情况正常更新
|
||||
setOpenMobile(open)
|
||||
}
|
||||
|
||||
// 监听openMobile变化,在移动端教程第3步时,侧边栏打开后自动推进到第4步
|
||||
watch(
|
||||
() => openMobile.value,
|
||||
(isOpen) => {
|
||||
if (isMobile.value && tutorialState.value.isActive && currentStep.value) {
|
||||
// 如果在第3步且侧边栏刚打开,自动推进到第4步
|
||||
if (currentStep.value.id === 'menu_intro_mobile' && isOpen) {
|
||||
setTimeout(() => {
|
||||
nextStep()
|
||||
}, 300) // 延迟300ms让侧边栏动画完成
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// 监听路由变化,在移动端关闭侧边栏
|
||||
watch(
|
||||
() => router.currentRoute.value.path,
|
||||
() => {
|
||||
if (isMobile.value && openMobile.value) {
|
||||
// 路由变化时关闭移动端侧边栏
|
||||
setOpenMobile(false)
|
||||
}
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
data-sidebar="menu-badge"
|
||||
:class="
|
||||
cn(
|
||||
'text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none',
|
||||
'text-sidebar-foreground pointer-events-none flex h-5 min-w-5 items-center justify-center rounded-sm px-1 text-xs font-medium tabular-nums select-none',
|
||||
'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
|
||||
'absolute right-1',
|
||||
'peer-data-[size=sm]/menu-button:top-1',
|
||||
'peer-data-[size=default]/menu-button:top-1.5',
|
||||
'peer-data-[size=lg]/menu-button:top-2.5',
|
||||
'group-data-[collapsible=icon]:hidden',
|
||||
'group-data-[collapsible=icon]:absolute group-data-[collapsible=icon]:right-0 group-data-[collapsible=icon]:-top-1 group-data-[collapsible=icon]:h-4 group-data-[collapsible=icon]:min-w-4',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
|
||||
@@ -53,19 +53,19 @@
|
||||
passive: (props.open === undefined) as false
|
||||
}) as Ref<boolean>
|
||||
|
||||
function setOpen(value: boolean) {
|
||||
const setOpen = (value: boolean) => {
|
||||
open.value = value // emits('update:open', value)
|
||||
|
||||
// This sets the cookie to keep the sidebar state.
|
||||
document.cookie = `${SIDEBAR_COOKIE_NAME}=${open.value}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
|
||||
}
|
||||
|
||||
function setOpenMobile(value: boolean) {
|
||||
const setOpenMobile = (value: boolean) => {
|
||||
openMobile.value = value
|
||||
}
|
||||
|
||||
// Helper to toggle the sidebar.
|
||||
function toggleSidebar() {
|
||||
const toggleSidebar = () => {
|
||||
return isMobile.value ? setOpenMobile(!openMobile.value) : setOpen(!open.value)
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,13 @@
|
||||
import { CircleCheckIcon, InfoIcon, Loader2Icon, OctagonXIcon, TriangleAlertIcon, XIcon } from 'lucide-vue-next'
|
||||
import { Toaster as Sonner } from 'vue-sonner'
|
||||
import { cn } from '@/lib/utils'
|
||||
import 'vue-sonner/style.css'
|
||||
|
||||
const props = defineProps<ToasterProps>()
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.dark [data-sonner-toast][data-styled='true'] [data-description] {
|
||||
color: oklch(0.91 0 0 / 1);
|
||||
}
|
||||
</style>
|
||||
|
||||
19
src/components/ui/tabs/Tabs.vue
Normal file
19
src/components/ui/tabs/Tabs.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<TabsRoot v-slot="slotProps" data-slot="tabs" v-bind="forwarded" :class="cn('flex flex-col gap-2', props.class)">
|
||||
<slot v-bind="slotProps" />
|
||||
</TabsRoot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { TabsRootEmits, TabsRootProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { TabsRoot, useForwardPropsEmits } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<TabsRootProps & { class?: HTMLAttributes['class'] }>()
|
||||
const emits = defineEmits<TabsRootEmits>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
const forwarded = useForwardPropsEmits(delegatedProps, emits)
|
||||
</script>
|
||||
17
src/components/ui/tabs/TabsContent.vue
Normal file
17
src/components/ui/tabs/TabsContent.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<TabsContentRoot data-slot="tabs-content" :class="cn('flex-1 outline-none', props.class)" v-bind="delegatedProps">
|
||||
<slot />
|
||||
</TabsContentRoot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { TabsContentProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { TabsContent as TabsContentRoot } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<TabsContentProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
</script>
|
||||
27
src/components/ui/tabs/TabsList.vue
Normal file
27
src/components/ui/tabs/TabsList.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<TabsListRoot
|
||||
data-slot="tabs-list"
|
||||
v-bind="delegatedProps"
|
||||
:class="
|
||||
cn(
|
||||
'bg-muted text-muted-foreground inline-flex w-fit items-center justify-center rounded-lg p-[3px]',
|
||||
tabCount && tabCount > 3 ? (tabCount > 6 ? 'h-[85px] sm:h-9' : 'h-[65px] sm:h-9') : 'h-9',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
>
|
||||
<slot />
|
||||
</TabsListRoot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { TabsListProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { TabsList as TabsListRoot } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<TabsListProps & { class?: HTMLAttributes['class']; tabCount?: number }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class', 'tabCount')
|
||||
</script>
|
||||
34
src/components/ui/tabs/TabsTrigger.vue
Normal file
34
src/components/ui/tabs/TabsTrigger.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<TabsTriggerRoot
|
||||
data-slot="tabs-trigger"
|
||||
:class="
|
||||
cn(
|
||||
'inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-all',
|
||||
'text-muted-foreground hover:text-foreground',
|
||||
'data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-md data-[state=active]:border-border',
|
||||
'dark:data-[state=active]:bg-background dark:data-[state=active]:text-foreground dark:data-[state=active]:border-border dark:data-[state=active]:shadow-lg',
|
||||
'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:outline-1',
|
||||
'disabled:pointer-events-none disabled:opacity-50',
|
||||
'[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\'size-\'])]:size-4',
|
||||
props.class
|
||||
)
|
||||
"
|
||||
v-bind="forwardedProps"
|
||||
>
|
||||
<slot />
|
||||
</TabsTriggerRoot>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { TabsTriggerProps } from 'reka-ui'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { reactiveOmit } from '@vueuse/core'
|
||||
import { TabsTrigger as TabsTriggerRoot, useForwardProps } from 'reka-ui'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const props = defineProps<TabsTriggerProps & { class?: HTMLAttributes['class'] }>()
|
||||
|
||||
const delegatedProps = reactiveOmit(props, 'class')
|
||||
|
||||
const forwardedProps = useForwardProps(delegatedProps)
|
||||
</script>
|
||||
4
src/components/ui/tabs/index.ts
Normal file
4
src/components/ui/tabs/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as Tabs } from './Tabs.vue'
|
||||
export { default as TabsContent } from './TabsContent.vue'
|
||||
export { default as TabsList } from './TabsList.vue'
|
||||
export { default as TabsTrigger } from './TabsTrigger.vue'
|
||||
@@ -25,14 +25,18 @@ export const useGameConfig = () => {
|
||||
[BuildingType.CrystalMine]: 'crystalMine',
|
||||
[BuildingType.DeuteriumSynthesizer]: 'deuteriumSynthesizer',
|
||||
[BuildingType.SolarPlant]: 'solarPlant',
|
||||
[BuildingType.FusionReactor]: 'fusionReactor',
|
||||
[BuildingType.RoboticsFactory]: 'roboticsFactory',
|
||||
[BuildingType.NaniteFactory]: 'naniteFactory',
|
||||
[BuildingType.Shipyard]: 'shipyard',
|
||||
[BuildingType.Hangar]: 'hangar',
|
||||
[BuildingType.ResearchLab]: 'researchLab',
|
||||
[BuildingType.MetalStorage]: 'metalStorage',
|
||||
[BuildingType.CrystalStorage]: 'crystalStorage',
|
||||
[BuildingType.DeuteriumTank]: 'deuteriumTank',
|
||||
[BuildingType.DarkMatterCollector]: 'darkMatterCollector',
|
||||
[BuildingType.DarkMatterTank]: 'darkMatterTank',
|
||||
[BuildingType.MissileSilo]: 'missileSilo',
|
||||
[BuildingType.Terraformer]: 'terraformer',
|
||||
[BuildingType.LunarBase]: 'lunarBase',
|
||||
[BuildingType.SensorPhalanx]: 'sensorPhalanx',
|
||||
@@ -46,11 +50,15 @@ export const useGameConfig = () => {
|
||||
[ShipType.HeavyFighter]: 'heavyFighter',
|
||||
[ShipType.Cruiser]: 'cruiser',
|
||||
[ShipType.Battleship]: 'battleship',
|
||||
[ShipType.Battlecruiser]: 'battlecruiser',
|
||||
[ShipType.Bomber]: 'bomber',
|
||||
[ShipType.Destroyer]: 'destroyer',
|
||||
[ShipType.SmallCargo]: 'smallCargo',
|
||||
[ShipType.LargeCargo]: 'largeCargo',
|
||||
[ShipType.ColonyShip]: 'colonyShip',
|
||||
[ShipType.Recycler]: 'recycler',
|
||||
[ShipType.EspionageProbe]: 'espionageProbe',
|
||||
[ShipType.SolarSatellite]: 'solarSatellite',
|
||||
[ShipType.DarkMatterHarvester]: 'darkMatterHarvester',
|
||||
[ShipType.Deathstar]: 'deathstar'
|
||||
}
|
||||
@@ -65,6 +73,8 @@ export const useGameConfig = () => {
|
||||
[DefenseType.PlasmaTurret]: 'plasmaTurret',
|
||||
[DefenseType.SmallShieldDome]: 'smallShieldDome',
|
||||
[DefenseType.LargeShieldDome]: 'largeShieldDome',
|
||||
[DefenseType.AntiBallisticMissile]: 'antiBallisticMissile',
|
||||
[DefenseType.InterplanetaryMissile]: 'interplanetaryMissile',
|
||||
[DefenseType.PlanetaryShield]: 'planetaryShield'
|
||||
}
|
||||
|
||||
@@ -76,6 +86,12 @@ export const useGameConfig = () => {
|
||||
[TechnologyType.HyperspaceTechnology]: 'hyperspaceTechnology',
|
||||
[TechnologyType.PlasmaTechnology]: 'plasmaTechnology',
|
||||
[TechnologyType.ComputerTechnology]: 'computerTechnology',
|
||||
[TechnologyType.EspionageTechnology]: 'espionageTechnology',
|
||||
[TechnologyType.WeaponsTechnology]: 'weaponsTechnology',
|
||||
[TechnologyType.ShieldingTechnology]: 'shieldingTechnology',
|
||||
[TechnologyType.ArmourTechnology]: 'armourTechnology',
|
||||
[TechnologyType.Astrophysics]: 'astrophysics',
|
||||
[TechnologyType.GravitonTechnology]: 'gravitonTechnology',
|
||||
[TechnologyType.CombustionDrive]: 'combustionDrive',
|
||||
[TechnologyType.ImpulseDrive]: 'impulseDrive',
|
||||
[TechnologyType.HyperspaceDrive]: 'hyperspaceDrive',
|
||||
|
||||
@@ -10,7 +10,7 @@ export const useI18n = () => {
|
||||
const messages = computed(() => locales[currentLocale.value])
|
||||
|
||||
// 获取翻译文本的辅助函数
|
||||
const t = (key: string): string => {
|
||||
const t = (key: string, params?: Record<string, string | number>): string => {
|
||||
const keys = key.split('.')
|
||||
let value: any = messages.value
|
||||
|
||||
@@ -22,7 +22,16 @@ export const useI18n = () => {
|
||||
}
|
||||
}
|
||||
|
||||
return typeof value === 'string' ? value : key
|
||||
let result = typeof value === 'string' ? value : key
|
||||
|
||||
// 替换参数占位符
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
result = result.replace(new RegExp(`\\{${paramKey}\\}`, 'g'), String(paramValue))
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
const setLocale = (locale: Locale) => {
|
||||
|
||||
562
src/composables/useTutorial.ts
Normal file
562
src/composables/useTutorial.ts
Normal file
@@ -0,0 +1,562 @@
|
||||
import { ref, computed, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useGameStore } from '@/stores/gameStore'
|
||||
import type { TutorialStep, TutorialState } from '@/types/game'
|
||||
import { BuildingType, TechnologyType } from '@/types/game'
|
||||
|
||||
// 桌面端引导步骤定义
|
||||
export const desktopTutorialSteps: TutorialStep[] = [
|
||||
// 第1步:欢迎和基础介绍
|
||||
{
|
||||
id: 'welcome',
|
||||
title: 'tutorial.welcome.title',
|
||||
content: 'tutorial.welcome.content',
|
||||
placement: 'center',
|
||||
route: '/',
|
||||
action: 'none',
|
||||
canSkip: true
|
||||
},
|
||||
// 第2步:资源栏介绍
|
||||
{
|
||||
id: 'resources_intro',
|
||||
title: 'tutorial.resources.title',
|
||||
content: 'tutorial.resources.content',
|
||||
target: '.resource-bar',
|
||||
placement: 'bottom',
|
||||
route: '/',
|
||||
action: 'none',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第3步:星球选择器介绍
|
||||
{
|
||||
id: 'planet_info',
|
||||
title: 'tutorial.planet.title',
|
||||
content: 'tutorial.planet.content',
|
||||
target: '[data-tutorial="planet-selector"]',
|
||||
placement: 'bottom',
|
||||
route: '/',
|
||||
action: 'none',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第4步:导航菜单介绍
|
||||
{
|
||||
id: 'navigation',
|
||||
title: 'tutorial.navigation.title',
|
||||
content: 'tutorial.navigation.content',
|
||||
target: '[data-tutorial="navigation"]',
|
||||
placement: 'right',
|
||||
route: '/',
|
||||
action: 'none',
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第5步:前往建筑页面
|
||||
{
|
||||
id: 'goto_buildings',
|
||||
title: 'tutorial.gotoBuildings.title',
|
||||
content: 'tutorial.gotoBuildings.content',
|
||||
target: '[data-nav-path="/buildings"]',
|
||||
placement: 'right',
|
||||
route: '/',
|
||||
action: 'click',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第6步:建造太阳能电站(提供能源,是所有资源建筑的前置条件)
|
||||
{
|
||||
id: 'build_solar_plant',
|
||||
title: 'tutorial.buildSolarPlant.title',
|
||||
content: 'tutorial.buildSolarPlant.content',
|
||||
target: `[data-building="${BuildingType.SolarPlant}"]`,
|
||||
placement: 'top',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.SolarPlant,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第7步:了解建造队列
|
||||
{
|
||||
id: 'wait_for_build',
|
||||
title: 'tutorial.waitBuild.title',
|
||||
content: 'tutorial.waitBuild.content',
|
||||
target: '[data-tutorial="queue-button"]',
|
||||
placement: 'bottom',
|
||||
route: '/buildings',
|
||||
action: 'none',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第8步:建造金属矿(有了太阳能电站后才能建造)
|
||||
{
|
||||
id: 'build_metal_mine',
|
||||
title: 'tutorial.buildMetalMine.title',
|
||||
content: 'tutorial.buildMetalMine.content',
|
||||
target: `[data-building="${BuildingType.MetalMine}"]`,
|
||||
placement: 'top',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.MetalMine,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第9步:建造晶体矿
|
||||
{
|
||||
id: 'build_crystal_mine',
|
||||
title: 'tutorial.buildCrystalMine.title',
|
||||
content: 'tutorial.buildCrystalMine.content',
|
||||
target: `[data-building="${BuildingType.CrystalMine}"]`,
|
||||
placement: 'top',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.CrystalMine,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第10步:建造重氢合成器
|
||||
{
|
||||
id: 'build_deuterium',
|
||||
title: 'tutorial.buildDeuterium.title',
|
||||
content: 'tutorial.buildDeuterium.content',
|
||||
target: `[data-building="${BuildingType.DeuteriumSynthesizer}"]`,
|
||||
placement: 'top',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.DeuteriumSynthesizer,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第11步:升级资源矿到2级(为机器人工厂做准备)
|
||||
{
|
||||
id: 'upgrade_mines_intro',
|
||||
title: 'tutorial.upgradeMines.title',
|
||||
content: 'tutorial.upgradeMines.content',
|
||||
placement: 'center',
|
||||
route: '/buildings',
|
||||
action: 'none'
|
||||
},
|
||||
// 第12步:建造机器人工厂(需要三种资源矿各2级)
|
||||
{
|
||||
id: 'build_robotics',
|
||||
title: 'tutorial.buildRobotics.title',
|
||||
content: 'tutorial.buildRobotics.content',
|
||||
target: `[data-building="${BuildingType.RoboticsFactory}"]`,
|
||||
placement: 'top',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.RoboticsFactory,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第13步:继续升级资源矿到3级(为研究实验室做准备)
|
||||
{
|
||||
id: 'upgrade_mines_for_lab',
|
||||
title: 'tutorial.upgradeMinesForLab.title',
|
||||
content: 'tutorial.upgradeMinesForLab.content',
|
||||
placement: 'center',
|
||||
route: '/buildings',
|
||||
action: 'none'
|
||||
},
|
||||
// 第14步:建造研究实验室(需要三种资源矿各3级)
|
||||
{
|
||||
id: 'build_research_lab',
|
||||
title: 'tutorial.buildResearchLab.title',
|
||||
content: 'tutorial.buildResearchLab.content',
|
||||
target: `[data-building="${BuildingType.ResearchLab}"]`,
|
||||
placement: 'top',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.ResearchLab,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第15步:前往研究页面
|
||||
{
|
||||
id: 'goto_research',
|
||||
title: 'tutorial.gotoResearch.title',
|
||||
content: 'tutorial.gotoResearch.content',
|
||||
target: '[data-nav-path="/research"]',
|
||||
placement: 'right',
|
||||
route: '/buildings',
|
||||
action: 'click',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第16步:研究能量科技
|
||||
{
|
||||
id: 'research_energy',
|
||||
title: 'tutorial.researchEnergy.title',
|
||||
content: 'tutorial.researchEnergy.content',
|
||||
target: `[data-tech="${TechnologyType.EnergyTechnology}"]`,
|
||||
placement: 'top',
|
||||
route: '/research',
|
||||
action: 'research',
|
||||
actionTarget: TechnologyType.EnergyTechnology,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第17步:介绍船坞(需要机器人工厂2级)
|
||||
{
|
||||
id: 'shipyard_intro',
|
||||
title: 'tutorial.shipyardIntro.title',
|
||||
content: 'tutorial.shipyardIntro.content',
|
||||
placement: 'center',
|
||||
route: '/research',
|
||||
action: 'none'
|
||||
},
|
||||
// 第18步:返回建筑页面建造船坞
|
||||
{
|
||||
id: 'goto_buildings_for_shipyard',
|
||||
title: 'tutorial.gotoBuildingsForShipyard.title',
|
||||
content: 'tutorial.gotoBuildingsForShipyard.content',
|
||||
target: '[data-nav-path="/buildings"]',
|
||||
placement: 'right',
|
||||
route: '/research',
|
||||
action: 'click',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第19步:建造船坞
|
||||
{
|
||||
id: 'build_shipyard',
|
||||
title: 'tutorial.buildShipyard.title',
|
||||
content: 'tutorial.buildShipyard.content',
|
||||
target: `[data-building="${BuildingType.Shipyard}"]`,
|
||||
placement: 'top',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.Shipyard,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第20步:舰队和探索介绍
|
||||
{
|
||||
id: 'fleet_intro',
|
||||
title: 'tutorial.fleetIntro.title',
|
||||
content: 'tutorial.fleetIntro.content',
|
||||
placement: 'center',
|
||||
route: '/buildings',
|
||||
action: 'none'
|
||||
},
|
||||
// 第21步:银河系探索介绍
|
||||
{
|
||||
id: 'galaxy_intro',
|
||||
title: 'tutorial.galaxyIntro.title',
|
||||
content: 'tutorial.galaxyIntro.content',
|
||||
target: '[data-nav-path="/galaxy"]',
|
||||
placement: 'right',
|
||||
route: '/buildings',
|
||||
action: 'none',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第22步:引导完成
|
||||
{
|
||||
id: 'tutorial_complete',
|
||||
title: 'tutorial.complete.title',
|
||||
content: 'tutorial.complete.content',
|
||||
placement: 'center',
|
||||
route: '/buildings',
|
||||
action: 'none'
|
||||
}
|
||||
]
|
||||
|
||||
// 移动端引导步骤定义
|
||||
export const mobileTutorialSteps: TutorialStep[] = [
|
||||
// 第1步:欢迎(移动端)
|
||||
{
|
||||
id: 'welcome_mobile',
|
||||
title: 'tutorial.mobile.welcome.title',
|
||||
content: 'tutorial.mobile.welcome.content',
|
||||
placement: 'center',
|
||||
route: '/',
|
||||
action: 'none',
|
||||
canSkip: true
|
||||
},
|
||||
// 第2步:顶部资源栏介绍
|
||||
{
|
||||
id: 'resources_intro_mobile',
|
||||
title: 'tutorial.mobile.resources.title',
|
||||
content: 'tutorial.mobile.resources.content',
|
||||
target: '.resource-bar',
|
||||
placement: 'bottom',
|
||||
route: '/',
|
||||
action: 'none',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第3步:汉堡菜单介绍 - 引导玩家手动点击打开菜单
|
||||
{
|
||||
id: 'menu_intro_mobile',
|
||||
title: 'tutorial.mobile.menu.title',
|
||||
content: 'tutorial.mobile.menu.content',
|
||||
target: '[data-tutorial="mobile-menu"]',
|
||||
placement: 'bottom',
|
||||
route: '/',
|
||||
action: 'none', // 让玩家手动点击汉堡菜单打开侧边栏
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第4步:前往建筑页面 - 此时侧边栏已打开,让玩家手动点击
|
||||
{
|
||||
id: 'goto_buildings_mobile',
|
||||
title: 'tutorial.mobile.gotoBuildings.title',
|
||||
content: 'tutorial.mobile.gotoBuildings.content',
|
||||
target: '[data-nav-path="/buildings"]',
|
||||
placement: 'right', // 改为right,因为菜单在左侧展开
|
||||
route: '/',
|
||||
action: 'click', // 使用click,但不会自动触发,只是用来标识这是一个点击操作
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第5步:建造太阳能电站
|
||||
{
|
||||
id: 'build_solar_plant_mobile',
|
||||
title: 'tutorial.mobile.buildSolarPlant.title',
|
||||
content: 'tutorial.mobile.buildSolarPlant.content',
|
||||
target: `[data-building="${BuildingType.SolarPlant}"]`,
|
||||
placement: 'bottom',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.SolarPlant,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第6步:了解建造队列
|
||||
{
|
||||
id: 'wait_for_build_mobile',
|
||||
title: 'tutorial.mobile.waitBuild.title',
|
||||
content: 'tutorial.mobile.waitBuild.content',
|
||||
target: '[data-tutorial="queue-button"]',
|
||||
placement: 'bottom',
|
||||
route: '/buildings',
|
||||
action: 'none',
|
||||
highlightPadding: 8
|
||||
},
|
||||
// 第7步:建造金属矿
|
||||
{
|
||||
id: 'build_metal_mine_mobile',
|
||||
title: 'tutorial.mobile.buildMetalMine.title',
|
||||
content: 'tutorial.mobile.buildMetalMine.content',
|
||||
target: `[data-building="${BuildingType.MetalMine}"]`,
|
||||
placement: 'bottom',
|
||||
route: '/buildings',
|
||||
action: 'build',
|
||||
actionTarget: BuildingType.MetalMine,
|
||||
highlightPadding: 12
|
||||
},
|
||||
// 第8步:完成教程
|
||||
{
|
||||
id: 'tutorial_complete_mobile',
|
||||
title: 'tutorial.mobile.complete.title',
|
||||
content: 'tutorial.mobile.complete.content',
|
||||
placement: 'center',
|
||||
route: '/buildings',
|
||||
action: 'none'
|
||||
}
|
||||
]
|
||||
|
||||
// 检测是否为移动端
|
||||
const isMobileDevice = () => {
|
||||
return window.innerWidth < 768
|
||||
}
|
||||
|
||||
// 根据设备类型获取教程步骤
|
||||
export const getTutorialSteps = (): TutorialStep[] => {
|
||||
return isMobileDevice() ? mobileTutorialSteps : desktopTutorialSteps
|
||||
}
|
||||
|
||||
// 导出统一的 tutorialSteps(为了兼容性)
|
||||
export const tutorialSteps = getTutorialSteps()
|
||||
|
||||
const tutorialState = ref<TutorialState>({
|
||||
isActive: false,
|
||||
currentStepIndex: 0,
|
||||
completedSteps: [],
|
||||
skipped: false
|
||||
})
|
||||
|
||||
export function useTutorial() {
|
||||
const router = useRouter()
|
||||
const gameStore = useGameStore()
|
||||
|
||||
// 动态获取教程步骤
|
||||
const currentTutorialSteps = computed(() => getTutorialSteps())
|
||||
|
||||
const currentStep = computed(() => {
|
||||
if (!tutorialState.value.isActive || tutorialState.value.currentStepIndex >= currentTutorialSteps.value.length) {
|
||||
return null
|
||||
}
|
||||
return currentTutorialSteps.value[tutorialState.value.currentStepIndex]
|
||||
})
|
||||
|
||||
const progress = computed(() => {
|
||||
return Math.round((tutorialState.value.currentStepIndex / currentTutorialSteps.value.length) * 100)
|
||||
})
|
||||
|
||||
const isLastStep = computed(() => {
|
||||
return tutorialState.value.currentStepIndex === currentTutorialSteps.value.length - 1
|
||||
})
|
||||
|
||||
// 初始化引导
|
||||
const startTutorial = () => {
|
||||
const player = gameStore.player
|
||||
if (!player.tutorialProgress || !player.tutorialProgress.tutorialCompleted) {
|
||||
const now = Date.now()
|
||||
tutorialState.value = {
|
||||
isActive: true,
|
||||
currentStepIndex: 0,
|
||||
completedSteps: player.tutorialProgress?.completedStepIds || [],
|
||||
skipped: false,
|
||||
lastActiveTime: now
|
||||
}
|
||||
|
||||
// 如果有进度,恢复到上次的步骤
|
||||
if (player.tutorialProgress?.currentStep) {
|
||||
const stepIndex = currentTutorialSteps.value.findIndex((s: TutorialStep) => s.id === player.tutorialProgress?.currentStep)
|
||||
if (stepIndex !== -1) {
|
||||
tutorialState.value.currentStepIndex = stepIndex
|
||||
}
|
||||
}
|
||||
|
||||
// 跳转到当前步骤的路由
|
||||
if (currentStep.value?.route) {
|
||||
router.push(currentStep.value.route)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 下一步
|
||||
const nextStep = () => {
|
||||
if (!currentStep.value) return
|
||||
|
||||
// 标记当前步骤为已完成
|
||||
if (!tutorialState.value.completedSteps.includes(currentStep.value.id)) {
|
||||
tutorialState.value.completedSteps.push(currentStep.value.id)
|
||||
}
|
||||
|
||||
// 保存进度到store
|
||||
saveProgress()
|
||||
|
||||
// 移动到下一步
|
||||
if (tutorialState.value.currentStepIndex < currentTutorialSteps.value.length - 1) {
|
||||
tutorialState.value.currentStepIndex++
|
||||
|
||||
// 跳转到新步骤的路由
|
||||
if (currentStep.value?.route) {
|
||||
router.push(currentStep.value.route)
|
||||
}
|
||||
} else {
|
||||
// 引导完成
|
||||
completeTutorial()
|
||||
}
|
||||
}
|
||||
|
||||
// 上一步
|
||||
const previousStep = () => {
|
||||
if (tutorialState.value.currentStepIndex > 0) {
|
||||
tutorialState.value.currentStepIndex--
|
||||
|
||||
// 跳转到新步骤的路由
|
||||
if (currentStep.value?.route) {
|
||||
router.push(currentStep.value.route)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 跳过引导
|
||||
const skipTutorial = () => {
|
||||
tutorialState.value.isActive = false
|
||||
tutorialState.value.skipped = true
|
||||
|
||||
// 保存跳过状态(跳过也视为已完成,避免刷新后重新弹出)
|
||||
if (!gameStore.player.tutorialProgress) {
|
||||
gameStore.player.tutorialProgress = {
|
||||
tutorialCompleted: true,
|
||||
completedStepIds: tutorialState.value.completedSteps,
|
||||
currentStep: null,
|
||||
skippedAt: Date.now()
|
||||
}
|
||||
} else {
|
||||
gameStore.player.tutorialProgress.tutorialCompleted = true
|
||||
gameStore.player.tutorialProgress.skippedAt = Date.now()
|
||||
gameStore.player.tutorialProgress.currentStep = null
|
||||
}
|
||||
}
|
||||
|
||||
// 完成引导
|
||||
const completeTutorial = () => {
|
||||
tutorialState.value.isActive = false
|
||||
|
||||
// 保存完成状态
|
||||
gameStore.player.tutorialProgress = {
|
||||
tutorialCompleted: true,
|
||||
completedStepIds: tutorialState.value.completedSteps,
|
||||
currentStep: null
|
||||
}
|
||||
}
|
||||
|
||||
// 保存进度
|
||||
const saveProgress = () => {
|
||||
if (!gameStore.player.tutorialProgress) {
|
||||
gameStore.player.tutorialProgress = {
|
||||
tutorialCompleted: false,
|
||||
completedStepIds: [],
|
||||
currentStep: null
|
||||
}
|
||||
}
|
||||
|
||||
gameStore.player.tutorialProgress.completedStepIds = [...tutorialState.value.completedSteps]
|
||||
gameStore.player.tutorialProgress.currentStep = currentStep.value?.id || null
|
||||
}
|
||||
|
||||
// 检查步骤完成条件
|
||||
const checkStepCompletion = (stepId: string): boolean => {
|
||||
const step = currentTutorialSteps.value.find((s: TutorialStep) => s.id === stepId)
|
||||
if (!step) return false
|
||||
|
||||
const planet = gameStore.currentPlanet
|
||||
if (!planet) return false
|
||||
|
||||
switch (step.action) {
|
||||
case 'build':
|
||||
if (step.actionTarget) {
|
||||
// 简单检查队列中是否有该建筑
|
||||
const inQueue = planet.buildQueue.some(
|
||||
item => item.itemType === step.actionTarget && (item.type === 'building' || item.type === 'demolish')
|
||||
)
|
||||
return inQueue
|
||||
}
|
||||
return false
|
||||
|
||||
case 'research':
|
||||
if (step.actionTarget) {
|
||||
// 简单检查队列中是否有该科技
|
||||
const inQueue = planet.buildQueue.some(item => item.itemType === step.actionTarget && item.type === 'technology')
|
||||
return inQueue
|
||||
}
|
||||
return false
|
||||
|
||||
case 'click':
|
||||
case 'none':
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// 不再自动推进,完全由玩家手动点击"下一步"按钮控制
|
||||
|
||||
// 监听路由变化,自动推进需要导航的教程步骤
|
||||
watch(
|
||||
() => router.currentRoute.value.path,
|
||||
newPath => {
|
||||
if (tutorialState.value.isActive && currentStep.value) {
|
||||
// 如果当前步骤需要导航到特定页面,且已经到达该页面,自动推进
|
||||
if (currentStep.value.action === 'none' && currentStep.value.target && currentStep.value.target.includes('data-nav-path')) {
|
||||
// 提取目标路径
|
||||
const match = currentStep.value.target.match(/data-nav-path="([^"]+)"/)
|
||||
if (match && match[1] === newPath) {
|
||||
setTimeout(() => {
|
||||
nextStep()
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
tutorialState,
|
||||
currentStep,
|
||||
progress,
|
||||
isLastStep,
|
||||
startTutorial,
|
||||
nextStep,
|
||||
previousStep,
|
||||
skipTutorial,
|
||||
completeTutorial,
|
||||
checkStepCompletion
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,23 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
35: { [BuildingType.NaniteFactory]: 1, [BuildingType.ResearchLab]: 10 }
|
||||
}
|
||||
},
|
||||
[BuildingType.FusionReactor]: {
|
||||
id: BuildingType.FusionReactor,
|
||||
name: '核聚变反应堆',
|
||||
description: '使用重氢产生大量能源',
|
||||
baseCost: { metal: 900, crystal: 360, deuterium: 180, darkMatter: 0, energy: 0 },
|
||||
baseTime: 30,
|
||||
costMultiplier: 1.8,
|
||||
spaceUsage: 4,
|
||||
requirements: {
|
||||
[TechnologyType.EnergyTechnology]: 3,
|
||||
[BuildingType.DeuteriumSynthesizer]: 5
|
||||
},
|
||||
levelRequirements: {
|
||||
10: { [BuildingType.RoboticsFactory]: 5, [TechnologyType.EnergyTechnology]: 6 },
|
||||
20: { [BuildingType.RoboticsFactory]: 8, [TechnologyType.EnergyTechnology]: 10, [BuildingType.NaniteFactory]: 2 }
|
||||
}
|
||||
},
|
||||
[BuildingType.RoboticsFactory]: {
|
||||
id: BuildingType.RoboticsFactory,
|
||||
name: '机器人工厂',
|
||||
@@ -80,8 +97,7 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
},
|
||||
levelRequirements: {
|
||||
5: { [BuildingType.ResearchLab]: 3, [BuildingType.SolarPlant]: 8 },
|
||||
8: { [BuildingType.ResearchLab]: 6, [BuildingType.SolarPlant]: 12, [BuildingType.MetalMine]: 12, [BuildingType.CrystalMine]: 12 },
|
||||
10: { [BuildingType.ResearchLab]: 8, [BuildingType.NaniteFactory]: 1 }
|
||||
8: { [BuildingType.ResearchLab]: 6, [BuildingType.SolarPlant]: 12, [BuildingType.MetalMine]: 12, [BuildingType.CrystalMine]: 12 }
|
||||
}
|
||||
},
|
||||
[BuildingType.NaniteFactory]: {
|
||||
@@ -107,13 +123,28 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
baseTime: 30, // 减少建造时间:60→30秒
|
||||
costMultiplier: 2,
|
||||
spaceUsage: 5,
|
||||
fleetStorageBonus: 1000, // 每级增加100舰队仓储
|
||||
fleetStorageBonus: 1000, // 每级增加1000舰队仓储
|
||||
requirements: { [BuildingType.RoboticsFactory]: 2 },
|
||||
levelRequirements: {
|
||||
8: { [BuildingType.RoboticsFactory]: 5, [BuildingType.ResearchLab]: 5 },
|
||||
12: { [BuildingType.RoboticsFactory]: 8, [BuildingType.ResearchLab]: 8, [BuildingType.NaniteFactory]: 2 }
|
||||
}
|
||||
},
|
||||
[BuildingType.Hangar]: {
|
||||
id: BuildingType.Hangar,
|
||||
name: '机库',
|
||||
description: '专门用于扩展舰队存储容量,支持星球专业化发展',
|
||||
baseCost: { metal: 200, crystal: 100, deuterium: 50, darkMatter: 0, energy: 0 },
|
||||
baseTime: 20,
|
||||
costMultiplier: 1.8,
|
||||
spaceUsage: 3,
|
||||
fleetStorageBonus: 1500, // 每级增加1500舰队仓储,比船坞更高
|
||||
requirements: { [BuildingType.RoboticsFactory]: 1 }, // 只需要1级机器人工厂
|
||||
levelRequirements: {
|
||||
10: { [BuildingType.RoboticsFactory]: 3 },
|
||||
20: { [BuildingType.RoboticsFactory]: 5 }
|
||||
}
|
||||
},
|
||||
[BuildingType.ResearchLab]: {
|
||||
id: BuildingType.ResearchLab,
|
||||
name: '研究实验室',
|
||||
@@ -197,10 +228,45 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
8: { [BuildingType.ResearchLab]: 10, [TechnologyType.DarkMatterTechnology]: 5, [BuildingType.NaniteFactory]: 2 }
|
||||
}
|
||||
},
|
||||
[BuildingType.DarkMatterTank]: {
|
||||
id: BuildingType.DarkMatterTank,
|
||||
name: '暗物质储罐',
|
||||
description: '增加暗物质存储上限',
|
||||
baseCost: { metal: 10000, crystal: 10000, deuterium: 5000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 20,
|
||||
costMultiplier: 2,
|
||||
spaceUsage: 2,
|
||||
planetOnly: true,
|
||||
requirements: {
|
||||
[BuildingType.DarkMatterCollector]: 2,
|
||||
[TechnologyType.DarkMatterTechnology]: 1
|
||||
},
|
||||
levelRequirements: {
|
||||
8: { [BuildingType.DarkMatterCollector]: 8, [BuildingType.RoboticsFactory]: 3 },
|
||||
12: { [BuildingType.DarkMatterCollector]: 15, [BuildingType.RoboticsFactory]: 6, [TechnologyType.DarkMatterTechnology]: 3 }
|
||||
}
|
||||
},
|
||||
[BuildingType.MissileSilo]: {
|
||||
id: BuildingType.MissileSilo,
|
||||
name: '导弹发射井',
|
||||
description: '存储和发射导弹,每级可存储10枚导弹',
|
||||
baseCost: { metal: 20000, crystal: 20000, deuterium: 1000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 45,
|
||||
costMultiplier: 2,
|
||||
spaceUsage: 5,
|
||||
maxLevel: 10,
|
||||
requirements: {
|
||||
[BuildingType.Shipyard]: 1
|
||||
},
|
||||
levelRequirements: {
|
||||
5: { [BuildingType.Shipyard]: 5, [TechnologyType.ComputerTechnology]: 3 },
|
||||
8: { [BuildingType.Shipyard]: 8, [TechnologyType.ComputerTechnology]: 6, [BuildingType.NaniteFactory]: 2 }
|
||||
}
|
||||
},
|
||||
[BuildingType.Terraformer]: {
|
||||
id: BuildingType.Terraformer,
|
||||
name: '地形改造器',
|
||||
description: '改造行星地形,每级增加5个可用空间',
|
||||
description: '改造行星地形,每级增加30个可用空间',
|
||||
baseCost: { metal: 0, crystal: 50000, deuterium: 100000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 2,
|
||||
@@ -250,7 +316,7 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
id: BuildingType.JumpGate,
|
||||
name: '跳跃门',
|
||||
description: '瞬间传送舰队到其他月球',
|
||||
baseCost: { metal: 2000000, crystal: 4000000, deuterium: 2000000, darkMatter: 0, energy: 0 },
|
||||
baseCost: { metal: 2000000, crystal: 4000000, deuterium: 2000000, darkMatter: 50000, energy: 0 },
|
||||
baseTime: 240, // 减少建造时间:300→240秒
|
||||
costMultiplier: 2,
|
||||
spaceUsage: 10,
|
||||
@@ -269,7 +335,7 @@ export const BUILDINGS: Record<BuildingType, BuildingConfig> = {
|
||||
id: BuildingType.PlanetDestroyerFactory,
|
||||
name: '行星毁灭者工厂',
|
||||
description: '建造能够摧毁行星的终极武器',
|
||||
baseCost: { metal: 5000000, crystal: 4000000, deuterium: 1000000, darkMatter: 0, energy: 0 },
|
||||
baseCost: { metal: 5000000, crystal: 4000000, deuterium: 1000000, darkMatter: 100000, energy: 0 },
|
||||
baseTime: 300,
|
||||
costMultiplier: 2,
|
||||
spaceUsage: 15,
|
||||
@@ -297,7 +363,7 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
||||
[TechnologyType.EnergyTechnology]: {
|
||||
id: TechnologyType.EnergyTechnology,
|
||||
name: '能源技术',
|
||||
description: '提高能源利用效率',
|
||||
description: '加快研究速度',
|
||||
baseCost: { metal: 0, crystal: 800, deuterium: 400, darkMatter: 0, energy: 0 },
|
||||
baseTime: 30, // 减少研究时间:60→30秒
|
||||
costMultiplier: 2,
|
||||
@@ -382,7 +448,7 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
||||
baseCost: { metal: 0, crystal: 400, deuterium: 600, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 2,
|
||||
fleetStorageBonus: 500, // 每级全局增加50舰队仓储
|
||||
fleetStorageBonus: 500, // 每级全局增加500舰队仓储
|
||||
maxLevel: 10, // 最多10级(最多11个研究队列)
|
||||
requirements: { [BuildingType.ResearchLab]: 1 },
|
||||
levelRequirements: {
|
||||
@@ -391,6 +457,87 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
||||
8: { [BuildingType.ResearchLab]: 10, [BuildingType.NaniteFactory]: 2 }
|
||||
}
|
||||
},
|
||||
[TechnologyType.EspionageTechnology]: {
|
||||
id: TechnologyType.EspionageTechnology,
|
||||
name: '间谍技术',
|
||||
description: '提高间谍探测效果,每级提高1级侦查深度',
|
||||
baseCost: { metal: 200, crystal: 1000, deuterium: 200, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 2,
|
||||
requirements: { [BuildingType.ResearchLab]: 3 },
|
||||
levelRequirements: {
|
||||
5: { [BuildingType.ResearchLab]: 6, [TechnologyType.ComputerTechnology]: 3 },
|
||||
8: { [BuildingType.ResearchLab]: 8, [TechnologyType.ComputerTechnology]: 5 }
|
||||
}
|
||||
},
|
||||
[TechnologyType.WeaponsTechnology]: {
|
||||
id: TechnologyType.WeaponsTechnology,
|
||||
name: '武器技术',
|
||||
description: '提高舰船和防御的攻击力,每级+10%',
|
||||
baseCost: { metal: 800, crystal: 200, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 2,
|
||||
requirements: { [BuildingType.ResearchLab]: 4 },
|
||||
levelRequirements: {
|
||||
5: { [BuildingType.ResearchLab]: 7, [BuildingType.Shipyard]: 4 },
|
||||
10: { [BuildingType.ResearchLab]: 10, [BuildingType.Shipyard]: 8, [BuildingType.NaniteFactory]: 2 }
|
||||
}
|
||||
},
|
||||
[TechnologyType.ShieldingTechnology]: {
|
||||
id: TechnologyType.ShieldingTechnology,
|
||||
name: '护盾技术',
|
||||
description: '提高舰船和防御的护盾值,每级+10%',
|
||||
baseCost: { metal: 200, crystal: 600, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 2,
|
||||
requirements: { [BuildingType.ResearchLab]: 6, [TechnologyType.EnergyTechnology]: 3 },
|
||||
levelRequirements: {
|
||||
5: { [BuildingType.ResearchLab]: 8, [TechnologyType.EnergyTechnology]: 6 },
|
||||
10: { [BuildingType.ResearchLab]: 10, [TechnologyType.EnergyTechnology]: 10, [BuildingType.NaniteFactory]: 2 }
|
||||
}
|
||||
},
|
||||
[TechnologyType.ArmourTechnology]: {
|
||||
id: TechnologyType.ArmourTechnology,
|
||||
name: '装甲技术',
|
||||
description: '提高舰船和防御的装甲值,每级+10%',
|
||||
baseCost: { metal: 1000, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 2,
|
||||
requirements: { [BuildingType.ResearchLab]: 2 },
|
||||
levelRequirements: {
|
||||
5: { [BuildingType.ResearchLab]: 6, [BuildingType.Shipyard]: 3 },
|
||||
10: { [BuildingType.ResearchLab]: 10, [BuildingType.Shipyard]: 7, [BuildingType.NaniteFactory]: 1 }
|
||||
}
|
||||
},
|
||||
[TechnologyType.Astrophysics]: {
|
||||
id: TechnologyType.Astrophysics,
|
||||
name: '天体物理学',
|
||||
description: '每级增加1个殖民地槽位,增加探险成功率',
|
||||
baseCost: { metal: 4000, crystal: 8000, deuterium: 4000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 60,
|
||||
costMultiplier: 1.75,
|
||||
requirements: {
|
||||
[BuildingType.ResearchLab]: 3,
|
||||
[TechnologyType.EspionageTechnology]: 4,
|
||||
[TechnologyType.ImpulseDrive]: 3
|
||||
},
|
||||
levelRequirements: {
|
||||
5: { [BuildingType.ResearchLab]: 8, [TechnologyType.EspionageTechnology]: 8 },
|
||||
10: { [BuildingType.ResearchLab]: 12, [TechnologyType.HyperspaceTechnology]: 5, [BuildingType.NaniteFactory]: 3 }
|
||||
}
|
||||
},
|
||||
[TechnologyType.GravitonTechnology]: {
|
||||
id: TechnologyType.GravitonTechnology,
|
||||
name: '引力技术',
|
||||
description: '研究引力操纵,死星的必要技术',
|
||||
baseCost: { metal: 0, crystal: 0, deuterium: 0, darkMatter: 300000, energy: 0 },
|
||||
baseTime: 0,
|
||||
costMultiplier: 3,
|
||||
maxLevel: 1, // 只有1级
|
||||
requirements: {
|
||||
[BuildingType.ResearchLab]: 12
|
||||
}
|
||||
},
|
||||
[TechnologyType.CombustionDrive]: {
|
||||
id: TechnologyType.CombustionDrive,
|
||||
name: '燃烧引擎',
|
||||
@@ -456,7 +603,7 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
||||
[TechnologyType.TerraformingTechnology]: {
|
||||
id: TechnologyType.TerraformingTechnology,
|
||||
name: '地形改造技术',
|
||||
description: '研究行星地形改造技术,每级为所有行星增加5个可用空间',
|
||||
description: '研究行星地形改造技术,每级为所有行星增加30个可用空间',
|
||||
baseCost: { metal: 0, crystal: 20000, deuterium: 40000, darkMatter: 0, energy: 0 },
|
||||
baseTime: 90,
|
||||
costMultiplier: 2,
|
||||
@@ -470,7 +617,7 @@ export const TECHNOLOGIES: Record<TechnologyType, TechnologyConfig> = {
|
||||
id: TechnologyType.PlanetDestructionTech,
|
||||
name: '行星毁灭技术',
|
||||
description: '研究如何摧毁整个行星的恐怖技术',
|
||||
baseCost: { metal: 4000000, crystal: 8000000, deuterium: 4000000, darkMatter: 0, energy: 0 },
|
||||
baseCost: { metal: 4000000, crystal: 8000000, deuterium: 4000000, darkMatter: 200000, energy: 0 },
|
||||
baseTime: 300,
|
||||
costMultiplier: 2,
|
||||
maxLevel: 5, // 最多5级
|
||||
@@ -542,18 +689,76 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
||||
[ShipType.Battleship]: {
|
||||
id: ShipType.Battleship,
|
||||
name: '战列舰',
|
||||
description: '重型战舰',
|
||||
description: '重型战舰,主力作战单位',
|
||||
cost: { metal: 45000, crystal: 15000, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
buildTime: 90,
|
||||
cargoCapacity: 1500,
|
||||
attack: 1000,
|
||||
shield: 200,
|
||||
armor: 6000,
|
||||
attack: 1200,
|
||||
shield: 300,
|
||||
armor: 10000,
|
||||
speed: 10000,
|
||||
fuelConsumption: 500,
|
||||
storageUsage: 25,
|
||||
requirements: { [BuildingType.Shipyard]: 7, [TechnologyType.HyperspaceDrive]: 4 }
|
||||
},
|
||||
[ShipType.Battlecruiser]: {
|
||||
id: ShipType.Battlecruiser,
|
||||
name: '战列巡洋舰',
|
||||
description: '快速强大的战斗舰船,擅长攻击战列舰',
|
||||
cost: { metal: 30000, crystal: 40000, deuterium: 15000, darkMatter: 0, energy: 0 },
|
||||
buildTime: 70,
|
||||
cargoCapacity: 750,
|
||||
attack: 700,
|
||||
shield: 400,
|
||||
armor: 7000,
|
||||
speed: 10000,
|
||||
fuelConsumption: 250,
|
||||
storageUsage: 20,
|
||||
requirements: {
|
||||
[BuildingType.Shipyard]: 8,
|
||||
[TechnologyType.HyperspaceDrive]: 5,
|
||||
[TechnologyType.HyperspaceTechnology]: 5,
|
||||
[TechnologyType.LaserTechnology]: 12
|
||||
}
|
||||
},
|
||||
[ShipType.Bomber]: {
|
||||
id: ShipType.Bomber,
|
||||
name: '轰炸机',
|
||||
description: '专门对付防御设施的轰炸舰',
|
||||
cost: { metal: 50000, crystal: 25000, deuterium: 15000, darkMatter: 0, energy: 0 },
|
||||
buildTime: 100,
|
||||
cargoCapacity: 500,
|
||||
attack: 1000,
|
||||
shield: 500,
|
||||
armor: 7500,
|
||||
speed: 4000,
|
||||
fuelConsumption: 700,
|
||||
storageUsage: 35,
|
||||
requirements: {
|
||||
[BuildingType.Shipyard]: 8,
|
||||
[TechnologyType.ImpulseDrive]: 6,
|
||||
[TechnologyType.PlasmaTechnology]: 5
|
||||
}
|
||||
},
|
||||
[ShipType.Destroyer]: {
|
||||
id: ShipType.Destroyer,
|
||||
name: '驱逐舰',
|
||||
description: '专业反大型舰船战舰,高火力低防护',
|
||||
cost: { metal: 60000, crystal: 50000, deuterium: 15000, darkMatter: 0, energy: 0 },
|
||||
buildTime: 120,
|
||||
cargoCapacity: 2000,
|
||||
attack: 2500,
|
||||
shield: 250,
|
||||
armor: 8000,
|
||||
speed: 5000,
|
||||
fuelConsumption: 1000,
|
||||
storageUsage: 40,
|
||||
requirements: {
|
||||
[BuildingType.Shipyard]: 9,
|
||||
[TechnologyType.HyperspaceDrive]: 6,
|
||||
[TechnologyType.HyperspaceTechnology]: 5
|
||||
}
|
||||
},
|
||||
[ShipType.SmallCargo]: {
|
||||
id: ShipType.SmallCargo,
|
||||
name: '小型运输船',
|
||||
@@ -629,6 +834,21 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
||||
storageUsage: 2,
|
||||
requirements: { [BuildingType.Shipyard]: 3, [TechnologyType.CombustionDrive]: 3 }
|
||||
},
|
||||
[ShipType.SolarSatellite]: {
|
||||
id: ShipType.SolarSatellite,
|
||||
name: '太阳能卫星',
|
||||
description: '提供额外能源,每个产生50点能量',
|
||||
cost: { metal: 0, crystal: 2000, deuterium: 500, darkMatter: 0, energy: 0 },
|
||||
buildTime: 10,
|
||||
cargoCapacity: 0,
|
||||
attack: 1,
|
||||
shield: 1,
|
||||
armor: 200,
|
||||
speed: 0,
|
||||
fuelConsumption: 0,
|
||||
storageUsage: 1,
|
||||
requirements: { [BuildingType.Shipyard]: 1 }
|
||||
},
|
||||
[ShipType.DarkMatterHarvester]: {
|
||||
id: ShipType.DarkMatterHarvester,
|
||||
name: '暗物质采集船',
|
||||
@@ -652,7 +872,7 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
||||
id: ShipType.Deathstar,
|
||||
name: '死星',
|
||||
description: '终极武器,能够摧毁整个行星',
|
||||
cost: { metal: 5000000, crystal: 4000000, deuterium: 1000000, darkMatter: 0, energy: 0 },
|
||||
cost: { metal: 5000000, crystal: 4000000, deuterium: 1000000, darkMatter: 50000, energy: 0 },
|
||||
buildTime: 600,
|
||||
cargoCapacity: 1000000,
|
||||
attack: 200000,
|
||||
@@ -662,7 +882,7 @@ export const SHIPS: Record<ShipType, ShipConfig> = {
|
||||
fuelConsumption: 1,
|
||||
storageUsage: 100,
|
||||
requirements: {
|
||||
[BuildingType.PlanetDestroyerFactory]: 10,
|
||||
[BuildingType.PlanetDestroyerFactory]: 3,
|
||||
[TechnologyType.PlanetDestructionTech]: 7,
|
||||
[TechnologyType.HyperspaceDrive]: 7
|
||||
}
|
||||
@@ -763,7 +983,7 @@ export const DEFENSES: Record<DefenseType, DefenseConfig> = {
|
||||
id: DefenseType.PlanetaryShield,
|
||||
name: '行星护盾',
|
||||
description: '保护行星免受毁灭攻击的超级护盾',
|
||||
cost: { metal: 2000000, crystal: 2000000, deuterium: 1000000, darkMatter: 0, energy: 0 },
|
||||
cost: { metal: 2000000, crystal: 2000000, deuterium: 1000000, darkMatter: 50000, energy: 0 },
|
||||
buildTime: 180,
|
||||
attack: 1,
|
||||
shield: 100000,
|
||||
@@ -773,6 +993,33 @@ export const DEFENSES: Record<DefenseType, DefenseConfig> = {
|
||||
[TechnologyType.EnergyTechnology]: 10,
|
||||
[TechnologyType.HyperspaceTechnology]: 8
|
||||
}
|
||||
},
|
||||
[DefenseType.AntiBallisticMissile]: {
|
||||
id: DefenseType.AntiBallisticMissile,
|
||||
name: '反弹道导弹',
|
||||
description: '拦截敌方导弹,每个可拦截1枚星际导弹',
|
||||
cost: { metal: 8000, crystal: 0, deuterium: 2000, darkMatter: 0, energy: 0 },
|
||||
buildTime: 20,
|
||||
attack: 1,
|
||||
shield: 1,
|
||||
armor: 800,
|
||||
requirements: {
|
||||
[BuildingType.MissileSilo]: 2
|
||||
}
|
||||
},
|
||||
[DefenseType.InterplanetaryMissile]: {
|
||||
id: DefenseType.InterplanetaryMissile,
|
||||
name: '星际导弹',
|
||||
description: '可以攻击其他星球的防御设施,射程取决于脉冲引擎等级',
|
||||
cost: { metal: 12500, crystal: 2500, deuterium: 10000, darkMatter: 0, energy: 0 },
|
||||
buildTime: 30,
|
||||
attack: 12000,
|
||||
shield: 1,
|
||||
armor: 1500,
|
||||
requirements: {
|
||||
[BuildingType.MissileSilo]: 4,
|
||||
[TechnologyType.ImpulseDrive]: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,8 +1029,8 @@ export const OFFICERS: Record<OfficerType, OfficerConfig> = {
|
||||
id: OfficerType.Commander,
|
||||
name: '指挥官',
|
||||
description: '提升建筑速度和管理能力',
|
||||
cost: { metal: 0, crystal: 50000, deuterium: 25000, darkMatter: 0, energy: 0 },
|
||||
weeklyMaintenance: { metal: 0, crystal: 5000, deuterium: 2500, darkMatter: 0, energy: 0 },
|
||||
cost: { metal: 0, crystal: 50000, deuterium: 25000, darkMatter: 7000, energy: 0 },
|
||||
weeklyMaintenance: { metal: 0, crystal: 5000, deuterium: 2500, darkMatter: 900, energy: 0 },
|
||||
benefits: {
|
||||
buildingSpeedBonus: 10, // 建筑速度 +10%
|
||||
additionalBuildQueue: 1, // 额外1个建筑队列
|
||||
@@ -794,8 +1041,8 @@ export const OFFICERS: Record<OfficerType, OfficerConfig> = {
|
||||
id: OfficerType.Admiral,
|
||||
name: '上将',
|
||||
description: '提升舰队作战能力',
|
||||
cost: { metal: 50000, crystal: 25000, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
weeklyMaintenance: { metal: 5000, crystal: 2500, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
cost: { metal: 50000, crystal: 25000, deuterium: 0, darkMatter: 7000, energy: 0 },
|
||||
weeklyMaintenance: { metal: 5000, crystal: 2500, deuterium: 0, darkMatter: 900, energy: 0 },
|
||||
benefits: {
|
||||
additionalFleetSlots: 2, // 额外2个舰队槽位
|
||||
fleetSpeedBonus: 10, // 舰队速度 +10%
|
||||
@@ -806,8 +1053,8 @@ export const OFFICERS: Record<OfficerType, OfficerConfig> = {
|
||||
id: OfficerType.Engineer,
|
||||
name: '工程师',
|
||||
description: '增强防御和能量系统',
|
||||
cost: { metal: 40000, crystal: 20000, deuterium: 10000, darkMatter: 0, energy: 0 },
|
||||
weeklyMaintenance: { metal: 4000, crystal: 2000, deuterium: 1000, darkMatter: 0, energy: 0 },
|
||||
cost: { metal: 40000, crystal: 20000, deuterium: 10000, darkMatter: 7000, energy: 0 },
|
||||
weeklyMaintenance: { metal: 4000, crystal: 2000, deuterium: 1000, darkMatter: 900, energy: 0 },
|
||||
benefits: {
|
||||
defenseBonus: 15, // 防御力 +15%
|
||||
energyProductionBonus: 10, // 电量产出 +10%
|
||||
@@ -818,8 +1065,8 @@ export const OFFICERS: Record<OfficerType, OfficerConfig> = {
|
||||
id: OfficerType.Geologist,
|
||||
name: '地质学家',
|
||||
description: '提高资源开采效率',
|
||||
cost: { metal: 30000, crystal: 30000, deuterium: 20000, darkMatter: 0, energy: 0 },
|
||||
weeklyMaintenance: { metal: 3000, crystal: 3000, deuterium: 2000, darkMatter: 0, energy: 0 },
|
||||
cost: { metal: 30000, crystal: 30000, deuterium: 20000, darkMatter: 7000, energy: 0 },
|
||||
weeklyMaintenance: { metal: 3000, crystal: 3000, deuterium: 2000, darkMatter: 900, energy: 0 },
|
||||
benefits: {
|
||||
resourceProductionBonus: 15, // 资源产量 +15%
|
||||
storageCapacityBonus: 10 // 仓储容量 +10%
|
||||
@@ -829,8 +1076,8 @@ export const OFFICERS: Record<OfficerType, OfficerConfig> = {
|
||||
id: OfficerType.Technocrat,
|
||||
name: '技术专家',
|
||||
description: '加快科技研究速度',
|
||||
cost: { metal: 20000, crystal: 40000, deuterium: 20000, darkMatter: 0, energy: 0 },
|
||||
weeklyMaintenance: { metal: 2000, crystal: 4000, deuterium: 2000, darkMatter: 0, energy: 0 },
|
||||
cost: { metal: 20000, crystal: 40000, deuterium: 20000, darkMatter: 7000, energy: 0 },
|
||||
weeklyMaintenance: { metal: 2000, crystal: 4000, deuterium: 2000, darkMatter: 900, energy: 0 },
|
||||
benefits: {
|
||||
researchSpeedBonus: 15 // 研究速度 +15%
|
||||
}
|
||||
@@ -853,15 +1100,15 @@ export const MOON_CONFIG = {
|
||||
baseChance: 1, // 基础1%概率
|
||||
maxChance: 20, // 最大20%概率
|
||||
chancePerDebris: 100000, // 每10万资源增加1%概率
|
||||
baseSize: 60, // 月球基础空间
|
||||
lunarBaseSpaceBonus: 5 // 每级月球基地增加的空间
|
||||
baseSize: 100, // 月球基础空间
|
||||
lunarBaseSpaceBonus: 30 // 每级月球基地增加的空间
|
||||
}
|
||||
|
||||
// 行星配置
|
||||
export const PLANET_CONFIG = {
|
||||
baseSize: 200, // 行星基础空间
|
||||
terraformerSpaceBonus: 5, // 每级地形改造器增加的空间
|
||||
terraformingTechSpaceBonus: 3 // 每级地形改造技术增加的空间
|
||||
baseSize: 300, // 行星基础空间
|
||||
terraformerSpaceBonus: 30, // 每级地形改造器增加的空间
|
||||
terraformingTechSpaceBonus: 30 // 每级地形改造技术增加的空间
|
||||
}
|
||||
|
||||
// 舰队仓储配置
|
||||
@@ -870,3 +1117,81 @@ export const FLEET_STORAGE_CONFIG = {
|
||||
shipyardBonus: 1000, // 每级造船厂增加的仓储
|
||||
computerTechBonus: 500 // 每级计算机技术全局增加的仓储
|
||||
}
|
||||
|
||||
// 外交系统配置
|
||||
export const DIPLOMATIC_CONFIG = {
|
||||
// 好感度范围
|
||||
MIN_REPUTATION: -100,
|
||||
MAX_REPUTATION: 100,
|
||||
|
||||
// 关系状态阈值
|
||||
HOSTILE_THRESHOLD: -20, // 低于此值为敌对
|
||||
FRIENDLY_THRESHOLD: 20, // 高于此值为友好
|
||||
|
||||
// 各种行为的好感度变化值
|
||||
REPUTATION_CHANGES: {
|
||||
// 赠送资源(基于资源价值计算)
|
||||
GIFT_BASE: 0, // 基础好感度(移除固定奖励,完全基于资源量)
|
||||
GIFT_PER_1K_RESOURCES: 2, // 每1000资源价值增加2点(提高权重)
|
||||
GIFT_MIN_VALUE: 500, // 最小资源价值门槛(低于此值不增加好感度)
|
||||
GIFT_MAX_SINGLE: 20, // 单次赠送最大好感度增加
|
||||
|
||||
// 负面行为
|
||||
ATTACK: -15, // 攻击一次
|
||||
ATTACK_WIN: -25, // 攻击并获胜
|
||||
ATTACK_DESTROY_PLANET: -50, // 摧毁星球
|
||||
SPY_DETECTED: -5, // 侦查被发现
|
||||
SPY_UNDETECTED: -2, // 侦查未被发现
|
||||
STEAL_DEBRIS: -10, // 抢夺残骸(在NPC星球位置)
|
||||
DESTROY_FLEET: -3, // 每摧毁1单位战力扣除好感度
|
||||
|
||||
// 正面行为
|
||||
HELP_ATTACK_ENEMY: 15, // 帮助攻击NPC的敌人
|
||||
LONG_PEACE_DECAY: 1, // 长期不攻击的友好衰减(每周+1)
|
||||
TRADE: 5, // 贸易(未来功能预留)
|
||||
|
||||
// 关系网络影响
|
||||
ALLY_ATTACKED: -10, // 攻击盟友导致的好感度降低
|
||||
ALLY_HELPED: 5 // 帮助盟友导致的好感度增加
|
||||
},
|
||||
|
||||
// 好感度自然变化
|
||||
NATURAL_DECAY: {
|
||||
ENABLED: true,
|
||||
INTERVAL: 7 * 24 * 3600, // 7天(秒)
|
||||
TOWARDS_NEUTRAL_RATE: 2 // 每周向中立值回归2点
|
||||
},
|
||||
|
||||
// 基于关系的行为调整
|
||||
BEHAVIOR_MODIFIERS: {
|
||||
HOSTILE_ATTACK_MULTIPLIER: 2.0, // 敌对状态攻击频率翻倍
|
||||
HOSTILE_SPY_MULTIPLIER: 1.5, // 敌对状态侦查频率提高50%
|
||||
FRIENDLY_ATTACK_PROBABILITY: 0, // 友好状态不攻击
|
||||
FRIENDLY_SPY_PROBABILITY: 0.5, // 友好状态侦查概率降低到50%
|
||||
NEUTRAL_ATTACK_PROBABILITY: 1.0, // 中立状态正常攻击概率
|
||||
NEUTRAL_SPY_PROBABILITY: 1.0 // 中立状态正常侦查概率
|
||||
},
|
||||
|
||||
// NPC主动赠送资源配置
|
||||
NPC_GIFT_CONFIG: {
|
||||
ENABLED: true,
|
||||
MIN_REPUTATION: 60, // NPC对玩家好感度≥60才会赠送
|
||||
CHECK_INTERVAL: 24 * 3600, // 每天检查一次(秒)
|
||||
GIFT_PROBABILITY: 0.05, // 5%概率赠送
|
||||
GIFT_AMOUNT: {
|
||||
METAL: { min: 1000, max: 5000 },
|
||||
CRYSTAL: { min: 500, max: 2500 },
|
||||
DEUTERIUM: { min: 200, max: 1000 }
|
||||
}
|
||||
},
|
||||
|
||||
// 礼物接受/拒绝配置
|
||||
GIFT_ACCEPTANCE_CONFIG: {
|
||||
NPC_REJECTION_BASE_PROBABILITY: 0.3, // NPC拒绝礼物的基础概率(30%)
|
||||
NPC_REJECTION_REPUTATION_MODIFIER: 0.01, // 好感度每降低1点,拒绝概率增加1%
|
||||
MIN_REJECTION_PROBABILITY: 0.05, // 最小拒绝概率(5%,即使关系很好)
|
||||
MAX_REJECTION_PROBABILITY: 0.8, // 最大拒绝概率(80%,即使关系很差)
|
||||
GIFT_EXPIRATION_DAYS: 7, // 礼物通知过期天数
|
||||
REJECTION_REPUTATION_PENALTY: -5 // 拒绝礼物导致的好感度降低
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ export default {
|
||||
close: 'Schließen',
|
||||
back: 'Zurück',
|
||||
next: 'Weiter',
|
||||
gotIt: '',
|
||||
previous: 'Vorherige',
|
||||
submit: 'Absenden',
|
||||
reset: 'Zurücksetzen',
|
||||
@@ -33,13 +34,19 @@ export default {
|
||||
viewRequirements: 'Anforderungen anzeigen',
|
||||
requirementsNotMet: 'Anforderungen nicht erfüllt',
|
||||
current: 'Aktuell',
|
||||
level: 'Stufe'
|
||||
level: 'Stufe',
|
||||
gmModeActivated: 'GM-Modus aktiviert! Überprüfen Sie das Navigationsmenü.'
|
||||
},
|
||||
errors: {
|
||||
requirementsNotMet: 'Anforderungen nicht erfüllt',
|
||||
insufficientResources: 'Unzureichende Ressourcen',
|
||||
insufficientFleetStorage: 'Unzureichender Flottenspeicher',
|
||||
shieldDomeLimit: 'Schildkuppel-Limit erreicht',
|
||||
missileSiloLimit: 'Raketensilokapazität überschritten',
|
||||
insufficientMissiles: 'Unzureichende Interkontinentalraketen',
|
||||
invalidMissileCount: 'Ungültige Raketenanzahl',
|
||||
targetOutOfRange: 'Ziel außer Reichweite',
|
||||
cannotAttackOwnPlanet: 'Eigenen Planeten kann nicht angegriffen werden',
|
||||
fleetMissionsFull: 'Flottenmissionsplätze voll',
|
||||
insufficientFleet: 'Unzureichende Flotte',
|
||||
insufficientFuel: 'Unzureichender Treibstoff',
|
||||
@@ -62,6 +69,7 @@ export default {
|
||||
officers: 'Offiziere',
|
||||
simulator: 'Simulator',
|
||||
galaxy: 'Galaxie',
|
||||
diplomacy: 'Diplomacy',
|
||||
messages: 'Nachrichten',
|
||||
settings: 'Einstellungen',
|
||||
gm: 'GM'
|
||||
@@ -97,6 +105,8 @@ export default {
|
||||
coordinates: 'Koordinaten',
|
||||
switchToMoon: 'Zum Mond',
|
||||
backToPlanet: 'Zurück zum Planeten',
|
||||
switchPlanet: 'Planet wechseln',
|
||||
currentPlanet: 'Aktueller Planet',
|
||||
fields: 'Felder',
|
||||
temperature: 'Temperatur',
|
||||
homePlanet: 'Heimatplanet',
|
||||
@@ -112,14 +122,18 @@ export default {
|
||||
crystalMine: 'Kristallmine',
|
||||
deuteriumSynthesizer: 'Deuterium-Synthesizer',
|
||||
solarPlant: 'Solarkraftwerk',
|
||||
fusionReactor: 'Fusionsreaktor',
|
||||
roboticsFactory: 'Roboterfabrik',
|
||||
naniteFactory: 'Nanitenfabrik',
|
||||
shipyard: 'Raumschiffwerft',
|
||||
hangar: 'Hangar',
|
||||
researchLab: 'Forschungslabor',
|
||||
metalStorage: 'Metallspeicher',
|
||||
crystalStorage: 'Kristallspeicher',
|
||||
deuteriumTank: 'Deuteriumtank',
|
||||
darkMatterCollector: 'Dunkle-Materie-Kollektor',
|
||||
darkMatterTank: 'Dunkle-Materie-Tank',
|
||||
missileSilo: 'Raketensilo',
|
||||
terraformer: 'Terraformer',
|
||||
lunarBase: 'Mondbasis',
|
||||
sensorPhalanx: 'Sensorphalanx',
|
||||
@@ -130,23 +144,39 @@ export default {
|
||||
consumption: 'Verbrauch',
|
||||
totalCost: 'Gesamtkosten',
|
||||
totalPoints: 'Gesamtpunkte',
|
||||
levelRange: 'Stufenbereich'
|
||||
levelRange: 'Stufenbereich',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
buildQueueBonus: 'Bauauftrag',
|
||||
spaceBonus: 'Raumbonus',
|
||||
buildSpeedBonus: 'Baugeschwindigkeitsbonus',
|
||||
researchSpeedBonus: 'Forschungsgeschwindigkeitsbonus',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
buildingDescriptions: {
|
||||
metalMine: 'Fördert Metallressourcen',
|
||||
crystalMine: 'Fördert Kristallressourcen',
|
||||
deuteriumSynthesizer: 'Synthesiert Deuteriumressourcen',
|
||||
solarPlant: 'Liefert Energie',
|
||||
fusionReactor: 'Nutzt Deuterium zur Erzeugung großer Energiemengen',
|
||||
roboticsFactory: 'Beschleunigt Baugeschwindigkeit',
|
||||
naniteFactory: 'Erhöht Bauauftragskapazität, +1 pro Stufe (max 10 Stufen)',
|
||||
shipyard: 'Baut Schiffe',
|
||||
hangar: 'Spezialisierte Einrichtung zur Erweiterung der Flottenspeicherkapazität, unterstützt Planetenspezialisierung',
|
||||
researchLab: 'Erforscht Technologien',
|
||||
metalStorage: 'Erhöht Metallspeicherkapazität',
|
||||
crystalStorage: 'Erhöht Kristallspeicherkapazität',
|
||||
deuteriumTank: 'Erhöht Deuteriumspeicherkapazität',
|
||||
darkMatterCollector: 'Sammelt seltene Dunkle-Materie-Ressourcen',
|
||||
terraformer: 'Terraformt Planetenoberfläche, erhöht verfügbaren Platz um 5 pro Stufe',
|
||||
lunarBase: 'Erhöht verfügbaren Platz auf dem Mond, +5 Platz pro Stufe',
|
||||
darkMatterTank: 'Erhöht Dunkle-Materie-Speicherkapazität',
|
||||
missileSilo: 'Lagert und startet Raketen, 10 Raketen pro Stufe',
|
||||
terraformer: 'Terraformt Planetenoberfläche, erhöht verfügbaren Platz um 30 pro Stufe',
|
||||
lunarBase: 'Erhöht verfügbaren Platz auf dem Mond, +30 Platz pro Stufe',
|
||||
sensorPhalanx: 'Erkennt Flottenaktivitäten in umliegenden Systemen',
|
||||
jumpGate: 'Überträgt Flotten sofort zu anderen Monden',
|
||||
planetDestroyerFactory: 'Konstruiert ultimative Waffen zur Zerstörung von Planeten'
|
||||
@@ -156,11 +186,15 @@ export default {
|
||||
heavyFighter: 'Schwerer Jäger',
|
||||
cruiser: 'Kreuzer',
|
||||
battleship: 'Schlachtschiff',
|
||||
battlecruiser: 'Schlachtkreuzer',
|
||||
bomber: 'Bomber',
|
||||
destroyer: 'Zerstörer',
|
||||
smallCargo: 'Kleiner Transporter',
|
||||
largeCargo: 'Großer Transporter',
|
||||
colonyShip: 'Kolonieschiff',
|
||||
recycler: 'Recycler',
|
||||
espionageProbe: 'Spionagesonde',
|
||||
solarSatellite: 'Solarsatellit',
|
||||
darkMatterHarvester: 'Dunkle-Materie-Ernter',
|
||||
deathstar: 'Todesstern'
|
||||
},
|
||||
@@ -168,12 +202,16 @@ export default {
|
||||
lightFighter: 'Grundlegende Kampfeinheit',
|
||||
heavyFighter: 'Schwer gepanzerter Jäger',
|
||||
cruiser: 'Mittleres Kriegsschiff, ausgewogene Offensive und Defensive',
|
||||
battleship: 'Mächtiges Kriegsschiff',
|
||||
battleship: 'Schweres Hauptkriegsschiff mit starker Feuerkraft und hoher Verteidigung',
|
||||
battlecruiser: 'Schnelles mächtiges Kriegsschiff, hervorragend gegen Schlachtschiffe',
|
||||
bomber: 'Spezialisiertes Schiff zum Angriff auf Verteidigungsanlagen',
|
||||
destroyer: 'Spezialisiertes Anti-Großschiff mit hoher Feuerkraft aber geringer Verteidigung',
|
||||
smallCargo: 'Transportiert kleine Mengen Ressourcen',
|
||||
largeCargo: 'Transportiert große Mengen Ressourcen',
|
||||
colonyShip: 'Zur Kolonisierung neuer Planeten',
|
||||
recycler: 'Sammelt Trümmerfeld-Ressourcen',
|
||||
espionageProbe: 'Späht feindliche Planeten aus',
|
||||
solarSatellite: 'Liefert zusätzliche Energie, erzeugt 50 Energie pro Satellit',
|
||||
darkMatterHarvester: 'Spezielles Schiff zum Ernten von Dunkler Materie',
|
||||
deathstar: 'Ultimative Waffe, die ganze Planeten zerstören kann'
|
||||
},
|
||||
@@ -186,6 +224,8 @@ export default {
|
||||
plasmaTurret: 'Plasmawerfer',
|
||||
smallShieldDome: 'Kleine Schildkuppel',
|
||||
largeShieldDome: 'Große Schildkuppel',
|
||||
antiBallisticMissile: 'Abfangrakete',
|
||||
interplanetaryMissile: 'Interkontinentalrakete',
|
||||
planetaryShield: 'Planetarschild'
|
||||
},
|
||||
defenseDescriptions: {
|
||||
@@ -197,13 +237,23 @@ export default {
|
||||
plasmaTurret: 'Mächtige Verteidigungsanlage',
|
||||
smallShieldDome: 'Kleiner Schild zum Schutz des gesamten Planeten',
|
||||
largeShieldDome: 'Großer Schild zum Schutz des gesamten Planeten',
|
||||
antiBallisticMissile: 'Fängt feindliche Raketen ab, kann 1 Interkontinentalrakete abfangen',
|
||||
interplanetaryMissile: 'Kann Verteidigungsanlagen auf anderen Planeten angreifen',
|
||||
planetaryShield: 'Superschild zum Schutz des Planeten vor Vernichtungsangriffen'
|
||||
},
|
||||
research: {
|
||||
researchTime: 'Forschungszeit',
|
||||
totalCost: 'Gesamtkosten',
|
||||
totalPoints: 'Gesamtpunkte',
|
||||
levelRange: 'Stufenbereich'
|
||||
levelRange: 'Stufenbereich',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'Energietechnik',
|
||||
@@ -212,6 +262,12 @@ export default {
|
||||
hyperspaceTechnology: 'Hyperraumtechnik',
|
||||
plasmaTechnology: 'Plasmatechnik',
|
||||
computerTechnology: 'Computertechnologie',
|
||||
espionageTechnology: 'Spionagetechnik',
|
||||
weaponsTechnology: 'Waffentechnik',
|
||||
shieldingTechnology: 'Schildtechnik',
|
||||
armourTechnology: 'Panzerung',
|
||||
astrophysics: 'Astrophysik',
|
||||
gravitonTechnology: 'Gravitontechnik',
|
||||
combustionDrive: 'Verbrennungsantrieb',
|
||||
impulseDrive: 'Impulsantrieb',
|
||||
hyperspaceDrive: 'Hyperraumantrieb',
|
||||
@@ -226,11 +282,17 @@ export default {
|
||||
hyperspaceTechnology: 'Hyperraumsprung-Technologie',
|
||||
plasmaTechnology: 'Plasmawaffentechnologie',
|
||||
computerTechnology: 'Erhöht Forschungsauftragskapazität, +1 pro Stufe (max 10 Stufen)',
|
||||
espionageTechnology: 'Verbessert Sondenwirksamkeit, +1 Spionagestufe pro Stufe',
|
||||
weaponsTechnology: 'Erhöht Angriffskraft von Schiffen und Verteidigung um 10% pro Stufe',
|
||||
shieldingTechnology: 'Erhöht Schilde von Schiffen und Verteidigung um 10% pro Stufe',
|
||||
armourTechnology: 'Erhöht Panzerung von Schiffen und Verteidigung um 10% pro Stufe',
|
||||
astrophysics: 'Jede Stufe fügt 1 Kolonieslot hinzu und erhöht Expeditionserfolgsrate',
|
||||
gravitonTechnology: 'Erforscht Gravitonmanipulation, erforderlich für Todesstern',
|
||||
combustionDrive: 'Grundlegende Antriebstechnologie',
|
||||
impulseDrive: 'Mittlere Antriebstechnologie',
|
||||
hyperspaceDrive: 'Fortgeschrittene Antriebstechnologie',
|
||||
darkMatterTechnology: 'Forschung zu Eigenschaften und Anwendungen von Dunkler Materie',
|
||||
terraformingTechnology: 'Forschung zur Planeten-Terraforming-Technologie, erhöht verfügbaren Platz aller Planeten um 3 pro Stufe',
|
||||
terraformingTechnology: 'Forschung zur Planeten-Terraforming-Technologie, erhöht verfügbaren Platz aller Planeten um 30 pro Stufe',
|
||||
planetDestructionTech: 'Schreckliche Technologie zur Zerstörung ganzer Planeten'
|
||||
},
|
||||
officers: {
|
||||
@@ -253,16 +315,20 @@ export default {
|
||||
darkMatterSpecialist: 'Verbessert Dunkle-Materie-Sammlungseffizienz'
|
||||
},
|
||||
queue: {
|
||||
title: 'Bauauftrag',
|
||||
empty: 'Keine aktiven Aufgaben',
|
||||
buildQueue: 'Bauauftrag',
|
||||
researchQueue: 'Forschungsauftrag',
|
||||
building: 'Im Bau',
|
||||
researching: 'In Forschung',
|
||||
demolishing: 'Wird abgerissen',
|
||||
remaining: 'Verbleibend',
|
||||
cancel: 'Abbrechen',
|
||||
cancelBuild: 'Bau abbrechen',
|
||||
cancelResearch: 'Forschung abbrechen',
|
||||
confirmCancel: 'Möchten Sie wirklich abbrechen? 50% der Ressourcen werden zurückerstattet.',
|
||||
level: 'Stufe',
|
||||
gmModeActivated: '',
|
||||
upgradeToLevel: 'Auf Stufe aufrüsten'
|
||||
},
|
||||
overview: {
|
||||
@@ -283,6 +349,7 @@ export default {
|
||||
usedSpace: 'Verwendeter Platz',
|
||||
spaceUsage: 'Platzbedarf',
|
||||
level: 'Stufe',
|
||||
gmModeActivated: '',
|
||||
upgradeCost: 'Ausbaukosten',
|
||||
buildTime: 'Bauzeit',
|
||||
upgrade: 'Ausbauen',
|
||||
@@ -293,7 +360,9 @@ export default {
|
||||
demolish: 'Abreißen',
|
||||
demolishRefund: 'Abriss-Rückerstattung',
|
||||
demolishFailed: 'Abriss fehlgeschlagen',
|
||||
demolishFailedMessage: 'Abriss nicht möglich. Bitte überprüfen Sie, ob die Bauqueue voll ist oder die Gebäudestufe 0 ist.'
|
||||
demolishFailedMessage: 'Abriss nicht möglich. Bitte überprüfen Sie, ob die Bauqueue voll ist oder die Gebäudestufe 0 ist.',
|
||||
confirmDemolish: '',
|
||||
confirmDemolishMessage: ''
|
||||
},
|
||||
researchView: {
|
||||
title: 'Forschung',
|
||||
@@ -306,6 +375,7 @@ export default {
|
||||
},
|
||||
shipyard: {
|
||||
attack: 'Angriff',
|
||||
missileAttack: 'Raketenangriff',
|
||||
shield: 'Schild',
|
||||
armor: 'Panzerung',
|
||||
speed: 'Geschwindigkeit',
|
||||
@@ -323,6 +393,7 @@ export default {
|
||||
title: 'Raumschiffwerft',
|
||||
fleetStorage: 'Flottenspeicher',
|
||||
attack: 'Angriff',
|
||||
missileAttack: 'Raketenangriff',
|
||||
shield: 'Schild',
|
||||
speed: 'Geschwindigkeit',
|
||||
cargoCapacity: 'Ladekapazität',
|
||||
@@ -337,6 +408,7 @@ export default {
|
||||
},
|
||||
defense: {
|
||||
attack: 'Angriff',
|
||||
missileAttack: 'Raketenangriff',
|
||||
shield: 'Schild',
|
||||
armor: 'Panzerung',
|
||||
buildCost: 'Baukosten',
|
||||
@@ -350,6 +422,7 @@ export default {
|
||||
defenseView: {
|
||||
title: 'Verteidigung',
|
||||
attack: 'Angriff',
|
||||
missileAttack: 'Raketenangriff',
|
||||
shield: 'Schild',
|
||||
armor: 'Panzerung',
|
||||
buildTime: 'Bauzeit',
|
||||
@@ -359,6 +432,7 @@ export default {
|
||||
totalCost: 'Gesamtkosten',
|
||||
build: 'Bauen',
|
||||
shieldDomeBuilt: 'Schildkuppel bereits gebaut',
|
||||
missileCapacity: 'Raketenkapazität',
|
||||
inputError: 'Eingabefehler',
|
||||
inputErrorMessage: 'Bitte Baumenge eingeben!',
|
||||
buildFailed: 'Bau fehlgeschlagen',
|
||||
@@ -372,6 +446,7 @@ export default {
|
||||
flightMissions: 'Flugmissionen',
|
||||
currentPlanetFleet: 'Flotte auf diesem Planeten',
|
||||
attack: 'Angriff',
|
||||
missileAttack: 'Raketenangriff',
|
||||
shield: 'Schild',
|
||||
armor: 'Panzerung',
|
||||
speed: 'Geschwindigkeit',
|
||||
@@ -382,6 +457,7 @@ export default {
|
||||
all: 'Alle',
|
||||
targetCoordinates: 'Zielkoordinaten',
|
||||
galaxy: 'Galaxie',
|
||||
diplomacy: 'Diplomacy',
|
||||
system: 'System',
|
||||
position: 'Position',
|
||||
missionType: 'Missionstyp',
|
||||
@@ -405,6 +481,11 @@ export default {
|
||||
arrivalTime: 'Ankunftszeit',
|
||||
returnTime: 'Rückkehrzeit',
|
||||
recallFleet: 'Flotte zurückrufen',
|
||||
abortMission: '',
|
||||
abortMissionTitle: '',
|
||||
abortMissionWarning: '',
|
||||
abortMissionSuccess: '',
|
||||
abortMissionSuccessMessage: '',
|
||||
sendFailed: 'Senden fehlgeschlagen',
|
||||
sendFailedMessage: 'Bitte überprüfen Sie Flottenanzahl, Treibstoffverfügbarkeit oder Ladekapazitätsgrenzen.',
|
||||
recallFailed: 'Zurückrufen fehlgeschlagen',
|
||||
@@ -415,7 +496,11 @@ export default {
|
||||
cannotSendToOwnPlanet: 'Flotte kann nicht zu eigenem Planeten gesendet werden',
|
||||
cargoExceedsCapacity: 'Fracht überschreitet Kapazität',
|
||||
noColonyShip: 'Kolonieschiff für Kolonisierungsmission erforderlich',
|
||||
noDebrisAtTarget: 'Kein Trümmerfeld an Zielkoordinaten oder Trümmerfeld ist leer'
|
||||
noDebrisAtTarget: 'Kein Trümmerfeld an Zielkoordinaten oder Trümmerfeld ist leer',
|
||||
noDeathstar: 'Todesstern für Zerstörungsmission erforderlich',
|
||||
giftMode: 'Geschenkmodus',
|
||||
giftModeDescription: 'Ressourcen als Geschenk senden an',
|
||||
estimatedReputationGain: 'Geschätzter Reputationsgewinn'
|
||||
},
|
||||
officersView: {
|
||||
title: 'Offiziere',
|
||||
@@ -455,47 +540,75 @@ export default {
|
||||
title: 'Galaxie',
|
||||
selectCoordinates: 'Koordinaten auswählen',
|
||||
galaxy: 'Galaxie',
|
||||
diplomacy: 'Diplomacy',
|
||||
selectGalaxy: 'Galaxie auswählen',
|
||||
system: 'System',
|
||||
selectSystem: 'System auswählen',
|
||||
view: 'Anzeigen',
|
||||
myPlanet: 'Mein Planet',
|
||||
myPlanets: 'Meine Systeme ansehen',
|
||||
npcPlanets: 'NPC-Planeten',
|
||||
selectPlanetToView: 'Planet auswählen, um sein System anzuzeigen',
|
||||
totalPositions: 'Insgesamt 10 Planetenpositionen',
|
||||
mine: 'Mein',
|
||||
hostile: 'Feindlich',
|
||||
emptySlot: 'Leer - Kolonisierbar',
|
||||
scout: 'Spähen',
|
||||
attack: 'Angriff',
|
||||
missileAttack: 'Raketenangriff',
|
||||
colonize: 'Kolonisieren',
|
||||
switch: 'Wechseln',
|
||||
recycle: 'Recyceln',
|
||||
debrisField: 'Trümmerfeld',
|
||||
scoutPlanetTitle: 'Planet ausspionieren',
|
||||
attackPlanetTitle: 'Planet angreifen',
|
||||
missileAttackTitle: 'Raketenangriff',
|
||||
colonizePlanetTitle: 'Planet kolonisieren',
|
||||
recyclePlanetTitle: 'Trümmer recyceln',
|
||||
scoutPlanetMessage:
|
||||
'Möchten Sie wirklich Spionagesonden senden, um Planet [{coordinates}] auszuspionieren?\n\nBitte gehen Sie zur Flottenseite, um Schiffe auszuwählen und zu senden.',
|
||||
attackPlanetMessage:
|
||||
'Möchten Sie wirklich Planet [{coordinates}] angreifen?\n\nBitte gehen Sie zur Flottenseite, um Schiffe auszuwählen und zu senden.',
|
||||
missileAttackMessage: 'Interkontinentalraketen starten, um Planet [{coordinates}] anzugreifen',
|
||||
missileCount: 'Raketenanzahl',
|
||||
availableMissiles: 'Verfügbare Raketen',
|
||||
missileRange: 'Raketenreichweite',
|
||||
systems: 'Systeme',
|
||||
distance: 'Entfernung',
|
||||
flightTime: 'Flugzeit',
|
||||
launchMissile: 'Starten',
|
||||
cancel: 'Abbrechen',
|
||||
colonizePlanetMessage:
|
||||
'Möchten Sie wirklich Position [{coordinates}] kolonisieren?\n\nBitte gehen Sie zur Flottenseite, um ein Kolonieschiff zu senden.',
|
||||
recyclePlanetMessage:
|
||||
'Möchten Sie wirklich Trümmer bei Position [{coordinates}] recyceln?\n\nBitte gehen Sie zur Flottenseite, um Recycler zu senden.'
|
||||
'Möchten Sie wirklich Trümmer bei Position [{coordinates}] recyceln?\n\nBitte gehen Sie zur Flottenseite, um Recycler zu senden.',
|
||||
sendGift: 'Geschenk senden',
|
||||
debris: 'Trümmer',
|
||||
giftPlanetTitle: 'Geschenk senden',
|
||||
giftPlanetMessage:
|
||||
'Möchten Sie wirklich Ressourcen als Geschenk an Planet [{coordinates}] senden?\n\nBitte gehen Sie zur Flottenseite, um Transporter auszuwählen und Ressourcen zu laden.'
|
||||
},
|
||||
messagesView: {
|
||||
title: 'Nachrichten',
|
||||
battles: 'Kämpfe',
|
||||
spy: 'Spionage',
|
||||
npc: 'NPC',
|
||||
diplomacy: '',
|
||||
spied: 'Ausspioniert',
|
||||
battleReports: 'Kampfberichte',
|
||||
spyReports: 'Spionageberichte',
|
||||
noBattleReports: 'Keine Kampfberichte',
|
||||
noSpyReports: 'Keine Spionageberichte',
|
||||
noDiplomaticReports: '',
|
||||
noSpiedNotifications: 'Keine Ausspionierungs-Benachrichtigungen',
|
||||
battleReport: 'Kampfbericht',
|
||||
spyReport: 'Spionagebericht',
|
||||
spiedNotification: 'Ausspionierungs-Benachrichtigung',
|
||||
victory: 'Sieg',
|
||||
defeat: 'Niederlage',
|
||||
draw: 'Unentschieden',
|
||||
detected: 'Entdeckt',
|
||||
undetected: 'Unentdeckt',
|
||||
attackerFleet: 'Angreiferflotte',
|
||||
defenderFleet: 'Verteidigerflotte',
|
||||
defenderDefense: 'Verteidigerverteidigung',
|
||||
@@ -517,7 +630,74 @@ export default {
|
||||
hideRoundDetails: 'Rundendetails ausblenden',
|
||||
round: 'Runde {round}',
|
||||
attackerRemainingPower: 'Verbleibende Angreiferkraft',
|
||||
defenderRemainingPower: 'Verbleibende Verteidigerkraft'
|
||||
defenderRemainingPower: 'Verbleibende Verteidigerkraft',
|
||||
missions: 'Missionen',
|
||||
noMissionReports: 'Keine Missionsberichte',
|
||||
success: 'Erfolg',
|
||||
failed: 'Fehlgeschlagen',
|
||||
npcActivity: 'NPC-Aktivität',
|
||||
noNPCActivity: 'Keine NPC-Aktivitätsbenachrichtigungen',
|
||||
npcRecycleActivity: 'NPC recycelt Trümmer',
|
||||
gifts: 'Geschenke',
|
||||
giftRejected: 'Abgelehnt',
|
||||
noGiftNotifications: 'Keine Geschenkbenachrichtigungen',
|
||||
noGiftRejected: 'Keine abgelehnten Geschenke',
|
||||
giftFrom: 'Geschenk von {npcName}',
|
||||
giftRejectedBy: '{npcName} hat das Geschenk abgelehnt',
|
||||
giftResources: 'Geschenk-Ressourcen',
|
||||
rejectedResources: 'Abgelehnte Ressourcen',
|
||||
expectedReputation: 'Erwarteter Ruf',
|
||||
currentReputation: 'Aktueller Ruf',
|
||||
acceptGift: 'Annehmen',
|
||||
rejectGift: 'Ablehnen',
|
||||
rejectionReason: {
|
||||
hostile: 'Sie sind feindlich und nehmen keine Geschenke an',
|
||||
neutral_distrust: 'Sie vertrauen Ihnen nicht',
|
||||
polite_decline: 'Sie lehnten höflich ab'
|
||||
},
|
||||
// Spied notification dialog
|
||||
spiedNotificationDetails: '',
|
||||
spyDetected: '',
|
||||
detectionResult: '',
|
||||
detectionSuccess: '',
|
||||
spiedNotificationMessage: '',
|
||||
spiedNotificationTip: '',
|
||||
viewInGalaxy: '',
|
||||
// Mission report dialog
|
||||
missionReportDetails: '',
|
||||
missionSuccess: '',
|
||||
missionFailed: '',
|
||||
origin: '',
|
||||
destination: '',
|
||||
missionDetails: '',
|
||||
transportedResources: '',
|
||||
recycledResources: '',
|
||||
remainingDebris: '',
|
||||
newPlanet: '',
|
||||
// NPC activity dialog
|
||||
npcActivityDetails: '',
|
||||
activityType: {
|
||||
recycle: ''
|
||||
},
|
||||
activityLocation: '',
|
||||
position: '',
|
||||
nearPlanet: '',
|
||||
activityDescription: '',
|
||||
npcActivityMessage: '',
|
||||
arrivalTime: '',
|
||||
npcActivityTip: ''
|
||||
},
|
||||
missionReports: {
|
||||
transportSuccess: 'Transportmission erfolgreich abgeschlossen',
|
||||
transportFailed: 'Transportmission fehlgeschlagen',
|
||||
colonizeSuccess: 'Kolonisierungsmission erfolgreich, neuer Planet gegründet',
|
||||
colonizeFailed: 'Kolonisierungsmission fehlgeschlagen',
|
||||
deploySuccess: 'Einsatzmission erfolgreich abgeschlossen',
|
||||
deployFailed: 'Einsatzmission fehlgeschlagen',
|
||||
recycleSuccess: 'Recyclingmission erfolgreich abgeschlossen',
|
||||
recycleFailed: 'Recyclingmission fehlgeschlagen, keine Trümmer am Zielort',
|
||||
destroySuccess: 'Planetenzerstörungsmission erfolgreich ausgeführt',
|
||||
destroyFailed: 'Planetenzerstörungsmission fehlgeschlagen'
|
||||
},
|
||||
simulatorView: {
|
||||
title: 'Kampfsimulator',
|
||||
@@ -570,13 +750,15 @@ export default {
|
||||
selectFile: 'Datei auswählen',
|
||||
importSuccess: 'Import erfolgreich',
|
||||
importConfirmTitle: 'Import bestätigen',
|
||||
importConfirmMessage: 'Beim Importieren wird der aktuelle Spielfortschritt überschrieben. Diese Aktion kann nicht rückgängig gemacht werden. Fortfahren?',
|
||||
importConfirmMessage:
|
||||
'Beim Importieren wird der aktuelle Spielfortschritt überschrieben. Diese Aktion kann nicht rückgängig gemacht werden. Fortfahren?',
|
||||
importFailed: 'Import fehlgeschlagen, bitte Dateiformat überprüfen',
|
||||
clearData: 'Daten löschen',
|
||||
clearDataDesc: 'Alle Spieldaten löschen und zurücksetzen',
|
||||
clear: 'Löschen',
|
||||
clearConfirmTitle: 'Löschen bestätigen',
|
||||
clearConfirmMessage: 'Alle Spieldaten werden gelöscht und von vorne begonnen. Diese Aktion kann nicht rückgängig gemacht werden. Fortfahren?',
|
||||
clearConfirmMessage:
|
||||
'Alle Spieldaten werden gelöscht und von vorne begonnen. Diese Aktion kann nicht rückgängig gemacht werden. Fortfahren?',
|
||||
gameSettings: 'Spieleinstellungen',
|
||||
gameSettingsDesc: 'Spielparameter und Einstellungen anpassen',
|
||||
gamePause: 'Spielpause',
|
||||
@@ -586,10 +768,24 @@ export default {
|
||||
gamePaused: 'Spiel pausiert',
|
||||
gameResumed: 'Spiel fortgesetzt',
|
||||
playerName: 'Spielername',
|
||||
gameSpeed: 'Spielgeschwindigkeit',
|
||||
gameSpeedDesc: 'Aktueller Spielgeschwindigkeitsmultiplikator',
|
||||
gameSpeed: 'Ressourcenproduktionsgeschwindigkeit',
|
||||
gameSpeedDesc: 'Aktueller Ressourcenproduktionsgeschwindigkeitsmultiplikator',
|
||||
speedChanged: 'Ressourcenproduktionsgeschwindigkeit auf {speed}x geändert',
|
||||
speedReset: 'Ressourcenproduktionsgeschwindigkeit auf 1x zurückgesetzt',
|
||||
reset: 'Zurücksetzen',
|
||||
about: 'Über',
|
||||
version: 'Version',
|
||||
latestVersion: 'Neueste Version',
|
||||
checkUpdate: 'Update prüfen',
|
||||
checking: 'Prüfen...',
|
||||
newVersionAvailable: 'Neue Version {version} verfügbar',
|
||||
upToDate: 'Bereits auf dem neuesten Stand',
|
||||
checkUpdateCooldown: 'Bitte versuchen Sie es später erneut (5 Minuten Abklingzeit)',
|
||||
checkUpdateFailed: 'Update-Prüfung fehlgeschlagen, bitte überprüfen Sie Ihre Netzwerkverbindung',
|
||||
viewUpdate: 'Update ansehen',
|
||||
updateAvailable: 'Eine neue Version ist verfügbar. Klicken Sie, um die Versionshinweise anzuzeigen.',
|
||||
download: 'Herunterladen',
|
||||
goToDownload: 'Zum Download',
|
||||
buildDate: 'Build-Datum',
|
||||
community: 'Community',
|
||||
github: 'GitHub-Repository',
|
||||
@@ -608,6 +804,8 @@ export default {
|
||||
officers: 'Offiziere',
|
||||
modifyResources: 'Ressourcen ändern',
|
||||
resourcesDesc: 'Planetenressourcen schnell ändern',
|
||||
maxAllResources: '',
|
||||
maxAllResourcesSuccess: '',
|
||||
modifyBuildings: 'Gebäude ändern',
|
||||
buildingsDesc: 'Gebäudelevel schnell festlegen',
|
||||
modifyResearch: 'Forschung ändern',
|
||||
@@ -619,9 +817,178 @@ export default {
|
||||
modifyOfficers: 'Offiziere ändern',
|
||||
officersDesc: 'Offiziersablaufzeit schnell festlegen',
|
||||
days: 'T',
|
||||
npcTesting: 'NPC-Test',
|
||||
npcTestingDesc: 'NPC-Spionage- und Angriffsverhalten testen',
|
||||
selectNPC: 'NPC auswählen',
|
||||
chooseNPC: 'Wählen Sie einen NPC',
|
||||
targetPlanet: 'Zielplanet',
|
||||
chooseTarget: 'Zielplanet auswählen',
|
||||
testSpy: 'Spionage testen',
|
||||
testAttack: 'Angriff testen',
|
||||
testSpyAndAttack: 'Spionage & Angriff testen',
|
||||
testSpyMessage: 'Klicken Sie auf Bestätigen, um die Spionagemission zu beschleunigen',
|
||||
testAttackMessage: 'Klicken Sie auf Bestätigen, um die Angriffsmission zu beschleunigen',
|
||||
testSpyAndAttackMessage: 'Klicken Sie auf Bestätigen, um die Missionen zu beschleunigen',
|
||||
initializeFleet: 'NPC-Flotte initialisieren',
|
||||
accelerateMissions: 'Alle Missionen beschleunigen (5s)',
|
||||
selectNPCFirst: 'Bitte wählen Sie zuerst einen NPC',
|
||||
npcNoProbes: 'NPC hat keine Spionagesonden',
|
||||
npcNoSpyReport: 'NPC muss zuerst spionieren',
|
||||
npcMissionFailed: 'Mission konnte nicht erstellt werden',
|
||||
npcNoPlanets: 'NPC hat keine Planeten',
|
||||
npcWillSpyIn5s: '{npcName} wird in 5 Sekunden spionieren',
|
||||
npcWillAttackIn5s: '{npcName} wird in 5 Sekunden angreifen',
|
||||
npcWillSpyAndAttack: '{npcName} wird in 5s spionieren und in 10s angreifen',
|
||||
acceleratedMissions: '{count} Missionen auf 5 Sekunden beschleunigt',
|
||||
npcFleetInitialized: '{npcName} Flotte initialisiert',
|
||||
npcFleetDetails:
|
||||
'100 Spionagesonden\n500 Leichte Jäger\n300 Schwere Jäger\n200 Kreuzer\n100 Schlachtschiffe\n50 Bomber\n30 Zerstörer\n20 Schlachtkreuzer',
|
||||
dangerZone: 'Gefahrenzone',
|
||||
dangerZoneDesc: 'Die folgenden Vorgänge sind irreversibel',
|
||||
resetGame: 'Spiel zurücksetzen',
|
||||
resetGameConfirm: 'Möchten Sie das Spiel wirklich zurücksetzen? Alle Daten werden gelöscht!'
|
||||
resetGameConfirm: 'Möchten Sie das Spiel wirklich zurücksetzen? Alle Daten werden gelöscht!',
|
||||
completeAllQueues: '',
|
||||
completeAllQueuesDesc: '',
|
||||
completeQueues: '',
|
||||
completeQueuesSuccess: ''
|
||||
},
|
||||
alerts: {
|
||||
npcSpyIncoming: 'NPC-Spionagesonde nähert sich',
|
||||
npcAttackIncoming: 'NPC-Flotten-Angriff im Anmarsch!',
|
||||
npcFleetIncoming: 'NPC-Flotte nähert sich',
|
||||
ships: 'Schiffe',
|
||||
spiedBy: 'Ausspioniert von',
|
||||
attackedBy: 'Angegriffen von',
|
||||
detectionSuccess: 'Spionage entdeckt',
|
||||
detectionFailed: 'Spionage nicht entdeckt',
|
||||
npcSpiedYourPlanet: 'NPC hat deinen Planeten ausspioniert',
|
||||
npcAttackedYourPlanet: 'NPC hat deinen Planeten angegriffen'
|
||||
},
|
||||
diplomacy: {
|
||||
title: 'Diplomatie',
|
||||
description: 'Verwalte diplomatische Beziehungen mit NPCs',
|
||||
tabs: {
|
||||
all: 'Alle',
|
||||
friendly: 'Freundlich',
|
||||
neutral: 'Neutral',
|
||||
hostile: 'Feindlich'
|
||||
},
|
||||
noNpcs: 'Keine NPCs',
|
||||
noFriendlyNpcs: 'Keine freundlichen NPCs',
|
||||
noNeutralNpcs: 'Keine neutralen NPCs',
|
||||
noHostileNpcs: 'Keine feindlichen NPCs',
|
||||
recentEvents: 'Aktuelle Ereignisse',
|
||||
recentEventsDescription: 'Protokoll der jüngsten diplomatischen Aktivitäten',
|
||||
ago: 'vor',
|
||||
notifications: '',
|
||||
markAllRead: '',
|
||||
noReports: '',
|
||||
viewAll: '',
|
||||
status: {
|
||||
friendly: 'Freundlich',
|
||||
neutral: 'Neutral',
|
||||
hostile: 'Feindlich'
|
||||
},
|
||||
planets: 'Planeten',
|
||||
allies: 'Verbündete',
|
||||
reputation: 'Ansehen',
|
||||
alliedWith: 'Verbündet mit',
|
||||
more: 'weitere',
|
||||
actions: {
|
||||
gift: 'Geschenk senden',
|
||||
viewPlanets: 'Planeten ansehen'
|
||||
},
|
||||
lastEvent: 'Letztes Ereignis',
|
||||
reportDetails: '',
|
||||
eventDescription: '',
|
||||
reputationChange: '',
|
||||
before: '',
|
||||
after: '',
|
||||
statusChange: '',
|
||||
viewDiplomacy: '',
|
||||
events: {
|
||||
gift: 'Geschenk gesendet',
|
||||
attack: 'Angriff',
|
||||
missileAttack: 'Raketenangriff',
|
||||
allyAttacked: 'Verbündeter angegriffen',
|
||||
spy: 'Spionage',
|
||||
stealDebris: 'Trümmer gestohlen'
|
||||
},
|
||||
reports: {
|
||||
giftedResources: '{metal}M {crystal}K {deuterium}D geschenkt',
|
||||
receivedGiftFromPlayer: 'Geschenk von Spieler erhalten',
|
||||
giftedToNpc: 'Sie haben {npcName} Ressourcen geschenkt. Ansehen +{reputation}',
|
||||
rejectedPlayerGift: 'Geschenk des Spielers abgelehnt',
|
||||
npcRejectedGift: '{npcName} hat Ihr Geschenk abgelehnt. Ansehen {reputation}',
|
||||
attackedNpc: '{npcName} angegriffen',
|
||||
wasAttackedByPlayer: 'Wurde von Spieler angegriffen',
|
||||
youAttackedNpc: 'Sie haben {npcName} angegriffen',
|
||||
playerAttackedAlly: 'Spieler hat Verbündeten {allyName} angegriffen',
|
||||
allyDispleased: '{allyName} ist unzufrieden, dass Sie ihren Verbündeten {targetName} angegriffen haben',
|
||||
wasSpiedByPlayer: 'Wurde von Spieler ausspioniert (entdeckt: {detected})',
|
||||
spyDetected: 'Ihre Spionage wurde von {npcName} entdeckt',
|
||||
stoleDebrisFromTerritory: 'Trümmer aus {npcName}s Territorium gestohlen',
|
||||
playerStoleDebris: 'Spieler hat Trümmer aus Territorium gestohlen',
|
||||
recycledDebrisNearNpc: 'Sie haben Trümmer in der Nähe von {npcName}s Planeten recycelt. Sie sind unzufrieden.',
|
||||
giftedResourcesToPlayer: 'Ressourcen an Spieler geschenkt',
|
||||
receivedGiftFromNpc: 'Geschenk von {npcName} erhalten',
|
||||
acceptedGiftFromNpc: 'Sie haben ein Geschenk von {npcName} angenommen: {metal}M {crystal}K {deuterium}D',
|
||||
playerRejectedGift: 'Spieler hat Geschenk abgelehnt',
|
||||
rejectedGiftFromNpc: 'Sie haben ein Geschenk von {npcName} abgelehnt. Ansehen {reputation}',
|
||||
destroyedNpcPlanet: '{npcName}s {planetName} zerstört',
|
||||
playerDestroyedPlanet: 'Spieler hat {planetName} zerstört',
|
||||
youDestroyedNpcPlanet: 'Sie haben {npcName}s {planetName} zerstört. Ansehen {reputation}',
|
||||
playerDestroyedAllyPlanet: 'Spieler hat Verbündeten {allyName}s {planetName} zerstört',
|
||||
allyOutraged: '{allyName} ist empört, dass Sie den Planeten {planetName} ihres Verbündeten {targetName} zerstört haben',
|
||||
npcEliminated: 'NPC {npcName} wurde vollständig eliminiert',
|
||||
npcEliminatedMessage: 'Sie haben alle Planeten von {npcName} zerstört! Diese Fraktion wurde vollständig ausgelöscht.'
|
||||
}
|
||||
},
|
||||
pagination: {
|
||||
previous: 'Vorherige',
|
||||
next: 'Nächste',
|
||||
gotIt: '',
|
||||
first: 'Erste',
|
||||
last: 'Letzte',
|
||||
page: 'Seite {page}'
|
||||
},
|
||||
notFound: {
|
||||
title: 'Seite nicht gefunden',
|
||||
description: 'Entschuldigung, die gesuchte Seite existiert nicht',
|
||||
goHome: 'Zur Startseite'
|
||||
},
|
||||
time: {
|
||||
days: 'Tage',
|
||||
hours: 'Stunden',
|
||||
minutes: 'Minuten',
|
||||
seconds: 'Sekunden'
|
||||
},
|
||||
tutorial: {
|
||||
welcome: {
|
||||
title: 'Willkommen bei OGame',
|
||||
content: 'Willkommen, Kommandant! Beginnen wir mit den Grundlagen und bauen Sie Ihr Weltraum-Imperium auf.'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: 'Solarkraftwerk bauen',
|
||||
content:
|
||||
'Bauen Sie zuerst ein Solarkraftwerk! Es liefert Energie für Ihren Planeten. Ohne Energie können andere Ressourcengebäude nicht funktionieren. Dies ist der wichtigste erste Schritt.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Bauauftrag',
|
||||
content:
|
||||
'Ihr Gebäude befindet sich jetzt in der Bauauftragsliste. Klicken Sie auf das Warteschlangensymbol oben rechts, um alle laufenden Bau- und Forschungsaufträge anzuzeigen. Gebäude brauchen Zeit zum Fertigstellen, aber Sie können während des Wartens weitermachen.'
|
||||
},
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: 'Willkommen bei OGame (Mobil)',
|
||||
content:
|
||||
'Willkommen, Kommandant! Dies ist ein optimiertes Tutorial für Touchscreens. Wir werden schnell die Kernfunktionen durchgehen, damit Sie mit dem Aufbau Ihres Imperiums beginnen können.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Bauauftrag',
|
||||
content:
|
||||
'Klicken Sie auf das Warteschlangensymbol oben rechts, um den Baufortschritt anzuzeigen. Sie können weiter andere Seiten durchsuchen - der Bau läuft im Hintergrund.'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,19 @@ export default {
|
||||
viewRequirements: 'View Requirements',
|
||||
requirementsNotMet: 'Requirements Not Met',
|
||||
current: 'Current',
|
||||
level: 'Level'
|
||||
level: 'Level',
|
||||
gmModeActivated: 'GM Mode Activated! Check the navigation menu.'
|
||||
},
|
||||
errors: {
|
||||
requirementsNotMet: 'Requirements not met',
|
||||
insufficientResources: 'Insufficient resources',
|
||||
insufficientFleetStorage: 'Insufficient fleet storage',
|
||||
shieldDomeLimit: 'Shield dome limit reached',
|
||||
missileSiloLimit: 'Missile silo capacity exceeded',
|
||||
insufficientMissiles: 'Insufficient interplanetary missiles',
|
||||
invalidMissileCount: 'Invalid missile count',
|
||||
targetOutOfRange: 'Target out of range',
|
||||
cannotAttackOwnPlanet: 'Cannot attack your own planet',
|
||||
fleetMissionsFull: 'Fleet mission slots full',
|
||||
insufficientFleet: 'Insufficient fleet',
|
||||
insufficientFuel: 'Insufficient fuel',
|
||||
@@ -62,6 +68,7 @@ export default {
|
||||
officers: 'Officers',
|
||||
simulator: 'Simulator',
|
||||
galaxy: 'Galaxy',
|
||||
diplomacy: 'Diplomacy',
|
||||
messages: 'Messages',
|
||||
settings: 'Settings',
|
||||
gm: 'GM'
|
||||
@@ -97,6 +104,8 @@ export default {
|
||||
coordinates: 'Coordinates',
|
||||
switchToMoon: 'View Moon',
|
||||
backToPlanet: 'Back to Planet',
|
||||
switchPlanet: 'Switch Planet',
|
||||
currentPlanet: 'Current Planet',
|
||||
fields: 'Fields',
|
||||
temperature: 'Temperature',
|
||||
homePlanet: 'Home Planet',
|
||||
@@ -112,14 +121,18 @@ export default {
|
||||
crystalMine: 'Crystal Mine',
|
||||
deuteriumSynthesizer: 'Deuterium Synthesizer',
|
||||
solarPlant: 'Solar Plant',
|
||||
fusionReactor: 'Fusion Reactor',
|
||||
roboticsFactory: 'Robotics Factory',
|
||||
naniteFactory: 'Nanite Factory',
|
||||
shipyard: 'Shipyard',
|
||||
hangar: 'Hangar',
|
||||
researchLab: 'Research Lab',
|
||||
metalStorage: 'Metal Storage',
|
||||
crystalStorage: 'Crystal Storage',
|
||||
deuteriumTank: 'Deuterium Tank',
|
||||
darkMatterCollector: 'Dark Matter Collector',
|
||||
darkMatterTank: 'Dark Matter Tank',
|
||||
missileSilo: 'Missile Silo',
|
||||
terraformer: 'Terraformer',
|
||||
lunarBase: 'Lunar Base',
|
||||
sensorPhalanx: 'Sensor Phalanx',
|
||||
@@ -130,23 +143,37 @@ export default {
|
||||
consumption: 'Consumption',
|
||||
totalCost: 'Total Cost',
|
||||
totalPoints: 'Total Points',
|
||||
levelRange: 'Level Range'
|
||||
levelRange: 'Level Range',
|
||||
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueueBonus: 'Build Queue',
|
||||
spaceBonus: 'Space Bonus',
|
||||
buildSpeedBonus: 'Build Speed Bonus',
|
||||
researchSpeedBonus: 'Research Speed Bonus',
|
||||
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
buildingDescriptions: {
|
||||
metalMine: 'Extracts metal resources',
|
||||
crystalMine: 'Extracts crystal resources',
|
||||
deuteriumSynthesizer: 'Synthesizes deuterium resources',
|
||||
solarPlant: 'Provides energy',
|
||||
fusionReactor: 'Uses deuterium to generate large amounts of energy',
|
||||
roboticsFactory: 'Accelerates construction speed',
|
||||
naniteFactory: 'Increases build queue capacity, +1 per level (max 10 levels)',
|
||||
shipyard: 'Constructs ships',
|
||||
hangar: 'Specialized facility for expanding fleet storage capacity, supports planetary specialization',
|
||||
researchLab: 'Researches technologies',
|
||||
metalStorage: 'Increases metal storage capacity',
|
||||
crystalStorage: 'Increases crystal storage capacity',
|
||||
deuteriumTank: 'Increases deuterium storage capacity',
|
||||
darkMatterCollector: 'Collects rare dark matter resources',
|
||||
terraformer: 'Terraforms planet surface, adds 5 available space per level',
|
||||
lunarBase: 'Increases available space on the moon, +5 space per level',
|
||||
darkMatterTank: 'Increases dark matter storage capacity',
|
||||
missileSilo: 'Stores and launches missiles, 10 missiles per level',
|
||||
terraformer: 'Terraforms planet surface, adds 30 available space per level',
|
||||
lunarBase: 'Increases available space on the moon, +30 space per level',
|
||||
sensorPhalanx: 'Detects fleet activities in surrounding systems',
|
||||
jumpGate: 'Instantly transfers fleets to other moons',
|
||||
planetDestroyerFactory: 'Constructs ultimate weapons capable of destroying planets'
|
||||
@@ -156,11 +183,15 @@ export default {
|
||||
heavyFighter: 'Heavy Fighter',
|
||||
cruiser: 'Cruiser',
|
||||
battleship: 'Battleship',
|
||||
battlecruiser: 'Battlecruiser',
|
||||
bomber: 'Bomber',
|
||||
destroyer: 'Destroyer',
|
||||
smallCargo: 'Small Cargo',
|
||||
largeCargo: 'Large Cargo',
|
||||
colonyShip: 'Colony Ship',
|
||||
recycler: 'Recycler',
|
||||
espionageProbe: 'Espionage Probe',
|
||||
solarSatellite: 'Solar Satellite',
|
||||
darkMatterHarvester: 'Dark Matter Harvester',
|
||||
deathstar: 'Deathstar'
|
||||
},
|
||||
@@ -168,12 +199,16 @@ export default {
|
||||
lightFighter: 'Basic combat unit',
|
||||
heavyFighter: 'Heavily armored fighter',
|
||||
cruiser: 'Medium warship, balanced offense and defense',
|
||||
battleship: 'Powerful warship',
|
||||
battleship: 'Main heavy warship with powerful firepower and strong defense',
|
||||
battlecruiser: 'Fast powerful warship, excels at attacking battleships',
|
||||
bomber: 'Specialized ship for attacking defense structures',
|
||||
destroyer: 'Specialized anti-capital ship with high firepower but low defense',
|
||||
smallCargo: 'Transports small amounts of resources',
|
||||
largeCargo: 'Transports large amounts of resources',
|
||||
colonyShip: 'Used to colonize new planets',
|
||||
recycler: 'Collects debris field resources',
|
||||
espionageProbe: 'Scouts enemy planets',
|
||||
solarSatellite: 'Provides extra energy, generates 50 energy per satellite',
|
||||
darkMatterHarvester: 'Special ship for harvesting dark matter',
|
||||
deathstar: 'Ultimate weapon capable of destroying entire planets'
|
||||
},
|
||||
@@ -186,6 +221,8 @@ export default {
|
||||
plasmaTurret: 'Plasma Turret',
|
||||
smallShieldDome: 'Small Shield Dome',
|
||||
largeShieldDome: 'Large Shield Dome',
|
||||
antiBallisticMissile: 'Anti-Ballistic Missile',
|
||||
interplanetaryMissile: 'Interplanetary Missile',
|
||||
planetaryShield: 'Planetary Shield'
|
||||
},
|
||||
defenseDescriptions: {
|
||||
@@ -197,13 +234,25 @@ export default {
|
||||
plasmaTurret: 'Powerful defense facility',
|
||||
smallShieldDome: 'Small shield protecting the entire planet',
|
||||
largeShieldDome: 'Large shield protecting the entire planet',
|
||||
antiBallisticMissile: 'Intercepts enemy missiles, can intercept 1 interplanetary missile each',
|
||||
interplanetaryMissile: 'Can attack defense structures on other planets',
|
||||
planetaryShield: 'Super shield protecting planet from destruction attacks'
|
||||
},
|
||||
research: {
|
||||
researchTime: 'Research Time',
|
||||
totalCost: 'Total Cost',
|
||||
totalPoints: 'Total Points',
|
||||
levelRange: 'Level Range'
|
||||
levelRange: 'Level Range',
|
||||
|
||||
attackBonus: 'Attack Bonus',
|
||||
shieldBonus: 'Shield Bonus',
|
||||
armorBonus: 'Armor Bonus',
|
||||
spyLevel: 'Spy Level',
|
||||
researchQueueBonus: 'Research Queue',
|
||||
colonySlots: 'Colony Slots',
|
||||
forAllPlanets: '(Global)',
|
||||
speedBonus: 'Speed Bonus',
|
||||
researchSpeedBonus: 'Research Speed Bonus'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'Energy Technology',
|
||||
@@ -212,6 +261,12 @@ export default {
|
||||
hyperspaceTechnology: 'Hyperspace Technology',
|
||||
plasmaTechnology: 'Plasma Technology',
|
||||
computerTechnology: 'Computer Technology',
|
||||
espionageTechnology: 'Espionage Technology',
|
||||
weaponsTechnology: 'Weapons Technology',
|
||||
shieldingTechnology: 'Shielding Technology',
|
||||
armourTechnology: 'Armour Technology',
|
||||
astrophysics: 'Astrophysics',
|
||||
gravitonTechnology: 'Graviton Technology',
|
||||
combustionDrive: 'Combustion Drive',
|
||||
impulseDrive: 'Impulse Drive',
|
||||
hyperspaceDrive: 'Hyperspace Drive',
|
||||
@@ -226,11 +281,17 @@ export default {
|
||||
hyperspaceTechnology: 'Hyperspace jump technology',
|
||||
plasmaTechnology: 'Plasma weapon technology',
|
||||
computerTechnology: 'Increases research queue capacity, +1 per level (max 10 levels)',
|
||||
espionageTechnology: 'Improves spy probe effectiveness, +1 espionage level per level',
|
||||
weaponsTechnology: 'Increases ship and defense attack power by 10% per level',
|
||||
shieldingTechnology: 'Increases ship and defense shields by 10% per level',
|
||||
armourTechnology: 'Increases ship and defense armour by 10% per level',
|
||||
astrophysics: 'Each level adds 1 colony slot and increases expedition success rate',
|
||||
gravitonTechnology: 'Studies graviton manipulation, required for Death Star',
|
||||
combustionDrive: 'Basic propulsion technology',
|
||||
impulseDrive: 'Intermediate propulsion technology',
|
||||
hyperspaceDrive: 'Advanced propulsion technology',
|
||||
darkMatterTechnology: 'Research into dark matter properties and applications',
|
||||
terraformingTechnology: 'Research planet terraforming technology, adds 3 available space to all planets per level',
|
||||
terraformingTechnology: 'Research planet terraforming technology, adds 30 available space to all planets per level',
|
||||
planetDestructionTech: 'Terrifying technology for destroying entire planets'
|
||||
},
|
||||
officers: {
|
||||
@@ -253,10 +314,16 @@ export default {
|
||||
darkMatterSpecialist: 'Improves dark matter collection efficiency'
|
||||
},
|
||||
queue: {
|
||||
buildQueue: 'Build Queue',
|
||||
researchQueue: 'Research Queue',
|
||||
title: 'Build Queue',
|
||||
empty: 'No active tasks',
|
||||
buildQueueBonus: 'Build Queue',
|
||||
spaceBonus: 'Space Bonus',
|
||||
buildSpeedBonus: 'Build Speed Bonus',
|
||||
researchSpeedBonus: 'Research Speed Bonus',
|
||||
researchQueueBonus: 'Research Queue',
|
||||
building: 'Building',
|
||||
researching: 'Researching',
|
||||
demolishing: 'Demolishing',
|
||||
remaining: 'Remaining',
|
||||
cancel: 'Cancel',
|
||||
cancelBuild: 'Cancel Build',
|
||||
@@ -294,7 +361,9 @@ export default {
|
||||
demolish: 'Demolish',
|
||||
demolishRefund: 'Demolish Refund',
|
||||
demolishFailed: 'Demolish Failed',
|
||||
demolishFailedMessage: 'Unable to demolish this building. Please check if the build queue is full or the building level is 0.'
|
||||
demolishFailedMessage: 'Unable to demolish this building. Please check if the build queue is full or the building level is 0.',
|
||||
confirmDemolish: 'Confirm Demolish',
|
||||
confirmDemolishMessage: 'Are you sure you want to demolish'
|
||||
},
|
||||
researchView: {
|
||||
title: 'Research',
|
||||
@@ -306,6 +375,7 @@ export default {
|
||||
},
|
||||
shipyard: {
|
||||
attack: 'Attack',
|
||||
missileAttack: 'Missile Attack',
|
||||
shield: 'Shield',
|
||||
armor: 'Armor',
|
||||
speed: 'Speed',
|
||||
@@ -323,6 +393,7 @@ export default {
|
||||
title: 'Shipyard',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
attack: 'Attack',
|
||||
missileAttack: 'Missile Attack',
|
||||
shield: 'Shield',
|
||||
speed: 'Speed',
|
||||
cargoCapacity: 'Cargo Capacity',
|
||||
@@ -337,6 +408,7 @@ export default {
|
||||
},
|
||||
defense: {
|
||||
attack: 'Attack',
|
||||
missileAttack: 'Missile Attack',
|
||||
shield: 'Shield',
|
||||
armor: 'Armor',
|
||||
buildCost: 'Build Cost',
|
||||
@@ -350,6 +422,7 @@ export default {
|
||||
defenseView: {
|
||||
title: 'Defense',
|
||||
attack: 'Attack',
|
||||
missileAttack: 'Missile Attack',
|
||||
shield: 'Shield',
|
||||
armor: 'Armor',
|
||||
buildTime: 'Build Time',
|
||||
@@ -359,6 +432,7 @@ export default {
|
||||
totalCost: 'Total Cost',
|
||||
build: 'Build',
|
||||
shieldDomeBuilt: 'Shield dome already built',
|
||||
missileCapacity: 'Missile Capacity',
|
||||
inputError: 'Input Error',
|
||||
inputErrorMessage: 'Please enter build quantity!',
|
||||
buildFailed: 'Build Failed',
|
||||
@@ -371,6 +445,7 @@ export default {
|
||||
flightMissions: 'Flight Missions',
|
||||
currentPlanetFleet: 'Current Planet Fleet',
|
||||
attack: 'Attack',
|
||||
missileAttack: 'Missile Attack',
|
||||
shield: 'Shield',
|
||||
armor: 'Armor',
|
||||
speed: 'Speed',
|
||||
@@ -405,6 +480,12 @@ export default {
|
||||
arrivalTime: 'Arrival Time',
|
||||
returnTime: 'Return Time',
|
||||
recallFleet: 'Recall Fleet',
|
||||
abortMission: 'Abort Mission',
|
||||
abortMissionTitle: 'Confirm Abort Mission',
|
||||
abortMissionWarning:
|
||||
'WARNING: Aborting this mission will permanently lose {ships} ships and {resources} resources!\n\nThis action is irreversible and the fleet and resources will not return.',
|
||||
abortMissionSuccess: 'Mission Aborted',
|
||||
abortMissionSuccessMessage: 'Mission has been aborted, fleet and resources are lost.',
|
||||
sendFailed: 'Send Failed',
|
||||
sendFailedMessage: 'Please check fleet count, fuel availability, or cargo capacity limits.',
|
||||
recallFailed: 'Recall Failed',
|
||||
@@ -416,7 +497,10 @@ export default {
|
||||
cargoExceedsCapacity: 'Cargo exceeds capacity',
|
||||
noColonyShip: 'Colony ship required for colonization mission',
|
||||
noDebrisAtTarget: 'No debris field at target coordinates or debris field is empty',
|
||||
noDeathstar: 'Deathstar required for destruction mission'
|
||||
noDeathstar: 'Deathstar required for destruction mission',
|
||||
giftMode: 'Gift Mode',
|
||||
giftModeDescription: 'Send resources as a gift to',
|
||||
estimatedReputationGain: 'Estimated reputation gain'
|
||||
},
|
||||
officersView: {
|
||||
title: 'Officers',
|
||||
@@ -437,7 +521,10 @@ export default {
|
||||
fuelConsumption: 'Fuel Consumption',
|
||||
defense: 'Defense',
|
||||
storageCapacity: 'Storage Capacity',
|
||||
buildQueue: 'Build Queue',
|
||||
buildQueueBonus: 'Build Queue',
|
||||
spaceBonus: 'Space Bonus',
|
||||
buildSpeedBonus: 'Build Speed Bonus',
|
||||
researchSpeedBonus: 'Research Speed Bonus',
|
||||
fleetSlots: 'Fleet Slots',
|
||||
hire: 'Hire',
|
||||
renew: 'Renew',
|
||||
@@ -461,35 +548,58 @@ export default {
|
||||
selectSystem: 'Select System',
|
||||
view: 'View',
|
||||
myPlanet: 'My Planet',
|
||||
myPlanets: 'View My Systems',
|
||||
npcPlanets: 'NPC Planets',
|
||||
selectPlanetToView: 'Select planet to view its system',
|
||||
totalPositions: '10 planet positions total',
|
||||
mine: 'Mine',
|
||||
hostile: 'Hostile',
|
||||
emptySlot: 'Empty - Colonizable',
|
||||
scout: 'Scout',
|
||||
attack: 'Attack',
|
||||
missileAttack: 'Missile Attack',
|
||||
colonize: 'Colonize',
|
||||
switch: 'Switch',
|
||||
recycle: 'Recycle',
|
||||
debrisField: 'Debris Field',
|
||||
scoutPlanetTitle: 'Scout Planet',
|
||||
attackPlanetTitle: 'Attack Planet',
|
||||
missileAttackTitle: 'Missile Attack',
|
||||
colonizePlanetTitle: 'Colonize Planet',
|
||||
recyclePlanetTitle: 'Recycle Debris',
|
||||
scoutPlanetMessage:
|
||||
'Are you sure you want to send espionage probes to scout planet [{coordinates}]?\n\nPlease go to the fleet page to select ships and send.',
|
||||
attackPlanetMessage: 'Are you sure you want to attack planet [{coordinates}]?\n\nPlease go to the fleet page to select ships and send.',
|
||||
missileAttackMessage: 'Launch interplanetary missiles to attack planet [{coordinates}]',
|
||||
missileCount: 'Missile Count',
|
||||
availableMissiles: 'Available Missiles',
|
||||
missileRange: 'Missile Range',
|
||||
systems: 'systems',
|
||||
distance: 'Distance',
|
||||
flightTime: 'Flight Time',
|
||||
launchMissile: 'Launch',
|
||||
cancel: 'Cancel',
|
||||
colonizePlanetMessage:
|
||||
'Are you sure you want to colonize position [{coordinates}]?\n\nPlease go to the fleet page to send a colony ship.',
|
||||
recyclePlanetMessage: 'Are you sure you want to recycle debris at position [{coordinates}]?\n\nPlease go to the fleet page to send recycler ships.'
|
||||
recyclePlanetMessage:
|
||||
'Are you sure you want to recycle debris at position [{coordinates}]?\n\nPlease go to the fleet page to send recycler ships.',
|
||||
sendGift: 'Send Gift',
|
||||
debris: 'Debris',
|
||||
giftPlanetTitle: 'Send Gift',
|
||||
giftPlanetMessage:
|
||||
'Are you sure you want to send resources as a gift to planet [{coordinates}]?\n\nPlease go to the fleet page to select transport ships and load resources.'
|
||||
},
|
||||
messagesView: {
|
||||
title: 'Messages',
|
||||
battles: 'Battles',
|
||||
spy: 'Spy',
|
||||
npc: 'NPC',
|
||||
diplomacy: 'Diplomacy',
|
||||
battleReports: 'Battle Reports',
|
||||
spyReports: 'Spy Reports',
|
||||
noBattleReports: 'No battle reports',
|
||||
noSpyReports: 'No spy reports',
|
||||
noDiplomaticReports: 'No diplomatic reports',
|
||||
battleReport: 'Battle Report',
|
||||
spyReport: 'Spy Report',
|
||||
victory: 'Victory',
|
||||
@@ -508,7 +618,79 @@ export default {
|
||||
defense: 'Defense',
|
||||
buildings: 'Buildings',
|
||||
unread: 'Unread',
|
||||
targetPlanet: 'Target Planet'
|
||||
targetPlanet: 'Target Planet',
|
||||
spied: 'Spied',
|
||||
spiedNotification: 'Spied Notification',
|
||||
noSpiedNotifications: 'No spied notifications',
|
||||
detected: 'Detected',
|
||||
undetected: 'Undetected',
|
||||
missions: 'Missions',
|
||||
noMissionReports: 'No mission reports',
|
||||
success: 'Success',
|
||||
failed: 'Failed',
|
||||
npcActivity: 'NPC Activity',
|
||||
noNPCActivity: 'No NPC activity notifications',
|
||||
npcRecycleActivity: 'NPC Recycling Debris',
|
||||
gifts: 'Gifts',
|
||||
giftRejected: 'Rejected',
|
||||
noGiftNotifications: 'No gift notifications',
|
||||
noGiftRejected: 'No rejected gifts',
|
||||
giftFrom: 'Gift from {npcName}',
|
||||
giftRejectedBy: '{npcName} rejected the gift',
|
||||
giftResources: 'Gift resources',
|
||||
rejectedResources: 'Rejected resources',
|
||||
expectedReputation: 'Expected reputation',
|
||||
currentReputation: 'Current reputation',
|
||||
acceptGift: 'Accept',
|
||||
rejectGift: 'Reject',
|
||||
rejectionReason: {
|
||||
hostile: 'They are hostile towards you and do not accept gifts',
|
||||
neutral_distrust: 'They lack trust in you',
|
||||
polite_decline: 'They politely declined'
|
||||
},
|
||||
// Spied notification dialog
|
||||
spiedNotificationDetails: 'Spied Notification Details',
|
||||
spyDetected: 'Spy Detected',
|
||||
detectionResult: 'Detection Result',
|
||||
detectionSuccess: 'Your spy probe was detected!',
|
||||
spiedNotificationMessage: '{npc} attempted to spy on your planet {planet}',
|
||||
spiedNotificationTip: 'Consider increasing your defense or counter-attacking if this NPC is hostile',
|
||||
viewInGalaxy: 'View in Galaxy',
|
||||
// Mission report dialog
|
||||
missionReportDetails: 'Mission Report Details',
|
||||
missionSuccess: 'Success',
|
||||
missionFailed: 'Failed',
|
||||
origin: 'Origin',
|
||||
destination: 'Destination',
|
||||
missionDetails: 'Mission Details',
|
||||
transportedResources: 'Transported Resources',
|
||||
recycledResources: 'Recycled Resources',
|
||||
remainingDebris: 'Remaining Debris',
|
||||
newPlanet: 'New Planet',
|
||||
// NPC activity dialog
|
||||
npcActivityDetails: 'NPC Activity Details',
|
||||
activityType: {
|
||||
recycle: 'Recycling Debris'
|
||||
},
|
||||
activityLocation: 'Activity Location',
|
||||
position: 'Position',
|
||||
nearPlanet: 'Near Planet',
|
||||
activityDescription: 'Activity Description',
|
||||
npcActivityMessage: '{npc} is {activity} at {position}',
|
||||
arrivalTime: 'Arrival Time',
|
||||
npcActivityTip: 'NPCs may collect debris from battles. You can try to reach the location first if you want to compete for resources'
|
||||
},
|
||||
missionReports: {
|
||||
transportSuccess: 'Transport mission completed successfully',
|
||||
transportFailed: 'Transport mission failed',
|
||||
colonizeSuccess: 'Colonization mission successful, new planet established',
|
||||
colonizeFailed: 'Colonization mission failed',
|
||||
deploySuccess: 'Deployment mission completed successfully',
|
||||
deployFailed: 'Deployment mission failed',
|
||||
recycleSuccess: 'Recycling mission completed successfully',
|
||||
recycleFailed: 'Recycling mission failed, no debris at target location',
|
||||
destroySuccess: 'Planet destruction mission executed successfully',
|
||||
destroyFailed: 'Planet destruction mission failed'
|
||||
},
|
||||
simulatorView: {
|
||||
title: 'Battle Simulator',
|
||||
@@ -545,7 +727,12 @@ export default {
|
||||
hideRoundDetails: 'Hide round details',
|
||||
round: 'Round {round}',
|
||||
attackerRemainingPower: 'Attacker remaining power',
|
||||
defenderRemainingPower: 'Defender remaining power'
|
||||
defenderRemainingPower: 'Defender remaining power',
|
||||
spied: 'Spied',
|
||||
spiedNotification: 'Spied Notification',
|
||||
noSpiedNotifications: 'No spied notifications',
|
||||
detected: 'Detected',
|
||||
undetected: 'Undetected'
|
||||
},
|
||||
settings: {
|
||||
dataManagement: 'Data Management',
|
||||
@@ -577,10 +764,24 @@ export default {
|
||||
gamePaused: 'Game paused',
|
||||
gameResumed: 'Game resumed',
|
||||
playerName: 'Player Name',
|
||||
gameSpeed: 'Game Speed',
|
||||
gameSpeedDesc: 'Current game speed multiplier',
|
||||
gameSpeed: 'Resource Production Speed',
|
||||
gameSpeedDesc: 'Current resource production speed multiplier',
|
||||
speedChanged: 'Resource production speed changed to {speed}x',
|
||||
speedReset: 'Resource production speed reset to 1x',
|
||||
reset: 'Reset',
|
||||
about: 'About',
|
||||
version: 'Version',
|
||||
latestVersion: 'Latest Version',
|
||||
checkUpdate: 'Check Update',
|
||||
checking: 'Checking...',
|
||||
newVersionAvailable: 'New version {version} available',
|
||||
upToDate: 'Already up to date',
|
||||
checkUpdateCooldown: 'Please try again later (5 minute cooldown)',
|
||||
checkUpdateFailed: 'Failed to check for updates, please check your network connection',
|
||||
viewUpdate: 'View Update',
|
||||
updateAvailable: 'A new version is available. Click to view release notes.',
|
||||
download: 'Download',
|
||||
goToDownload: 'Go to Download',
|
||||
buildDate: 'Build Date',
|
||||
community: 'Community',
|
||||
github: 'GitHub Repository',
|
||||
@@ -599,6 +800,8 @@ export default {
|
||||
officers: 'Officers',
|
||||
modifyResources: 'Modify Resources',
|
||||
resourcesDesc: 'Quickly modify planet resources',
|
||||
maxAllResources: 'Max All',
|
||||
maxAllResourcesSuccess: 'All resources maxed out',
|
||||
modifyBuildings: 'Modify Buildings',
|
||||
buildingsDesc: 'Quickly set building levels',
|
||||
modifyResearch: 'Modify Research',
|
||||
@@ -610,9 +813,301 @@ export default {
|
||||
modifyOfficers: 'Modify Officers',
|
||||
officersDesc: 'Quickly set officer expiration time',
|
||||
days: 'd',
|
||||
npcTesting: 'NPC Testing',
|
||||
npcTestingDesc: 'Test NPC spy and attack behavior',
|
||||
selectNPC: 'Select NPC',
|
||||
chooseNPC: 'Choose an NPC',
|
||||
targetPlanet: 'Target Planet',
|
||||
chooseTarget: 'Choose target planet',
|
||||
testSpy: 'Test Spy',
|
||||
testAttack: 'Test Attack',
|
||||
testSpyAndAttack: 'Test Spy & Attack',
|
||||
testSpyMessage: 'Click confirm to accelerate the spy mission',
|
||||
testAttackMessage: 'Click confirm to accelerate the attack mission',
|
||||
testSpyAndAttackMessage: 'Click confirm to accelerate the missions',
|
||||
initializeFleet: 'Initialize NPC Fleet',
|
||||
accelerateMissions: 'Accelerate All Missions (5s)',
|
||||
selectNPCFirst: 'Please select an NPC first',
|
||||
npcNoProbes: 'NPC has no spy probes',
|
||||
npcNoSpyReport: 'NPC needs to spy first',
|
||||
npcMissionFailed: 'Failed to create mission',
|
||||
npcNoPlanets: 'NPC has no planets',
|
||||
npcWillSpyIn5s: '{npcName} will spy in 5 seconds',
|
||||
npcWillAttackIn5s: '{npcName} will attack in 5 seconds',
|
||||
npcWillSpyAndAttack: '{npcName} will spy in 5s and attack in 10s',
|
||||
acceleratedMissions: 'Accelerated {count} missions to 5 seconds',
|
||||
npcFleetInitialized: '{npcName} fleet initialized',
|
||||
npcFleetDetails:
|
||||
'100 Spy Probes\n500 Light Fighters\n300 Heavy Fighters\n200 Cruisers\n100 Battleships\n50 Bombers\n30 Destroyers\n20 Battlecruisers',
|
||||
dangerZone: 'Danger Zone',
|
||||
dangerZoneDesc: 'The following operations are irreversible',
|
||||
resetGame: 'Reset Game',
|
||||
resetGameConfirm: 'Are you sure you want to reset the game? This will delete all data!'
|
||||
resetGameConfirm: 'Are you sure you want to reset the game? This will delete all data!',
|
||||
completeAllQueues: 'Complete All Queues',
|
||||
completeAllQueuesDesc: 'Instantly complete all building, research, ship, defense queues and fleet missions',
|
||||
completeQueues: 'Complete Queues',
|
||||
completeQueuesSuccess:
|
||||
'Completed {buildingCount} building queues, {researchCount} research queues, {missionCount} fleet missions, {missileCount} missile attacks'
|
||||
},
|
||||
alerts: {
|
||||
npcSpyIncoming: 'NPC Spy Probe Incoming',
|
||||
npcAttackIncoming: 'NPC Fleet Attack Incoming!',
|
||||
npcFleetIncoming: 'NPC Fleet Approaching',
|
||||
ships: 'ships',
|
||||
spiedBy: 'Spied By',
|
||||
attackedBy: 'Attacked By',
|
||||
detectionSuccess: 'Spy detected',
|
||||
detectionFailed: 'Spy not detected',
|
||||
npcSpiedYourPlanet: 'NPC spied your planet',
|
||||
npcAttackedYourPlanet: 'NPC attacked your planet'
|
||||
},
|
||||
diplomacy: {
|
||||
title: 'Diplomacy',
|
||||
description: 'Manage diplomatic relations with NPCs',
|
||||
tabs: {
|
||||
all: 'All',
|
||||
friendly: 'Friendly',
|
||||
neutral: 'Neutral',
|
||||
hostile: 'Hostile'
|
||||
},
|
||||
noNpcs: 'No NPCs',
|
||||
noFriendlyNpcs: 'No friendly NPCs',
|
||||
noNeutralNpcs: 'No neutral NPCs',
|
||||
noHostileNpcs: 'No hostile NPCs',
|
||||
recentEvents: 'Recent Events',
|
||||
recentEventsDescription: 'Recent diplomatic activity log',
|
||||
ago: 'ago',
|
||||
notifications: 'Diplomatic Notifications',
|
||||
markAllRead: 'Mark All Read',
|
||||
noReports: 'No diplomatic events',
|
||||
viewAll: 'View All',
|
||||
status: {
|
||||
friendly: 'Friendly',
|
||||
neutral: 'Neutral',
|
||||
hostile: 'Hostile'
|
||||
},
|
||||
planets: 'planets',
|
||||
allies: 'allies',
|
||||
reputation: 'Reputation',
|
||||
alliedWith: 'Allied with',
|
||||
more: 'more',
|
||||
actions: {
|
||||
gift: 'Send Gift',
|
||||
viewPlanets: 'View Planets'
|
||||
},
|
||||
lastEvent: 'Last Event',
|
||||
reportDetails: 'Diplomatic Report Details',
|
||||
eventDescription: 'Event Description',
|
||||
reputationChange: 'Reputation Change',
|
||||
before: 'Before',
|
||||
after: 'After',
|
||||
statusChange: 'Status Change',
|
||||
viewDiplomacy: 'View Diplomacy Page',
|
||||
events: {
|
||||
gift: 'Sent Gift',
|
||||
attack: 'Attack',
|
||||
missileAttack: 'Missile Attack',
|
||||
allyAttacked: 'Ally Attacked',
|
||||
spy: 'Espionage',
|
||||
stealDebris: 'Debris Stolen'
|
||||
},
|
||||
reports: {
|
||||
giftedResources: 'Gifted {metal}M {crystal}C {deuterium}D',
|
||||
receivedGiftFromPlayer: 'Received gift from player',
|
||||
giftedToNpc: 'You gifted resources to {npcName}. Reputation +{reputation}',
|
||||
rejectedPlayerGift: "Rejected player's gift",
|
||||
npcRejectedGift: '{npcName} rejected your gift. Reputation {reputation}',
|
||||
attackedNpc: 'Attacked {npcName}',
|
||||
wasAttackedByPlayer: 'Was attacked by player',
|
||||
youAttackedNpc: 'You attacked {npcName}',
|
||||
playerAttackedAlly: 'Player attacked ally {allyName}',
|
||||
allyDispleased: '{allyName} is displeased that you attacked their ally {targetName}',
|
||||
wasSpiedByPlayer: 'Was spied by player (detected: {detected})',
|
||||
spyDetected: 'Your espionage was detected by {npcName}',
|
||||
stoleDebrisFromTerritory: "Stole debris from {npcName}'s territory",
|
||||
playerStoleDebris: 'Player stole debris from territory',
|
||||
recycledDebrisNearNpc: "You recycled debris near {npcName}'s planet. They are displeased.",
|
||||
giftedResourcesToPlayer: 'Gifted resources to player',
|
||||
receivedGiftFromNpc: 'Received gift from {npcName}',
|
||||
acceptedGiftFromNpc: 'You accepted a gift from {npcName}: {metal}M {crystal}C {deuterium}D',
|
||||
playerRejectedGift: 'Player rejected gift',
|
||||
rejectedGiftFromNpc: 'You rejected a gift from {npcName}. Reputation {reputation}',
|
||||
destroyedNpcPlanet: "Destroyed {npcName}'s {planetName}",
|
||||
playerDestroyedPlanet: 'Player destroyed {planetName}',
|
||||
youDestroyedNpcPlanet: "You destroyed {npcName}'s {planetName}. Reputation {reputation}",
|
||||
playerDestroyedAllyPlanet: "Player destroyed ally {allyName}'s {planetName}",
|
||||
allyOutraged: "{allyName} is outraged that you destroyed their ally {targetName}'s {planetName}",
|
||||
npcEliminated: 'NPC {npcName} has been completely eliminated',
|
||||
npcEliminatedMessage: "You destroyed all of {npcName}'s planets! This faction has been completely wiped out."
|
||||
}
|
||||
},
|
||||
pagination: {
|
||||
previous: 'Previous',
|
||||
next: 'Next',
|
||||
first: 'First',
|
||||
last: 'Last',
|
||||
page: 'Page {page}'
|
||||
},
|
||||
notFound: {
|
||||
title: 'Page Not Found',
|
||||
description: 'Sorry, the page you are looking for does not exist',
|
||||
goHome: 'Go Home'
|
||||
},
|
||||
time: {
|
||||
days: 'days',
|
||||
hours: 'hours',
|
||||
minutes: 'minutes',
|
||||
seconds: 'seconds'
|
||||
},
|
||||
tutorial: {
|
||||
progress: 'Progress',
|
||||
previous: 'Previous',
|
||||
next: 'Next',
|
||||
gotIt: 'Got It',
|
||||
completeButton: 'Complete',
|
||||
skip: 'Skip Tutorial',
|
||||
welcome: {
|
||||
title: 'Welcome to OGame',
|
||||
content:
|
||||
'Welcome, Commander! This tutorial will guide you through the basics of building your empire. Click "Next" to begin your journey.'
|
||||
},
|
||||
resources: {
|
||||
title: 'Resource Overview',
|
||||
content:
|
||||
'These are your resources: Metal, Crystal, and Deuterium. They are essential for building structures and researching technologies. Energy is also important to power your infrastructure.'
|
||||
},
|
||||
planet: {
|
||||
title: 'Your Planet',
|
||||
content: 'This is your home planet. You can view its name, coordinates, and switch between planets here as you expand your empire.'
|
||||
},
|
||||
navigation: {
|
||||
title: 'Navigation Menu',
|
||||
content:
|
||||
'Use this menu to navigate between different sections: Buildings, Research, Fleet, Galaxy, and more. Each section offers unique gameplay features.'
|
||||
},
|
||||
gotoBuildings: {
|
||||
title: 'Go to Buildings',
|
||||
content: 'Let\'s start by building some structures. Click on the "Buildings" menu item to view available structures.'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: 'Build Solar Plant',
|
||||
content:
|
||||
'First, build a Solar Plant! It generates energy for your planet. Without energy, other resource buildings cannot function. This is the most important first step.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Build Queue',
|
||||
content:
|
||||
'Your building is now in the construction queue. Click the queue icon in the top-right corner to view all ongoing construction and research tasks. Buildings take time to complete, but you can continue working while waiting.'
|
||||
},
|
||||
buildMetalMine: {
|
||||
title: 'Build Metal Mine',
|
||||
content:
|
||||
"Now that you have energy, you can build the Metal Mine. It's your primary source of metal, which is used in almost every structure and ship."
|
||||
},
|
||||
buildCrystalMine: {
|
||||
title: 'Build Crystal Mine',
|
||||
content: 'Crystal is rarer but essential for advanced technologies. Build a Crystal Mine to start collecting this valuable resource.'
|
||||
},
|
||||
buildDeuterium: {
|
||||
title: 'Build Deuterium Synthesizer',
|
||||
content:
|
||||
'Deuterium is essential for ship fuel and advanced research. Build a Deuterium Synthesizer to start producing this critical resource.'
|
||||
},
|
||||
upgradeMines: {
|
||||
title: 'Upgrade Resource Mines',
|
||||
content:
|
||||
'Next, you need to upgrade all three resource mines (Metal, Crystal, Deuterium) to level 2 to meet the requirements for building a Robotics Factory. Upgrade them when you have enough resources.'
|
||||
},
|
||||
buildRobotics: {
|
||||
title: 'Build Robotics Factory',
|
||||
content:
|
||||
'The Robotics Factory significantly speeds up construction. It requires Metal Mine, Crystal Mine, and Deuterium Synthesizer at level 2 each. Build it to improve construction efficiency!'
|
||||
},
|
||||
upgradeMinesForLab: {
|
||||
title: 'Continue Upgrading Mines',
|
||||
content:
|
||||
'Now you need to upgrade all three resource mines to level 3 to meet the requirements for the Research Lab. Keep developing your resource production.'
|
||||
},
|
||||
buildResearchLab: {
|
||||
title: 'Build Research Lab',
|
||||
content:
|
||||
'The Research Lab is the foundation of technological advancement. It requires all three resource mines at level 3. Build it to unlock technology research!'
|
||||
},
|
||||
gotoResearch: {
|
||||
title: 'Go to Research',
|
||||
content: 'Now that you have a Research Lab, click on the "Research" menu to view available technologies.'
|
||||
},
|
||||
researchEnergy: {
|
||||
title: 'Research Energy Technology',
|
||||
content:
|
||||
"Energy Technology improves your energy production and unlocks advanced structures. It's one of the most fundamental and important technologies."
|
||||
},
|
||||
shipyardIntro: {
|
||||
title: 'Fleet and Shipyard',
|
||||
content:
|
||||
'Ships allow you to explore the galaxy, transport resources, and defend your empire. To build ships, you need a Shipyard (requires Robotics Factory level 2).'
|
||||
},
|
||||
gotoBuildingsForShipyard: {
|
||||
title: 'Return to Buildings',
|
||||
content: 'Go back to the Buildings page to construct your Shipyard.'
|
||||
},
|
||||
buildShipyard: {
|
||||
title: 'Build Shipyard',
|
||||
content: 'The Shipyard allows you to construct ships and defense systems. This is crucial for fleet operations.'
|
||||
},
|
||||
fleetIntro: {
|
||||
title: 'Fleet Operations',
|
||||
content:
|
||||
'Once you have ships, you can send them on missions: transport resources, colonize planets, attack enemies, or explore debris fields.'
|
||||
},
|
||||
galaxyIntro: {
|
||||
title: 'Explore the Galaxy',
|
||||
content:
|
||||
'The Galaxy view shows other planets, debris fields, and opportunities for expansion. Use it to scout targets and plan your strategy.'
|
||||
},
|
||||
complete: {
|
||||
title: 'Tutorial Complete!',
|
||||
content:
|
||||
'Congratulations, Commander! You now know the basics. Continue building your empire, research technologies, and explore the galaxy. Remember: develop energy first, then resources, then factories and research! Good luck!'
|
||||
},
|
||||
// Mobile tutorial
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: 'Welcome to OGame (Mobile)',
|
||||
content:
|
||||
"Welcome, Commander! This is a streamlined tutorial designed for touchscreens. We'll quickly cover the core features to get you started building your empire."
|
||||
},
|
||||
resources: {
|
||||
title: 'Top Resource Bar',
|
||||
content: 'At the top, you see your resources: Metal, Crystal, and Deuterium. Tap to view detailed production info.'
|
||||
},
|
||||
menu: {
|
||||
title: 'Open Navigation Menu',
|
||||
content:
|
||||
'Tap this menu icon to open the navigation bar. You can access Buildings, Research, Fleet, and all other features from here.'
|
||||
},
|
||||
gotoBuildings: {
|
||||
title: 'Go to Buildings Page',
|
||||
content: 'The menu is now open! Now tap "Buildings" to start constructing your infrastructure.'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: 'Build Solar Plant',
|
||||
content: 'First, build a Solar Plant! Scroll down to find it and tap the card to build. Energy is the foundation of everything.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Build Queue',
|
||||
content:
|
||||
'Click the queue icon in the top-right corner to view build progress. You can continue browsing other pages - construction happens in the background.'
|
||||
},
|
||||
buildMetalMine: {
|
||||
title: 'Build Metal Mine',
|
||||
content: 'Now that you have energy, build a Metal Mine. Scroll down to find it and tap to build.'
|
||||
},
|
||||
complete: {
|
||||
title: 'Quick Tutorial Complete!',
|
||||
content:
|
||||
"Great! You've mastered the basics. Continue building Crystal and Deuterium facilities, then explore other features. Remember: energy first, then resources!"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ export default {
|
||||
close: '閉じる',
|
||||
back: '戻る',
|
||||
next: '次へ',
|
||||
gotIt: '',
|
||||
previous: '前へ',
|
||||
submit: '送信',
|
||||
reset: 'リセット',
|
||||
@@ -33,13 +34,19 @@ export default {
|
||||
viewRequirements: '必要条件を表示',
|
||||
requirementsNotMet: '必要条件が満たされていません',
|
||||
current: '現在',
|
||||
level: 'レベル'
|
||||
level: 'レベル',
|
||||
gmModeActivated: 'GMモードが有効になりました!ナビゲーションメニューをご確認ください。'
|
||||
},
|
||||
errors: {
|
||||
requirementsNotMet: '前提条件を満たしていません',
|
||||
insufficientResources: '資源が不足しています',
|
||||
insufficientFleetStorage: '艦隊ストレージが不足しています',
|
||||
shieldDomeLimit: 'シールドドームの上限に達しました',
|
||||
missileSiloLimit: 'ミサイル格納庫の容量を超えています',
|
||||
insufficientMissiles: '惑星間ミサイルが不足しています',
|
||||
invalidMissileCount: 'ミサイル数が無効です',
|
||||
targetOutOfRange: 'ターゲットが射程外です',
|
||||
cannotAttackOwnPlanet: '自分の惑星を攻撃できません',
|
||||
fleetMissionsFull: '艦隊ミッションスロットが満杯です',
|
||||
insufficientFleet: '艦隊が不足しています',
|
||||
insufficientFuel: '燃料が不足しています',
|
||||
@@ -62,6 +69,7 @@ export default {
|
||||
officers: '士官',
|
||||
simulator: 'シミュレーター',
|
||||
galaxy: '銀河',
|
||||
diplomacy: 'Diplomacy',
|
||||
messages: 'メッセージ',
|
||||
settings: '設定',
|
||||
gm: 'GM'
|
||||
@@ -97,6 +105,8 @@ export default {
|
||||
coordinates: '座標',
|
||||
switchToMoon: '月を表示',
|
||||
backToPlanet: '母星に戻る',
|
||||
switchPlanet: '惑星を切り替える',
|
||||
currentPlanet: '現在の惑星',
|
||||
fields: 'フィールド',
|
||||
temperature: '温度',
|
||||
homePlanet: '母星',
|
||||
@@ -112,14 +122,18 @@ export default {
|
||||
crystalMine: 'クリスタル鉱山',
|
||||
deuteriumSynthesizer: '重水素合成装置',
|
||||
solarPlant: '太陽光発電所',
|
||||
fusionReactor: '核融合炉',
|
||||
roboticsFactory: 'ロボット工場',
|
||||
naniteFactory: 'ナノマシン工場',
|
||||
shipyard: '造船所',
|
||||
hangar: '格納庫',
|
||||
researchLab: '研究所',
|
||||
metalStorage: '金属倉庫',
|
||||
crystalStorage: 'クリスタル倉庫',
|
||||
deuteriumTank: '重水素タンク',
|
||||
darkMatterCollector: 'ダークマター採取装置',
|
||||
darkMatterTank: 'ダークマタータンク',
|
||||
missileSilo: 'ミサイル格納庫',
|
||||
terraformer: 'テラフォーマー',
|
||||
lunarBase: '月面基地',
|
||||
sensorPhalanx: 'センサーファランクス',
|
||||
@@ -130,23 +144,39 @@ export default {
|
||||
consumption: '消費',
|
||||
totalCost: '総コスト',
|
||||
totalPoints: '総ポイント',
|
||||
levelRange: 'レベル範囲'
|
||||
levelRange: 'レベル範囲',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
buildQueueBonus: '建造隊列',
|
||||
spaceBonus: 'スペースボーナス',
|
||||
buildSpeedBonus: '建設速度ボーナス',
|
||||
researchSpeedBonus: '研究速度ボーナス',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
buildingDescriptions: {
|
||||
metalMine: '金属資源を採掘',
|
||||
crystalMine: 'クリスタル資源を採掘',
|
||||
deuteriumSynthesizer: '重水素資源を合成',
|
||||
solarPlant: 'エネルギーを供給',
|
||||
fusionReactor: '重水素を使用して大量のエネルギーを生成',
|
||||
roboticsFactory: '建設速度を向上',
|
||||
naniteFactory: '建設キュー数を増加、レベル毎に+1(最大10レベル)',
|
||||
shipyard: '艦船を建造',
|
||||
hangar: '艦隊収容能力を拡張する専用施設、惑星の専門化をサポート',
|
||||
researchLab: '技術を研究',
|
||||
metalStorage: '金属の貯蔵上限を増加',
|
||||
crystalStorage: 'クリスタルの貯蔵上限を増加',
|
||||
deuteriumTank: '重水素の貯蔵上限を増加',
|
||||
darkMatterCollector: '希少なダークマター資源を収集',
|
||||
terraformer: '惑星地形を改造、レベル毎に利用可能スペース5増加',
|
||||
lunarBase: '月の利用可能スペースを増加、レベル毎に+5スペース',
|
||||
darkMatterTank: 'ダークマターの貯蔵上限を増加',
|
||||
missileSilo: 'ミサイルを保管・発射、レベル毎に10発',
|
||||
terraformer: '惑星地形を改造、レベル毎に利用可能スペース30増加',
|
||||
lunarBase: '月の利用可能スペースを増加、レベル毎に+30スペース',
|
||||
sensorPhalanx: '周辺星系の艦隊活動を探知',
|
||||
jumpGate: '他の月へ艦隊を瞬間移動',
|
||||
planetDestroyerFactory: '惑星を破壊できる究極兵器を建造'
|
||||
@@ -156,11 +186,15 @@ export default {
|
||||
heavyFighter: '重戦闘機',
|
||||
cruiser: '巡洋艦',
|
||||
battleship: '戦艦',
|
||||
battlecruiser: '巡洋戦艦',
|
||||
bomber: '爆撃機',
|
||||
destroyer: '駆逐艦',
|
||||
smallCargo: '小型輸送船',
|
||||
largeCargo: '大型輸送船',
|
||||
colonyShip: 'コロニーシップ',
|
||||
recycler: 'リサイクラー',
|
||||
espionageProbe: 'スパイプローブ',
|
||||
solarSatellite: '太陽光衛星',
|
||||
darkMatterHarvester: 'ダークマター採取船',
|
||||
deathstar: 'デススター'
|
||||
},
|
||||
@@ -168,12 +202,16 @@ export default {
|
||||
lightFighter: '基本戦闘ユニット',
|
||||
heavyFighter: '重装甲戦闘機',
|
||||
cruiser: '中型戦艦、攻守バランス型',
|
||||
battleship: '強力な戦艦',
|
||||
battleship: '主力重戦艦、強力な火力と高い防御力を持つ',
|
||||
battlecruiser: '高速強力な戦闘艦、戦艦への攻撃に優れる',
|
||||
bomber: '防御施設への攻撃に特化した艦船',
|
||||
destroyer: '対大型艦専用艦、高火力だが防御力が低い',
|
||||
smallCargo: '少量の資源を輸送',
|
||||
largeCargo: '大量の資源を輸送',
|
||||
colonyShip: '新惑星の植民に使用',
|
||||
recycler: 'デブリフィールドの資源を回収',
|
||||
espionageProbe: '敵惑星を偵察',
|
||||
solarSatellite: '追加エネルギーを提供、衛星1つにつき50エネルギー生成',
|
||||
darkMatterHarvester: 'ダークマター採取専用の特殊艦',
|
||||
deathstar: '惑星全体を破壊できる究極兵器'
|
||||
},
|
||||
@@ -186,6 +224,8 @@ export default {
|
||||
plasmaTurret: 'プラズマタレット',
|
||||
smallShieldDome: '小型シールドドーム',
|
||||
largeShieldDome: '大型シールドドーム',
|
||||
antiBallisticMissile: '迎撃ミサイル',
|
||||
interplanetaryMissile: '惑星間ミサイル',
|
||||
planetaryShield: '惑星シールド'
|
||||
},
|
||||
defenseDescriptions: {
|
||||
@@ -197,13 +237,23 @@ export default {
|
||||
plasmaTurret: '強力な防衛施設',
|
||||
smallShieldDome: '惑星全体を保護する小型シールド',
|
||||
largeShieldDome: '惑星全体を保護する大型シールド',
|
||||
antiBallisticMissile: '敵ミサイルを迎撃、惑星間ミサイル1発を迎撃可能',
|
||||
interplanetaryMissile: '他の惑星の防御施設を攻撃可能',
|
||||
planetaryShield: '破壊攻撃から惑星を保護する超級シールド'
|
||||
},
|
||||
research: {
|
||||
researchTime: '研究時間',
|
||||
totalCost: '総コスト',
|
||||
totalPoints: '総ポイント',
|
||||
levelRange: 'レベル範囲'
|
||||
levelRange: 'レベル範囲',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'エネルギー技術',
|
||||
@@ -212,6 +262,12 @@ export default {
|
||||
hyperspaceTechnology: 'ハイパースペース技術',
|
||||
plasmaTechnology: 'プラズマ技術',
|
||||
computerTechnology: 'コンピューター技術',
|
||||
espionageTechnology: 'スパイ技術',
|
||||
weaponsTechnology: '兵器技術',
|
||||
shieldingTechnology: 'シールド技術',
|
||||
armourTechnology: '装甲技術',
|
||||
astrophysics: '天体物理学',
|
||||
gravitonTechnology: '重力技術',
|
||||
combustionDrive: '燃焼ドライブ',
|
||||
impulseDrive: 'インパルスドライブ',
|
||||
hyperspaceDrive: 'ハイパースペースドライブ',
|
||||
@@ -226,11 +282,17 @@ export default {
|
||||
hyperspaceTechnology: 'ハイパースペースジャンプ技術',
|
||||
plasmaTechnology: 'プラズマ兵器技術',
|
||||
computerTechnology: '研究キュー数を増加、レベル毎に+1(最大10レベル)',
|
||||
espionageTechnology: 'スパイ探査機の効果を向上、レベル毎に偵察深度+1',
|
||||
weaponsTechnology: '艦船と防御の攻撃力をレベル毎に10%増加',
|
||||
shieldingTechnology: '艦船と防御のシールドをレベル毎に10%増加',
|
||||
armourTechnology: '艦船と防御の装甲をレベル毎に10%増加',
|
||||
astrophysics: 'レベル毎に植民地スロット+1、探検成功率を向上',
|
||||
gravitonTechnology: '重力操作を研究、デススターに必要',
|
||||
combustionDrive: '基本推進技術',
|
||||
impulseDrive: '中級推進技術',
|
||||
hyperspaceDrive: '高級推進技術',
|
||||
darkMatterTechnology: 'ダークマターの性質と応用を研究',
|
||||
terraformingTechnology: '惑星地形改造技術を研究、レベル毎に全惑星の利用可能スペース3増加',
|
||||
terraformingTechnology: '惑星地形改造技術を研究、レベル毎に全惑星の利用可能スペース30増加',
|
||||
planetDestructionTech: '惑星全体を破壊する恐怖の技術を研究'
|
||||
},
|
||||
officers: {
|
||||
@@ -253,20 +315,25 @@ export default {
|
||||
darkMatterSpecialist: 'ダークマター採取効率を向上'
|
||||
},
|
||||
queue: {
|
||||
title: '建設キュー',
|
||||
empty: '進行中のタスクはありません',
|
||||
buildQueue: '建設キュー',
|
||||
researchQueue: '研究キュー',
|
||||
building: '建設中',
|
||||
researching: '研究中',
|
||||
demolishing: '解体中',
|
||||
remaining: '残り時間',
|
||||
cancel: 'キャンセル',
|
||||
cancelBuild: '建設キャンセル',
|
||||
cancelResearch: '研究キャンセル',
|
||||
confirmCancel: 'キャンセルしますか?資源の50%が返還されます。',
|
||||
level: 'レベル',
|
||||
gmModeActivated: '',
|
||||
upgradeToLevel: 'レベルにアップグレード'
|
||||
},
|
||||
shipyard: {
|
||||
attack: '攻撃力',
|
||||
missileAttack: 'ミサイル攻撃',
|
||||
shield: 'シールド',
|
||||
armor: '装甲',
|
||||
speed: '速度',
|
||||
@@ -298,6 +365,7 @@ export default {
|
||||
usedSpace: '使用済みスペース',
|
||||
spaceUsage: 'スペース使用量',
|
||||
level: 'レベル',
|
||||
gmModeActivated: '',
|
||||
upgradeCost: 'アップグレードコスト',
|
||||
buildTime: '建設時間',
|
||||
upgrade: 'アップグレード',
|
||||
@@ -308,7 +376,9 @@ export default {
|
||||
demolish: '解体',
|
||||
demolishRefund: '解体返還',
|
||||
demolishFailed: '解体失敗',
|
||||
demolishFailedMessage: 'この建物を解体できません。建設キューが満杯か、建物レベルが0でないか確認してください。'
|
||||
demolishFailedMessage: 'この建物を解体できません。建設キューが満杯か、建物レベルが0でないか確認してください。',
|
||||
confirmDemolish: '解体確認',
|
||||
confirmDemolishMessage: '以下の建物を解体しますか?'
|
||||
},
|
||||
researchView: {
|
||||
title: '研究',
|
||||
@@ -320,6 +390,7 @@ export default {
|
||||
},
|
||||
defense: {
|
||||
attack: '攻撃力',
|
||||
missileAttack: 'ミサイル攻撃',
|
||||
shield: 'シールド',
|
||||
armor: '装甲',
|
||||
buildCost: '建設コスト',
|
||||
@@ -334,6 +405,7 @@ export default {
|
||||
title: '造船所',
|
||||
fleetStorage: '艦隊ストレージ',
|
||||
attack: '攻撃力',
|
||||
missileAttack: 'ミサイル攻撃',
|
||||
shield: 'シールド',
|
||||
speed: '速度',
|
||||
cargoCapacity: '積載量',
|
||||
@@ -349,6 +421,7 @@ export default {
|
||||
defenseView: {
|
||||
title: '防衛施設',
|
||||
attack: '攻撃力',
|
||||
missileAttack: 'ミサイル攻撃',
|
||||
shield: 'シールド',
|
||||
armor: '装甲',
|
||||
buildTime: '建設時間',
|
||||
@@ -358,6 +431,7 @@ export default {
|
||||
totalCost: '総コスト',
|
||||
build: '建造',
|
||||
shieldDomeBuilt: 'シールドドーム建設済み',
|
||||
missileCapacity: 'ミサイル容量',
|
||||
inputError: '入力エラー',
|
||||
inputErrorMessage: '建造数を入力してください!',
|
||||
buildFailed: '建造失敗',
|
||||
@@ -370,6 +444,7 @@ export default {
|
||||
flightMissions: '飛行ミッション',
|
||||
currentPlanetFleet: '現在の惑星艦隊',
|
||||
attack: '攻撃',
|
||||
missileAttack: 'ミサイル攻撃',
|
||||
shield: 'シールド',
|
||||
armor: '装甲',
|
||||
speed: '速度',
|
||||
@@ -380,6 +455,7 @@ export default {
|
||||
all: '全て',
|
||||
targetCoordinates: '目標座標',
|
||||
galaxy: '銀河',
|
||||
diplomacy: 'Diplomacy',
|
||||
system: '星系',
|
||||
position: '位置',
|
||||
missionType: 'ミッションタイプ',
|
||||
@@ -403,6 +479,11 @@ export default {
|
||||
arrivalTime: '到着時刻',
|
||||
returnTime: '帰還時刻',
|
||||
recallFleet: '艦隊召還',
|
||||
abortMission: '',
|
||||
abortMissionTitle: '',
|
||||
abortMissionWarning: '',
|
||||
abortMissionSuccess: '',
|
||||
abortMissionSuccessMessage: '',
|
||||
sendFailed: '派遣失敗',
|
||||
sendFailedMessage: '艦隊数、燃料の充足、または積載量の制限を確認してください。',
|
||||
recallFailed: '召還失敗',
|
||||
@@ -413,7 +494,11 @@ export default {
|
||||
cannotSendToOwnPlanet: '自分の惑星に艦隊を派遣できません',
|
||||
cargoExceedsCapacity: '積載量が容量を超えています',
|
||||
noColonyShip: '植民ミッションにはコロニーシップが必要です',
|
||||
noDebrisAtTarget: '目標座標にデブリフィールドがないか、デブリフィールドが空です'
|
||||
noDebrisAtTarget: '目標座標にデブリフィールドがないか、デブリフィールドが空です',
|
||||
noDeathstar: '破壊ミッションにはデススターが必要です',
|
||||
giftMode: 'ギフトモード',
|
||||
giftModeDescription: '資源を贈り物として送る',
|
||||
estimatedReputationGain: '推定評判獲得'
|
||||
},
|
||||
officersView: {
|
||||
title: '士官',
|
||||
@@ -453,38 +538,60 @@ export default {
|
||||
title: '銀河',
|
||||
selectCoordinates: '座標選択',
|
||||
galaxy: '銀河',
|
||||
diplomacy: 'Diplomacy',
|
||||
selectGalaxy: '銀河を選択',
|
||||
system: '星系',
|
||||
selectSystem: '星系を選択',
|
||||
view: '表示',
|
||||
myPlanet: '自分の惑星',
|
||||
myPlanets: '自分の星系を表示',
|
||||
npcPlanets: 'NPCの惑星',
|
||||
selectPlanetToView: '惑星を選択して星系を表示',
|
||||
totalPositions: '全10惑星位置',
|
||||
mine: '自分',
|
||||
hostile: '敵対',
|
||||
emptySlot: '空き - 植民可能',
|
||||
scout: '偵察',
|
||||
attack: '攻撃',
|
||||
missileAttack: 'ミサイル攻撃',
|
||||
colonize: '植民',
|
||||
switch: '切り替え',
|
||||
recycle: '回収',
|
||||
debrisField: 'デブリフィールド',
|
||||
scoutPlanetTitle: '惑星偵察',
|
||||
attackPlanetTitle: '惑星攻撃',
|
||||
missileAttackTitle: 'ミサイル攻撃',
|
||||
colonizePlanetTitle: '惑星植民',
|
||||
recyclePlanetTitle: 'デブリ回収',
|
||||
scoutPlanetMessage: '惑星[{coordinates}]にスパイプローブを送りますか?\n\n艦隊ページに移動して艦船を選択して派遣してください。',
|
||||
attackPlanetMessage: '惑星[{coordinates}]を攻撃しますか?\n\n艦隊ページに移動して艦船を選択して派遣してください。',
|
||||
missileAttackMessage: '惑星[{coordinates}]に惑星間ミサイルを発射',
|
||||
missileCount: 'ミサイル数',
|
||||
availableMissiles: '利用可能なミサイル',
|
||||
missileRange: 'ミサイル射程',
|
||||
systems: 'システム',
|
||||
distance: '距離',
|
||||
flightTime: '飛行時間',
|
||||
launchMissile: '発射',
|
||||
cancel: 'キャンセル',
|
||||
colonizePlanetMessage: '位置[{coordinates}]を植民しますか?\n\n艦隊ページに移動してコロニーシップを派遣してください。',
|
||||
recyclePlanetMessage: '位置[{coordinates}]のデブリを回収しますか?\n\n艦隊ページに移動してリサイクラーを派遣してください。'
|
||||
recyclePlanetMessage: '位置[{coordinates}]のデブリを回収しますか?\n\n艦隊ページに移動してリサイクラーを派遣してください。',
|
||||
sendGift: 'ギフト送信',
|
||||
debris: '破片',
|
||||
giftPlanetTitle: 'ギフト送信',
|
||||
giftPlanetMessage: '惑星[{coordinates}]にリソースを贈りますか?\n\n艦隊ページに移動して輸送船を選択し、リソースを積載してください。'
|
||||
},
|
||||
messagesView: {
|
||||
title: 'メッセージセンター',
|
||||
battles: '戦闘',
|
||||
spy: 'スパイ',
|
||||
npc: 'NPC',
|
||||
diplomacy: '',
|
||||
battleReports: '戦闘レポート',
|
||||
spyReports: 'スパイレポート',
|
||||
noBattleReports: '戦闘レポートなし',
|
||||
noSpyReports: 'スパイレポートなし',
|
||||
noDiplomaticReports: '',
|
||||
battleReport: '戦闘レポート',
|
||||
spyReport: 'スパイレポート',
|
||||
victory: '勝利',
|
||||
@@ -511,7 +618,79 @@ export default {
|
||||
hideRoundDetails: 'ラウンド詳細非表示',
|
||||
round: '第{round}ラウンド',
|
||||
attackerRemainingPower: '攻撃側残存火力',
|
||||
defenderRemainingPower: '防御側残存火力'
|
||||
defenderRemainingPower: '防御側残存火力',
|
||||
spied: '偵察された',
|
||||
spiedNotification: '偵察通知',
|
||||
noSpiedNotifications: '偵察通知はありません',
|
||||
detected: '発見された',
|
||||
undetected: '未発見',
|
||||
missions: 'ミッション',
|
||||
noMissionReports: 'ミッションレポートなし',
|
||||
success: '成功',
|
||||
failed: '失敗',
|
||||
npcActivity: 'NPC活動',
|
||||
noNPCActivity: 'NPC活動通知はありません',
|
||||
npcRecycleActivity: 'NPCがデブリを回収',
|
||||
gifts: 'ギフト',
|
||||
giftRejected: '拒否',
|
||||
noGiftNotifications: 'ギフト通知はありません',
|
||||
noGiftRejected: '拒否された記録はありません',
|
||||
giftFrom: '{npcName}からのギフト',
|
||||
giftRejectedBy: '{npcName}がギフトを拒否しました',
|
||||
giftResources: 'ギフトリソース',
|
||||
rejectedResources: '拒否されたリソース',
|
||||
expectedReputation: '期待される評判',
|
||||
currentReputation: '現在の評判',
|
||||
acceptGift: '受け取る',
|
||||
rejectGift: '拒否',
|
||||
rejectionReason: {
|
||||
hostile: '相手は敵対的でギフトを受け取りません',
|
||||
neutral_distrust: '相手はあなたを信頼していません',
|
||||
polite_decline: '丁重に断りました'
|
||||
},
|
||||
// Spied notification dialog
|
||||
spiedNotificationDetails: '',
|
||||
spyDetected: '',
|
||||
detectionResult: '',
|
||||
detectionSuccess: '',
|
||||
spiedNotificationMessage: '',
|
||||
spiedNotificationTip: '',
|
||||
viewInGalaxy: '',
|
||||
// Mission report dialog
|
||||
missionReportDetails: '',
|
||||
missionSuccess: '',
|
||||
missionFailed: '',
|
||||
origin: '',
|
||||
destination: '',
|
||||
missionDetails: '',
|
||||
transportedResources: '',
|
||||
recycledResources: '',
|
||||
remainingDebris: '',
|
||||
newPlanet: '',
|
||||
// NPC activity dialog
|
||||
npcActivityDetails: '',
|
||||
activityType: {
|
||||
recycle: ''
|
||||
},
|
||||
activityLocation: '',
|
||||
position: '',
|
||||
nearPlanet: '',
|
||||
activityDescription: '',
|
||||
npcActivityMessage: '',
|
||||
arrivalTime: '',
|
||||
npcActivityTip: ''
|
||||
},
|
||||
missionReports: {
|
||||
transportSuccess: '輸送ミッションが正常に完了しました',
|
||||
transportFailed: '輸送ミッションが失敗しました',
|
||||
colonizeSuccess: '植民ミッション成功、新しい惑星が確立されました',
|
||||
colonizeFailed: '植民ミッションが失敗しました',
|
||||
deploySuccess: '配備ミッションが正常に完了しました',
|
||||
deployFailed: '配備ミッションが失敗しました',
|
||||
recycleSuccess: '回収ミッションが正常に完了しました',
|
||||
recycleFailed: '回収ミッションが失敗しました。目標位置にデブリがありません',
|
||||
destroySuccess: '惑星破壊ミッションが正常に実行されました',
|
||||
destroyFailed: '惑星破壊ミッションが失敗しました'
|
||||
},
|
||||
simulatorView: {
|
||||
title: '戦闘シミュレーター',
|
||||
@@ -580,10 +759,24 @@ export default {
|
||||
gamePaused: 'ゲームを一時停止しました',
|
||||
gameResumed: 'ゲームを再開しました',
|
||||
playerName: 'プレイヤー名',
|
||||
gameSpeed: 'ゲーム速度',
|
||||
gameSpeedDesc: '現在のゲーム速度倍率',
|
||||
gameSpeed: '資源生産速度',
|
||||
gameSpeedDesc: '現在の資源生産速度倍率',
|
||||
speedChanged: '資源生産速度を{speed}xに変更しました',
|
||||
speedReset: '資源生産速度を1xにリセットしました',
|
||||
reset: 'リセット',
|
||||
about: 'について',
|
||||
version: 'バージョン',
|
||||
latestVersion: '最新バージョン',
|
||||
checkUpdate: 'アップデート確認',
|
||||
checking: '確認中...',
|
||||
newVersionAvailable: '新バージョン{version}が利用可能です',
|
||||
upToDate: '最新バージョンです',
|
||||
checkUpdateCooldown: 'しばらくしてから再度お試しください(5分間のクールダウン)',
|
||||
checkUpdateFailed: 'アップデートの確認に失敗しました。ネットワーク接続を確認してください',
|
||||
viewUpdate: '更新を表示',
|
||||
updateAvailable: '新しいバージョンが利用可能です。クリックしてリリースノートを表示します。',
|
||||
download: 'ダウンロード',
|
||||
goToDownload: 'ダウンロードへ',
|
||||
buildDate: 'ビルド日',
|
||||
community: 'コミュニティ',
|
||||
github: 'GitHubリポジトリ',
|
||||
@@ -602,6 +795,8 @@ export default {
|
||||
officers: '士官',
|
||||
modifyResources: '資源を変更',
|
||||
resourcesDesc: '惑星の資源を素早く変更',
|
||||
maxAllResources: '',
|
||||
maxAllResourcesSuccess: '',
|
||||
modifyBuildings: '建物を変更',
|
||||
buildingsDesc: '建物レベルを素早く設定',
|
||||
modifyResearch: '研究を変更',
|
||||
@@ -613,9 +808,177 @@ export default {
|
||||
modifyOfficers: '士官を変更',
|
||||
officersDesc: '士官の有効期限を素早く設定',
|
||||
days: '日',
|
||||
npcTesting: 'NPCテスト',
|
||||
npcTestingDesc: 'NPCの偵察と攻撃動作をテスト',
|
||||
selectNPC: 'NPCを選択',
|
||||
chooseNPC: 'NPCを選択してください',
|
||||
targetPlanet: 'ターゲット惑星',
|
||||
chooseTarget: 'ターゲット惑星を選択',
|
||||
testSpy: '偵察テスト',
|
||||
testAttack: '攻撃テスト',
|
||||
testSpyAndAttack: '偵察&攻撃テスト',
|
||||
testSpyMessage: '確認をクリックして偵察ミッションを加速',
|
||||
testAttackMessage: '確認をクリックして攻撃ミッションを加速',
|
||||
testSpyAndAttackMessage: '確認をクリックしてミッションを加速',
|
||||
initializeFleet: 'NPC艦隊を初期化',
|
||||
accelerateMissions: 'すべてのミッションを加速(5秒)',
|
||||
selectNPCFirst: '最初にNPCを選択してください',
|
||||
npcNoProbes: 'NPCには偵察プローブがありません',
|
||||
npcNoSpyReport: 'NPCは最初に偵察する必要があります',
|
||||
npcMissionFailed: 'ミッションの作成に失敗しました',
|
||||
npcNoPlanets: 'NPCに惑星がありません',
|
||||
npcWillSpyIn5s: '{npcName}は5秒後に偵察します',
|
||||
npcWillAttackIn5s: '{npcName}は5秒後に攻撃します',
|
||||
npcWillSpyAndAttack: '{npcName}は5秒後に偵察し、10秒後に攻撃します',
|
||||
acceleratedMissions: '{count}個のミッションを5秒後に加速しました',
|
||||
npcFleetInitialized: '{npcName}艦隊が初期化されました',
|
||||
npcFleetDetails: '100 偵察プローブ\n500 軽戦闘機\n300 重戦闘機\n200 巡洋艦\n100 戦艦\n50 爆撃機\n30 駆逐艦\n20 巡洋戦艦',
|
||||
dangerZone: '危険ゾーン',
|
||||
dangerZoneDesc: '以下の操作は元に戻せません',
|
||||
resetGame: 'ゲームをリセット',
|
||||
resetGameConfirm: 'ゲームをリセットしてもよろしいですか?すべてのデータが削除されます!'
|
||||
resetGameConfirm: 'ゲームをリセットしてもよろしいですか?すべてのデータが削除されます!',
|
||||
completeAllQueues: '',
|
||||
completeAllQueuesDesc: '',
|
||||
completeQueues: '',
|
||||
completeQueuesSuccess: ''
|
||||
},
|
||||
alerts: {
|
||||
npcSpyIncoming: 'NPC偵察プローブが接近中',
|
||||
npcAttackIncoming: 'NPC艦隊攻撃が接近中!',
|
||||
npcFleetIncoming: 'NPC艦隊が接近中',
|
||||
ships: '隻',
|
||||
spiedBy: '偵察された',
|
||||
attackedBy: '攻撃された',
|
||||
detectionSuccess: '偵察が発見された',
|
||||
detectionFailed: '偵察が発見されなかった',
|
||||
npcSpiedYourPlanet: 'NPCがあなたの惑星を偵察しました',
|
||||
npcAttackedYourPlanet: 'NPCがあなたの惑星を攻撃しました'
|
||||
},
|
||||
diplomacy: {
|
||||
title: '外交',
|
||||
description: 'NPCとの外交関係を管理',
|
||||
tabs: {
|
||||
all: 'すべて',
|
||||
friendly: '友好的',
|
||||
neutral: '中立',
|
||||
hostile: '敵対的'
|
||||
},
|
||||
noNpcs: 'NPCなし',
|
||||
noFriendlyNpcs: '友好的なNPCなし',
|
||||
noNeutralNpcs: '中立なNPCなし',
|
||||
noHostileNpcs: '敵対的なNPCなし',
|
||||
recentEvents: '最近のイベント',
|
||||
recentEventsDescription: '最近の外交活動ログ',
|
||||
ago: '前',
|
||||
notifications: '',
|
||||
markAllRead: '',
|
||||
noReports: '',
|
||||
viewAll: '',
|
||||
status: {
|
||||
friendly: '友好的',
|
||||
neutral: '中立',
|
||||
hostile: '敵対的'
|
||||
},
|
||||
planets: '惑星',
|
||||
allies: '同盟',
|
||||
reputation: '評判',
|
||||
alliedWith: '同盟関係',
|
||||
more: 'その他',
|
||||
actions: {
|
||||
gift: 'ギフトを送る',
|
||||
viewPlanets: '惑星を表示'
|
||||
},
|
||||
lastEvent: '最後のイベント',
|
||||
reportDetails: '',
|
||||
eventDescription: '',
|
||||
reputationChange: '',
|
||||
before: '',
|
||||
after: '',
|
||||
statusChange: '',
|
||||
viewDiplomacy: '',
|
||||
events: {
|
||||
gift: 'ギフト送信',
|
||||
attack: '攻撃',
|
||||
missileAttack: 'ミサイル攻撃',
|
||||
allyAttacked: '同盟が攻撃された',
|
||||
spy: '諜報活動',
|
||||
stealDebris: '残骸を略奪'
|
||||
},
|
||||
reports: {
|
||||
giftedResources: '{metal}M {crystal}C {deuterium}Dを贈呈',
|
||||
receivedGiftFromPlayer: 'プレイヤーからギフトを受け取りました',
|
||||
giftedToNpc: '{npcName}にリソースを贈呈しました。評判+{reputation}',
|
||||
rejectedPlayerGift: 'プレイヤーのギフトを拒否しました',
|
||||
npcRejectedGift: '{npcName}があなたのギフトを拒否しました。評判{reputation}',
|
||||
attackedNpc: '{npcName}を攻撃しました',
|
||||
wasAttackedByPlayer: 'プレイヤーに攻撃されました',
|
||||
youAttackedNpc: 'あなたは{npcName}を攻撃しました',
|
||||
playerAttackedAlly: 'プレイヤーが同盟{allyName}を攻撃しました',
|
||||
allyDispleased: '{allyName}はあなたが同盟{targetName}を攻撃したことに不満です',
|
||||
wasSpiedByPlayer: 'プレイヤーに偵察されました(発見:{detected})',
|
||||
spyDetected: 'あなたの偵察が{npcName}に発見されました',
|
||||
stoleDebrisFromTerritory: '{npcName}の領域から残骸を略奪しました',
|
||||
playerStoleDebris: 'プレイヤーが領域から残骸を略奪しました',
|
||||
recycledDebrisNearNpc: '{npcName}の惑星近くで残骸を回収しました。彼らは不満です。',
|
||||
giftedResourcesToPlayer: 'プレイヤーにリソースを贈呈しました',
|
||||
receivedGiftFromNpc: '{npcName}からギフトを受け取りました',
|
||||
acceptedGiftFromNpc: '{npcName}からのギフトを受け取りました:{metal}M {crystal}C {deuterium}D',
|
||||
playerRejectedGift: 'プレイヤーがギフトを拒否しました',
|
||||
rejectedGiftFromNpc: '{npcName}からのギフトを拒否しました。評判{reputation}',
|
||||
destroyedNpcPlanet: '{npcName}の{planetName}を破壊しました',
|
||||
playerDestroyedPlanet: 'プレイヤーが{planetName}を破壊しました',
|
||||
youDestroyedNpcPlanet: 'あなたは{npcName}の{planetName}を破壊しました。評判{reputation}',
|
||||
playerDestroyedAllyPlanet: 'プレイヤーが同盟{allyName}の{planetName}を破壊しました',
|
||||
allyOutraged: '{allyName}はあなたが同盟{targetName}の{planetName}を破壊したことに激怒しています',
|
||||
npcEliminated: 'NPC {npcName}は完全に排除されました',
|
||||
npcEliminatedMessage: 'あなたは{npcName}のすべての惑星を破壊しました!この勢力は完全に壊滅しました。'
|
||||
}
|
||||
},
|
||||
pagination: {
|
||||
previous: '前へ',
|
||||
next: '次へ',
|
||||
gotIt: '',
|
||||
first: '最初',
|
||||
last: '最後',
|
||||
page: '{page}ページ'
|
||||
},
|
||||
notFound: {
|
||||
title: 'ページが見つかりません',
|
||||
description: '申し訳ございません。お探しのページは存在しません',
|
||||
goHome: 'ホームに戻る'
|
||||
},
|
||||
time: {
|
||||
days: '日',
|
||||
hours: '時間',
|
||||
minutes: '分',
|
||||
seconds: '秒'
|
||||
},
|
||||
tutorial: {
|
||||
welcome: {
|
||||
title: 'OGame-Vue-Ts へようこそ',
|
||||
content: 'ようこそ、司令官!基礎から始めて、宇宙帝国を築きましょう。'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: '太陽光発電所を建設',
|
||||
content:
|
||||
'まず太陽光発電所を建設しましょう!惑星にエネルギーを供給します。エネルギーがないと、他の資源施設が機能しません。これが最も重要な第一歩です。'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '建設キュー',
|
||||
content:
|
||||
'建物は建設キューに追加されました。右上のキューアイコンをクリックすると、進行中のすべての建設と研究タスクを確認できます。建設には時間がかかりますが、待機中も作業を続けられます。'
|
||||
},
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: 'OGame-Vue-Ts へようこそ(モバイル版)',
|
||||
content:
|
||||
'ようこそ、司令官!これはタッチスクリーン向けに最適化された簡易チュートリアルです。帝国建設を始めるために、コア機能を素早くご紹介します。'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '建設キュー',
|
||||
content:
|
||||
'右上のキューアイコンをクリックして建設進度を確認できます。他のページを閲覧し続けることができます。建設はバックグラウンドで進行します。'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ export default {
|
||||
close: '닫기',
|
||||
back: '돌아가기',
|
||||
next: '다음',
|
||||
gotIt: '',
|
||||
previous: '이전',
|
||||
submit: '제출',
|
||||
reset: '초기화',
|
||||
@@ -33,13 +34,19 @@ export default {
|
||||
viewRequirements: '요구사항 보기',
|
||||
requirementsNotMet: '요구사항 미충족',
|
||||
current: '현재',
|
||||
level: '레벨'
|
||||
level: '레벨',
|
||||
gmModeActivated: 'GM 모드가 활성화되었습니다! 탐색 메뉴를 확인하세요.'
|
||||
},
|
||||
errors: {
|
||||
requirementsNotMet: '전제 조건 미충족',
|
||||
insufficientResources: '자원 부족',
|
||||
insufficientFleetStorage: '함대 저장소 부족',
|
||||
shieldDomeLimit: '실드 돔 한도 도달',
|
||||
missileSiloLimit: '미사일 사일로 용량 초과',
|
||||
insufficientMissiles: '행성간 미사일 부족',
|
||||
invalidMissileCount: '잘못된 미사일 수량',
|
||||
targetOutOfRange: '목표가 사정거리 밖',
|
||||
cannotAttackOwnPlanet: '자신의 행성 공격 불가',
|
||||
fleetMissionsFull: '함대 임무 슬롯 가득 참',
|
||||
insufficientFleet: '함대 부족',
|
||||
insufficientFuel: '연료 부족',
|
||||
@@ -62,6 +69,7 @@ export default {
|
||||
officers: '장교',
|
||||
simulator: '시뮬레이터',
|
||||
galaxy: '은하계',
|
||||
diplomacy: 'Diplomacy',
|
||||
messages: '메시지',
|
||||
settings: '설정',
|
||||
gm: 'GM'
|
||||
@@ -97,6 +105,8 @@ export default {
|
||||
coordinates: '좌표',
|
||||
switchToMoon: '위성 보기',
|
||||
backToPlanet: '모행성으로 돌아가기',
|
||||
switchPlanet: '행성 전환',
|
||||
currentPlanet: '현재 행성',
|
||||
fields: '필드',
|
||||
temperature: '온도',
|
||||
homePlanet: '모행성',
|
||||
@@ -112,14 +122,18 @@ export default {
|
||||
crystalMine: '크리스탈 광산',
|
||||
deuteriumSynthesizer: '중수소 합성기',
|
||||
solarPlant: '태양광 발전소',
|
||||
fusionReactor: '핵융합 반응로',
|
||||
roboticsFactory: '로봇 공장',
|
||||
naniteFactory: '나노 공장',
|
||||
shipyard: '조선소',
|
||||
hangar: '격납고',
|
||||
researchLab: '연구소',
|
||||
metalStorage: '금속 창고',
|
||||
crystalStorage: '크리스탈 창고',
|
||||
deuteriumTank: '중수소 탱크',
|
||||
darkMatterCollector: '암흑 물질 수집기',
|
||||
darkMatterTank: '암흑 물질 탱크',
|
||||
missileSilo: '미사일 발사대',
|
||||
terraformer: '지형 변환기',
|
||||
lunarBase: '달 기지',
|
||||
sensorPhalanx: '센서 팔랑크스',
|
||||
@@ -130,23 +144,39 @@ export default {
|
||||
consumption: '소비',
|
||||
totalCost: '총 비용',
|
||||
totalPoints: '총 점수',
|
||||
levelRange: '레벨 범위'
|
||||
levelRange: '레벨 범위',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
buildQueueBonus: '건설 대기열',
|
||||
spaceBonus: '공간 보너스',
|
||||
buildSpeedBonus: '건설 속도 보너스',
|
||||
researchSpeedBonus: '연구 속도 보너스',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
buildingDescriptions: {
|
||||
metalMine: '금속 자원 채굴',
|
||||
crystalMine: '크리스탈 자원 채굴',
|
||||
deuteriumSynthesizer: '중수소 자원 합성',
|
||||
solarPlant: '에너지 제공',
|
||||
fusionReactor: '중수소를 사용하여 대량의 에너지 생산',
|
||||
roboticsFactory: '건설 속도 향상',
|
||||
naniteFactory: '건설 대기열 수 증가, 레벨당 +1 (최대 10레벨)',
|
||||
shipyard: '함선 건조',
|
||||
hangar: '함대 저장 용량 확장 전용 시설, 행성 전문화 지원',
|
||||
researchLab: '기술 연구',
|
||||
metalStorage: '금속 저장 용량 증가',
|
||||
crystalStorage: '크리스탈 저장 용량 증가',
|
||||
deuteriumTank: '중수소 저장 용량 증가',
|
||||
darkMatterCollector: '희귀한 암흑 물질 자원 수집',
|
||||
terraformer: '행성 지형 개조, 레벨당 가용 공간 5 증가',
|
||||
lunarBase: '달 가용 공간 증가, 레벨당 +5 공간',
|
||||
darkMatterTank: '암흑 물질 저장 용량 증가',
|
||||
missileSilo: '미사일을 저장 및 발사, 레벨당 10발',
|
||||
terraformer: '행성 지형 개조, 레벨당 가용 공간 30 증가',
|
||||
lunarBase: '달 가용 공간 증가, 레벨당 +30 공간',
|
||||
sensorPhalanx: '주변 행성계의 함대 활동 감지',
|
||||
jumpGate: '다른 위성으로 함대 순간 이동',
|
||||
planetDestroyerFactory: '행성을 파괴할 수 있는 궁극 병기 건조'
|
||||
@@ -156,11 +186,15 @@ export default {
|
||||
heavyFighter: '중전투기',
|
||||
cruiser: '순양함',
|
||||
battleship: '전함',
|
||||
battlecruiser: '순양전함',
|
||||
bomber: '폭격기',
|
||||
destroyer: '구축함',
|
||||
smallCargo: '소형 수송선',
|
||||
largeCargo: '대형 수송선',
|
||||
colonyShip: '식민선',
|
||||
recycler: '재활용선',
|
||||
espionageProbe: '정찰기',
|
||||
solarSatellite: '태양광 위성',
|
||||
darkMatterHarvester: '암흑 물질 채취선',
|
||||
deathstar: '데스스타'
|
||||
},
|
||||
@@ -168,12 +202,16 @@ export default {
|
||||
lightFighter: '기본 전투 유닛',
|
||||
heavyFighter: '중장갑 전투기',
|
||||
cruiser: '중형 전함, 공격과 방어 균형',
|
||||
battleship: '강력한 전함',
|
||||
battleship: '주력 중전함, 강력한 화력과 높은 방어력 보유',
|
||||
battlecruiser: '빠르고 강력한 전투함, 전함 공격에 탁월',
|
||||
bomber: '방어 시설 공격 전문 함선',
|
||||
destroyer: '대형 함선 전문 격파함, 높은 화력이지만 방어력 낮음',
|
||||
smallCargo: '소량의 자원 운송',
|
||||
largeCargo: '대량의 자원 운송',
|
||||
colonyShip: '새로운 행성 식민에 사용',
|
||||
recycler: '잔해장 자원 수집',
|
||||
espionageProbe: '적 행성 정찰',
|
||||
solarSatellite: '추가 에너지 제공, 위성당 50 에너지 생성',
|
||||
darkMatterHarvester: '암흑 물질 채취 전용 특수 함선',
|
||||
deathstar: '행성 전체를 파괴할 수 있는 궁극 병기'
|
||||
},
|
||||
@@ -186,6 +224,8 @@ export default {
|
||||
plasmaTurret: '플라즈마 포탑',
|
||||
smallShieldDome: '소형 실드 돔',
|
||||
largeShieldDome: '대형 실드 돔',
|
||||
antiBallisticMissile: '요격 미사일',
|
||||
interplanetaryMissile: '행성간 미사일',
|
||||
planetaryShield: '행성 실드'
|
||||
},
|
||||
defenseDescriptions: {
|
||||
@@ -197,13 +237,23 @@ export default {
|
||||
plasmaTurret: '강력한 방어 시설',
|
||||
smallShieldDome: '행성 전체를 보호하는 소형 실드',
|
||||
largeShieldDome: '행성 전체를 보호하는 대형 실드',
|
||||
antiBallisticMissile: '적 미사일 요격, 행성간 미사일 1발 요격 가능',
|
||||
interplanetaryMissile: '다른 행성의 방어 시설 공격 가능',
|
||||
planetaryShield: '파괴 공격으로부터 행성을 보호하는 초급 실드'
|
||||
},
|
||||
research: {
|
||||
researchTime: '연구 시간',
|
||||
totalCost: '총 비용',
|
||||
totalPoints: '총 점수',
|
||||
levelRange: '레벨 범위'
|
||||
levelRange: '레벨 범위',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: '에너지 기술',
|
||||
@@ -212,6 +262,12 @@ export default {
|
||||
hyperspaceTechnology: '초공간 기술',
|
||||
plasmaTechnology: '플라즈마 기술',
|
||||
computerTechnology: '컴퓨터 기술',
|
||||
espionageTechnology: '스파이 기술',
|
||||
weaponsTechnology: '무기 기술',
|
||||
shieldingTechnology: '실드 기술',
|
||||
armourTechnology: '장갑 기술',
|
||||
astrophysics: '천체물리학',
|
||||
gravitonTechnology: '중력자 기술',
|
||||
combustionDrive: '연소 엔진',
|
||||
impulseDrive: '임펄스 엔진',
|
||||
hyperspaceDrive: '초공간 엔진',
|
||||
@@ -226,11 +282,17 @@ export default {
|
||||
hyperspaceTechnology: '초공간 점프 기술',
|
||||
plasmaTechnology: '플라즈마 무기 기술',
|
||||
computerTechnology: '연구 대기열 수 증가, 레벨당 +1 (최대 10레벨)',
|
||||
espionageTechnology: '스파이 탐사기 효과 향상, 레벨당 정찰 깊이 +1',
|
||||
weaponsTechnology: '함선과 방어의 공격력 레벨당 10% 증가',
|
||||
shieldingTechnology: '함선과 방어의 실드 레벨당 10% 증가',
|
||||
armourTechnology: '함선과 방어의 장갑 레벨당 10% 증가',
|
||||
astrophysics: '레벨당 식민지 슬롯 +1, 탐험 성공률 향상',
|
||||
gravitonTechnology: '중력 조작 연구, 데스스타 필요 기술',
|
||||
combustionDrive: '기본 추진 기술',
|
||||
impulseDrive: '중급 추진 기술',
|
||||
hyperspaceDrive: '고급 추진 기술',
|
||||
darkMatterTechnology: '암흑 물질의 성질과 응용 연구',
|
||||
terraformingTechnology: '행성 지형 개조 기술 연구, 레벨당 모든 행성의 가용 공간 3 증가',
|
||||
terraformingTechnology: '행성 지형 개조 기술 연구, 레벨당 모든 행성의 가용 공간 30 증가',
|
||||
planetDestructionTech: '행성 전체를 파괴하는 공포의 기술 연구'
|
||||
},
|
||||
officers: {
|
||||
@@ -253,16 +315,20 @@ export default {
|
||||
darkMatterSpecialist: '암흑 물질 수집 효율 향상'
|
||||
},
|
||||
queue: {
|
||||
title: '건설 대기열',
|
||||
empty: '활성 작업 없음',
|
||||
buildQueue: '건설 대기열',
|
||||
researchQueue: '연구 대기열',
|
||||
building: '건설 중',
|
||||
researching: '연구 중',
|
||||
demolishing: '철거 중',
|
||||
remaining: '남은 시간',
|
||||
cancel: '취소',
|
||||
cancelBuild: '건설 취소',
|
||||
cancelResearch: '연구 취소',
|
||||
confirmCancel: '취소하시겠습니까? 자원의 50%가 환불됩니다.',
|
||||
level: '레벨',
|
||||
gmModeActivated: '',
|
||||
upgradeToLevel: '레벨로 업그레이드'
|
||||
},
|
||||
overview: {
|
||||
@@ -283,6 +349,7 @@ export default {
|
||||
usedSpace: '사용된 공간',
|
||||
spaceUsage: '공간 사용',
|
||||
level: '레벨',
|
||||
gmModeActivated: '',
|
||||
upgradeCost: '업그레이드 비용',
|
||||
buildTime: '건설 시간',
|
||||
upgrade: '업그레이드',
|
||||
@@ -293,7 +360,9 @@ export default {
|
||||
demolish: '철거',
|
||||
demolishRefund: '철거 환불',
|
||||
demolishFailed: '철거 실패',
|
||||
demolishFailedMessage: '이 건물을 철거할 수 없습니다. 건설 대기열이 가득 찼거나 건물 레벨이 0인지 확인하세요.'
|
||||
demolishFailedMessage: '이 건물을 철거할 수 없습니다. 건설 대기열이 가득 찼거나 건물 레벨이 0인지 확인하세요.',
|
||||
confirmDemolish: '철거 확인',
|
||||
confirmDemolishMessage: '다음 건물을 철거하시겠습니까?'
|
||||
},
|
||||
researchView: {
|
||||
title: '연구',
|
||||
@@ -305,6 +374,7 @@ export default {
|
||||
},
|
||||
shipyard: {
|
||||
attack: '공격력',
|
||||
missileAttack: '미사일 공격',
|
||||
shield: '쉴드',
|
||||
armor: '장갑',
|
||||
speed: '속도',
|
||||
@@ -322,6 +392,7 @@ export default {
|
||||
title: '조선소',
|
||||
fleetStorage: '함대 저장소',
|
||||
attack: '공격력',
|
||||
missileAttack: '미사일 공격',
|
||||
shield: '실드',
|
||||
speed: '속도',
|
||||
cargoCapacity: '적재량',
|
||||
@@ -336,6 +407,7 @@ export default {
|
||||
},
|
||||
defense: {
|
||||
attack: '공격력',
|
||||
missileAttack: '미사일 공격',
|
||||
shield: '쉴드',
|
||||
armor: '장갑',
|
||||
buildCost: '건설 비용',
|
||||
@@ -349,6 +421,7 @@ export default {
|
||||
defenseView: {
|
||||
title: '방어 시설',
|
||||
attack: '공격력',
|
||||
missileAttack: '미사일 공격',
|
||||
shield: '실드',
|
||||
armor: '장갑',
|
||||
buildTime: '건설 시간',
|
||||
@@ -358,6 +431,7 @@ export default {
|
||||
totalCost: '총 비용',
|
||||
build: '건조',
|
||||
shieldDomeBuilt: '실드 돔이 이미 건설됨',
|
||||
missileCapacity: '미사일 용량',
|
||||
inputError: '입력 오류',
|
||||
inputErrorMessage: '건조 수량을 입력하세요!',
|
||||
buildFailed: '건조 실패',
|
||||
@@ -370,6 +444,7 @@ export default {
|
||||
flightMissions: '비행 임무',
|
||||
currentPlanetFleet: '현재 행성 함대',
|
||||
attack: '공격',
|
||||
missileAttack: '미사일 공격',
|
||||
shield: '실드',
|
||||
armor: '장갑',
|
||||
speed: '속도',
|
||||
@@ -380,6 +455,7 @@ export default {
|
||||
all: '전체',
|
||||
targetCoordinates: '목표 좌표',
|
||||
galaxy: '은하계',
|
||||
diplomacy: 'Diplomacy',
|
||||
system: '행성계',
|
||||
position: '위치',
|
||||
missionType: '임무 유형',
|
||||
@@ -403,6 +479,11 @@ export default {
|
||||
arrivalTime: '도착 시간',
|
||||
returnTime: '귀환 시간',
|
||||
recallFleet: '함대 소환',
|
||||
abortMission: '',
|
||||
abortMissionTitle: '',
|
||||
abortMissionWarning: '',
|
||||
abortMissionSuccess: '',
|
||||
abortMissionSuccessMessage: '',
|
||||
sendFailed: '파견 실패',
|
||||
sendFailedMessage: '함대 수, 연료 충분 여부 또는 적재량 한계를 확인하세요.',
|
||||
recallFailed: '소환 실패',
|
||||
@@ -413,7 +494,11 @@ export default {
|
||||
cannotSendToOwnPlanet: '자신의 행성으로 함대를 파견할 수 없습니다',
|
||||
cargoExceedsCapacity: '적재량이 용량을 초과합니다',
|
||||
noColonyShip: '식민 임무를 위해 식민선이 필요합니다',
|
||||
noDebrisAtTarget: '대상 좌표에 잔해장이 없거나 잔해장이 비어 있습니다'
|
||||
noDebrisAtTarget: '대상 좌표에 잔해장이 없거나 잔해장이 비어 있습니다',
|
||||
noDeathstar: '파괴 임무를 위해 데스스타가 필요합니다',
|
||||
giftMode: '선물 모드',
|
||||
giftModeDescription: '자원을 선물로 보내기',
|
||||
estimatedReputationGain: '예상 평판 획득'
|
||||
},
|
||||
officersView: {
|
||||
title: '장교',
|
||||
@@ -453,39 +538,61 @@ export default {
|
||||
title: '은하계',
|
||||
selectCoordinates: '좌표 선택',
|
||||
galaxy: '은하계',
|
||||
diplomacy: 'Diplomacy',
|
||||
selectGalaxy: '은하계 선택',
|
||||
system: '행성계',
|
||||
selectSystem: '행성계 선택',
|
||||
view: '보기',
|
||||
myPlanet: '내 행성',
|
||||
myPlanets: '내 행성계 보기',
|
||||
npcPlanets: 'NPC 행성들',
|
||||
selectPlanetToView: '행성을 선택하여 행성계 보기',
|
||||
totalPositions: '총 10개 행성 위치',
|
||||
mine: '내 것',
|
||||
hostile: '적대',
|
||||
emptySlot: '빈 자리 - 식민 가능',
|
||||
scout: '정찰',
|
||||
attack: '공격',
|
||||
missileAttack: '미사일 공격',
|
||||
colonize: '식민',
|
||||
switch: '전환',
|
||||
recycle: '회수',
|
||||
debrisField: '잔해 필드',
|
||||
scoutPlanetTitle: '행성 정찰',
|
||||
attackPlanetTitle: '행성 공격',
|
||||
missileAttackTitle: '미사일 공격',
|
||||
colonizePlanetTitle: '행성 식민',
|
||||
recyclePlanetTitle: '잔해 회수',
|
||||
scoutPlanetMessage:
|
||||
'행성 [{coordinates}]을(를) 정찰하기 위해 정찰기를 보내시겠습니까?\n\n함대 페이지로 이동하여 함선을 선택하고 파견하세요.',
|
||||
attackPlanetMessage: '행성 [{coordinates}]을(를) 공격하시겠습니까?\n\n함대 페이지로 이동하여 함선을 선택하고 파견하세요.',
|
||||
missileAttackMessage: '행성 [{coordinates}]에 행성간 미사일 발사',
|
||||
missileCount: '미사일 수량',
|
||||
availableMissiles: '사용 가능한 미사일',
|
||||
missileRange: '미사일 사정거리',
|
||||
systems: '시스템',
|
||||
distance: '거리',
|
||||
flightTime: '비행 시간',
|
||||
launchMissile: '발사',
|
||||
cancel: '취소',
|
||||
colonizePlanetMessage: '위치 [{coordinates}]을(를) 식민하시겠습니까?\n\n함대 페이지로 이동하여 식민선을 파견하세요.',
|
||||
recyclePlanetMessage: '위치 [{coordinates}]의 잔해를 회수하시겠습니까?\n\n함대 페이지로 이동하여 회수선을 파견하세요.'
|
||||
recyclePlanetMessage: '위치 [{coordinates}]의 잔해를 회수하시겠습니까?\n\n함대 페이지로 이동하여 회수선을 파견하세요.',
|
||||
sendGift: '선물 보내기',
|
||||
debris: '잔해',
|
||||
giftPlanetTitle: '선물 보내기',
|
||||
giftPlanetMessage: '행성 [{coordinates}]에 자원을 선물로 보내시겠습니까?\n\n함대 페이지로 이동하여 수송선을 선택하고 자원을 적재하세요.'
|
||||
},
|
||||
messagesView: {
|
||||
title: '메시지 센터',
|
||||
battles: '전투',
|
||||
spy: '정찰',
|
||||
npc: 'NPC',
|
||||
diplomacy: '',
|
||||
battleReports: '전투 보고서',
|
||||
spyReports: '정찰 보고서',
|
||||
noBattleReports: '전투 보고서 없음',
|
||||
noSpyReports: '정찰 보고서 없음',
|
||||
noDiplomaticReports: '',
|
||||
battleReport: '전투 보고서',
|
||||
spyReport: '정찰 보고서',
|
||||
victory: '승리',
|
||||
@@ -512,7 +619,79 @@ export default {
|
||||
hideRoundDetails: '라운드 상세 숨기기',
|
||||
round: '제{round}라운드',
|
||||
attackerRemainingPower: '공격자 잔여 화력',
|
||||
defenderRemainingPower: '방어자 잔여 화력'
|
||||
defenderRemainingPower: '방어자 잔여 화력',
|
||||
spied: '정찰당함',
|
||||
spiedNotification: '정찰 알림',
|
||||
noSpiedNotifications: '정찰 알림 없음',
|
||||
detected: '발견됨',
|
||||
undetected: '미발견',
|
||||
missions: '임무',
|
||||
noMissionReports: '임무 보고서 없음',
|
||||
success: '성공',
|
||||
failed: '실패',
|
||||
npcActivity: 'NPC 활동',
|
||||
noNPCActivity: 'NPC 활동 알림 없음',
|
||||
npcRecycleActivity: 'NPC가 잔해 회수',
|
||||
gifts: '선물',
|
||||
giftRejected: '거부됨',
|
||||
noGiftNotifications: '선물 알림 없음',
|
||||
noGiftRejected: '거부된 기록 없음',
|
||||
giftFrom: '{npcName}의 선물',
|
||||
giftRejectedBy: '{npcName}가 선물을 거부했습니다',
|
||||
giftResources: '선물 자원',
|
||||
rejectedResources: '거부된 자원',
|
||||
expectedReputation: '예상 평판',
|
||||
currentReputation: '현재 평판',
|
||||
acceptGift: '수락',
|
||||
rejectGift: '거부',
|
||||
rejectionReason: {
|
||||
hostile: '상대방이 적대적이어서 선물을 받지 않습니다',
|
||||
neutral_distrust: '상대방이 당신을 신뢰하지 않습니다',
|
||||
polite_decline: '정중하게 거절했습니다'
|
||||
},
|
||||
// Spied notification dialog
|
||||
spiedNotificationDetails: '',
|
||||
spyDetected: '',
|
||||
detectionResult: '',
|
||||
detectionSuccess: '',
|
||||
spiedNotificationMessage: '',
|
||||
spiedNotificationTip: '',
|
||||
viewInGalaxy: '',
|
||||
// Mission report dialog
|
||||
missionReportDetails: '',
|
||||
missionSuccess: '',
|
||||
missionFailed: '',
|
||||
origin: '',
|
||||
destination: '',
|
||||
missionDetails: '',
|
||||
transportedResources: '',
|
||||
recycledResources: '',
|
||||
remainingDebris: '',
|
||||
newPlanet: '',
|
||||
// NPC activity dialog
|
||||
npcActivityDetails: '',
|
||||
activityType: {
|
||||
recycle: ''
|
||||
},
|
||||
activityLocation: '',
|
||||
position: '',
|
||||
nearPlanet: '',
|
||||
activityDescription: '',
|
||||
npcActivityMessage: '',
|
||||
arrivalTime: '',
|
||||
npcActivityTip: ''
|
||||
},
|
||||
missionReports: {
|
||||
transportSuccess: '수송 임무가 성공적으로 완료되었습니다',
|
||||
transportFailed: '수송 임무 실패',
|
||||
colonizeSuccess: '식민 임무 성공, 새로운 행성이 건설되었습니다',
|
||||
colonizeFailed: '식민 임무 실패',
|
||||
deploySuccess: '배치 임무가 성공적으로 완료되었습니다',
|
||||
deployFailed: '배치 임무 실패',
|
||||
recycleSuccess: '회수 임무가 성공적으로 완료되었습니다',
|
||||
recycleFailed: '회수 임무 실패, 목표 위치에 잔해가 없습니다',
|
||||
destroySuccess: '행성 파괴 임무가 성공적으로 실행되었습니다',
|
||||
destroyFailed: '행성 파괴 임무 실패'
|
||||
},
|
||||
simulatorView: {
|
||||
title: '전투 시뮬레이터',
|
||||
@@ -581,10 +760,24 @@ export default {
|
||||
gamePaused: '게임이 일시정지되었습니다',
|
||||
gameResumed: '게임이 재개되었습니다',
|
||||
playerName: '플레이어 이름',
|
||||
gameSpeed: '게임 속도',
|
||||
gameSpeedDesc: '현재 게임 속도 배율',
|
||||
gameSpeed: '자원 생산 속도',
|
||||
gameSpeedDesc: '현재 자원 생산 속도 배율',
|
||||
speedChanged: '자원 생산 속도가 {speed}x로 변경되었습니다',
|
||||
speedReset: '자원 생산 속도가 1x로 재설정되었습니다',
|
||||
reset: '재설정',
|
||||
about: '정보',
|
||||
version: '버전',
|
||||
latestVersion: '최신 버전',
|
||||
checkUpdate: '업데이트 확인',
|
||||
checking: '확인 중...',
|
||||
newVersionAvailable: '새 버전 {version} 사용 가능',
|
||||
upToDate: '이미 최신 버전입니다',
|
||||
checkUpdateCooldown: '나중에 다시 시도해주세요 (5분 쿨다운)',
|
||||
checkUpdateFailed: '업데이트 확인 실패, 네트워크 연결을 확인하세요',
|
||||
viewUpdate: '업데이트 보기',
|
||||
updateAvailable: '새 버전이 사용 가능합니다. 릴리스 노트를 보려면 클릭하세요.',
|
||||
download: '다운로드',
|
||||
goToDownload: '다운로드로 이동',
|
||||
buildDate: '빌드 날짜',
|
||||
community: '커뮤니티',
|
||||
github: 'GitHub 저장소',
|
||||
@@ -603,6 +796,8 @@ export default {
|
||||
officers: '장교',
|
||||
modifyResources: '자원 수정',
|
||||
resourcesDesc: '행성 자원을 빠르게 수정',
|
||||
maxAllResources: '',
|
||||
maxAllResourcesSuccess: '',
|
||||
modifyBuildings: '건물 수정',
|
||||
buildingsDesc: '건물 레벨을 빠르게 설정',
|
||||
modifyResearch: '연구 수정',
|
||||
@@ -614,9 +809,177 @@ export default {
|
||||
modifyOfficers: '장교 수정',
|
||||
officersDesc: '장교 만료 시간을 빠르게 설정',
|
||||
days: '일',
|
||||
npcTesting: 'NPC 테스트',
|
||||
npcTestingDesc: 'NPC 정찰 및 공격 동작 테스트',
|
||||
selectNPC: 'NPC 선택',
|
||||
chooseNPC: 'NPC를 선택하세요',
|
||||
targetPlanet: '목표 행성',
|
||||
chooseTarget: '목표 행성 선택',
|
||||
testSpy: '정찰 테스트',
|
||||
testAttack: '공격 테스트',
|
||||
testSpyAndAttack: '정찰 & 공격 테스트',
|
||||
testSpyMessage: '확인을 클릭하여 정찰 임무를 가속화',
|
||||
testAttackMessage: '확인을 클릭하여 공격 임무를 가속화',
|
||||
testSpyAndAttackMessage: '확인을 클릭하여 임무를 가속화',
|
||||
initializeFleet: 'NPC 함대 초기化',
|
||||
accelerateMissions: '모든 임무 가속(5초)',
|
||||
selectNPCFirst: '먼저 NPC를 선택하세요',
|
||||
npcNoProbes: 'NPC에 정찰 프로브가 없습니다',
|
||||
npcNoSpyReport: 'NPC가 먼저 정찰해야 합니다',
|
||||
npcMissionFailed: '임무 생성 실패',
|
||||
npcNoPlanets: 'NPC에 행성이 없습니다',
|
||||
npcWillSpyIn5s: '{npcName}이(가) 5초 후에 정찰합니다',
|
||||
npcWillAttackIn5s: '{npcName}이(가) 5초 후에 공격합니다',
|
||||
npcWillSpyAndAttack: '{npcName}이(가) 5초 후에 정찰하고 10초 후에 공격합니다',
|
||||
acceleratedMissions: '{count}개의 임무를 5초로 가속화했습니다',
|
||||
npcFleetInitialized: '{npcName} 함대가 초기화되었습니다',
|
||||
npcFleetDetails: '100 정찰 프로브\n500 경전투기\n300 중전투기\n200 순양함\n100 전함\n50 폭격기\n30 구축함\n20 순양전함',
|
||||
dangerZone: '위험 구역',
|
||||
dangerZoneDesc: '다음 작업은 되돌릴 수 없습니다',
|
||||
resetGame: '게임 초기화',
|
||||
resetGameConfirm: '게임을 초기화하시겠습니까? 모든 데이터가 삭제됩니다!'
|
||||
resetGameConfirm: '게임을 초기화하시겠습니까? 모든 데이터가 삭제됩니다!',
|
||||
completeAllQueues: '',
|
||||
completeAllQueuesDesc: '',
|
||||
completeQueues: '',
|
||||
completeQueuesSuccess: ''
|
||||
},
|
||||
alerts: {
|
||||
npcSpyIncoming: 'NPC 정찰 프로브 접근 중',
|
||||
npcAttackIncoming: 'NPC 함대 공격 진행 중!',
|
||||
npcFleetIncoming: 'NPC 함대 접근 중',
|
||||
ships: '척',
|
||||
spiedBy: '정찰당함',
|
||||
attackedBy: '공격당함',
|
||||
detectionSuccess: '정찰 발견됨',
|
||||
detectionFailed: '정찰 미발견',
|
||||
npcSpiedYourPlanet: 'NPC가 당신의 행성을 정찰했습니다',
|
||||
npcAttackedYourPlanet: 'NPC가 당신의 행성을 공격했습니다'
|
||||
},
|
||||
diplomacy: {
|
||||
title: '외교',
|
||||
description: 'NPC와의 외교 관계 관리',
|
||||
tabs: {
|
||||
all: '전체',
|
||||
friendly: '우호적',
|
||||
neutral: '중립',
|
||||
hostile: '적대적'
|
||||
},
|
||||
noNpcs: 'NPC 없음',
|
||||
noFriendlyNpcs: '우호적인 NPC 없음',
|
||||
noNeutralNpcs: '중립적인 NPC 없음',
|
||||
noHostileNpcs: '적대적인 NPC 없음',
|
||||
recentEvents: '최근 이벤트',
|
||||
recentEventsDescription: '최근 외교 활동 로그',
|
||||
ago: '전',
|
||||
notifications: '',
|
||||
markAllRead: '',
|
||||
noReports: '',
|
||||
viewAll: '',
|
||||
status: {
|
||||
friendly: '우호적',
|
||||
neutral: '중립',
|
||||
hostile: '적대적'
|
||||
},
|
||||
planets: '행성',
|
||||
allies: '동맹',
|
||||
reputation: '평판',
|
||||
alliedWith: '동맹 관계',
|
||||
more: '더보기',
|
||||
actions: {
|
||||
gift: '선물 보내기',
|
||||
viewPlanets: '행성 보기'
|
||||
},
|
||||
lastEvent: '최근 이벤트',
|
||||
reportDetails: '',
|
||||
eventDescription: '',
|
||||
reputationChange: '',
|
||||
before: '',
|
||||
after: '',
|
||||
statusChange: '',
|
||||
viewDiplomacy: '',
|
||||
events: {
|
||||
gift: '선물 전송',
|
||||
attack: '공격',
|
||||
missileAttack: '미사일 공격',
|
||||
allyAttacked: '동맹 공격당함',
|
||||
spy: '정찰',
|
||||
stealDebris: '잔해 약탈'
|
||||
},
|
||||
reports: {
|
||||
giftedResources: '{metal}M {crystal}C {deuterium}D 선물함',
|
||||
receivedGiftFromPlayer: '플레이어로부터 선물을 받았습니다',
|
||||
giftedToNpc: '{npcName}에게 자원을 선물했습니다. 평판 +{reputation}',
|
||||
rejectedPlayerGift: '플레이어의 선물을 거부했습니다',
|
||||
npcRejectedGift: '{npcName}이(가) 당신의 선물을 거부했습니다. 평판 {reputation}',
|
||||
attackedNpc: '{npcName}을(를) 공격했습니다',
|
||||
wasAttackedByPlayer: '플레이어에게 공격당했습니다',
|
||||
youAttackedNpc: '당신은 {npcName}을(를) 공격했습니다',
|
||||
playerAttackedAlly: '플레이어가 동맹 {allyName}을(를) 공격했습니다',
|
||||
allyDispleased: '{allyName}은(는) 당신이 동맹 {targetName}을(를) 공격한 것에 불만입니다',
|
||||
wasSpiedByPlayer: '플레이어에게 정찰당했습니다 (발견: {detected})',
|
||||
spyDetected: '당신의 정찰이 {npcName}에게 발견되었습니다',
|
||||
stoleDebrisFromTerritory: '{npcName}의 영역에서 잔해를 약탈했습니다',
|
||||
playerStoleDebris: '플레이어가 영역에서 잔해를 약탈했습니다',
|
||||
recycledDebrisNearNpc: '{npcName}의 행성 근처에서 잔해를 수집했습니다. 그들은 불만족스러워합니다.',
|
||||
giftedResourcesToPlayer: '플레이어에게 자원을 선물했습니다',
|
||||
receivedGiftFromNpc: '{npcName}로부터 선물을 받았습니다',
|
||||
acceptedGiftFromNpc: '{npcName}의 선물을 받았습니다: {metal}M {crystal}C {deuterium}D',
|
||||
playerRejectedGift: '플레이어가 선물을 거부했습니다',
|
||||
rejectedGiftFromNpc: '{npcName}의 선물을 거부했습니다. 평판 {reputation}',
|
||||
destroyedNpcPlanet: '{npcName}의 {planetName}을(를) 파괴했습니다',
|
||||
playerDestroyedPlanet: '플레이어가 {planetName}을(를) 파괴했습니다',
|
||||
youDestroyedNpcPlanet: '당신은 {npcName}의 {planetName}을(를) 파괴했습니다. 평판 {reputation}',
|
||||
playerDestroyedAllyPlanet: '플레이어가 동맹 {allyName}의 {planetName}을(를) 파괴했습니다',
|
||||
allyOutraged: '{allyName}은(는) 당신이 동맹 {targetName}의 {planetName}을(를) 파괴한 것에 분노하고 있습니다',
|
||||
npcEliminated: 'NPC {npcName}이(가) 완전히 제거되었습니다',
|
||||
npcEliminatedMessage: '당신은 {npcName}의 모든 행성을 파괴했습니다! 이 세력은 완전히 소멸되었습니다.'
|
||||
}
|
||||
},
|
||||
pagination: {
|
||||
previous: '이전',
|
||||
next: '다음',
|
||||
gotIt: '',
|
||||
first: '처음',
|
||||
last: '마지막',
|
||||
page: '{page}페이지'
|
||||
},
|
||||
notFound: {
|
||||
title: '페이지를 찾을 수 없습니다',
|
||||
description: '죄송합니다. 찾으시는 페이지가 존재하지 않습니다',
|
||||
goHome: '홈으로 이동'
|
||||
},
|
||||
time: {
|
||||
days: '일',
|
||||
hours: '시간',
|
||||
minutes: '분',
|
||||
seconds: '초'
|
||||
},
|
||||
tutorial: {
|
||||
welcome: {
|
||||
title: 'OGame에 오신 것을 환영합니다',
|
||||
content: '환영합니다, 사령관! 기초부터 시작하여 우주 제국을 건설해 봅시다.'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: '태양광 발전소 건설',
|
||||
content:
|
||||
'먼저 태양광 발전소를 건설하세요! 행성에 에너지를 공급합니다. 에너지가 없으면 다른 자원 건물이 작동할 수 없습니다. 가장 중요한 첫 단계입니다.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '건설 대기열',
|
||||
content:
|
||||
'건물이 건설 대기열에 추가되었습니다. 오른쪽 상단의 대기열 아이콘을 클릭하면 진행 중인 모든 건설 및 연구 작업을 확인할 수 있습니다. 건설에는 시간이 걸리지만 대기하는 동안 계속 작업할 수 있습니다.'
|
||||
},
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: 'OGame에 오신 것을 환영합니다 (모바일)',
|
||||
content:
|
||||
'환영합니다, 사령관! 터치스크린용으로 설계된 간소화된 튜토리얼입니다. 제국 건설을 시작할 수 있도록 핵심 기능을 빠르게 소개하겠습니다.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '건설 대기열',
|
||||
content:
|
||||
'오른쪽 상단의 대기열 아이콘을 클릭하여 건설 진행 상황을 확인하세요. 다른 페이지를 계속 탐색할 수 있으며, 건설은 백그라운드에서 진행됩니다.'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ export default {
|
||||
close: 'Закрыть',
|
||||
back: 'Назад',
|
||||
next: 'Далее',
|
||||
gotIt: '',
|
||||
previous: 'Предыдущий',
|
||||
submit: 'Отправить',
|
||||
reset: 'Сбросить',
|
||||
@@ -33,13 +34,19 @@ export default {
|
||||
viewRequirements: 'Просмотр требований',
|
||||
requirementsNotMet: 'Требования не выполнены',
|
||||
current: 'Текущий',
|
||||
level: 'Уровень'
|
||||
level: 'Уровень',
|
||||
gmModeActivated: 'Режим GM активирован! Проверьте навигационное меню.'
|
||||
},
|
||||
errors: {
|
||||
requirementsNotMet: 'Требования не выполнены',
|
||||
insufficientResources: 'Недостаточно ресурсов',
|
||||
insufficientFleetStorage: 'Недостаточно места для флота',
|
||||
shieldDomeLimit: 'Достигнут лимит щитовых куполов',
|
||||
missileSiloLimit: 'Превышена вместимость ракетной шахты',
|
||||
insufficientMissiles: 'Недостаточно межпланетных ракет',
|
||||
invalidMissileCount: 'Неверное количество ракет',
|
||||
targetOutOfRange: 'Цель вне дальности',
|
||||
cannotAttackOwnPlanet: 'Нельзя атаковать свою планету',
|
||||
fleetMissionsFull: 'Слоты миссий флота заполнены',
|
||||
insufficientFleet: 'Недостаточно флота',
|
||||
insufficientFuel: 'Недостаточно топлива',
|
||||
@@ -62,6 +69,7 @@ export default {
|
||||
officers: 'Офицеры',
|
||||
simulator: 'Симулятор',
|
||||
galaxy: 'Галактика',
|
||||
diplomacy: 'Diplomacy',
|
||||
messages: 'Сообщения',
|
||||
settings: 'Настройки',
|
||||
gm: 'GM'
|
||||
@@ -97,6 +105,8 @@ export default {
|
||||
coordinates: 'Координаты',
|
||||
switchToMoon: 'На луну',
|
||||
backToPlanet: 'Вернуться на планету',
|
||||
switchPlanet: 'Переключить планету',
|
||||
currentPlanet: 'Текущая планета',
|
||||
fields: 'Поля',
|
||||
temperature: 'Температура',
|
||||
homePlanet: 'Родная планета',
|
||||
@@ -112,14 +122,18 @@ export default {
|
||||
crystalMine: 'Рудник кристалла',
|
||||
deuteriumSynthesizer: 'Синтезатор дейтерия',
|
||||
solarPlant: 'Солнечная электростанция',
|
||||
fusionReactor: 'Термоядерный реактор',
|
||||
roboticsFactory: 'Фабрика роботов',
|
||||
naniteFactory: 'Нанитная фабрика',
|
||||
shipyard: 'Верфь',
|
||||
hangar: 'Ангар',
|
||||
researchLab: 'Исследовательская лаборатория',
|
||||
metalStorage: 'Хранилище металла',
|
||||
crystalStorage: 'Хранилище кристалла',
|
||||
deuteriumTank: 'Цистерна дейтерия',
|
||||
darkMatterCollector: 'Коллектор тёмной материи',
|
||||
darkMatterTank: 'Резервуар тёмной материи',
|
||||
missileSilo: 'Ракетная шахта',
|
||||
terraformer: 'Терраформер',
|
||||
lunarBase: 'Лунная база',
|
||||
sensorPhalanx: 'Сенсорная фаланга',
|
||||
@@ -130,23 +144,39 @@ export default {
|
||||
consumption: 'Потребление',
|
||||
totalCost: 'Общая стоимость',
|
||||
totalPoints: 'Общие очки',
|
||||
levelRange: 'Диапазон уровней'
|
||||
levelRange: 'Диапазон уровней',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
buildQueueBonus: 'Очередь строительства',
|
||||
spaceBonus: 'Бонус пространства',
|
||||
buildSpeedBonus: 'Бонус скорости строительства',
|
||||
researchSpeedBonus: 'Бонус скорости исследования',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
buildingDescriptions: {
|
||||
metalMine: 'Добывает металлические ресурсы',
|
||||
crystalMine: 'Добывает кристаллические ресурсы',
|
||||
deuteriumSynthesizer: 'Синтезирует дейтериевые ресурсы',
|
||||
solarPlant: 'Обеспечивает энергией',
|
||||
fusionReactor: 'Использует дейтерий для производства большого количества энергии',
|
||||
roboticsFactory: 'Ускоряет скорость строительства',
|
||||
naniteFactory: 'Увеличивает вместимость очереди строительства, +1 за уровень (макс 10 уровней)',
|
||||
shipyard: 'Строит корабли',
|
||||
hangar: 'Специализированное сооружение для расширения вместимости флота, поддерживает специализацию планет',
|
||||
researchLab: 'Исследует технологии',
|
||||
metalStorage: 'Увеличивает ёмкость хранилища металла',
|
||||
crystalStorage: 'Увеличивает ёмкость хранилища кристалла',
|
||||
deuteriumTank: 'Увеличивает ёмкость хранилища дейтерия',
|
||||
darkMatterCollector: 'Собирает редкие ресурсы тёмной материи',
|
||||
terraformer: 'Терраформирует поверхность планеты, увеличивает доступное пространство на 5 за уровень',
|
||||
lunarBase: 'Увеличивает доступное пространство на луне, +5 пространства за уровень',
|
||||
darkMatterTank: 'Увеличивает ёмкость хранилища тёмной материи',
|
||||
missileSilo: 'Хранит и запускает ракеты, 10 ракет на уровень',
|
||||
terraformer: 'Терраформирует поверхность планеты, увеличивает доступное пространство на 30 за уровень',
|
||||
lunarBase: 'Увеличивает доступное пространство на луне, +30 пространства за уровень',
|
||||
sensorPhalanx: 'Обнаруживает активность флота в окружающих системах',
|
||||
jumpGate: 'Мгновенно переносит флоты на другие луны',
|
||||
planetDestroyerFactory: 'Производит абсолютное оружие, способное уничтожать планеты'
|
||||
@@ -156,11 +186,15 @@ export default {
|
||||
heavyFighter: 'Тяжёлый истребитель',
|
||||
cruiser: 'Крейсер',
|
||||
battleship: 'Линкор',
|
||||
battlecruiser: 'Линейный крейсер',
|
||||
bomber: 'Бомбардировщик',
|
||||
destroyer: 'Эсминец',
|
||||
smallCargo: 'Малый транспорт',
|
||||
largeCargo: 'Большой транспорт',
|
||||
colonyShip: 'Колонизатор',
|
||||
recycler: 'Переработчик',
|
||||
espionageProbe: 'Шпионский зонд',
|
||||
solarSatellite: 'Солнечный спутник',
|
||||
darkMatterHarvester: 'Сборщик тёмной материи',
|
||||
deathstar: 'Звезда Смерти'
|
||||
},
|
||||
@@ -168,12 +202,16 @@ export default {
|
||||
lightFighter: 'Базовая боевая единица',
|
||||
heavyFighter: 'Тяжелобронированный истребитель',
|
||||
cruiser: 'Средний боевой корабль, сбалансированная атака и защита',
|
||||
battleship: 'Мощный боевой корабль',
|
||||
battleship: 'Основной тяжёлый боевой корабль с мощной огневой мощью и высокой защитой',
|
||||
battlecruiser: 'Быстрый мощный боевой корабль, отлично атакует линкоры',
|
||||
bomber: 'Специализированный корабль для атаки оборонительных сооружений',
|
||||
destroyer: 'Специализированный противокапитальный корабль с высокой огневой мощью, но низкой защитой',
|
||||
smallCargo: 'Транспортирует небольшое количество ресурсов',
|
||||
largeCargo: 'Транспортирует большое количество ресурсов',
|
||||
colonyShip: 'Используется для колонизации новых планет',
|
||||
recycler: 'Собирает ресурсы с поля обломков',
|
||||
espionageProbe: 'Разведывает вражеские планеты',
|
||||
solarSatellite: 'Обеспечивает дополнительную энергию, генерирует 50 энергии на спутник',
|
||||
darkMatterHarvester: 'Специальный корабль для сбора тёмной материи',
|
||||
deathstar: 'Абсолютное оружие, способное уничтожать целые планеты'
|
||||
},
|
||||
@@ -186,6 +224,8 @@ export default {
|
||||
plasmaTurret: 'Плазменная турель',
|
||||
smallShieldDome: 'Малый щитовой купол',
|
||||
largeShieldDome: 'Большой щитовой купол',
|
||||
antiBallisticMissile: 'Противоракета',
|
||||
interplanetaryMissile: 'Межпланетная ракета',
|
||||
planetaryShield: 'Планетарный щит'
|
||||
},
|
||||
defenseDescriptions: {
|
||||
@@ -197,13 +237,23 @@ export default {
|
||||
plasmaTurret: 'Мощное оборонительное сооружение',
|
||||
smallShieldDome: 'Малый щит, защищающий всю планету',
|
||||
largeShieldDome: 'Большой щит, защищающий всю планету',
|
||||
antiBallisticMissile: 'Перехватывает вражеские ракеты, может перехватить 1 межпланетную ракету',
|
||||
interplanetaryMissile: 'Может атаковать оборонительные сооружения на других планетах',
|
||||
planetaryShield: 'Суперщит, защищающий планету от атак уничтожения'
|
||||
},
|
||||
research: {
|
||||
researchTime: 'Время исследования',
|
||||
totalCost: 'Общая стоимость',
|
||||
totalPoints: 'Общие очки',
|
||||
levelRange: 'Диапазон уровней'
|
||||
levelRange: 'Диапазон уровней',
|
||||
capacity: 'Capacity/Effect',
|
||||
storageCapacity: 'Capacity',
|
||||
energyProduction: 'Energy Production',
|
||||
fleetStorage: 'Fleet Storage',
|
||||
buildQueue: 'Build Queue',
|
||||
planetSpace: 'Planet Space',
|
||||
moonSpace: 'Moon Space',
|
||||
missileCapacity: 'Missile Capacity'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: 'Энергетическая технология',
|
||||
@@ -212,6 +262,12 @@ export default {
|
||||
hyperspaceTechnology: 'Гиперпространственная технология',
|
||||
plasmaTechnology: 'Плазменная технология',
|
||||
computerTechnology: 'Компьютерная технология',
|
||||
espionageTechnology: 'Шпионаж',
|
||||
weaponsTechnology: 'Оружие',
|
||||
shieldingTechnology: 'Щиты',
|
||||
armourTechnology: 'Броня',
|
||||
astrophysics: 'Астрофизика',
|
||||
gravitonTechnology: 'Гравитоны',
|
||||
combustionDrive: 'Реактивный двигатель',
|
||||
impulseDrive: 'Импульсный двигатель',
|
||||
hyperspaceDrive: 'Гиперпространственный двигатель',
|
||||
@@ -226,11 +282,18 @@ export default {
|
||||
hyperspaceTechnology: 'Технология гиперпространственных прыжков',
|
||||
plasmaTechnology: 'Технология плазменного оружия',
|
||||
computerTechnology: 'Увеличивает вместимость очереди исследований, +1 за уровень (макс 10 уровней)',
|
||||
espionageTechnology: 'Повышает эффективность зондов, +1 уровень шпионажа за уровень',
|
||||
weaponsTechnology: 'Увеличивает силу атаки кораблей и обороны на 10% за уровень',
|
||||
shieldingTechnology: 'Увеличивает щиты кораблей и обороны на 10% за уровень',
|
||||
armourTechnology: 'Увеличивает броню кораблей и обороны на 10% за уровень',
|
||||
astrophysics: 'Каждый уровень добавляет 1 слот колонии и повышает шанс успеха экспедиций',
|
||||
gravitonTechnology: 'Изучает манипуляцию гравитонами, требуется для Звезды смерти',
|
||||
combustionDrive: 'Базовая технология двигателей',
|
||||
impulseDrive: 'Средняя технология двигателей',
|
||||
hyperspaceDrive: 'Продвинутая технология двигателей',
|
||||
darkMatterTechnology: 'Исследование свойств и применения тёмной материи',
|
||||
terraformingTechnology: 'Исследование технологии терраформирования планет, увеличивает доступное пространство всех планет на 3 за уровень',
|
||||
terraformingTechnology:
|
||||
'Исследование технологии терраформирования планет, увеличивает доступное пространство всех планет на 30 за уровень',
|
||||
planetDestructionTech: 'Исследование ужасающей технологии уничтожения целых планет'
|
||||
},
|
||||
officers: {
|
||||
@@ -253,16 +316,20 @@ export default {
|
||||
darkMatterSpecialist: 'Улучшает эффективность сбора тёмной материи'
|
||||
},
|
||||
queue: {
|
||||
title: 'Очередь строительства',
|
||||
empty: 'Нет активных задач',
|
||||
buildQueue: 'Очередь строительства',
|
||||
researchQueue: 'Очередь исследований',
|
||||
building: 'Строится',
|
||||
researching: 'Исследуется',
|
||||
demolishing: 'Сносится',
|
||||
remaining: 'Осталось',
|
||||
cancel: 'Отменить',
|
||||
cancelBuild: 'Отменить строительство',
|
||||
cancelResearch: 'Отменить исследование',
|
||||
confirmCancel: 'Вы уверены, что хотите отменить? 50% ресурсов будет возвращено.',
|
||||
level: 'Уровень',
|
||||
gmModeActivated: '',
|
||||
upgradeToLevel: 'Улучшить до уровня'
|
||||
},
|
||||
overview: {
|
||||
@@ -283,6 +350,7 @@ export default {
|
||||
usedSpace: 'Использовано полей',
|
||||
spaceUsage: 'Использование полей',
|
||||
level: 'Уровень',
|
||||
gmModeActivated: '',
|
||||
upgradeCost: 'Стоимость улучшения',
|
||||
buildTime: 'Время строительства',
|
||||
upgrade: 'Улучшить',
|
||||
@@ -293,7 +361,9 @@ export default {
|
||||
demolish: 'Снести',
|
||||
demolishRefund: 'Возврат от сноса',
|
||||
demolishFailed: 'Снос не удался',
|
||||
demolishFailedMessage: 'Невозможно снести это здание. Проверьте, не заполнена ли очередь строительства или уровень здания не равен 0.'
|
||||
demolishFailedMessage: 'Невозможно снести это здание. Проверьте, не заполнена ли очередь строительства или уровень здания не равен 0.',
|
||||
confirmDemolish: 'Подтвердить снос',
|
||||
confirmDemolishMessage: 'Вы уверены, что хотите снести следующее здание?'
|
||||
},
|
||||
researchView: {
|
||||
title: 'Исследования',
|
||||
@@ -306,6 +376,7 @@ export default {
|
||||
},
|
||||
shipyard: {
|
||||
attack: 'Атака',
|
||||
missileAttack: 'Ракетная атака',
|
||||
shield: 'Щит',
|
||||
armor: 'Броня',
|
||||
speed: 'Скорость',
|
||||
@@ -323,6 +394,7 @@ export default {
|
||||
title: 'Верфь',
|
||||
fleetStorage: 'Хранилище флота',
|
||||
attack: 'Атака',
|
||||
missileAttack: 'Ракетная атака',
|
||||
shield: 'Щит',
|
||||
speed: 'Скорость',
|
||||
cargoCapacity: 'Грузоподъёмность',
|
||||
@@ -337,6 +409,7 @@ export default {
|
||||
},
|
||||
defense: {
|
||||
attack: 'Атака',
|
||||
missileAttack: 'Ракетная атака',
|
||||
shield: 'Щит',
|
||||
armor: 'Броня',
|
||||
buildCost: 'Стоимость постройки',
|
||||
@@ -350,6 +423,7 @@ export default {
|
||||
defenseView: {
|
||||
title: 'Оборона',
|
||||
attack: 'Атака',
|
||||
missileAttack: 'Ракетная атака',
|
||||
shield: 'Щит',
|
||||
armor: 'Броня',
|
||||
buildTime: 'Время постройки',
|
||||
@@ -359,6 +433,7 @@ export default {
|
||||
totalCost: 'Общая стоимость',
|
||||
build: 'Построить',
|
||||
shieldDomeBuilt: 'Щитовой купол уже построен',
|
||||
missileCapacity: 'Вместимость ракет',
|
||||
inputError: 'Ошибка ввода',
|
||||
inputErrorMessage: 'Пожалуйста, введите количество для постройки!',
|
||||
buildFailed: 'Постройка не удалась',
|
||||
@@ -372,6 +447,7 @@ export default {
|
||||
flightMissions: 'Полетные миссии',
|
||||
currentPlanetFleet: 'Флот на этой планете',
|
||||
attack: 'Атака',
|
||||
missileAttack: 'Ракетная атака',
|
||||
shield: 'Щит',
|
||||
armor: 'Броня',
|
||||
speed: 'Скорость',
|
||||
@@ -382,6 +458,7 @@ export default {
|
||||
all: 'Все',
|
||||
targetCoordinates: 'Целевые координаты',
|
||||
galaxy: 'Галактика',
|
||||
diplomacy: 'Diplomacy',
|
||||
system: 'Система',
|
||||
position: 'Позиция',
|
||||
missionType: 'Тип миссии',
|
||||
@@ -405,6 +482,11 @@ export default {
|
||||
arrivalTime: 'Время прибытия',
|
||||
returnTime: 'Время возврата',
|
||||
recallFleet: 'Отозвать флот',
|
||||
abortMission: '',
|
||||
abortMissionTitle: '',
|
||||
abortMissionWarning: '',
|
||||
abortMissionSuccess: '',
|
||||
abortMissionSuccessMessage: '',
|
||||
sendFailed: 'Отправка не удалась',
|
||||
sendFailedMessage: 'Пожалуйста, проверьте количество флота, наличие топлива или ограничения грузоподъёмности.',
|
||||
recallFailed: 'Отзыв не удался',
|
||||
@@ -415,7 +497,11 @@ export default {
|
||||
cannotSendToOwnPlanet: 'Невозможно отправить флот на свою планету',
|
||||
cargoExceedsCapacity: 'Груз превышает вместимость',
|
||||
noColonyShip: 'Для колонизационной миссии требуется колониальный корабль',
|
||||
noDebrisAtTarget: 'Нет поля обломков по целевым координатам или поле обломков пусто'
|
||||
noDebrisAtTarget: 'Нет поля обломков по целевым координатам или поле обломков пусто',
|
||||
noDeathstar: 'Для миссии разрушения требуется Звезда Смерти',
|
||||
giftMode: 'Режим подарка',
|
||||
giftModeDescription: 'Отправить ресурсы в подарок',
|
||||
estimatedReputationGain: 'Ожидаемый прирост репутации'
|
||||
},
|
||||
officersView: {
|
||||
title: 'Офицеры',
|
||||
@@ -455,42 +541,65 @@ export default {
|
||||
title: 'Галактика',
|
||||
selectCoordinates: 'Выбрать координаты',
|
||||
galaxy: 'Галактика',
|
||||
diplomacy: 'Diplomacy',
|
||||
selectGalaxy: 'Выбрать галактику',
|
||||
system: 'Система',
|
||||
selectSystem: 'Выбрать систему',
|
||||
view: 'Показать',
|
||||
myPlanet: 'Моя планета',
|
||||
myPlanets: 'Просмотр моих систем',
|
||||
npcPlanets: 'Планеты NPC',
|
||||
selectPlanetToView: 'Выберите планету для просмотра её системы',
|
||||
totalPositions: 'Всего 10 позиций планет',
|
||||
mine: 'Моя',
|
||||
hostile: 'Враждебная',
|
||||
emptySlot: 'Пусто - можно колонизировать',
|
||||
scout: 'Разведка',
|
||||
attack: 'Атака',
|
||||
missileAttack: 'Ракетная атака',
|
||||
colonize: 'Колонизация',
|
||||
switch: 'Переключить',
|
||||
recycle: 'Переработка',
|
||||
debrisField: 'Поле обломков',
|
||||
scoutPlanetTitle: 'Разведать планету',
|
||||
attackPlanetTitle: 'Атаковать планету',
|
||||
missileAttackTitle: 'Ракетная атака',
|
||||
colonizePlanetTitle: 'Колонизировать планету',
|
||||
recyclePlanetTitle: 'Переработать обломки',
|
||||
scoutPlanetMessage:
|
||||
'Вы уверены, что хотите отправить шпионские зонды для разведки планеты [{coordinates}]?\n\nПерейдите на страницу флота, чтобы выбрать корабли и отправить.',
|
||||
attackPlanetMessage:
|
||||
'Вы уверены, что хотите атаковать планету [{coordinates}]?\n\nПерейдите на страницу флота, чтобы выбрать корабли и отправить.',
|
||||
missileAttackMessage: 'Запустить межпланетные ракеты по планете [{coordinates}]',
|
||||
missileCount: 'Количество ракет',
|
||||
availableMissiles: 'Доступно ракет',
|
||||
missileRange: 'Дальность ракет',
|
||||
systems: 'систем',
|
||||
distance: 'Расстояние',
|
||||
flightTime: 'Время полета',
|
||||
launchMissile: 'Запустить',
|
||||
cancel: 'Отмена',
|
||||
colonizePlanetMessage:
|
||||
'Вы уверены, что хотите колонизировать позицию [{coordinates}]?\n\nПерейдите на страницу флота, чтобы отправить колонизационный корабль.',
|
||||
recyclePlanetMessage:
|
||||
'Вы уверены, что хотите переработать обломки в позиции [{coordinates}]?\n\nПерейдите на страницу флота, чтобы отправить переработчики.'
|
||||
'Вы уверены, что хотите переработать обломки в позиции [{coordinates}]?\n\nПерейдите на страницу флота, чтобы отправить переработчики.',
|
||||
sendGift: 'Отправить подарок',
|
||||
debris: 'Обломки',
|
||||
giftPlanetTitle: 'Отправить подарок',
|
||||
giftPlanetMessage:
|
||||
'Вы уверены, что хотите отправить ресурсы в подарок планете [{coordinates}]?\n\nПерейдите на страницу флота, чтобы выбрать транспортные корабли и загрузить ресурсы.'
|
||||
},
|
||||
messagesView: {
|
||||
title: 'Сообщения',
|
||||
battles: 'Битвы',
|
||||
spy: 'Разведка',
|
||||
npc: 'NPC',
|
||||
diplomacy: '',
|
||||
battleReports: 'Отчёты о боях',
|
||||
spyReports: 'Отчёты разведки',
|
||||
noBattleReports: 'Нет отчётов о боях',
|
||||
noSpyReports: 'Нет отчётов разведки',
|
||||
noDiplomaticReports: '',
|
||||
battleReport: 'Отчёт о бое',
|
||||
spyReport: 'Отчёт разведки',
|
||||
victory: 'Победа',
|
||||
@@ -517,7 +626,79 @@ export default {
|
||||
hideRoundDetails: 'Скрыть детали раундов',
|
||||
round: 'Раунд {round}',
|
||||
attackerRemainingPower: 'Оставшаяся мощь нападающего',
|
||||
defenderRemainingPower: 'Оставшаяся мощь защитника'
|
||||
defenderRemainingPower: 'Оставшаяся мощь защитника',
|
||||
spied: 'Шпионаж',
|
||||
spiedNotification: 'Уведомление о шпионаже',
|
||||
noSpiedNotifications: 'Нет уведомлений о шпионаже',
|
||||
detected: 'Обнаружено',
|
||||
undetected: 'Не обнаружено',
|
||||
missions: 'Миссии',
|
||||
noMissionReports: 'Нет отчётов о миссиях',
|
||||
success: 'Успех',
|
||||
failed: 'Неудача',
|
||||
npcActivity: 'Активность NPC',
|
||||
noNPCActivity: 'Нет уведомлений об активности NPC',
|
||||
npcRecycleActivity: 'NPC перерабатывает обломки',
|
||||
gifts: 'Подарки',
|
||||
giftRejected: 'Отклонено',
|
||||
noGiftNotifications: 'Нет уведомлений о подарках',
|
||||
noGiftRejected: 'Нет отклоненных подарков',
|
||||
giftFrom: 'Подарок от {npcName}',
|
||||
giftRejectedBy: '{npcName} отклонил подарок',
|
||||
giftResources: 'Ресурсы подарка',
|
||||
rejectedResources: 'Отклоненные ресурсы',
|
||||
expectedReputation: 'Ожидаемая репутация',
|
||||
currentReputation: 'Текущая репутация',
|
||||
acceptGift: 'Принять',
|
||||
rejectGift: 'Отклонить',
|
||||
rejectionReason: {
|
||||
hostile: 'Они враждебны и не принимают подарки',
|
||||
neutral_distrust: 'Они вам не доверяют',
|
||||
polite_decline: 'Вежливо отказались'
|
||||
},
|
||||
// Spied notification dialog
|
||||
spiedNotificationDetails: '',
|
||||
spyDetected: '',
|
||||
detectionResult: '',
|
||||
detectionSuccess: '',
|
||||
spiedNotificationMessage: '',
|
||||
spiedNotificationTip: '',
|
||||
viewInGalaxy: '',
|
||||
// Mission report dialog
|
||||
missionReportDetails: '',
|
||||
missionSuccess: '',
|
||||
missionFailed: '',
|
||||
origin: '',
|
||||
destination: '',
|
||||
missionDetails: '',
|
||||
transportedResources: '',
|
||||
recycledResources: '',
|
||||
remainingDebris: '',
|
||||
newPlanet: '',
|
||||
// NPC activity dialog
|
||||
npcActivityDetails: '',
|
||||
activityType: {
|
||||
recycle: ''
|
||||
},
|
||||
activityLocation: '',
|
||||
position: '',
|
||||
nearPlanet: '',
|
||||
activityDescription: '',
|
||||
npcActivityMessage: '',
|
||||
arrivalTime: '',
|
||||
npcActivityTip: ''
|
||||
},
|
||||
missionReports: {
|
||||
transportSuccess: 'Миссия транспортировки успешно завершена',
|
||||
transportFailed: 'Миссия транспортировки провалена',
|
||||
colonizeSuccess: 'Миссия колонизации успешна, новая планета создана',
|
||||
colonizeFailed: 'Миссия колонизации провалена',
|
||||
deploySuccess: 'Миссия размещения успешно завершена',
|
||||
deployFailed: 'Миссия размещения провалена',
|
||||
recycleSuccess: 'Миссия переработки успешно завершена',
|
||||
recycleFailed: 'Миссия переработки провалена, нет обломков в целевой позиции',
|
||||
destroySuccess: 'Миссия уничтожения планеты успешно выполнена',
|
||||
destroyFailed: 'Миссия уничтожения планеты провалена'
|
||||
},
|
||||
simulatorView: {
|
||||
title: 'Симулятор боя',
|
||||
@@ -586,10 +767,24 @@ export default {
|
||||
gamePaused: 'Игра приостановлена',
|
||||
gameResumed: 'Игра возобновлена',
|
||||
playerName: 'Имя игрока',
|
||||
gameSpeed: 'Скорость игры',
|
||||
gameSpeedDesc: 'Текущий множитель скорости игры',
|
||||
gameSpeed: 'Скорость производства ресурсов',
|
||||
gameSpeedDesc: 'Текущий множитель скорости производства ресурсов',
|
||||
speedChanged: 'Скорость производства ресурсов изменена на {speed}x',
|
||||
speedReset: 'Скорость производства ресурсов сброшена на 1x',
|
||||
reset: 'Сбросить',
|
||||
about: 'О программе',
|
||||
version: 'Версия',
|
||||
latestVersion: 'Последняя версия',
|
||||
checkUpdate: 'Проверить обновление',
|
||||
checking: 'Проверка...',
|
||||
newVersionAvailable: 'Доступна новая версия {version}',
|
||||
upToDate: 'Уже актуальная версия',
|
||||
checkUpdateCooldown: 'Пожалуйста, попробуйте позже (5 минут перезарядки)',
|
||||
checkUpdateFailed: 'Не удалось проверить обновления, проверьте подключение к Интернету',
|
||||
viewUpdate: 'Просмотреть обновление',
|
||||
updateAvailable: 'Доступна новая версия. Нажмите, чтобы просмотреть примечания к выпуску.',
|
||||
download: 'Скачать',
|
||||
goToDownload: 'Перейти к загрузке',
|
||||
buildDate: 'Дата сборки',
|
||||
community: 'Сообщество',
|
||||
github: 'Репозиторий GitHub',
|
||||
@@ -608,6 +803,8 @@ export default {
|
||||
officers: 'Офицеры',
|
||||
modifyResources: 'Изменить ресурсы',
|
||||
resourcesDesc: 'Быстрое изменение ресурсов планеты',
|
||||
maxAllResources: '',
|
||||
maxAllResourcesSuccess: '',
|
||||
modifyBuildings: 'Изменить здания',
|
||||
buildingsDesc: 'Быстрая установка уровней зданий',
|
||||
modifyResearch: 'Изменить исследования',
|
||||
@@ -619,9 +816,178 @@ export default {
|
||||
modifyOfficers: 'Изменить офицеров',
|
||||
officersDesc: 'Быстрая установка времени истечения офицеров',
|
||||
days: 'д',
|
||||
npcTesting: 'Тестирование NPC',
|
||||
npcTestingDesc: 'Тестирование разведки и атак NPC',
|
||||
selectNPC: 'Выбрать NPC',
|
||||
chooseNPC: 'Выберите NPC',
|
||||
targetPlanet: 'Целевая планета',
|
||||
chooseTarget: 'Выберите целевую планету',
|
||||
testSpy: 'Тест разведки',
|
||||
testAttack: 'Тест атаки',
|
||||
testSpyAndAttack: 'Тест разведки и атаки',
|
||||
testSpyMessage: 'Нажмите подтвердить, чтобы ускорить миссию разведки',
|
||||
testAttackMessage: 'Нажмите подтвердить, чтобы ускорить миссию атаки',
|
||||
testSpyAndAttackMessage: 'Нажмите подтвердить, чтобы ускорить миссии',
|
||||
initializeFleet: 'Инициализировать флот NPC',
|
||||
accelerateMissions: 'Ускорить все миссии (5с)',
|
||||
selectNPCFirst: 'Сначала выберите NPC',
|
||||
npcNoProbes: 'У NPC нет шпионских зондов',
|
||||
npcNoSpyReport: 'NPC нужно сначала разведать',
|
||||
npcMissionFailed: 'Не удалось создать миссию',
|
||||
npcNoPlanets: 'У NPC нет планет',
|
||||
npcWillSpyIn5s: '{npcName} проведет разведку через 5 секунд',
|
||||
npcWillAttackIn5s: '{npcName} атакует через 5 секунд',
|
||||
npcWillSpyAndAttack: '{npcName} проведет разведку через 5с и атакует через 10с',
|
||||
acceleratedMissions: 'Ускорено {count} миссий до 5 секунд',
|
||||
npcFleetInitialized: 'Флот {npcName} инициализирован',
|
||||
npcFleetDetails:
|
||||
'100 шпионских зондов\n500 легких истребителей\n300 тяжелых истребителей\n200 крейсеров\n100 линкоров\n50 бомбардировщиков\n30 эсминцев\n20 линейных крейсеров',
|
||||
dangerZone: 'Опасная зона',
|
||||
dangerZoneDesc: 'Следующие операции необратимы',
|
||||
resetGame: 'Сбросить игру',
|
||||
resetGameConfirm: 'Вы уверены, что хотите сбросить игру? Все данные будут удалены!'
|
||||
resetGameConfirm: 'Вы уверены, что хотите сбросить игру? Все данные будут удалены!',
|
||||
completeAllQueues: '',
|
||||
completeAllQueuesDesc: '',
|
||||
completeQueues: '',
|
||||
completeQueuesSuccess: ''
|
||||
},
|
||||
alerts: {
|
||||
npcSpyIncoming: 'Приближается шпионский зонд NPC',
|
||||
npcAttackIncoming: 'Атака флота NPC приближается!',
|
||||
npcFleetIncoming: 'Приближается флот NPC',
|
||||
ships: 'кораблей',
|
||||
spiedBy: 'Разведан',
|
||||
attackedBy: 'Атакован',
|
||||
detectionSuccess: 'Разведка обнаружена',
|
||||
detectionFailed: 'Разведка не обнаружена',
|
||||
npcSpiedYourPlanet: 'NPC разведал вашу планету',
|
||||
npcAttackedYourPlanet: 'NPC атаковал вашу планету'
|
||||
},
|
||||
diplomacy: {
|
||||
title: 'Дипломатия',
|
||||
description: 'Управление дипломатическими отношениями с NPC',
|
||||
tabs: {
|
||||
all: 'Все',
|
||||
friendly: 'Дружественные',
|
||||
neutral: 'Нейтральные',
|
||||
hostile: 'Враждебные'
|
||||
},
|
||||
noNpcs: 'Нет NPC',
|
||||
noFriendlyNpcs: 'Нет дружественных NPC',
|
||||
noNeutralNpcs: 'Нет нейтральных NPC',
|
||||
noHostileNpcs: 'Нет враждебных NPC',
|
||||
recentEvents: 'Недавние события',
|
||||
recentEventsDescription: 'Журнал последних дипломатических действий',
|
||||
ago: 'назад',
|
||||
notifications: '',
|
||||
markAllRead: '',
|
||||
noReports: '',
|
||||
viewAll: '',
|
||||
status: {
|
||||
friendly: 'Дружественный',
|
||||
neutral: 'Нейтральный',
|
||||
hostile: 'Враждебный'
|
||||
},
|
||||
planets: 'планет',
|
||||
allies: 'союзников',
|
||||
reputation: 'Репутация',
|
||||
alliedWith: 'В союзе с',
|
||||
more: 'еще',
|
||||
actions: {
|
||||
gift: 'Отправить подарок',
|
||||
viewPlanets: 'Посмотреть планеты'
|
||||
},
|
||||
lastEvent: 'Последнее событие',
|
||||
reportDetails: '',
|
||||
eventDescription: '',
|
||||
reputationChange: '',
|
||||
before: '',
|
||||
after: '',
|
||||
statusChange: '',
|
||||
viewDiplomacy: '',
|
||||
events: {
|
||||
gift: 'Подарок отправлен',
|
||||
attack: 'Атака',
|
||||
missileAttack: 'Ракетная атака',
|
||||
allyAttacked: 'Союзник атакован',
|
||||
spy: 'Шпионаж',
|
||||
stealDebris: 'Обломки украдены'
|
||||
},
|
||||
reports: {
|
||||
giftedResources: 'Подарено {metal}M {crystal}C {deuterium}D',
|
||||
receivedGiftFromPlayer: 'Получен подарок от игрока',
|
||||
giftedToNpc: 'Вы подарили ресурсы {npcName}. Репутация +{reputation}',
|
||||
rejectedPlayerGift: 'Отклонен подарок игрока',
|
||||
npcRejectedGift: '{npcName} отклонил ваш подарок. Репутация {reputation}',
|
||||
attackedNpc: 'Атакован {npcName}',
|
||||
wasAttackedByPlayer: 'Был атакован игроком',
|
||||
youAttackedNpc: 'Вы атаковали {npcName}',
|
||||
playerAttackedAlly: 'Игрок атаковал союзника {allyName}',
|
||||
allyDispleased: '{allyName} недоволен тем, что вы атаковали их союзника {targetName}',
|
||||
wasSpiedByPlayer: 'Был разведан игроком (обнаружен: {detected})',
|
||||
spyDetected: 'Ваш шпионаж был обнаружен {npcName}',
|
||||
stoleDebrisFromTerritory: 'Украдены обломки с территории {npcName}',
|
||||
playerStoleDebris: 'Игрок украл обломки с территории',
|
||||
recycledDebrisNearNpc: 'Вы переработали обломки возле планеты {npcName}. Они недовольны.',
|
||||
giftedResourcesToPlayer: 'Подарены ресурсы игроку',
|
||||
receivedGiftFromNpc: 'Получен подарок от {npcName}',
|
||||
acceptedGiftFromNpc: 'Вы приняли подарок от {npcName}: {metal}M {crystal}C {deuterium}D',
|
||||
playerRejectedGift: 'Игрок отклонил подарок',
|
||||
rejectedGiftFromNpc: 'Вы отклонили подарок от {npcName}. Репутация {reputation}',
|
||||
destroyedNpcPlanet: 'Уничтожена {planetName} игрока {npcName}',
|
||||
playerDestroyedPlanet: 'Игрок уничтожил {planetName}',
|
||||
youDestroyedNpcPlanet: 'Вы уничтожили {planetName} игрока {npcName}. Репутация {reputation}',
|
||||
playerDestroyedAllyPlanet: 'Игрок уничтожил {planetName} союзника {allyName}',
|
||||
allyOutraged: '{allyName} возмущен тем, что вы уничтожили {planetName} их союзника {targetName}',
|
||||
npcEliminated: 'NPC {npcName} полностью уничтожен',
|
||||
npcEliminatedMessage: 'Вы уничтожили все планеты {npcName}! Эта фракция полностью уничтожена.'
|
||||
}
|
||||
},
|
||||
pagination: {
|
||||
previous: 'Предыдущая',
|
||||
next: 'Следующая',
|
||||
gotIt: '',
|
||||
first: 'Первая',
|
||||
last: 'Последняя',
|
||||
page: 'Страница {page}'
|
||||
},
|
||||
notFound: {
|
||||
title: 'Страница не найдена',
|
||||
description: 'Извините, страница, которую вы ищете, не существует',
|
||||
goHome: 'На главную'
|
||||
},
|
||||
time: {
|
||||
days: 'дней',
|
||||
hours: 'часов',
|
||||
minutes: 'минут',
|
||||
seconds: 'секунд'
|
||||
},
|
||||
tutorial: {
|
||||
welcome: {
|
||||
title: 'Добро пожаловать в OGame',
|
||||
content: 'Добро пожаловать, Командир! Давайте начнём с основ и построим вашу космическую империю.'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: 'Постройте солнечную электростанцию',
|
||||
content:
|
||||
'Сначала постройте солнечную электростанцию! Она обеспечивает энергией вашу планету. Без энергии другие ресурсные здания не могут функционировать. Это самый важный первый шаг.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Очередь строительства',
|
||||
content:
|
||||
'Ваше здание теперь в очереди строительства. Нажмите на значок очереди в правом верхнем углу, чтобы увидеть все текущие задачи строительства и исследований. Строительство занимает время, но вы можете продолжать работать во время ожидания.'
|
||||
},
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: 'Добро пожаловать в OGame (Мобильная версия)',
|
||||
content:
|
||||
'Добро пожаловать, Командир! Это упрощённое руководство, разработанное для сенсорных экранов. Мы быстро рассмотрим основные функции, чтобы вы могли начать строить свою империю.'
|
||||
},
|
||||
waitBuild: {
|
||||
title: 'Очередь строительства',
|
||||
content:
|
||||
'Нажмите на значок очереди в правом верхнем углу, чтобы увидеть прогресс строительства. Вы можете продолжать просматривать другие страницы - строительство происходит в фоновом режиме.'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,20 @@ export default {
|
||||
viewRequirements: '查看前置条件',
|
||||
requirementsNotMet: '前置条件未满足',
|
||||
current: '当前',
|
||||
level: '等级'
|
||||
level: '等级',
|
||||
gmModeActivated: 'GM 模式已激活!请查看导航菜单。'
|
||||
},
|
||||
errors: {
|
||||
requirementsNotMet: '不满足前置条件',
|
||||
insufficientResources: '资源不足',
|
||||
insufficientFleetStorage: '舰队仓储空间不足',
|
||||
shieldDomeLimit: '护盾罩数量限制',
|
||||
missileSiloLimit: '导弹发射井容量不足',
|
||||
insufficientMissiles: '星际导弹数量不足',
|
||||
invalidMissileCount: '导弹数量无效',
|
||||
targetOutOfRange: '目标超出射程',
|
||||
cannotAttackOwnPlanet: '不能攻击自己的星球',
|
||||
launchFailed: '发射失败',
|
||||
fleetMissionsFull: '舰队任务槽位已满',
|
||||
insufficientFleet: '舰队数量不足',
|
||||
insufficientFuel: '燃料不足',
|
||||
@@ -62,6 +69,7 @@ export default {
|
||||
officers: '军官',
|
||||
simulator: '模拟',
|
||||
galaxy: '星系',
|
||||
diplomacy: '外交',
|
||||
messages: '消息',
|
||||
settings: '设置',
|
||||
gm: 'GM'
|
||||
@@ -78,7 +86,7 @@ export default {
|
||||
crystal: '晶体',
|
||||
deuterium: '重氢',
|
||||
darkMatter: '暗物质',
|
||||
energy: '能量',
|
||||
energy: '电力',
|
||||
production: '产量',
|
||||
consumption: '消耗',
|
||||
capacity: '容量',
|
||||
@@ -87,7 +95,7 @@ export default {
|
||||
perHour: '小时',
|
||||
perMinute: '分钟',
|
||||
hour: '小时',
|
||||
noEnergy: '能量不足'
|
||||
noEnergy: '电力不足'
|
||||
},
|
||||
planet: {
|
||||
planet: '星球',
|
||||
@@ -97,6 +105,8 @@ export default {
|
||||
coordinates: '坐标',
|
||||
switchToMoon: '查看月球',
|
||||
backToPlanet: '返回母星',
|
||||
switchPlanet: '切换星球',
|
||||
currentPlanet: '当前星球',
|
||||
fields: '场地',
|
||||
temperature: '温度',
|
||||
homePlanet: '母星',
|
||||
@@ -112,14 +122,18 @@ export default {
|
||||
crystalMine: '晶体矿',
|
||||
deuteriumSynthesizer: '重氢合成器',
|
||||
solarPlant: '太阳能电站',
|
||||
fusionReactor: '核聚变反应堆',
|
||||
roboticsFactory: '机器人工厂',
|
||||
naniteFactory: '纳米工厂',
|
||||
shipyard: '船坞',
|
||||
hangar: '机库',
|
||||
researchLab: '研究实验室',
|
||||
metalStorage: '金属仓库',
|
||||
crystalStorage: '晶体仓库',
|
||||
deuteriumTank: '重氢罐',
|
||||
darkMatterCollector: '暗物质收集器',
|
||||
darkMatterTank: '暗物质储罐',
|
||||
missileSilo: '导弹发射井',
|
||||
terraformer: '地形改造器',
|
||||
lunarBase: '月球基地',
|
||||
sensorPhalanx: '传感器阵列',
|
||||
@@ -130,23 +144,37 @@ export default {
|
||||
consumption: '消耗',
|
||||
totalCost: '累积成本',
|
||||
totalPoints: '累积积分',
|
||||
levelRange: '等级范围'
|
||||
levelRange: '等级范围',
|
||||
|
||||
storageCapacity: '容量',
|
||||
energyProduction: '电力产出',
|
||||
fleetStorage: '舰队仓储',
|
||||
buildQueueBonus: '建造队列',
|
||||
spaceBonus: '空间加成',
|
||||
buildSpeedBonus: '建造速度加成',
|
||||
researchSpeedBonus: '研究速度加成',
|
||||
|
||||
missileCapacity: '导弹容量'
|
||||
},
|
||||
buildingDescriptions: {
|
||||
metalMine: '开采金属资源',
|
||||
crystalMine: '开采晶体资源',
|
||||
deuteriumSynthesizer: '合成重氢资源',
|
||||
solarPlant: '提供能源',
|
||||
fusionReactor: '使用重氢产生大量能源',
|
||||
roboticsFactory: '加快建造速度',
|
||||
naniteFactory: '增加建造队列数量,每级+1队列(最多10级)',
|
||||
shipyard: '建造舰船',
|
||||
hangar: '专门用于扩展舰队存储容量,支持星球专业化发展',
|
||||
researchLab: '研究科技',
|
||||
metalStorage: '增加金属存储上限',
|
||||
crystalStorage: '增加晶体存储上限',
|
||||
deuteriumTank: '增加重氢存储上限',
|
||||
darkMatterCollector: '收集稀有的暗物质资源',
|
||||
terraformer: '改造行星地形,每级增加5个可用空间',
|
||||
lunarBase: '增加月球可用空间,每级+5空间',
|
||||
darkMatterTank: '增加暗物质存储上限',
|
||||
missileSilo: '存储和发射导弹,每级可存储10枚导弹',
|
||||
terraformer: '改造行星地形,每级增加30个可用空间',
|
||||
lunarBase: '增加月球可用空间,每级+30空间',
|
||||
sensorPhalanx: '侦测周围星系的舰队活动',
|
||||
jumpGate: '瞬间传送舰队到其他月球',
|
||||
planetDestroyerFactory: '建造能够摧毁行星的终极武器'
|
||||
@@ -156,11 +184,15 @@ export default {
|
||||
heavyFighter: '重型战斗机',
|
||||
cruiser: '巡洋舰',
|
||||
battleship: '战列舰',
|
||||
battlecruiser: '战列巡洋舰',
|
||||
bomber: '轰炸机',
|
||||
destroyer: '驱逐舰',
|
||||
smallCargo: '小型运输船',
|
||||
largeCargo: '大型运输船',
|
||||
colonyShip: '殖民船',
|
||||
recycler: '回收船',
|
||||
espionageProbe: '间谍探测器',
|
||||
solarSatellite: '太阳能卫星',
|
||||
darkMatterHarvester: '暗物质采集船',
|
||||
deathstar: '死星'
|
||||
},
|
||||
@@ -168,12 +200,16 @@ export default {
|
||||
lightFighter: '基础战斗单位',
|
||||
heavyFighter: '重装战斗机',
|
||||
cruiser: '中型战舰,攻守平衡',
|
||||
battleship: '强力战舰',
|
||||
battleship: '主力重型战舰,拥有强大的火力和防护',
|
||||
battlecruiser: '快速强大的战斗舰船,擅长攻击战列舰',
|
||||
bomber: '专门对付防御设施的轰炸舰',
|
||||
destroyer: '专业反大型舰船战舰,高火力低防护',
|
||||
smallCargo: '运输少量资源',
|
||||
largeCargo: '运输大量资源',
|
||||
colonyShip: '用于殖民新星球',
|
||||
recycler: '收集残骸场资源',
|
||||
espionageProbe: '侦察敌方星球',
|
||||
solarSatellite: '提供额外能源,每个产生50点电力',
|
||||
darkMatterHarvester: '专门用于采集暗物质的特殊飞船',
|
||||
deathstar: '终极武器,能够摧毁整个行星'
|
||||
},
|
||||
@@ -186,24 +222,38 @@ export default {
|
||||
plasmaTurret: '等离子炮塔',
|
||||
smallShieldDome: '小型护盾罩',
|
||||
largeShieldDome: '大型护盾罩',
|
||||
antiBallisticMissile: '反弹道导弹',
|
||||
interplanetaryMissile: '星际导弹',
|
||||
planetaryShield: '行星护盾'
|
||||
},
|
||||
defenseDescriptions: {
|
||||
rocketLauncher: '基础防御设施',
|
||||
lightLaser: '轻型能量武器',
|
||||
heavyLaser: '重型能量武器',
|
||||
lightLaser: '轻型电力武器',
|
||||
heavyLaser: '重型电力武器',
|
||||
gaussCannon: '高速动能武器',
|
||||
ionCannon: '破坏护盾的利器',
|
||||
plasmaTurret: '强力防御设施',
|
||||
smallShieldDome: '保护整个星球的小型护盾',
|
||||
largeShieldDome: '保护整个星球的大型护盾',
|
||||
antiBallisticMissile: '拦截敌方导弹,每个可拦截1枚星际导弹',
|
||||
interplanetaryMissile: '可以攻击其他星球的防御设施',
|
||||
planetaryShield: '保护行星免受毁灭攻击的超级护盾'
|
||||
},
|
||||
research: {
|
||||
researchTime: '研究时间',
|
||||
totalCost: '累积成本',
|
||||
totalPoints: '累积积分',
|
||||
levelRange: '等级范围'
|
||||
levelRange: '等级范围',
|
||||
|
||||
attackBonus: '攻击加成',
|
||||
shieldBonus: '护盾加成',
|
||||
armorBonus: '装甲加成',
|
||||
spyLevel: '侦查等级',
|
||||
researchQueueBonus: '研究队列',
|
||||
colonySlots: '殖民地槽位',
|
||||
forAllPlanets: '(全局)',
|
||||
speedBonus: '速度加成',
|
||||
researchSpeedBonus: '研究速度加成'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: '能源技术',
|
||||
@@ -212,6 +262,12 @@ export default {
|
||||
hyperspaceTechnology: '超空间技术',
|
||||
plasmaTechnology: '等离子技术',
|
||||
computerTechnology: '计算机技术',
|
||||
espionageTechnology: '间谍技术',
|
||||
weaponsTechnology: '武器技术',
|
||||
shieldingTechnology: '护盾技术',
|
||||
armourTechnology: '装甲技术',
|
||||
astrophysics: '天体物理学',
|
||||
gravitonTechnology: '引力技术',
|
||||
combustionDrive: '燃烧引擎',
|
||||
impulseDrive: '脉冲引擎',
|
||||
hyperspaceDrive: '超空间引擎',
|
||||
@@ -226,11 +282,17 @@ export default {
|
||||
hyperspaceTechnology: '超空间跳跃技术',
|
||||
plasmaTechnology: '等离子武器技术',
|
||||
computerTechnology: '增加研究队列数量,每级+1队列(最多10级)',
|
||||
espionageTechnology: '提高间谍探测效果,每级提高1级侦查深度',
|
||||
weaponsTechnology: '提高舰船和防御的攻击力,每级+10%',
|
||||
shieldingTechnology: '提高舰船和防御的护盾值,每级+10%',
|
||||
armourTechnology: '提高舰船和防御的装甲值,每级+10%',
|
||||
astrophysics: '每级增加1个殖民地槽位,增加探险成功率',
|
||||
gravitonTechnology: '研究引力操纵,死星的必要技术',
|
||||
combustionDrive: '基础推进技术',
|
||||
impulseDrive: '中级推进技术',
|
||||
hyperspaceDrive: '高级推进技术',
|
||||
darkMatterTechnology: '研究暗物质的性质和应用',
|
||||
terraformingTechnology: '研究行星地形改造技术,每级为所有行星增加3个可用空间',
|
||||
terraformingTechnology: '研究行星地形改造技术,每级为所有行星增加30个可用空间',
|
||||
planetDestructionTech: '研究如何摧毁整个行星的恐怖技术'
|
||||
},
|
||||
officers: {
|
||||
@@ -242,7 +304,7 @@ export default {
|
||||
darkMatterSpecialist: '暗物质专家',
|
||||
resourceBonus: '资源产量加成',
|
||||
darkMatterBonus: '暗物质产量加成',
|
||||
energyBonus: '能量产量加成'
|
||||
energyBonus: '电力产量加成'
|
||||
},
|
||||
officerDescriptions: {
|
||||
commander: '提升建筑速度和管理能力',
|
||||
@@ -253,10 +315,14 @@ export default {
|
||||
darkMatterSpecialist: '提升暗物质采集效率'
|
||||
},
|
||||
queue: {
|
||||
buildQueue: '建造队列',
|
||||
researchQueue: '研究队列',
|
||||
title: '建造队列',
|
||||
empty: '当前没有进行中的任务',
|
||||
buildQueueBonus: '建造队列',
|
||||
spaceBonus: '空间加成',
|
||||
researchQueueBonus: '研究队列',
|
||||
building: '建造中',
|
||||
researching: '研究中',
|
||||
demolishing: '拆除中',
|
||||
remaining: '剩余时间',
|
||||
cancel: '取消',
|
||||
cancelBuild: '取消建造',
|
||||
@@ -273,11 +339,11 @@ export default {
|
||||
currentShips: '当前星球的舰船数量',
|
||||
productionSources: '资源获取来源',
|
||||
productionSourcesDesc: '详细的资源产量及加成信息',
|
||||
consumptionSources: '能量消耗来源',
|
||||
consumptionSourcesDesc: '各建筑的能量消耗详情',
|
||||
consumptionSources: '电力消耗来源',
|
||||
consumptionSourcesDesc: '各建筑的电力消耗详情',
|
||||
totalProduction: '总产量',
|
||||
totalConsumption: '总消耗',
|
||||
noConsumption: '当前无能量消耗'
|
||||
noConsumption: '当前无电力消耗'
|
||||
},
|
||||
buildingsView: {
|
||||
title: '建筑',
|
||||
@@ -294,7 +360,9 @@ export default {
|
||||
demolish: '拆除',
|
||||
demolishRefund: '拆除返还',
|
||||
demolishFailed: '拆除失败',
|
||||
demolishFailedMessage: '无法拆除该建筑,请检查建造队列是否已满或建筑等级是否为0。'
|
||||
demolishFailedMessage: '无法拆除该建筑,请检查建造队列是否已满或建筑等级是否为0。',
|
||||
confirmDemolish: '确认拆除',
|
||||
confirmDemolishMessage: '确定要拆除'
|
||||
},
|
||||
researchView: {
|
||||
title: '研究',
|
||||
@@ -359,6 +427,7 @@ export default {
|
||||
totalCost: '总成本',
|
||||
build: '建造',
|
||||
shieldDomeBuilt: '护盾罩已建造',
|
||||
missileCapacity: '导弹容量',
|
||||
inputError: '输入错误',
|
||||
inputErrorMessage: '请输入建造数量!',
|
||||
buildFailed: '建造失败',
|
||||
@@ -405,6 +474,11 @@ export default {
|
||||
arrivalTime: '到达时间',
|
||||
returnTime: '返回时间',
|
||||
recallFleet: '召回舰队',
|
||||
abortMission: '终止任务',
|
||||
abortMissionTitle: '确认终止任务',
|
||||
abortMissionWarning: '警告:终止任务将永久损失 {ships} 艘舰船和 {resources} 资源!\n\n此操作不可撤销,舰队和资源将不会返回。',
|
||||
abortMissionSuccess: '任务已终止',
|
||||
abortMissionSuccessMessage: '任务已终止,舰队和资源已损失。',
|
||||
sendFailed: '派遣失败',
|
||||
sendFailedMessage: '请检查舰队数量、燃料是否充足,或载货量是否超出限制。',
|
||||
recallFailed: '召回失败',
|
||||
@@ -416,7 +490,10 @@ export default {
|
||||
cargoExceedsCapacity: '载货量超出限制',
|
||||
noColonyShip: '需要殖民船才能执行殖民任务',
|
||||
noDebrisAtTarget: '目标坐标没有残骸场或残骸场已空',
|
||||
noDeathstar: '需要死星才能执行毁灭任务'
|
||||
noDeathstar: '需要死星才能执行毁灭任务',
|
||||
giftMode: '赠送模式',
|
||||
giftModeDescription: '将资源作为礼物赠送给',
|
||||
estimatedReputationGain: '预计好感度增加'
|
||||
},
|
||||
officersView: {
|
||||
title: '军官',
|
||||
@@ -461,33 +538,55 @@ export default {
|
||||
selectSystem: '选择星系',
|
||||
view: '查看',
|
||||
myPlanet: '我的星球',
|
||||
myPlanets: '查看我的星系',
|
||||
npcPlanets: 'NPC星球',
|
||||
selectPlanetToView: '选择星球以查看其所在星系',
|
||||
totalPositions: '共10个星球位置',
|
||||
mine: '我的',
|
||||
hostile: '敌对',
|
||||
emptySlot: '空位 - 可殖民',
|
||||
scout: '侦察',
|
||||
attack: '攻击',
|
||||
missileAttack: '导弹攻击',
|
||||
colonize: '殖民',
|
||||
switch: '切换',
|
||||
recycle: '回收',
|
||||
sendGift: '赠送礼物',
|
||||
debris: '残骸',
|
||||
debrisField: '残骸场',
|
||||
scoutPlanetTitle: '侦察星球',
|
||||
attackPlanetTitle: '攻击星球',
|
||||
missileAttackTitle: '导弹攻击',
|
||||
colonizePlanetTitle: '殖民星球',
|
||||
recyclePlanetTitle: '回收残骸',
|
||||
giftPlanetTitle: '赠送礼物',
|
||||
scoutPlanetMessage: '确定要派遣间谍探测器侦察星球 [{coordinates}] 吗?\n\n请前往舰队页面选择舰船并派遣。',
|
||||
attackPlanetMessage: '确定要攻击星球 [{coordinates}] 吗?\n\n请前往舰队页面选择舰船并派遣。',
|
||||
missileAttackMessage: '向星球 [{coordinates}] 发射导弹',
|
||||
missileCount: '导弹数量',
|
||||
availableMissiles: '可用导弹',
|
||||
missileRange: '射程',
|
||||
systems: '系统',
|
||||
distance: '距离',
|
||||
flightTime: '飞行时间',
|
||||
launchMissile: '发射',
|
||||
missileLaunched: '导弹已发射',
|
||||
cancel: '取消',
|
||||
colonizePlanetMessage: '确定要殖民位置 [{coordinates}] 吗?\n\n请前往舰队页面派遣殖民船。',
|
||||
recyclePlanetMessage: '确定要回收位置 [{coordinates}] 的残骸吗?\n\n请前往舰队页面派遣回收船。'
|
||||
recyclePlanetMessage: '确定要回收位置 [{coordinates}] 的残骸吗?\n\n请前往舰队页面派遣回收船。',
|
||||
giftPlanetMessage: '确定要向星球 [{coordinates}] 赠送资源吗?\n\n请前往舰队页面选择运输船并装载资源。'
|
||||
},
|
||||
messagesView: {
|
||||
title: '消息中心',
|
||||
battles: '战斗',
|
||||
spy: '侦查',
|
||||
npc: 'NPC',
|
||||
diplomacy: '',
|
||||
battleReports: '战斗报告',
|
||||
spyReports: '间谍报告',
|
||||
noBattleReports: '暂无战斗报告',
|
||||
noSpyReports: '暂无间谍报告',
|
||||
noDiplomaticReports: '',
|
||||
battleReport: '战斗报告',
|
||||
spyReport: '间谍报告',
|
||||
victory: '胜利',
|
||||
@@ -514,7 +613,83 @@ export default {
|
||||
hideRoundDetails: '隐藏回合详情',
|
||||
round: '第{round}回合',
|
||||
attackerRemainingPower: '攻击方剩余火力',
|
||||
defenderRemainingPower: '防守方剩余火力'
|
||||
defenderRemainingPower: '防守方剩余火力',
|
||||
spied: '被侦查',
|
||||
spiedNotification: '被侦查通知',
|
||||
noSpiedNotifications: '暂无被侦查通知',
|
||||
detected: '已发现',
|
||||
undetected: '未发现',
|
||||
missions: '任务',
|
||||
noMissionReports: '暂无任务报告',
|
||||
success: '成功',
|
||||
failed: '失败',
|
||||
npcActivity: 'NPC活动',
|
||||
noNPCActivity: '暂无NPC活动通知',
|
||||
npcRecycleActivity: 'NPC回收残骸',
|
||||
gifts: '礼物',
|
||||
giftRejected: '被拒绝',
|
||||
noGiftNotifications: '暂无礼物通知',
|
||||
noGiftRejected: '暂无拒绝记录',
|
||||
giftFrom: '{npcName}的礼物',
|
||||
giftRejectedBy: '{npcName}拒绝了礼物',
|
||||
giftResources: '礼物资源',
|
||||
rejectedResources: '被拒绝的资源',
|
||||
expectedReputation: '预计好感度',
|
||||
currentReputation: '当前好感度',
|
||||
acceptGift: '接受',
|
||||
rejectGift: '拒绝',
|
||||
rejectionReason: {
|
||||
hostile: '对方对你有敌意,不接受礼物',
|
||||
neutral_distrust: '对方对你缺乏信任',
|
||||
polite_decline: '对方礼貌地拒绝了'
|
||||
},
|
||||
// 被侦查通知对话框
|
||||
spiedNotificationDetails: '被侦查通知详情',
|
||||
spyDetected: '侦查被发现',
|
||||
detectionResult: '检测结果',
|
||||
detectionSuccess: '你的侦查探测被发现了!',
|
||||
spiedNotificationMessage: '{npc}试图侦查你的星球{planet}',
|
||||
spiedNotificationTip: '考虑增强防御或反击,如果这个NPC对你有敌意',
|
||||
viewInGalaxy: '在星系中查看',
|
||||
// 任务报告对话框
|
||||
missionReportDetails: '任务报告详情',
|
||||
missionSuccess: '成功',
|
||||
missionFailed: '失败',
|
||||
origin: '起点',
|
||||
destination: '终点',
|
||||
missionDetails: '任务详情',
|
||||
transportedResources: '运输资源',
|
||||
recycledResources: '回收资源',
|
||||
remainingDebris: '剩余残骸',
|
||||
newPlanet: '新星球',
|
||||
// NPC活动对话框
|
||||
npcActivityDetails: 'NPC活动详情',
|
||||
activityType: {
|
||||
recycle: '回收残骸'
|
||||
},
|
||||
activityLocation: '活动位置',
|
||||
position: '位置',
|
||||
nearPlanet: '附近星球',
|
||||
activityDescription: '活动描述',
|
||||
npcActivityMessage: '{npc}正在{position}{activity}',
|
||||
arrivalTime: '到达时间',
|
||||
npcActivityTip: 'NPC可能会收集战斗产生的残骸。如果你想竞争资源,可以尝试先到达该位置'
|
||||
},
|
||||
missionReports: {
|
||||
transportSuccess: '运输任务成功完成',
|
||||
transportFailed: '运输任务失败',
|
||||
colonizeSuccess: '殖民任务成功,新星球已建立',
|
||||
colonizeFailed: '殖民任务失败',
|
||||
deploySuccess: '部署任务成功完成',
|
||||
deployFailed: '部署任务失败',
|
||||
recycleSuccess: '回收任务成功完成',
|
||||
recycleFailed: '回收任务失败,目标位置没有残骸',
|
||||
destroySuccess: '行星毁灭任务成功执行',
|
||||
destroyFailed: '行星毁灭任务失败',
|
||||
missileAttackSuccess: '导弹攻击成功',
|
||||
missileAttackFailed: '导弹攻击失败,目标星球不存在',
|
||||
missileAttackIntercepted: '所有导弹被拦截',
|
||||
hits: '枚命中'
|
||||
},
|
||||
simulatorView: {
|
||||
title: '战斗模拟器',
|
||||
@@ -583,10 +758,24 @@ export default {
|
||||
gamePaused: '游戏已暂停',
|
||||
gameResumed: '游戏已恢复',
|
||||
playerName: '玩家名称',
|
||||
gameSpeed: '游戏速度',
|
||||
gameSpeedDesc: '当前游戏速度倍率',
|
||||
gameSpeed: '资源产出速度',
|
||||
gameSpeedDesc: '当前资源产出速度倍率',
|
||||
speedChanged: '资源产出速度已更改为 {speed}x',
|
||||
speedReset: '资源产出速度已重置为 1x',
|
||||
reset: '重置',
|
||||
about: '关于',
|
||||
version: '版本',
|
||||
latestVersion: '最新版本',
|
||||
checkUpdate: '检查更新',
|
||||
checking: '检查中...',
|
||||
newVersionAvailable: '发现新版本 {version}',
|
||||
upToDate: '已是最新版本',
|
||||
checkUpdateCooldown: '请稍后再试(5分钟冷却时间)',
|
||||
checkUpdateFailed: '检查更新失败,请检查网络连接',
|
||||
viewUpdate: '查看更新',
|
||||
updateAvailable: '有新版本可用。点击查看更新内容。',
|
||||
download: '下载',
|
||||
goToDownload: '前往下载',
|
||||
buildDate: '构建日期',
|
||||
community: '社区',
|
||||
github: 'GitHub 仓库',
|
||||
@@ -605,6 +794,8 @@ export default {
|
||||
officers: '军官',
|
||||
modifyResources: '修改资源',
|
||||
resourcesDesc: '快速修改星球资源数量',
|
||||
maxAllResources: '一键拉满',
|
||||
maxAllResourcesSuccess: '所有资源已拉满',
|
||||
modifyBuildings: '修改建筑',
|
||||
buildingsDesc: '快速设置建筑等级',
|
||||
modifyResearch: '修改科技',
|
||||
@@ -616,9 +807,281 @@ export default {
|
||||
modifyOfficers: '修改军官',
|
||||
officersDesc: '快速设置军官到期时间',
|
||||
days: '天',
|
||||
npcTesting: 'NPC 测试',
|
||||
npcTestingDesc: '测试NPC侦查和攻击行为',
|
||||
selectNPC: '选择NPC',
|
||||
chooseNPC: '选择一个NPC',
|
||||
targetPlanet: '目标星球',
|
||||
chooseTarget: '选择目标星球',
|
||||
testSpy: '测试侦查',
|
||||
testAttack: '测试攻击',
|
||||
testSpyAndAttack: '测试侦查&攻击',
|
||||
testSpyMessage: '点击确认以加速侦查任务',
|
||||
testAttackMessage: '点击确认以加速攻击任务',
|
||||
testSpyAndAttackMessage: '点击确认以加速任务执行',
|
||||
initializeFleet: '初始化NPC舰队',
|
||||
accelerateMissions: '加速所有任务(5秒)',
|
||||
selectNPCFirst: '请先选择一个NPC',
|
||||
npcNoProbes: 'NPC没有间谍探测器',
|
||||
npcNoSpyReport: 'NPC需要先侦查',
|
||||
npcMissionFailed: '创建任务失败',
|
||||
npcNoPlanets: 'NPC没有星球',
|
||||
npcWillSpyIn5s: '{npcName}将在5秒后侦查',
|
||||
npcWillAttackIn5s: '{npcName}将在5秒后攻击',
|
||||
npcWillSpyAndAttack: '{npcName}将在5秒后侦查,10秒后攻击',
|
||||
acceleratedMissions: '已加速{count}个任务至5秒后',
|
||||
npcFleetInitialized: '{npcName}舰队已初始化',
|
||||
npcFleetDetails: '100 间谍探测器\n500 轻型战机\n300 重型战机\n200 巡洋舰\n100 战列舰\n50 轰炸机\n30 毁灭者\n20 战列巡洋舰',
|
||||
dangerZone: '危险区域',
|
||||
dangerZoneDesc: '以下操作不可撤销,请谨慎操作',
|
||||
resetGame: '重置游戏',
|
||||
resetGameConfirm: '确定要重置游戏吗?这将删除所有数据!'
|
||||
resetGameConfirm: '确定要重置游戏吗?这将删除所有数据!',
|
||||
completeAllQueues: '一键完成所有队列',
|
||||
completeAllQueuesDesc: '立即完成所有建筑、科技、舰船、防御队列和飞行任务',
|
||||
completeQueues: '完成队列',
|
||||
completeQueuesSuccess:
|
||||
'已完成 {buildingCount} 个建筑队列、{researchCount} 个科技队列、{missionCount} 个飞行任务、{missileCount} 个导弹任务'
|
||||
},
|
||||
alerts: {
|
||||
npcSpyIncoming: 'NPC侦查即将到达',
|
||||
npcAttackIncoming: 'NPC舰队来袭!',
|
||||
npcFleetIncoming: 'NPC舰队接近',
|
||||
ships: '艘舰船',
|
||||
spiedBy: '被侦查',
|
||||
attackedBy: '被攻击',
|
||||
detectionSuccess: '侦查被发现',
|
||||
detectionFailed: '侦查未被发现',
|
||||
npcSpiedYourPlanet: 'NPC侦查了你的星球',
|
||||
npcAttackedYourPlanet: 'NPC攻击了你的星球'
|
||||
},
|
||||
diplomacy: {
|
||||
title: '外交',
|
||||
description: '管理与NPC的外交关系',
|
||||
tabs: {
|
||||
all: '全部',
|
||||
friendly: '友好',
|
||||
neutral: '中立',
|
||||
hostile: '敌对'
|
||||
},
|
||||
noNpcs: '暂无NPC',
|
||||
noFriendlyNpcs: '暂无友好NPC',
|
||||
noNeutralNpcs: '暂无中立NPC',
|
||||
noHostileNpcs: '暂无敌对NPC',
|
||||
recentEvents: '最近事件',
|
||||
recentEventsDescription: '最近的外交活动记录',
|
||||
ago: '前',
|
||||
notifications: '外交通知',
|
||||
markAllRead: '全部已读',
|
||||
noReports: '暂无外交事件',
|
||||
viewAll: '查看全部',
|
||||
status: {
|
||||
friendly: '友好',
|
||||
neutral: '中立',
|
||||
hostile: '敌对'
|
||||
},
|
||||
planets: '个星球',
|
||||
allies: '个盟友',
|
||||
reputation: '好感度',
|
||||
alliedWith: '盟友',
|
||||
more: '更多',
|
||||
actions: {
|
||||
gift: '赠送资源',
|
||||
viewPlanets: '查看星球'
|
||||
},
|
||||
lastEvent: '最近活动',
|
||||
reportDetails: '外交报告详情',
|
||||
eventDescription: '事件描述',
|
||||
reputationChange: '好感度变化',
|
||||
before: '之前',
|
||||
after: '之后',
|
||||
statusChange: '关系状态变化',
|
||||
viewDiplomacy: '查看外交页面',
|
||||
events: {
|
||||
gift: '赠送资源',
|
||||
attack: '攻击',
|
||||
allyAttacked: '攻击盟友',
|
||||
spy: '侦查',
|
||||
stealDebris: '抢夺残骸'
|
||||
},
|
||||
reports: {
|
||||
giftedResources: '赠送了 {metal}金属 {crystal}晶体 {deuterium}氘',
|
||||
receivedGiftFromPlayer: '收到玩家的礼物',
|
||||
giftedToNpc: '你向{npcName}赠送了资源。好感度+{reputation}',
|
||||
rejectedPlayerGift: '拒绝了玩家的礼物',
|
||||
npcRejectedGift: '{npcName}拒绝了你的礼物。好感度{reputation}',
|
||||
attackedNpc: '攻击了{npcName}',
|
||||
wasAttackedByPlayer: '被玩家攻击',
|
||||
youAttackedNpc: '你攻击了{npcName}',
|
||||
playerAttackedAlly: '玩家攻击了盟友{allyName}',
|
||||
allyDispleased: '{allyName}对你攻击盟友{targetName}感到不满',
|
||||
wasSpiedByPlayer: '被玩家侦查(被发现:{detected})',
|
||||
spyDetected: '你的侦查被{npcName}发现了',
|
||||
stoleDebrisFromTerritory: '从{npcName}的领地抢夺了残骸',
|
||||
playerStoleDebris: '玩家从领地抢夺了残骸',
|
||||
recycledDebrisNearNpc: '你在{npcName}的星球附近回收了残骸。他们很不高兴。',
|
||||
giftedResourcesToPlayer: '向玩家赠送了资源',
|
||||
receivedGiftFromNpc: '收到了{npcName}的礼物',
|
||||
acceptedGiftFromNpc: '你接受了{npcName}的礼物:{metal}金属 {crystal}晶体 {deuterium}氘',
|
||||
playerRejectedGift: '玩家拒绝了礼物',
|
||||
rejectedGiftFromNpc: '你拒绝了{npcName}的礼物。好感度{reputation}',
|
||||
destroyedNpcPlanet: '摧毁了{npcName}的{planetName}',
|
||||
playerDestroyedPlanet: '玩家摧毁了{planetName}',
|
||||
youDestroyedNpcPlanet: '你摧毁了{npcName}的{planetName}。好感度{reputation}',
|
||||
playerDestroyedAllyPlanet: '玩家摧毁了盟友{allyName}的{planetName}',
|
||||
allyOutraged: '{allyName}对你摧毁盟友{targetName}的{planetName}感到愤怒',
|
||||
npcEliminated: 'NPC {npcName}已被彻底消灭',
|
||||
npcEliminatedMessage: '你消灭了{npcName}的所有星球!该势力已被彻底摧毁。'
|
||||
}
|
||||
},
|
||||
pagination: {
|
||||
previous: '上一页',
|
||||
next: '下一页',
|
||||
first: '首页',
|
||||
last: '末页',
|
||||
page: '第 {page} 页'
|
||||
},
|
||||
notFound: {
|
||||
title: '页面未找到',
|
||||
description: '抱歉,您访问的页面不存在',
|
||||
goHome: '返回首页'
|
||||
},
|
||||
time: {
|
||||
days: '天',
|
||||
hours: '小时',
|
||||
minutes: '分钟',
|
||||
seconds: '秒'
|
||||
},
|
||||
tutorial: {
|
||||
progress: '进度',
|
||||
previous: '上一步',
|
||||
next: '下一步',
|
||||
gotIt: '我知道了',
|
||||
completeButton: '完成',
|
||||
skip: '跳过引导',
|
||||
welcome: {
|
||||
title: '欢迎来到 OGame',
|
||||
content: '欢迎,指挥官!本教程将引导您了解建立帝国的基础知识。点击"下一步"开始您的征程。'
|
||||
},
|
||||
resources: {
|
||||
title: '资源概览',
|
||||
content: '这些是您的资源:金属、晶体和重氢。它们是建造建筑和研究科技的必需品。能量也很重要,用于为您的基础设施供电。'
|
||||
},
|
||||
planet: {
|
||||
title: '您的星球',
|
||||
content: '这是您的母星。您可以在这里查看星球名称、坐标,并在扩张帝国时切换星球。'
|
||||
},
|
||||
navigation: {
|
||||
title: '导航菜单',
|
||||
content: '使用此菜单在不同部分之间导航:建筑、研究、舰队、星系等。每个部分都提供独特的游戏功能。'
|
||||
},
|
||||
gotoBuildings: {
|
||||
title: '前往建筑页面',
|
||||
content: '让我们从建造一些建筑开始。点击"建筑"菜单项查看可用建筑。'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: '建造太阳能电站',
|
||||
content: '首先建造太阳能电站!它为您的星球提供能量。没有能量,其他资源建筑无法运作。这是最重要的第一步。'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '建造队列',
|
||||
content:
|
||||
'您的建筑现在在建造队列中。点击右上角的队列图标可以查看所有正在进行的建造和研究任务。建筑需要时间完成,但您可以在等待时继续操作。'
|
||||
},
|
||||
buildMetalMine: {
|
||||
title: '建造金属矿',
|
||||
content: '现在有了能量,可以建造金属矿了。金属矿是您的主要金属来源,金属几乎用于每个建筑和舰船。'
|
||||
},
|
||||
buildCrystalMine: {
|
||||
title: '建造晶体矿',
|
||||
content: '晶体更稀有但对高级科技至关重要。建造晶体矿开始收集这种宝贵的资源。'
|
||||
},
|
||||
buildDeuterium: {
|
||||
title: '建造重氢合成器',
|
||||
content: '重氢是舰船燃料和高级研究的必需品。建造重氢合成器开始生产这种关键资源。'
|
||||
},
|
||||
upgradeMines: {
|
||||
title: '升级资源矿',
|
||||
content: '接下来,您需要升级三种资源矿(金属、晶体、重氢)到2级,以满足建造机器人工厂的要求。资源充足后,继续升级它们。'
|
||||
},
|
||||
buildRobotics: {
|
||||
title: '建造机器人工厂',
|
||||
content: '机器人工厂可以大幅加快建造速度。它需要金属矿、晶体矿和重氢合成器各达到2级。建造它来提升建造效率!'
|
||||
},
|
||||
upgradeMinesForLab: {
|
||||
title: '继续升级资源矿',
|
||||
content: '现在需要将三种资源矿升级到3级,以满足研究实验室的建造要求。继续发展您的资源产能。'
|
||||
},
|
||||
buildResearchLab: {
|
||||
title: '建造研究实验室',
|
||||
content: '研究实验室是技术进步的基础。它需要三种资源矿各达到3级。建造它以解锁科技研究!'
|
||||
},
|
||||
gotoResearch: {
|
||||
title: '前往研究页面',
|
||||
content: '既然您有了研究实验室,点击"研究"菜单查看可用的科技。'
|
||||
},
|
||||
researchEnergy: {
|
||||
title: '研究能量科技',
|
||||
content: '能量科技可以提高您的能量产出并解锁高级建筑。这是最基础也是最重要的科技之一。'
|
||||
},
|
||||
shipyardIntro: {
|
||||
title: '舰队与船坞',
|
||||
content: '舰船让您能够探索星系、运输资源并保卫您的帝国。要建造舰船,您需要船坞(需要机器人工厂2级)。'
|
||||
},
|
||||
gotoBuildingsForShipyard: {
|
||||
title: '返回建筑页面',
|
||||
content: '返回建筑页面来建造您的船坞。'
|
||||
},
|
||||
buildShipyard: {
|
||||
title: '建造船坞',
|
||||
content: '船坞允许您建造舰船和防御系统。这对舰队行动至关重要。'
|
||||
},
|
||||
fleetIntro: {
|
||||
title: '舰队行动',
|
||||
content: '一旦您拥有舰船,就可以派遣它们执行任务:运输资源、殖民星球、攻击敌人或探索废墟场。'
|
||||
},
|
||||
galaxyIntro: {
|
||||
title: '探索星系',
|
||||
content: '星系视图显示其他星球、废墟场和扩张机会。使用它来侦察目标并规划您的战略。'
|
||||
},
|
||||
complete: {
|
||||
title: '教程完成!',
|
||||
content:
|
||||
'恭喜,指挥官!您现在了解了基础知识。继续建设您的帝国,研究科技,探索星系。记住:先发展能量,再建资源,然后是工厂和研究!祝您好运!'
|
||||
},
|
||||
// 移动端教程
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: '欢迎来到 OGame(移动版)',
|
||||
content: '欢迎,指挥官!这是专为触摸屏设计的简化教程。我们将快速介绍核心功能,让您开始建设帝国。'
|
||||
},
|
||||
resources: {
|
||||
title: '顶部资源栏',
|
||||
content: '顶部显示您的资源:金属、晶体和重氢。点击可查看详细生产信息。'
|
||||
},
|
||||
menu: {
|
||||
title: '打开导航菜单',
|
||||
content: '点击这个菜单图标打开导航栏,您可以访问建筑、研究、舰队等所有功能。'
|
||||
},
|
||||
gotoBuildings: {
|
||||
title: '前往建筑页面',
|
||||
content: '菜单已打开!现在点击"建筑"选项,开始建造基础设施。'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: '建造太阳能电站',
|
||||
content: '首先建造太阳能电站!向下滚动找到它,点击卡片进行建造。能量是一切的基础。'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '建造队列',
|
||||
content: '点击右上角的队列图标可以查看建造进度。您可以继续浏览其他页面,建造会在后台进行。'
|
||||
},
|
||||
buildMetalMine: {
|
||||
title: '建造金属矿',
|
||||
content: '有了能量后,建造金属矿。向下滚动找到金属矿,点击建造。'
|
||||
},
|
||||
complete: {
|
||||
title: '快速教程完成!',
|
||||
content: '很好!您已经掌握了基础操作。继续建造晶体矿和重氢合成器,然后探索其他功能。记住:先能量,再资源!'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ export default {
|
||||
close: '關閉',
|
||||
back: '返回',
|
||||
next: '下一步',
|
||||
gotIt: '',
|
||||
previous: '上一步',
|
||||
submit: '提交',
|
||||
reset: '重置',
|
||||
@@ -33,13 +34,19 @@ export default {
|
||||
viewRequirements: '查看前置條件',
|
||||
requirementsNotMet: '前置條件未滿足',
|
||||
current: '當前',
|
||||
level: '等級'
|
||||
level: '等級',
|
||||
gmModeActivated: 'GM 模式已啟用!請查看導航選單。'
|
||||
},
|
||||
errors: {
|
||||
requirementsNotMet: '不滿足前置條件',
|
||||
insufficientResources: '資源不足',
|
||||
insufficientFleetStorage: '艦隊倉儲空間不足',
|
||||
shieldDomeLimit: '護盾罩數量限制',
|
||||
missileSiloLimit: '導彈發射井容量已滿',
|
||||
insufficientMissiles: '星際導彈數量不足',
|
||||
invalidMissileCount: '導彈數量無效',
|
||||
targetOutOfRange: '目標超出射程',
|
||||
cannotAttackOwnPlanet: '不能攻擊自己的星球',
|
||||
fleetMissionsFull: '艦隊任務槽位已滿',
|
||||
insufficientFleet: '艦隊數量不足',
|
||||
insufficientFuel: '燃料不足',
|
||||
@@ -62,6 +69,7 @@ export default {
|
||||
officers: '軍官',
|
||||
simulator: '模擬',
|
||||
galaxy: '星系',
|
||||
diplomacy: 'Diplomacy',
|
||||
messages: '訊息',
|
||||
settings: '設定',
|
||||
gm: 'GM'
|
||||
@@ -78,7 +86,7 @@ export default {
|
||||
crystal: '晶體',
|
||||
deuterium: '重氫',
|
||||
darkMatter: '暗物質',
|
||||
energy: '能量',
|
||||
energy: '電力',
|
||||
production: '產量',
|
||||
consumption: '消耗',
|
||||
capacity: '容量',
|
||||
@@ -87,7 +95,7 @@ export default {
|
||||
perHour: '小時',
|
||||
perMinute: '分鐘',
|
||||
hour: '小時',
|
||||
noEnergy: '能量不足'
|
||||
noEnergy: '電力不足'
|
||||
},
|
||||
planet: {
|
||||
planet: '星球',
|
||||
@@ -97,6 +105,8 @@ export default {
|
||||
coordinates: '座標',
|
||||
switchToMoon: '查看月球',
|
||||
backToPlanet: '返回母星',
|
||||
switchPlanet: '切換星球',
|
||||
currentPlanet: '當前星球',
|
||||
fields: '場地',
|
||||
temperature: '溫度',
|
||||
homePlanet: '母星',
|
||||
@@ -112,14 +122,18 @@ export default {
|
||||
crystalMine: '晶體礦',
|
||||
deuteriumSynthesizer: '重氫合成器',
|
||||
solarPlant: '太陽能電站',
|
||||
fusionReactor: '核聚變反應堆',
|
||||
roboticsFactory: '機器人工廠',
|
||||
naniteFactory: '納米工廠',
|
||||
shipyard: '船塢',
|
||||
hangar: '機庫',
|
||||
researchLab: '研究實驗室',
|
||||
metalStorage: '金屬倉庫',
|
||||
crystalStorage: '晶體倉庫',
|
||||
deuteriumTank: '重氫罐',
|
||||
darkMatterCollector: '暗物質收集器',
|
||||
darkMatterTank: '暗物質儲罐',
|
||||
missileSilo: '導彈發射井',
|
||||
terraformer: '地形改造器',
|
||||
lunarBase: '月球基地',
|
||||
sensorPhalanx: '傳感器陣列',
|
||||
@@ -130,23 +144,39 @@ export default {
|
||||
consumption: '消耗',
|
||||
totalCost: '累積成本',
|
||||
totalPoints: '累積積分',
|
||||
levelRange: '等級範圍'
|
||||
levelRange: '等級範圍',
|
||||
capacity: '容量/效果',
|
||||
storageCapacity: '容量',
|
||||
energyProduction: '電力產出',
|
||||
fleetStorage: '艦隊倉儲',
|
||||
buildQueue: '建造隊列',
|
||||
buildQueueBonus: '建造隊列',
|
||||
spaceBonus: '空間加成',
|
||||
buildSpeedBonus: '建造速度加成',
|
||||
researchSpeedBonus: '研究速度加成',
|
||||
planetSpace: '行星空間',
|
||||
moonSpace: '月球空間',
|
||||
missileCapacity: '導彈容量'
|
||||
},
|
||||
buildingDescriptions: {
|
||||
metalMine: '開採金屬資源',
|
||||
crystalMine: '開採晶體資源',
|
||||
deuteriumSynthesizer: '合成重氫資源',
|
||||
solarPlant: '提供能源',
|
||||
fusionReactor: '使用重氫產生大量能源',
|
||||
roboticsFactory: '加快建造速度',
|
||||
naniteFactory: '增加建造佇列數量,每級+1佇列(最多10級)',
|
||||
shipyard: '建造艦船',
|
||||
hangar: '專門用於擴展艦隊儲存容量,支援行星專業化發展',
|
||||
researchLab: '研究科技',
|
||||
metalStorage: '增加金屬儲存上限',
|
||||
crystalStorage: '增加晶體儲存上限',
|
||||
deuteriumTank: '增加重氫儲存上限',
|
||||
darkMatterCollector: '收集稀有的暗物質資源',
|
||||
terraformer: '改造行星地形,每級增加5個可用空間',
|
||||
lunarBase: '增加月球可用空間,每級+5空間',
|
||||
darkMatterTank: '增加暗物質儲存上限',
|
||||
missileSilo: '存儲和發射導彈,每級可存儲10枚導彈',
|
||||
terraformer: '改造行星地形,每級增加30個可用空間',
|
||||
lunarBase: '增加月球可用空間,每級+30空間',
|
||||
sensorPhalanx: '偵測周圍星系的艦隊活動',
|
||||
jumpGate: '瞬間傳送艦隊到其他月球',
|
||||
planetDestroyerFactory: '建造能夠摧毀行星的終極武器'
|
||||
@@ -156,11 +186,15 @@ export default {
|
||||
heavyFighter: '重型戰鬥機',
|
||||
cruiser: '巡洋艦',
|
||||
battleship: '戰列艦',
|
||||
battlecruiser: '戰列巡洋艦',
|
||||
bomber: '轟炸機',
|
||||
destroyer: '驅逐艦',
|
||||
smallCargo: '小型運輸船',
|
||||
largeCargo: '大型運輸船',
|
||||
colonyShip: '殖民船',
|
||||
recycler: '回收船',
|
||||
espionageProbe: '間諜探測器',
|
||||
solarSatellite: '太陽能衛星',
|
||||
darkMatterHarvester: '暗物質採集船',
|
||||
deathstar: '死星'
|
||||
},
|
||||
@@ -168,12 +202,16 @@ export default {
|
||||
lightFighter: '基礎戰鬥單位',
|
||||
heavyFighter: '重裝戰鬥機',
|
||||
cruiser: '中型戰艦,攻守平衡',
|
||||
battleship: '強力戰艦',
|
||||
battleship: '主力重型戰艦,擁有強大的火力和防護',
|
||||
battlecruiser: '快速強大的戰鬥艦船,擅長攻擊戰列艦',
|
||||
bomber: '專門對付防禦設施的轟炸艦',
|
||||
destroyer: '專業反大型艦船戰艦,高火力低防護',
|
||||
smallCargo: '運輸少量資源',
|
||||
largeCargo: '運輸大量資源',
|
||||
colonyShip: '用於殖民新星球',
|
||||
recycler: '收集殘骸場資源',
|
||||
espionageProbe: '偵察敵方星球',
|
||||
solarSatellite: '提供額外能源,每個產生50點電力',
|
||||
darkMatterHarvester: '專門用於採集暗物質的特殊飛船',
|
||||
deathstar: '終極武器,能夠摧毀整個行星'
|
||||
},
|
||||
@@ -186,24 +224,38 @@ export default {
|
||||
plasmaTurret: '等離子炮塔',
|
||||
smallShieldDome: '小型護盾罩',
|
||||
largeShieldDome: '大型護盾罩',
|
||||
antiBallisticMissile: '反彈道導彈',
|
||||
interplanetaryMissile: '星際導彈',
|
||||
planetaryShield: '行星護盾'
|
||||
},
|
||||
defenseDescriptions: {
|
||||
rocketLauncher: '基礎防禦設施',
|
||||
lightLaser: '輕型能量武器',
|
||||
heavyLaser: '重型能量武器',
|
||||
lightLaser: '輕型電力武器',
|
||||
heavyLaser: '重型電力武器',
|
||||
gaussCannon: '高速動能武器',
|
||||
ionCannon: '破壞護盾的利器',
|
||||
plasmaTurret: '強力防禦設施',
|
||||
smallShieldDome: '保護整個星球的小型護盾',
|
||||
largeShieldDome: '保護整個星球的大型護盾',
|
||||
antiBallisticMissile: '攔截敵方導彈,每個可攔截1枚星際導彈',
|
||||
interplanetaryMissile: '可以攻擊其他星球的防禦設施',
|
||||
planetaryShield: '保護行星免受毀滅攻擊的超級護盾'
|
||||
},
|
||||
research: {
|
||||
researchTime: '研究時間',
|
||||
totalCost: '累積成本',
|
||||
totalPoints: '累積積分',
|
||||
levelRange: '等級範圍'
|
||||
levelRange: '等級範圍',
|
||||
capacity: '容量/效果',
|
||||
attackBonus: '攻擊加成',
|
||||
shieldBonus: '護盾加成',
|
||||
armorBonus: '裝甲加成',
|
||||
spyLevel: '偵查等級',
|
||||
researchQueueBonus: '研究隊列',
|
||||
colonySlots: '殖民地槽位',
|
||||
forAllPlanets: '(全局)',
|
||||
speedBonus: '速度加成',
|
||||
researchSpeedBonus: '研究速度加成'
|
||||
},
|
||||
technologies: {
|
||||
energyTechnology: '能源技術',
|
||||
@@ -212,6 +264,12 @@ export default {
|
||||
hyperspaceTechnology: '超空間技術',
|
||||
plasmaTechnology: '等離子技術',
|
||||
computerTechnology: '計算機技術',
|
||||
espionageTechnology: '間諜技術',
|
||||
weaponsTechnology: '武器技術',
|
||||
shieldingTechnology: '護盾技術',
|
||||
armourTechnology: '裝甲技術',
|
||||
astrophysics: '天體物理學',
|
||||
gravitonTechnology: '引力技術',
|
||||
combustionDrive: '燃燒引擎',
|
||||
impulseDrive: '脈衝引擎',
|
||||
hyperspaceDrive: '超空間引擎',
|
||||
@@ -226,11 +284,17 @@ export default {
|
||||
hyperspaceTechnology: '超空間跳躍技術',
|
||||
plasmaTechnology: '等離子武器技術',
|
||||
computerTechnology: '增加研究佇列數量,每級+1佇列(最多10級)',
|
||||
espionageTechnology: '提高間諜探測效果,每級提高1級偵查深度',
|
||||
weaponsTechnology: '提高艦船和防禦的攻擊力,每級+10%',
|
||||
shieldingTechnology: '提高艦船和防禦的護盾值,每級+10%',
|
||||
armourTechnology: '提高艦船和防禦的裝甲值,每級+10%',
|
||||
astrophysics: '每級增加1個殖民地槽位,增加探險成功率',
|
||||
gravitonTechnology: '研究引力操縱,死星的必要技術',
|
||||
combustionDrive: '基礎推進技術',
|
||||
impulseDrive: '中級推進技術',
|
||||
hyperspaceDrive: '高級推進技術',
|
||||
darkMatterTechnology: '研究暗物質的性質和應用',
|
||||
terraformingTechnology: '研究行星地形改造技術,每級為所有行星增加3個可用空間',
|
||||
terraformingTechnology: '研究行星地形改造技術,每級為所有行星增加30個可用空間',
|
||||
planetDestructionTech: '研究如何摧毀整個行星的恐怖技術'
|
||||
},
|
||||
officers: {
|
||||
@@ -242,7 +306,7 @@ export default {
|
||||
darkMatterSpecialist: '暗物質專家',
|
||||
resourceBonus: '資源生產加成',
|
||||
darkMatterBonus: '暗物質生產加成',
|
||||
energyBonus: '能量生產加成'
|
||||
energyBonus: '電力產量加成'
|
||||
},
|
||||
officerDescriptions: {
|
||||
commander: '提升建築速度和管理能力',
|
||||
@@ -253,16 +317,20 @@ export default {
|
||||
darkMatterSpecialist: '提升暗物質採集效率'
|
||||
},
|
||||
queue: {
|
||||
title: '建造佇列',
|
||||
empty: '當前沒有進行中的任務',
|
||||
buildQueue: '建造佇列',
|
||||
researchQueue: '研究佇列',
|
||||
building: '建造中',
|
||||
researching: '研究中',
|
||||
demolishing: '拆除中',
|
||||
remaining: '剩餘時間',
|
||||
cancel: '取消',
|
||||
cancelBuild: '取消建造',
|
||||
cancelResearch: '取消研究',
|
||||
confirmCancel: '確定要取消嗎?將返還50%的資源。',
|
||||
level: '等級',
|
||||
gmModeActivated: '',
|
||||
upgradeToLevel: '升級到等級'
|
||||
},
|
||||
overview: {
|
||||
@@ -272,17 +340,18 @@ export default {
|
||||
currentShips: '當前星球的艦船數量',
|
||||
productionSources: '生產來源',
|
||||
productionSourcesDesc: '詳細資源生產和加成資訊',
|
||||
consumptionSources: '消耗來源',
|
||||
consumptionSourcesDesc: '建築能量消耗詳情',
|
||||
consumptionSources: '電力消耗來源',
|
||||
consumptionSourcesDesc: '各建築的電力消耗詳情',
|
||||
totalProduction: '總產量',
|
||||
totalConsumption: '總消耗',
|
||||
noConsumption: '無能量消耗'
|
||||
noConsumption: '當前無電力消耗'
|
||||
},
|
||||
buildingsView: {
|
||||
title: '建築',
|
||||
usedSpace: '已用空間',
|
||||
spaceUsage: '佔用空間',
|
||||
level: '等級',
|
||||
gmModeActivated: '',
|
||||
upgradeCost: '升級消耗',
|
||||
buildTime: '建造時間',
|
||||
upgrade: '升級',
|
||||
@@ -293,7 +362,9 @@ export default {
|
||||
demolish: '拆除',
|
||||
demolishRefund: '拆除返還',
|
||||
demolishFailed: '拆除失敗',
|
||||
demolishFailedMessage: '無法拆除該建築,請檢查建造隊列是否已滿或建築等級是否為0。'
|
||||
demolishFailedMessage: '無法拆除該建築,請檢查建造隊列是否已滿或建築等級是否為0。',
|
||||
confirmDemolish: '確認拆除',
|
||||
confirmDemolishMessage: '確定要拆除以下建築嗎?'
|
||||
},
|
||||
researchView: {
|
||||
title: '研究',
|
||||
@@ -305,6 +376,7 @@ export default {
|
||||
},
|
||||
shipyard: {
|
||||
attack: '攻擊力',
|
||||
missileAttack: '導彈攻擊',
|
||||
shield: '護盾',
|
||||
armor: '裝甲',
|
||||
speed: '速度',
|
||||
@@ -322,6 +394,7 @@ export default {
|
||||
title: '船塢',
|
||||
fleetStorage: '艦隊倉儲',
|
||||
attack: '攻擊力',
|
||||
missileAttack: '導彈攻擊',
|
||||
shield: '護盾',
|
||||
speed: '速度',
|
||||
cargoCapacity: '載貨量',
|
||||
@@ -336,6 +409,7 @@ export default {
|
||||
},
|
||||
defense: {
|
||||
attack: '攻擊力',
|
||||
missileAttack: '導彈攻擊',
|
||||
shield: '護盾',
|
||||
armor: '裝甲',
|
||||
buildCost: '建造成本',
|
||||
@@ -349,6 +423,7 @@ export default {
|
||||
defenseView: {
|
||||
title: '防禦設施',
|
||||
attack: '攻擊力',
|
||||
missileAttack: '導彈攻擊',
|
||||
shield: '護盾',
|
||||
armor: '裝甲',
|
||||
buildTime: '建造時間',
|
||||
@@ -358,6 +433,7 @@ export default {
|
||||
totalCost: '總成本',
|
||||
build: '建造',
|
||||
shieldDomeBuilt: '護盾罩已建造',
|
||||
missileCapacity: '導彈容量',
|
||||
inputError: '輸入錯誤',
|
||||
inputErrorMessage: '請輸入建造數量!',
|
||||
buildFailed: '建造失敗',
|
||||
@@ -370,6 +446,7 @@ export default {
|
||||
flightMissions: '飛行任務',
|
||||
currentPlanetFleet: '當前星球艦隊',
|
||||
attack: '攻擊',
|
||||
missileAttack: '導彈攻擊',
|
||||
shield: '護盾',
|
||||
armor: '裝甲',
|
||||
speed: '速度',
|
||||
@@ -380,6 +457,7 @@ export default {
|
||||
all: '全部',
|
||||
targetCoordinates: '目標座標',
|
||||
galaxy: '銀河系',
|
||||
diplomacy: 'Diplomacy',
|
||||
system: '星系',
|
||||
position: '位置',
|
||||
missionType: '任務類型',
|
||||
@@ -403,6 +481,11 @@ export default {
|
||||
arrivalTime: '到達時間',
|
||||
returnTime: '返回時間',
|
||||
recallFleet: '召回艦隊',
|
||||
abortMission: '',
|
||||
abortMissionTitle: '',
|
||||
abortMissionWarning: '',
|
||||
abortMissionSuccess: '',
|
||||
abortMissionSuccessMessage: '',
|
||||
sendFailed: '派遣失敗',
|
||||
sendFailedMessage: '請檢查艦隊數量、燃料是否充足,或載貨量是否超出限制。',
|
||||
recallFailed: '召回失敗',
|
||||
@@ -413,7 +496,11 @@ export default {
|
||||
cannotSendToOwnPlanet: '無法派遣艦隊到自己的星球',
|
||||
cargoExceedsCapacity: '載貨量超出限制',
|
||||
noColonyShip: '需要殖民船才能執行殖民任務',
|
||||
noDebrisAtTarget: '目標坐標沒有殘骸場或殘骸場已空'
|
||||
noDebrisAtTarget: '目標坐標沒有殘骸場或殘骸場已空',
|
||||
noDeathstar: '需要死星才能執行毀滅任務',
|
||||
giftMode: '贈送模式',
|
||||
giftModeDescription: '將資源作為禮物贈送給',
|
||||
estimatedReputationGain: '預計好感度增加'
|
||||
},
|
||||
officersView: {
|
||||
title: '軍官',
|
||||
@@ -453,38 +540,60 @@ export default {
|
||||
title: '星系',
|
||||
selectCoordinates: '選擇座標',
|
||||
galaxy: '銀河系',
|
||||
diplomacy: 'Diplomacy',
|
||||
selectGalaxy: '選擇銀河系',
|
||||
system: '星系',
|
||||
selectSystem: '選擇星系',
|
||||
view: '查看',
|
||||
myPlanet: '我的星球',
|
||||
myPlanets: '查看我的星系',
|
||||
npcPlanets: 'NPC星球',
|
||||
selectPlanetToView: '選擇星球以查看其所在星系',
|
||||
totalPositions: '共10個星球位置',
|
||||
mine: '我的',
|
||||
hostile: '敵對',
|
||||
emptySlot: '空位 - 可殖民',
|
||||
scout: '偵察',
|
||||
attack: '攻擊',
|
||||
missileAttack: '導彈攻擊',
|
||||
colonize: '殖民',
|
||||
switch: '切換',
|
||||
recycle: '回收',
|
||||
debrisField: '殘骸場',
|
||||
scoutPlanetTitle: '偵察星球',
|
||||
attackPlanetTitle: '攻擊星球',
|
||||
missileAttackTitle: '導彈攻擊',
|
||||
colonizePlanetTitle: '殖民星球',
|
||||
recyclePlanetTitle: '回收殘骸',
|
||||
scoutPlanetMessage: '確定要派遣間諜探測器偵察星球 [{coordinates}] 嗎?\n\n請前往艦隊頁面選擇艦船並派遣。',
|
||||
attackPlanetMessage: '確定要攻擊星球 [{coordinates}] 嗎?\n\n請前往艦隊頁面選擇艦船並派遣。',
|
||||
missileAttackMessage: '向星球 [{coordinates}] 發射星際導彈',
|
||||
missileCount: '導彈數量',
|
||||
availableMissiles: '可用導彈',
|
||||
missileRange: '導彈射程',
|
||||
systems: '星系',
|
||||
distance: '距離',
|
||||
flightTime: '飛行時間',
|
||||
launchMissile: '發射',
|
||||
cancel: '取消',
|
||||
colonizePlanetMessage: '確定要殖民位置 [{coordinates}] 嗎?\n\n請前往艦隊頁面派遣殖民船。',
|
||||
recyclePlanetMessage: '確定要回收位置 [{coordinates}] 的殘骸嗎?\n\n請前往艦隊頁面派遣回收船。'
|
||||
recyclePlanetMessage: '確定要回收位置 [{coordinates}] 的殘骸嗎?\n\n請前往艦隊頁面派遣回收船。',
|
||||
sendGift: '贈送禮物',
|
||||
debris: '殘骸',
|
||||
giftPlanetTitle: '贈送禮物',
|
||||
giftPlanetMessage: '確定要向星球 [{coordinates}] 贈送資源嗎?\n\n請前往艦隊頁面選擇運輸船並裝載資源。'
|
||||
},
|
||||
messagesView: {
|
||||
title: '訊息中心',
|
||||
battles: '戰鬥',
|
||||
spy: '偵查',
|
||||
npc: 'NPC',
|
||||
diplomacy: '',
|
||||
battleReports: '戰鬥報告',
|
||||
spyReports: '間諜報告',
|
||||
noBattleReports: '暫無戰鬥報告',
|
||||
noSpyReports: '暫無間諜報告',
|
||||
noDiplomaticReports: '',
|
||||
battleReport: '戰鬥報告',
|
||||
spyReport: '間諜報告',
|
||||
victory: '勝利',
|
||||
@@ -511,7 +620,79 @@ export default {
|
||||
hideRoundDetails: '隱藏回合詳情',
|
||||
round: '第{round}回合',
|
||||
attackerRemainingPower: '攻擊方剩餘火力',
|
||||
defenderRemainingPower: '防守方剩餘火力'
|
||||
defenderRemainingPower: '防守方剩餘火力',
|
||||
spied: '被偵查',
|
||||
spiedNotification: '被偵查通知',
|
||||
noSpiedNotifications: '暫無被偵查通知',
|
||||
detected: '已發現',
|
||||
undetected: '未發現',
|
||||
missions: '任務',
|
||||
noMissionReports: '暫無任務報告',
|
||||
success: '成功',
|
||||
failed: '失敗',
|
||||
npcActivity: 'NPC活動',
|
||||
noNPCActivity: '暫無NPC活動通知',
|
||||
npcRecycleActivity: 'NPC回收殘骸',
|
||||
gifts: '禮物',
|
||||
giftRejected: '被拒絕',
|
||||
noGiftNotifications: '暫無禮物通知',
|
||||
noGiftRejected: '暫無拒絕記錄',
|
||||
giftFrom: '{npcName}的禮物',
|
||||
giftRejectedBy: '{npcName}拒絕了禮物',
|
||||
giftResources: '禮物資源',
|
||||
rejectedResources: '被拒絕的資源',
|
||||
expectedReputation: '預計好感度',
|
||||
currentReputation: '當前好感度',
|
||||
acceptGift: '接受',
|
||||
rejectGift: '拒絕',
|
||||
rejectionReason: {
|
||||
hostile: '對方對你有敵意,不接受禮物',
|
||||
neutral_distrust: '對方對你缺乏信任',
|
||||
polite_decline: '對方禮貌地拒絕了'
|
||||
},
|
||||
// Spied notification dialog
|
||||
spiedNotificationDetails: '',
|
||||
spyDetected: '',
|
||||
detectionResult: '',
|
||||
detectionSuccess: '',
|
||||
spiedNotificationMessage: '',
|
||||
spiedNotificationTip: '',
|
||||
viewInGalaxy: '',
|
||||
// Mission report dialog
|
||||
missionReportDetails: '',
|
||||
missionSuccess: '',
|
||||
missionFailed: '',
|
||||
origin: '',
|
||||
destination: '',
|
||||
missionDetails: '',
|
||||
transportedResources: '',
|
||||
recycledResources: '',
|
||||
remainingDebris: '',
|
||||
newPlanet: '',
|
||||
// NPC activity dialog
|
||||
npcActivityDetails: '',
|
||||
activityType: {
|
||||
recycle: ''
|
||||
},
|
||||
activityLocation: '',
|
||||
position: '',
|
||||
nearPlanet: '',
|
||||
activityDescription: '',
|
||||
npcActivityMessage: '',
|
||||
arrivalTime: '',
|
||||
npcActivityTip: ''
|
||||
},
|
||||
missionReports: {
|
||||
transportSuccess: '運輸任務成功完成',
|
||||
transportFailed: '運輸任務失敗',
|
||||
colonizeSuccess: '殖民任務成功,新星球已建立',
|
||||
colonizeFailed: '殖民任務失敗',
|
||||
deploySuccess: '部署任務成功完成',
|
||||
deployFailed: '部署任務失敗',
|
||||
recycleSuccess: '回收任務成功完成',
|
||||
recycleFailed: '回收任務失敗,目標位置沒有殘骸',
|
||||
destroySuccess: '行星毀滅任務成功執行',
|
||||
destroyFailed: '行星毀滅任務失敗'
|
||||
},
|
||||
simulatorView: {
|
||||
title: '戰鬥模擬器',
|
||||
@@ -580,10 +761,24 @@ export default {
|
||||
gamePaused: '遊戲已暫停',
|
||||
gameResumed: '遊戲已恢復',
|
||||
playerName: '玩家名稱',
|
||||
gameSpeed: '遊戲速度',
|
||||
gameSpeedDesc: '目前遊戲速度倍率',
|
||||
gameSpeed: '資源產出速度',
|
||||
gameSpeedDesc: '目前資源產出速度倍率',
|
||||
speedChanged: '資源產出速度已更改為 {speed}x',
|
||||
speedReset: '資源產出速度已重置為 1x',
|
||||
reset: '重置',
|
||||
about: '關於',
|
||||
version: '版本',
|
||||
latestVersion: '最新版本',
|
||||
checkUpdate: '檢查更新',
|
||||
checking: '檢查中...',
|
||||
newVersionAvailable: '發現新版本 {version}',
|
||||
upToDate: '已是最新版本',
|
||||
checkUpdateCooldown: '請稍後再試(5分鐘冷卻時間)',
|
||||
checkUpdateFailed: '檢查更新失敗,請檢查網路連線',
|
||||
viewUpdate: '查看更新',
|
||||
updateAvailable: '有新版本可用。點擊查看更新內容。',
|
||||
download: '下載',
|
||||
goToDownload: '前往下載',
|
||||
buildDate: '建置日期',
|
||||
community: '社群',
|
||||
github: 'GitHub 儲存庫',
|
||||
@@ -602,6 +797,8 @@ export default {
|
||||
officers: '軍官',
|
||||
modifyResources: '修改資源',
|
||||
resourcesDesc: '快速修改星球資源數量',
|
||||
maxAllResources: '',
|
||||
maxAllResourcesSuccess: '',
|
||||
modifyBuildings: '修改建築',
|
||||
buildingsDesc: '快速設定建築等級',
|
||||
modifyResearch: '修改科技',
|
||||
@@ -613,9 +810,174 @@ export default {
|
||||
modifyOfficers: '修改軍官',
|
||||
officersDesc: '快速設定軍官到期時間',
|
||||
days: '天',
|
||||
npcTesting: 'NPC 測試',
|
||||
npcTestingDesc: '測試NPC偵查和攻擊行為',
|
||||
selectNPC: '選擇NPC',
|
||||
chooseNPC: '選擇一個NPC',
|
||||
targetPlanet: '目標星球',
|
||||
chooseTarget: '選擇目標星球',
|
||||
testSpy: '測試偵查',
|
||||
testAttack: '測試攻擊',
|
||||
testSpyAndAttack: '測試偵查&攻擊',
|
||||
testSpyMessage: '點擊確認以加速偵查任務',
|
||||
testAttackMessage: '點擊確認以加速攻擊任務',
|
||||
testSpyAndAttackMessage: '點擊確認以加速任務執行',
|
||||
initializeFleet: '初始化NPC艦隊',
|
||||
accelerateMissions: '加速所有任務(5秒)',
|
||||
selectNPCFirst: '請先選擇一個NPC',
|
||||
npcNoProbes: 'NPC沒有間諜探測器',
|
||||
npcNoSpyReport: 'NPC需要先偵查',
|
||||
npcMissionFailed: '創建任務失敗',
|
||||
npcNoPlanets: 'NPC沒有星球',
|
||||
npcWillSpyIn5s: '{npcName}將在5秒後偵查',
|
||||
npcWillAttackIn5s: '{npcName}將在5秒後攻擊',
|
||||
npcWillSpyAndAttack: '{npcName}將在5秒後偵查,10秒後攻擊',
|
||||
acceleratedMissions: '已加速{count}個任務至5秒後',
|
||||
npcFleetInitialized: '{npcName}艦隊已初始化',
|
||||
npcFleetDetails: '100 間諜探測器\n500 輕型戰機\n300 重型戰機\n200 巡洋艦\n100 戰列艦\n50 轟炸機\n30 毀滅者\n20 戰列巡洋艦',
|
||||
dangerZone: '危險區域',
|
||||
dangerZoneDesc: '以下操作不可撤銷,請謹慎操作',
|
||||
resetGame: '重置遊戲',
|
||||
resetGameConfirm: '確定要重置遊戲嗎?這將刪除所有資料!'
|
||||
resetGameConfirm: '確定要重置遊戲嗎?這將刪除所有資料!',
|
||||
completeAllQueues: '',
|
||||
completeAllQueuesDesc: '',
|
||||
completeQueues: '',
|
||||
completeQueuesSuccess: ''
|
||||
},
|
||||
alerts: {
|
||||
npcSpyIncoming: 'NPC偵查即將到達',
|
||||
npcAttackIncoming: 'NPC艦隊來襲!',
|
||||
npcFleetIncoming: 'NPC艦隊接近',
|
||||
ships: '艘艦船',
|
||||
spiedBy: '被偵查',
|
||||
attackedBy: '被攻擊',
|
||||
detectionSuccess: '偵查被發現',
|
||||
detectionFailed: '偵查未被發現',
|
||||
npcSpiedYourPlanet: 'NPC偵查了你的星球',
|
||||
npcAttackedYourPlanet: 'NPC攻擊了你的星球'
|
||||
},
|
||||
diplomacy: {
|
||||
title: '外交',
|
||||
description: '管理與NPC的外交關係',
|
||||
tabs: {
|
||||
all: '全部',
|
||||
friendly: '友好',
|
||||
neutral: '中立',
|
||||
hostile: '敵對'
|
||||
},
|
||||
noNpcs: '沒有NPC',
|
||||
noFriendlyNpcs: '沒有友好的NPC',
|
||||
noNeutralNpcs: '沒有中立的NPC',
|
||||
noHostileNpcs: '沒有敵對的NPC',
|
||||
recentEvents: '最近事件',
|
||||
recentEventsDescription: '最近的外交活動記錄',
|
||||
ago: '前',
|
||||
notifications: '',
|
||||
markAllRead: '',
|
||||
noReports: '',
|
||||
viewAll: '',
|
||||
status: {
|
||||
friendly: '友好',
|
||||
neutral: '中立',
|
||||
hostile: '敵對'
|
||||
},
|
||||
planets: '星球',
|
||||
allies: '盟友',
|
||||
reputation: '聲望',
|
||||
alliedWith: '結盟對象',
|
||||
more: '更多',
|
||||
actions: {
|
||||
gift: '贈送禮物',
|
||||
viewPlanets: '查看星球'
|
||||
},
|
||||
lastEvent: '最近事件',
|
||||
reportDetails: '外交報告詳情',
|
||||
eventDescription: '事件描述',
|
||||
reputationChange: '好感度變化',
|
||||
before: '之前',
|
||||
after: '之後',
|
||||
statusChange: '關係狀態變化',
|
||||
viewDiplomacy: '查看外交頁面',
|
||||
events: {
|
||||
gift: '已贈送禮物',
|
||||
attack: '攻擊',
|
||||
missileAttack: '導彈攻擊',
|
||||
allyAttacked: '盟友被攻擊',
|
||||
spy: '間諜活動',
|
||||
stealDebris: '掠奪殘骸'
|
||||
},
|
||||
reports: {
|
||||
giftedResources: '贈送了 {metal}金屬 {crystal}晶體 {deuterium}氘',
|
||||
receivedGiftFromPlayer: '收到玩家的禮物',
|
||||
giftedToNpc: '你向{npcName}贈送了資源。好感度+{reputation}',
|
||||
rejectedPlayerGift: '拒絕了玩家的禮物',
|
||||
npcRejectedGift: '{npcName}拒絕了你的禮物。好感度{reputation}',
|
||||
attackedNpc: '攻擊了{npcName}',
|
||||
wasAttackedByPlayer: '被玩家攻擊',
|
||||
youAttackedNpc: '你攻擊了{npcName}',
|
||||
playerAttackedAlly: '玩家攻擊了盟友{allyName}',
|
||||
allyDispleased: '{allyName}對你攻擊盟友{targetName}感到不滿',
|
||||
wasSpiedByPlayer: '被玩家偵查(被發現:{detected})',
|
||||
spyDetected: '你的偵查被{npcName}發現了',
|
||||
stoleDebrisFromTerritory: '從{npcName}的領地掠奪了殘骸',
|
||||
playerStoleDebris: '玩家從領地掠奪了殘骸',
|
||||
recycledDebrisNearNpc: '你在{npcName}的星球附近回收了殘骸。他們很不高興。',
|
||||
giftedResourcesToPlayer: '向玩家贈送了資源',
|
||||
receivedGiftFromNpc: '收到了{npcName}的禮物',
|
||||
acceptedGiftFromNpc: '你接受了{npcName}的禮物:{metal}金屬 {crystal}晶體 {deuterium}氘',
|
||||
playerRejectedGift: '玩家拒絕了禮物',
|
||||
rejectedGiftFromNpc: '你拒絕了{npcName}的禮物。好感度{reputation}',
|
||||
destroyedNpcPlanet: '摧毀了{npcName}的{planetName}',
|
||||
playerDestroyedPlanet: '玩家摧毀了{planetName}',
|
||||
youDestroyedNpcPlanet: '你摧毀了{npcName}的{planetName}。好感度{reputation}',
|
||||
playerDestroyedAllyPlanet: '玩家摧毀了盟友{allyName}的{planetName}',
|
||||
allyOutraged: '{allyName}對你摧毀盟友{targetName}的{planetName}感到憤怒',
|
||||
npcEliminated: 'NPC {npcName}已被徹底消滅',
|
||||
npcEliminatedMessage: '你消滅了{npcName}的所有星球!該勢力已被徹底摧毀。'
|
||||
}
|
||||
},
|
||||
pagination: {
|
||||
previous: '上一頁',
|
||||
next: '下一頁',
|
||||
gotIt: '',
|
||||
first: '首頁',
|
||||
last: '末頁',
|
||||
page: '第 {page} 頁'
|
||||
},
|
||||
notFound: {
|
||||
title: '找不到頁面',
|
||||
description: '抱歉,您訪問的頁面不存在',
|
||||
goHome: '返回首頁'
|
||||
},
|
||||
time: {
|
||||
days: '天',
|
||||
hours: '小時',
|
||||
minutes: '分鐘',
|
||||
seconds: '秒'
|
||||
},
|
||||
tutorial: {
|
||||
welcome: {
|
||||
title: '歡迎來到 OGame',
|
||||
content: '歡迎,指揮官!讓我們從基礎開始,建立您的宇宙帝國。'
|
||||
},
|
||||
buildSolarPlant: {
|
||||
title: '建造太陽能電站',
|
||||
content: '首先建造太陽能電站!它為您的星球提供能量。沒有能量,其他資源建築無法運作。這是最重要的第一步。'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '建造佇列',
|
||||
content:
|
||||
'您的建築現在在建造佇列中。點擊右上角的佇列圖示可以查看所有正在進行的建造和研究任務。建築需要時間完成,但您可以在等待時繼續操作。'
|
||||
},
|
||||
mobile: {
|
||||
welcome: {
|
||||
title: '歡迎來到 OGame(移動版)',
|
||||
content: '歡迎,指揮官!這是專為觸控螢幕設計的簡化教程。我們將快速介紹核心功能,讓您開始建設帝國。'
|
||||
},
|
||||
waitBuild: {
|
||||
title: '建造佇列',
|
||||
content: '點擊右上角的佇列圖示可以查看建造進度。您可以繼續瀏覽其他頁面,建造會在背景進行。'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { Fleet, Resources, BattleResult, Officer } from '@/types/game'
|
||||
import type { Fleet, Resources, BattleResult, Officer, TechnologyType } from '@/types/game'
|
||||
import { DefenseType, OfficerType } from '@/types/game'
|
||||
import * as officerLogic from './officerLogic'
|
||||
import { workerManager } from '@/workers/workerManager'
|
||||
import { MOON_CONFIG } from '@/config/gameConfig'
|
||||
|
||||
/**
|
||||
* 执行战斗模拟
|
||||
@@ -12,31 +12,34 @@ export const simulateBattle = async (
|
||||
defenderFleet: Partial<Fleet>,
|
||||
defenderDefense: Partial<Record<DefenseType, number>>,
|
||||
defenderResources: Resources,
|
||||
attackerOfficers: Record<OfficerType, Officer>,
|
||||
defenderOfficers: Record<OfficerType, Officer>
|
||||
_attackerOfficers: Record<OfficerType, Officer>,
|
||||
_defenderOfficers: Record<OfficerType, Officer>,
|
||||
attackerTechnologies: Record<TechnologyType, number>,
|
||||
defenderTechnologies: Record<TechnologyType, number>
|
||||
): Promise<BattleResult> => {
|
||||
// 计算军官加成
|
||||
const attackerBonuses = officerLogic.calculateActiveBonuses(attackerOfficers, Date.now())
|
||||
const defenderBonuses = officerLogic.calculateActiveBonuses(defenderOfficers, Date.now())
|
||||
// 从科技系统读取实际科技等级
|
||||
const attackerWeaponTech = attackerTechnologies['weaponsTechnology'] || 0
|
||||
const attackerShieldTech = attackerTechnologies['shieldingTechnology'] || 0
|
||||
const attackerArmorTech = attackerTechnologies['armourTechnology'] || 0
|
||||
|
||||
// 将防御加成转换为科技等级(简化:10%加成 = 1级科技)
|
||||
const attackerTechLevel = Math.floor(attackerBonuses.defenseBonus / 10)
|
||||
const defenderTechLevel = Math.floor(defenderBonuses.defenseBonus / 10)
|
||||
const defenderWeaponTech = defenderTechnologies['weaponsTechnology'] || 0
|
||||
const defenderShieldTech = defenderTechnologies['shieldingTechnology'] || 0
|
||||
const defenderArmorTech = defenderTechnologies['armourTechnology'] || 0
|
||||
|
||||
// 使用 Worker 执行战斗模拟
|
||||
const simulationResult = await workerManager.simulateBattle({
|
||||
attacker: {
|
||||
ships: attackerFleet,
|
||||
weaponTech: 0, // 暂时不考虑武器科技
|
||||
shieldTech: attackerTechLevel,
|
||||
armorTech: attackerTechLevel
|
||||
weaponTech: attackerWeaponTech,
|
||||
shieldTech: attackerShieldTech,
|
||||
armorTech: attackerArmorTech
|
||||
},
|
||||
defender: {
|
||||
ships: defenderFleet,
|
||||
defense: defenderDefense,
|
||||
weaponTech: 0,
|
||||
shieldTech: defenderTechLevel,
|
||||
armorTech: defenderTechLevel
|
||||
weaponTech: defenderWeaponTech,
|
||||
shieldTech: defenderShieldTech,
|
||||
armorTech: defenderArmorTech
|
||||
},
|
||||
maxRounds: 6 // 最多6回合
|
||||
})
|
||||
@@ -58,7 +61,7 @@ export const simulateBattle = async (
|
||||
|
||||
// 计算月球生成概率(根据残骸场总量)
|
||||
const totalDebris = debrisField.metal + debrisField.crystal
|
||||
const moonChance = Math.min(totalDebris / 100000, 0.2) // 最高20%概率
|
||||
const moonChance = Math.min(MOON_CONFIG.baseChance + Math.floor(totalDebris / MOON_CONFIG.chancePerDebris), MOON_CONFIG.maxChance) / 100 // 转换为0-1的概率
|
||||
|
||||
// 生成战斗报告
|
||||
const battleResult: BattleResult = {
|
||||
|
||||
@@ -3,6 +3,9 @@ import { BuildingType, TechnologyType, ShipType, DefenseType } from '@/types/gam
|
||||
import { BUILDINGS } from '@/config/gameConfig'
|
||||
import * as pointsLogic from './pointsLogic'
|
||||
|
||||
// 用于生成唯一ID的计数器
|
||||
let queueIdCounter = 0
|
||||
|
||||
/**
|
||||
* 计算建筑升级成本
|
||||
*/
|
||||
@@ -20,13 +23,30 @@ export const calculateBuildingCost = (buildingType: BuildingType, targetLevel: n
|
||||
|
||||
/**
|
||||
* 计算建筑升级时间
|
||||
* @param buildingType 建筑类型
|
||||
* @param targetLevel 目标等级
|
||||
* @param buildingSpeedBonus 指挥官等提供的速度加成百分比
|
||||
* @param roboticsFactoryLevel 机器人工厂等级
|
||||
* @param naniteFactoryLevel 纳米工厂等级
|
||||
*/
|
||||
export const calculateBuildingTime = (buildingType: BuildingType, targetLevel: number, buildingSpeedBonus: number = 0): number => {
|
||||
export const calculateBuildingTime = (
|
||||
buildingType: BuildingType,
|
||||
targetLevel: number,
|
||||
buildingSpeedBonus: number = 0,
|
||||
roboticsFactoryLevel: number = 0,
|
||||
naniteFactoryLevel: number = 0
|
||||
): number => {
|
||||
const config = BUILDINGS[buildingType]
|
||||
const multiplier = Math.pow(config.costMultiplier, targetLevel - 1)
|
||||
const baseTime = config.baseTime * multiplier
|
||||
|
||||
// 机器人工厂和纳米工厂的加速:建造时间 / (1 + 机器人工厂等级 + 纳米工厂等级 × 2)
|
||||
const factorySpeedDivisor = 1 + roboticsFactoryLevel + naniteFactoryLevel * 2
|
||||
|
||||
// 指挥官等的百分比加成
|
||||
const speedMultiplier = 1 - buildingSpeedBonus / 100
|
||||
return Math.floor(baseTime * speedMultiplier)
|
||||
|
||||
return Math.floor((baseTime / factorySpeedDivisor) * speedMultiplier)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,8 +105,9 @@ export const checkSpaceAvailable = (planet: Planet, buildingType: BuildingType):
|
||||
*/
|
||||
export const createBuildQueueItem = (buildingType: BuildingType, targetLevel: number, buildTime: number): BuildQueueItem => {
|
||||
const now = Date.now()
|
||||
queueIdCounter++
|
||||
return {
|
||||
id: `build_${now}`,
|
||||
id: `build_${now}_${queueIdCounter}`,
|
||||
type: 'building',
|
||||
itemType: buildingType,
|
||||
targetLevel,
|
||||
@@ -98,7 +119,11 @@ export const createBuildQueueItem = (buildingType: BuildingType, targetLevel: nu
|
||||
/**
|
||||
* 处理建造完成
|
||||
*/
|
||||
export const completeBuildQueue = (planet: Planet, now: number, onPointsEarned?: (points: number, type: 'building' | 'ship' | 'defense', itemType: string, level?: number, quantity?: number) => void): void => {
|
||||
export const completeBuildQueue = (
|
||||
planet: Planet,
|
||||
now: number,
|
||||
onPointsEarned?: (points: number, type: 'building' | 'ship' | 'defense', itemType: string, level?: number, quantity?: number) => void
|
||||
): void => {
|
||||
planet.buildQueue = planet.buildQueue.filter(item => {
|
||||
if (now >= item.endTime) {
|
||||
// 建造完成
|
||||
@@ -167,10 +192,18 @@ export const calculateDemolishRefund = (buildingType: BuildingType, currentLevel
|
||||
* @param buildingType 建筑类型
|
||||
* @param currentLevel 当前等级
|
||||
* @param buildingSpeedBonus 建筑速度加成
|
||||
* @param roboticsFactoryLevel 机器人工厂等级
|
||||
* @param naniteFactoryLevel 纳米工厂等级
|
||||
* @returns 拆除时间(建造时间的50%)
|
||||
*/
|
||||
export const calculateDemolishTime = (buildingType: BuildingType, currentLevel: number, buildingSpeedBonus: number = 0): number => {
|
||||
const buildTime = calculateBuildingTime(buildingType, currentLevel, buildingSpeedBonus)
|
||||
export const calculateDemolishTime = (
|
||||
buildingType: BuildingType,
|
||||
currentLevel: number,
|
||||
buildingSpeedBonus: number = 0,
|
||||
roboticsFactoryLevel: number = 0,
|
||||
naniteFactoryLevel: number = 0
|
||||
): number => {
|
||||
const buildTime = calculateBuildingTime(buildingType, currentLevel, buildingSpeedBonus, roboticsFactoryLevel, naniteFactoryLevel)
|
||||
return Math.floor(buildTime * 0.5)
|
||||
}
|
||||
|
||||
@@ -183,8 +216,9 @@ export const calculateDemolishTime = (buildingType: BuildingType, currentLevel:
|
||||
*/
|
||||
export const createDemolishQueueItem = (buildingType: BuildingType, currentLevel: number, demolishTime: number): BuildQueueItem => {
|
||||
const now = Date.now()
|
||||
queueIdCounter++
|
||||
return {
|
||||
id: `demolish_${now}`,
|
||||
id: `demolish_${now}_${queueIdCounter}`,
|
||||
type: 'demolish',
|
||||
itemType: buildingType,
|
||||
targetLevel: currentLevel - 1, // 目标等级为当前等级-1
|
||||
|
||||
@@ -23,6 +23,14 @@ export const validateBuildingUpgrade = (
|
||||
const cost = buildingLogic.calculateBuildingCost(buildingType, targetLevel)
|
||||
const buildingConfig = BUILDINGS[buildingType]
|
||||
|
||||
// 检查队列中是否已存在该建筑的升级或拆除任务
|
||||
const existingQueueItem = planet.buildQueue.find(
|
||||
item => (item.type === 'building' || item.type === 'demolish') && item.itemType === buildingType
|
||||
)
|
||||
if (existingQueueItem) {
|
||||
return { valid: false, reason: 'errors.buildingAlreadyInQueue' }
|
||||
}
|
||||
|
||||
// 检查星球/月球限制
|
||||
if (buildingConfig.planetOnly && planet.isMoon) {
|
||||
return { valid: false, reason: 'errors.planetOnly' }
|
||||
@@ -34,9 +42,10 @@ export const validateBuildingUpgrade = (
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
|
||||
// 检查建造队列是否已满
|
||||
// 检查建造队列是否已满(只计算建筑类型的队列项)
|
||||
const maxQueue = publicLogic.getMaxBuildQueue(planet, bonuses.additionalBuildQueue)
|
||||
if (planet.buildQueue.length >= maxQueue) {
|
||||
const buildingQueueCount = planet.buildQueue.filter(item => item.type === 'building' || item.type === 'demolish').length
|
||||
if (buildingQueueCount >= maxQueue) {
|
||||
return { valid: false, reason: 'errors.buildQueueFull' }
|
||||
}
|
||||
|
||||
@@ -61,14 +70,29 @@ export const validateBuildingUpgrade = (
|
||||
/**
|
||||
* 执行建筑升级(扣除资源,添加到队列)
|
||||
*/
|
||||
export const executeBuildingUpgrade = (planet: Planet, buildingType: BuildingType, officers: Record<OfficerType, Officer>): BuildQueueItem => {
|
||||
export const executeBuildingUpgrade = (
|
||||
planet: Planet,
|
||||
buildingType: BuildingType,
|
||||
officers: Record<OfficerType, Officer>
|
||||
): BuildQueueItem => {
|
||||
const currentLevel = planet.buildings[buildingType] || 0
|
||||
const targetLevel = currentLevel + 1
|
||||
const cost = buildingLogic.calculateBuildingCost(buildingType, targetLevel)
|
||||
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
const time = buildingLogic.calculateBuildingTime(buildingType, targetLevel, bonuses.buildingSpeedBonus)
|
||||
|
||||
// 获取机器人工厂和纳米工厂等级
|
||||
const roboticsFactoryLevel = planet.buildings[BuildingType.RoboticsFactory] || 0
|
||||
const naniteFactoryLevel = planet.buildings[BuildingType.NaniteFactory] || 0
|
||||
|
||||
const time = buildingLogic.calculateBuildingTime(
|
||||
buildingType,
|
||||
targetLevel,
|
||||
bonuses.buildingSpeedBonus,
|
||||
roboticsFactoryLevel,
|
||||
naniteFactoryLevel
|
||||
)
|
||||
|
||||
// 扣除资源
|
||||
resourceLogic.deductResources(planet.resources, cost)
|
||||
@@ -130,9 +154,10 @@ export const validateBuildingDemolish = (
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
|
||||
// 检查建造队列是否已满
|
||||
// 检查建造队列是否已满(只计算建筑类型的队列项)
|
||||
const maxQueue = publicLogic.getMaxBuildQueue(planet, bonuses.additionalBuildQueue)
|
||||
if (planet.buildQueue.length >= maxQueue) {
|
||||
const buildingQueueCount = planet.buildQueue.filter(item => item.type === 'building' || item.type === 'demolish').length
|
||||
if (buildingQueueCount >= maxQueue) {
|
||||
return { valid: false, reason: 'errors.buildQueueFull' }
|
||||
}
|
||||
|
||||
@@ -142,12 +167,27 @@ export const validateBuildingDemolish = (
|
||||
/**
|
||||
* 执行建筑拆除(返还资源,添加到队列)
|
||||
*/
|
||||
export const executeBuildingDemolish = (planet: Planet, buildingType: BuildingType, officers: Record<OfficerType, Officer>): BuildQueueItem => {
|
||||
export const executeBuildingDemolish = (
|
||||
planet: Planet,
|
||||
buildingType: BuildingType,
|
||||
officers: Record<OfficerType, Officer>
|
||||
): BuildQueueItem => {
|
||||
const currentLevel = planet.buildings[buildingType] || 0
|
||||
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
const demolishTime = buildingLogic.calculateDemolishTime(buildingType, currentLevel, bonuses.buildingSpeedBonus)
|
||||
|
||||
// 获取机器人工厂和纳米工厂等级
|
||||
const roboticsFactoryLevel = planet.buildings[BuildingType.RoboticsFactory] || 0
|
||||
const naniteFactoryLevel = planet.buildings[BuildingType.NaniteFactory] || 0
|
||||
|
||||
const demolishTime = buildingLogic.calculateDemolishTime(
|
||||
buildingType,
|
||||
currentLevel,
|
||||
bonuses.buildingSpeedBonus,
|
||||
roboticsFactoryLevel,
|
||||
naniteFactoryLevel
|
||||
)
|
||||
|
||||
// 返还50%资源
|
||||
const refund = buildingLogic.calculateDemolishRefund(buildingType, currentLevel)
|
||||
|
||||
957
src/logic/diplomaticLogic.ts
Normal file
957
src/logic/diplomaticLogic.ts
Normal file
@@ -0,0 +1,957 @@
|
||||
/**
|
||||
* 外交系统逻辑
|
||||
*
|
||||
* 管理玩家与NPC之间的双向好感度、关系状态和外交事件
|
||||
*/
|
||||
|
||||
import { DIPLOMATIC_CONFIG } from '@/config/gameConfig'
|
||||
import { locales, type Locale } from '@/locales'
|
||||
import type {
|
||||
DiplomaticRelation,
|
||||
RelationStatus,
|
||||
DiplomaticEventType,
|
||||
DiplomaticReport,
|
||||
Resources,
|
||||
Player,
|
||||
NPC,
|
||||
Planet,
|
||||
FleetMission,
|
||||
BattleResult,
|
||||
Position,
|
||||
GiftNotification,
|
||||
GiftRejectedNotification
|
||||
} from '@/types/game'
|
||||
import { RelationStatus as RS, DiplomaticEventType as DET } from '@/types/game'
|
||||
|
||||
/**
|
||||
* 获取翻译文本的辅助函数
|
||||
* @param key 翻译键
|
||||
* @param locale 语言代码
|
||||
* @param params 参数
|
||||
* @returns 翻译后的文本
|
||||
*/
|
||||
const t = (key: string, locale: Locale, params?: Record<string, string | number>): string => {
|
||||
const keys = key.split('.')
|
||||
let value: any = locales[locale]
|
||||
|
||||
for (const k of keys) {
|
||||
if (value && typeof value === 'object' && k in value) {
|
||||
value = value[k]
|
||||
} else {
|
||||
return key // 如果找不到翻译,返回原始 key
|
||||
}
|
||||
}
|
||||
|
||||
let result = typeof value === 'string' ? value : key
|
||||
|
||||
// 替换参数占位符
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([paramKey, paramValue]) => {
|
||||
result = result.replace(new RegExp(`\\{${paramKey}\\}`, 'g'), String(paramValue))
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据好感度值计算关系状态
|
||||
* @param reputation 好感度值 (-100 到 +100)
|
||||
* @returns 关系状态
|
||||
*/
|
||||
export const calculateRelationStatus = (reputation: number): RelationStatus => {
|
||||
if (reputation <= DIPLOMATIC_CONFIG.HOSTILE_THRESHOLD) {
|
||||
return RS.Hostile
|
||||
} else if (reputation >= DIPLOMATIC_CONFIG.FRIENDLY_THRESHOLD) {
|
||||
return RS.Friendly
|
||||
}
|
||||
return RS.Neutral
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化外交关系
|
||||
* @param fromId 关系发起方ID
|
||||
* @param toId 关系接收方ID
|
||||
* @returns 新的外交关系对象
|
||||
*/
|
||||
export const initializeDiplomaticRelation = (fromId: string, toId: string): DiplomaticRelation => {
|
||||
return {
|
||||
fromId,
|
||||
toId,
|
||||
reputation: 0, // 初始中立
|
||||
status: RS.Neutral,
|
||||
lastUpdated: Date.now(),
|
||||
history: []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新好感度值
|
||||
* @param relation 外交关系对象
|
||||
* @param change 好感度变化值
|
||||
* @param reason 变化原因
|
||||
* @param details 详细信息
|
||||
* @returns 更新后的外交关系对象
|
||||
*/
|
||||
export const updateReputation = (
|
||||
relation: DiplomaticRelation,
|
||||
change: number,
|
||||
reason: DiplomaticEventType,
|
||||
details?: string
|
||||
): DiplomaticRelation => {
|
||||
const oldReputation = relation.reputation
|
||||
|
||||
// 计算新的好感度(限制在范围内)
|
||||
const newReputation = Math.max(DIPLOMATIC_CONFIG.MIN_REPUTATION, Math.min(DIPLOMATIC_CONFIG.MAX_REPUTATION, oldReputation + change))
|
||||
|
||||
// 更新状态
|
||||
const newStatus = calculateRelationStatus(newReputation)
|
||||
|
||||
// 记录历史
|
||||
if (!relation.history) {
|
||||
relation.history = []
|
||||
}
|
||||
relation.history.push({
|
||||
timestamp: Date.now(),
|
||||
change,
|
||||
reason,
|
||||
details
|
||||
})
|
||||
|
||||
// 只保留最近50条历史记录
|
||||
if (relation.history.length > 50) {
|
||||
relation.history = relation.history.slice(-50)
|
||||
}
|
||||
|
||||
return {
|
||||
...relation,
|
||||
reputation: newReputation,
|
||||
status: newStatus,
|
||||
lastUpdated: Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算赠送资源的好感度增加值
|
||||
* @param resources 赠送的资源
|
||||
* @returns 好感度增加值
|
||||
*/
|
||||
export const calculateGiftReputationGain = (resources: Resources): number => {
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 计算资源总价值(晶体和氘气价值更高)
|
||||
const totalValue = resources.metal + resources.crystal * 1.5 + resources.deuterium * 3
|
||||
|
||||
// 检查是否达到最小价值门槛
|
||||
if (totalValue < REPUTATION_CHANGES.GIFT_MIN_VALUE) {
|
||||
return 0 // 低于门槛不获得好感度
|
||||
}
|
||||
|
||||
// 基础好感度 + 基于价值的额外好感度
|
||||
const baseGain = REPUTATION_CHANGES.GIFT_BASE
|
||||
const valueGain = Math.floor(totalValue / 1000) * REPUTATION_CHANGES.GIFT_PER_1K_RESOURCES
|
||||
|
||||
// 确保达到门槛的礼物至少获得1点好感度
|
||||
const totalGain = Math.max(baseGain + valueGain, 1)
|
||||
|
||||
// 限制在最大值范围内
|
||||
return Math.min(totalGain, REPUTATION_CHANGES.GIFT_MAX_SINGLE)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取或创建外交关系
|
||||
* @param relations 关系记录
|
||||
* @param fromId 关系发起方ID
|
||||
* @param toId 关系接收方ID
|
||||
* @returns 外交关系对象
|
||||
*/
|
||||
export const getOrCreateRelation = (relations: Record<string, DiplomaticRelation>, fromId: string, toId: string): DiplomaticRelation => {
|
||||
if (!relations[toId]) {
|
||||
relations[toId] = initializeDiplomaticRelation(fromId, toId)
|
||||
}
|
||||
return relations[toId]
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算NPC拒绝礼物的概率
|
||||
* @param npc NPC
|
||||
* @param player 玩家
|
||||
* @returns 拒绝概率(0-1)
|
||||
*/
|
||||
export const calculateNPCRejectionProbability = (npc: NPC, player: Player): number => {
|
||||
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 获取NPC对玩家的好感度
|
||||
const relation = npc.relations?.[player.id]
|
||||
const reputation = relation?.reputation || 0
|
||||
|
||||
// 基础概率 + 好感度修正
|
||||
// 好感度越低,拒绝概率越高
|
||||
let rejectionProb = GIFT_ACCEPTANCE_CONFIG.NPC_REJECTION_BASE_PROBABILITY
|
||||
|
||||
// 好感度修正:每低于0一点,增加1%拒绝概率
|
||||
if (reputation < 0) {
|
||||
rejectionProb += Math.abs(reputation) * GIFT_ACCEPTANCE_CONFIG.NPC_REJECTION_REPUTATION_MODIFIER
|
||||
} else if (reputation > 0) {
|
||||
// 好感度为正时,降低拒绝概率
|
||||
rejectionProb -= reputation * GIFT_ACCEPTANCE_CONFIG.NPC_REJECTION_REPUTATION_MODIFIER
|
||||
}
|
||||
|
||||
// 限制在最小和最大范围内
|
||||
return Math.max(
|
||||
GIFT_ACCEPTANCE_CONFIG.MIN_REJECTION_PROBABILITY,
|
||||
Math.min(GIFT_ACCEPTANCE_CONFIG.MAX_REJECTION_PROBABILITY, rejectionProb)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理赠送资源到达(需要NPC接受判定)
|
||||
* @param mission 舰队任务
|
||||
* @param player 玩家
|
||||
* @param targetNpc 目标NPC
|
||||
* @param locale 语言代码
|
||||
* @returns { accepted: boolean, reputationGain?: number }
|
||||
*/
|
||||
export const handleGiftArrival = (
|
||||
mission: FleetMission,
|
||||
player: Player,
|
||||
targetNpc: NPC,
|
||||
locale: Locale
|
||||
): { accepted: boolean; reputationGain?: number } => {
|
||||
// 计算NPC拒绝概率
|
||||
const rejectionProb = calculateNPCRejectionProbability(targetNpc, player)
|
||||
const isRejected = Math.random() < rejectionProb
|
||||
|
||||
if (isRejected) {
|
||||
// NPC拒绝礼物
|
||||
handleGiftRejection(player, targetNpc, mission.cargo, locale)
|
||||
return { accepted: false }
|
||||
}
|
||||
|
||||
// NPC接受礼物
|
||||
// 计算好感度增加值
|
||||
const reputationGain = calculateGiftReputationGain(mission.cargo)
|
||||
|
||||
// 更新玩家对NPC的关系
|
||||
if (!player.diplomaticRelations) {
|
||||
player.diplomaticRelations = {}
|
||||
}
|
||||
|
||||
const relation = getOrCreateRelation(player.diplomaticRelations, player.id, targetNpc.id)
|
||||
player.diplomaticRelations[targetNpc.id] = updateReputation(
|
||||
relation,
|
||||
reputationGain,
|
||||
DET.GiftResources,
|
||||
t('diplomacy.reports.giftedResources', locale, {
|
||||
metal: mission.cargo.metal.toString(),
|
||||
crystal: mission.cargo.crystal.toString(),
|
||||
deuterium: mission.cargo.deuterium.toString()
|
||||
})
|
||||
)
|
||||
|
||||
// 也更新NPC对玩家的关系(双向好感度)
|
||||
if (!targetNpc.relations) {
|
||||
targetNpc.relations = {}
|
||||
}
|
||||
|
||||
const npcRelation = getOrCreateRelation(targetNpc.relations, targetNpc.id, player.id)
|
||||
targetNpc.relations[player.id] = updateReputation(
|
||||
npcRelation,
|
||||
reputationGain,
|
||||
DET.GiftResources,
|
||||
t('diplomacy.reports.receivedGiftFromPlayer', locale)
|
||||
)
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
player,
|
||||
targetNpc,
|
||||
DET.GiftResources,
|
||||
reputationGain,
|
||||
t('diplomacy.reports.giftedToNpc', locale, { npcName: targetNpc.name, reputation: reputationGain.toString() })
|
||||
)
|
||||
|
||||
return { accepted: true, reputationGain }
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理礼物被拒绝
|
||||
* @param player 玩家
|
||||
* @param npc NPC
|
||||
* @param rejectedResources 被拒绝的资源
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
const handleGiftRejection = (player: Player, npc: NPC, rejectedResources: Resources, locale: Locale): void => {
|
||||
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 创建拒绝通知
|
||||
if (!player.giftRejectedNotifications) {
|
||||
player.giftRejectedNotifications = []
|
||||
}
|
||||
|
||||
const relation = npc.relations?.[player.id]
|
||||
const currentReputation = relation?.reputation || 0
|
||||
|
||||
const notification: GiftRejectedNotification = {
|
||||
id: `gift-rejected-${Date.now()}-${Math.random()}`,
|
||||
timestamp: Date.now(),
|
||||
npcId: npc.id,
|
||||
npcName: npc.name,
|
||||
rejectedResources,
|
||||
currentReputation,
|
||||
reason: currentReputation < -20 ? 'hostile' : currentReputation < 20 ? 'neutral_distrust' : 'polite_decline',
|
||||
read: false
|
||||
}
|
||||
|
||||
player.giftRejectedNotifications.push(notification)
|
||||
|
||||
// 限制通知数量
|
||||
if (player.giftRejectedNotifications.length > 50) {
|
||||
player.giftRejectedNotifications = player.giftRejectedNotifications.slice(-50)
|
||||
}
|
||||
|
||||
// 拒绝礼物会降低好感度
|
||||
if (!npc.relations) {
|
||||
npc.relations = {}
|
||||
}
|
||||
|
||||
const npcRelation = getOrCreateRelation(npc.relations, npc.id, player.id)
|
||||
npc.relations[player.id] = updateReputation(
|
||||
npcRelation,
|
||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||
DET.GiftResources,
|
||||
t('diplomacy.reports.rejectedPlayerGift', locale)
|
||||
)
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
player,
|
||||
npc,
|
||||
DET.GiftResources,
|
||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||
t('diplomacy.reports.npcRejectedGift', locale, {
|
||||
npcName: npc.name,
|
||||
reputation: GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY.toString()
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理攻击事件的好感度变化
|
||||
* @param attacker 攻击者(玩家)
|
||||
* @param defender 防御者(NPC)
|
||||
* @param battleResult 战斗结果
|
||||
* @param allNpcs 所有NPC列表
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const handleAttackReputation = (
|
||||
attacker: Player,
|
||||
defender: NPC,
|
||||
battleResult: BattleResult,
|
||||
allNpcs: NPC[],
|
||||
locale: Locale
|
||||
): void => {
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 计算好感度降低值
|
||||
let reputationLoss = REPUTATION_CHANGES.ATTACK
|
||||
|
||||
if (battleResult.winner === 'attacker') {
|
||||
reputationLoss = REPUTATION_CHANGES.ATTACK_WIN
|
||||
}
|
||||
|
||||
// 更新玩家对被攻击NPC的关系
|
||||
if (!attacker.diplomaticRelations) {
|
||||
attacker.diplomaticRelations = {}
|
||||
}
|
||||
|
||||
const relation = getOrCreateRelation(attacker.diplomaticRelations, attacker.id, defender.id)
|
||||
attacker.diplomaticRelations[defender.id] = updateReputation(
|
||||
relation,
|
||||
reputationLoss,
|
||||
DET.Attack,
|
||||
t('diplomacy.reports.attackedNpc', locale, { npcName: defender.name })
|
||||
)
|
||||
|
||||
// 更新被攻击NPC对玩家的关系
|
||||
if (!defender.relations) {
|
||||
defender.relations = {}
|
||||
}
|
||||
|
||||
const defenderRelation = getOrCreateRelation(defender.relations, defender.id, attacker.id)
|
||||
defender.relations[attacker.id] = updateReputation(
|
||||
defenderRelation,
|
||||
reputationLoss,
|
||||
DET.Attack,
|
||||
t('diplomacy.reports.wasAttackedByPlayer', locale)
|
||||
)
|
||||
|
||||
// 检查盟友关系网络
|
||||
if (defender.allies && defender.allies.length > 0) {
|
||||
handleAllyAttackedReputation(attacker, defender, allNpcs, locale)
|
||||
}
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
attacker,
|
||||
defender,
|
||||
DET.Attack,
|
||||
-reputationLoss,
|
||||
t('diplomacy.reports.youAttackedNpc', locale, { npcName: defender.name })
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理盟友被攻击的好感度变化
|
||||
* @param attacker 攻击者(玩家)
|
||||
* @param attackedNpc 被攻击的NPC
|
||||
* @param allNpcs 所有NPC列表
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const handleAllyAttackedReputation = (attacker: Player, attackedNpc: NPC, allNpcs: NPC[], locale: Locale): void => {
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 找到所有盟友
|
||||
const allies = allNpcs.filter(npc => attackedNpc.allies?.includes(npc.id))
|
||||
|
||||
allies.forEach(ally => {
|
||||
// 更新盟友对玩家的关系
|
||||
if (!ally.relations) {
|
||||
ally.relations = {}
|
||||
}
|
||||
|
||||
const allyRelation = getOrCreateRelation(ally.relations, ally.id, attacker.id)
|
||||
ally.relations[attacker.id] = updateReputation(
|
||||
allyRelation,
|
||||
REPUTATION_CHANGES.ALLY_ATTACKED,
|
||||
DET.AllyAttacked,
|
||||
t('diplomacy.reports.playerAttackedAlly', locale, { allyName: attackedNpc.name })
|
||||
)
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
attacker,
|
||||
ally,
|
||||
DET.AllyAttacked,
|
||||
REPUTATION_CHANGES.ALLY_ATTACKED,
|
||||
t('diplomacy.reports.allyDispleased', locale, { allyName: ally.name, targetName: attackedNpc.name })
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理侦查事件的好感度变化
|
||||
* @param spy 侦查者(玩家)
|
||||
* @param target 侦查目标(NPC)
|
||||
* @param wasDetected 是否被发现
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const handleSpyReputation = (spy: Player, target: NPC, wasDetected: boolean, locale: Locale): void => {
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
|
||||
const reputationLoss = wasDetected ? REPUTATION_CHANGES.SPY_DETECTED : REPUTATION_CHANGES.SPY_UNDETECTED
|
||||
|
||||
// NPC对玩家的关系始终受影响
|
||||
if (!target.relations) {
|
||||
target.relations = {}
|
||||
}
|
||||
|
||||
const targetRelation = getOrCreateRelation(target.relations, target.id, spy.id)
|
||||
target.relations[spy.id] = updateReputation(
|
||||
targetRelation,
|
||||
reputationLoss,
|
||||
DET.Spy,
|
||||
t('diplomacy.reports.wasSpiedByPlayer', locale, { detected: wasDetected ? 'true' : 'false' })
|
||||
)
|
||||
|
||||
// 如果被发现,生成外交报告
|
||||
if (wasDetected) {
|
||||
generateDiplomaticReport(spy, target, DET.Spy, reputationLoss, t('diplomacy.reports.spyDetected', locale, { npcName: target.name }))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理回收残骸事件的好感度变化
|
||||
* 如果残骸在NPC星球位置,视为抢夺
|
||||
* @param player 玩家
|
||||
* @param debrisPosition 残骸位置
|
||||
* @param allNpcs 所有NPC列表
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const handleDebrisRecycleReputation = (player: Player, debrisPosition: Position, allNpcs: NPC[], locale: Locale): void => {
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 找到该位置的NPC星球所有者
|
||||
const npcOwner = allNpcs.find(npc =>
|
||||
npc.planets.some(
|
||||
p =>
|
||||
p.position.galaxy === debrisPosition.galaxy &&
|
||||
p.position.system === debrisPosition.system &&
|
||||
p.position.position === debrisPosition.position
|
||||
)
|
||||
)
|
||||
|
||||
if (npcOwner) {
|
||||
// 这是在NPC星球位置回收残骸,视为抢夺
|
||||
if (!player.diplomaticRelations) {
|
||||
player.diplomaticRelations = {}
|
||||
}
|
||||
|
||||
const relation = getOrCreateRelation(player.diplomaticRelations, player.id, npcOwner.id)
|
||||
player.diplomaticRelations[npcOwner.id] = updateReputation(
|
||||
relation,
|
||||
REPUTATION_CHANGES.STEAL_DEBRIS,
|
||||
DET.StealDebris,
|
||||
t('diplomacy.reports.stoleDebrisFromTerritory', locale, { npcName: npcOwner.name })
|
||||
)
|
||||
|
||||
// 更新NPC对玩家的关系
|
||||
if (!npcOwner.relations) {
|
||||
npcOwner.relations = {}
|
||||
}
|
||||
|
||||
const npcRelation = getOrCreateRelation(npcOwner.relations, npcOwner.id, player.id)
|
||||
npcOwner.relations[player.id] = updateReputation(
|
||||
npcRelation,
|
||||
REPUTATION_CHANGES.STEAL_DEBRIS,
|
||||
DET.StealDebris,
|
||||
t('diplomacy.reports.playerStoleDebris', locale)
|
||||
)
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
player,
|
||||
npcOwner,
|
||||
DET.StealDebris,
|
||||
REPUTATION_CHANGES.STEAL_DEBRIS,
|
||||
t('diplomacy.reports.recycledDebrisNearNpc', locale, { npcName: npcOwner.name })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理星球摧毁事件的好感度变化
|
||||
* 摧毁星球是最严重的行为,直接导致敌对关系
|
||||
* @param attacker 攻击者(玩家)
|
||||
* @param destroyedPlanet 被摧毁的星球
|
||||
* @param planetOwner 星球所有者(NPC)
|
||||
* @param allNpcs 所有NPC列表
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const handlePlanetDestructionReputation = (
|
||||
attacker: Player,
|
||||
destroyedPlanet: Planet,
|
||||
planetOwner: NPC,
|
||||
allNpcs: NPC[],
|
||||
locale: Locale
|
||||
): void => {
|
||||
const { HOSTILE_THRESHOLD } = DIPLOMATIC_CONFIG
|
||||
const now = Date.now()
|
||||
|
||||
// 更新玩家对被摧毁星球所有者的关系 - 直接设为敌对
|
||||
if (!attacker.diplomaticRelations) {
|
||||
attacker.diplomaticRelations = {}
|
||||
}
|
||||
|
||||
const relation = getOrCreateRelation(attacker.diplomaticRelations, attacker.id, planetOwner.id)
|
||||
const eventDescription = t('diplomacy.reports.destroyedNpcPlanet', locale, {
|
||||
npcName: planetOwner.name,
|
||||
planetName: destroyedPlanet.name
|
||||
})
|
||||
|
||||
attacker.diplomaticRelations[planetOwner.id] = {
|
||||
...relation,
|
||||
reputation: HOSTILE_THRESHOLD, // 直接设为敌对阈值
|
||||
status: RS.Hostile,
|
||||
lastUpdated: now,
|
||||
history: [
|
||||
...(relation.history || []),
|
||||
{
|
||||
timestamp: now,
|
||||
change: HOSTILE_THRESHOLD - relation.reputation,
|
||||
reason: DET.DestroyPlanet,
|
||||
details: eventDescription
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 更新星球所有者对玩家的关系 - 直接设为敌对
|
||||
if (!planetOwner.relations) {
|
||||
planetOwner.relations = {}
|
||||
}
|
||||
|
||||
const ownerRelation = getOrCreateRelation(planetOwner.relations, planetOwner.id, attacker.id)
|
||||
const ownerEventDescription = t('diplomacy.reports.playerDestroyedPlanet', locale, {
|
||||
planetName: destroyedPlanet.name
|
||||
})
|
||||
|
||||
planetOwner.relations[attacker.id] = {
|
||||
...ownerRelation,
|
||||
reputation: HOSTILE_THRESHOLD, // 直接设为敌对阈值
|
||||
status: RS.Hostile,
|
||||
lastUpdated: now,
|
||||
history: [
|
||||
...(ownerRelation.history || []),
|
||||
{
|
||||
timestamp: now,
|
||||
change: HOSTILE_THRESHOLD - ownerRelation.reputation,
|
||||
reason: DET.DestroyPlanet,
|
||||
details: ownerEventDescription
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
attacker,
|
||||
planetOwner,
|
||||
DET.DestroyPlanet,
|
||||
HOSTILE_THRESHOLD,
|
||||
t('diplomacy.reports.youDestroyedNpcPlanet', locale, {
|
||||
npcName: planetOwner.name,
|
||||
planetName: destroyedPlanet.name,
|
||||
reputation: HOSTILE_THRESHOLD
|
||||
}),
|
||||
'diplomacy.reports.youDestroyedNpcPlanet',
|
||||
{ npcName: planetOwner.name, planetName: destroyedPlanet.name, reputation: HOSTILE_THRESHOLD }
|
||||
)
|
||||
|
||||
// 检查盟友关系网络 - 摧毁星球对盟友的影响更严重
|
||||
if (planetOwner.allies && planetOwner.allies.length > 0) {
|
||||
handleAllyPlanetDestroyedReputation(attacker, planetOwner, destroyedPlanet, allNpcs, locale)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理盟友星球被摧毁的好感度变化
|
||||
* @param attacker 攻击者(玩家)
|
||||
* @param attackedNpc 星球被摧毁的NPC
|
||||
* @param destroyedPlanet 被摧毁的星球
|
||||
* @param allNpcs 所有NPC列表
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const handleAllyPlanetDestroyedReputation = (
|
||||
attacker: Player,
|
||||
attackedNpc: NPC,
|
||||
destroyedPlanet: Planet,
|
||||
allNpcs: NPC[],
|
||||
locale: Locale
|
||||
): void => {
|
||||
const { REPUTATION_CHANGES } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 找到所有盟友
|
||||
const allies = allNpcs.filter(npc => attackedNpc.allies?.includes(npc.id))
|
||||
|
||||
allies.forEach(ally => {
|
||||
// 更新盟友对玩家的关系 - 摧毁盟友星球的惩罚是攻击的两倍
|
||||
if (!ally.relations) {
|
||||
ally.relations = {}
|
||||
}
|
||||
|
||||
const allyRelation = getOrCreateRelation(ally.relations, ally.id, attacker.id)
|
||||
const reputationLoss = REPUTATION_CHANGES.ALLY_ATTACKED * 2 // 双倍惩罚
|
||||
ally.relations[attacker.id] = updateReputation(
|
||||
allyRelation,
|
||||
reputationLoss,
|
||||
DET.DestroyPlanet,
|
||||
t('diplomacy.reports.playerDestroyedAllyPlanet', locale, { allyName: attackedNpc.name, planetName: destroyedPlanet.name })
|
||||
)
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
attacker,
|
||||
ally,
|
||||
DET.DestroyPlanet,
|
||||
reputationLoss,
|
||||
t('diplomacy.reports.allyOutraged', locale, {
|
||||
allyName: ally.name,
|
||||
targetName: attackedNpc.name,
|
||||
planetName: destroyedPlanet.name
|
||||
}),
|
||||
'diplomacy.reports.allyOutraged',
|
||||
{
|
||||
allyName: ally.name,
|
||||
targetName: attackedNpc.name,
|
||||
planetName: destroyedPlanet.name
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成外交报告
|
||||
* @param player 玩家
|
||||
* @param npc NPC
|
||||
* @param eventType 事件类型
|
||||
* @param reputationChange 好感度变化值
|
||||
* @param message 消息内容(已弃用,用于向后兼容)
|
||||
* @param messageKey 翻译键(可选)
|
||||
* @param messageParams 翻译参数(可选)
|
||||
*/
|
||||
const generateDiplomaticReport = (
|
||||
player: Player,
|
||||
npc: NPC,
|
||||
eventType: DiplomaticEventType,
|
||||
reputationChange: number,
|
||||
message: string,
|
||||
messageKey?: string,
|
||||
messageParams?: Record<string, string | number>
|
||||
): void => {
|
||||
if (!player.diplomaticReports) {
|
||||
player.diplomaticReports = []
|
||||
}
|
||||
|
||||
if (!player.diplomaticRelations) {
|
||||
player.diplomaticRelations = {}
|
||||
}
|
||||
|
||||
const relation = player.diplomaticRelations[npc.id] || initializeDiplomaticRelation(player.id, npc.id)
|
||||
const oldStatus = relation.status
|
||||
const newReputation = Math.max(
|
||||
DIPLOMATIC_CONFIG.MIN_REPUTATION,
|
||||
Math.min(DIPLOMATIC_CONFIG.MAX_REPUTATION, relation.reputation + reputationChange)
|
||||
)
|
||||
const newStatus = calculateRelationStatus(newReputation)
|
||||
|
||||
const report: DiplomaticReport = {
|
||||
id: `diplomatic-${Date.now()}-${Math.random()}`,
|
||||
timestamp: Date.now(),
|
||||
npcId: npc.id,
|
||||
npcName: npc.name,
|
||||
eventType,
|
||||
reputationChange,
|
||||
newReputation,
|
||||
oldStatus,
|
||||
newStatus,
|
||||
message,
|
||||
messageKey,
|
||||
messageParams,
|
||||
read: false
|
||||
}
|
||||
|
||||
player.diplomaticReports.push(report)
|
||||
|
||||
// 只保留最近100条报告
|
||||
if (player.diplomaticReports.length > 100) {
|
||||
player.diplomaticReports = player.diplomaticReports.slice(-100)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理NPC赠送资源给玩家(创建礼物通知,等待玩家接受/拒绝)
|
||||
* @param npc 赠送方NPC
|
||||
* @param player 接收方玩家
|
||||
* @param giftResources 赠送的资源
|
||||
*/
|
||||
export const handleNPCGiftToPlayer = (npc: NPC, player: Player, giftResources: Resources): void => {
|
||||
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 创建礼物通知
|
||||
if (!player.giftNotifications) {
|
||||
player.giftNotifications = []
|
||||
}
|
||||
|
||||
const npcRelation = npc.relations?.[player.id]
|
||||
const currentReputation = npcRelation?.reputation || 0
|
||||
const expectedReputationGain = Math.floor(calculateGiftReputationGain(giftResources) * 0.5)
|
||||
|
||||
const notification: GiftNotification = {
|
||||
id: `gift-${Date.now()}-${Math.random()}`,
|
||||
timestamp: Date.now(),
|
||||
fromNpcId: npc.id,
|
||||
fromNpcName: npc.name,
|
||||
resources: giftResources,
|
||||
currentReputation,
|
||||
expectedReputationGain,
|
||||
expiresAt: Date.now() + GIFT_ACCEPTANCE_CONFIG.GIFT_EXPIRATION_DAYS * 24 * 3600 * 1000,
|
||||
read: false
|
||||
}
|
||||
|
||||
player.giftNotifications.push(notification)
|
||||
|
||||
// 限制通知数量
|
||||
if (player.giftNotifications.length > 50) {
|
||||
player.giftNotifications = player.giftNotifications.slice(-50)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家接受NPC的礼物
|
||||
* @param player 玩家
|
||||
* @param npc NPC
|
||||
* @param giftNotification 礼物通知
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const acceptNPCGift = (player: Player, npc: NPC, giftNotification: GiftNotification, locale: Locale): void => {
|
||||
// 将资源添加到玩家主星球
|
||||
if (player.planets && player.planets.length > 0) {
|
||||
const mainPlanet = player.planets[0]
|
||||
if (mainPlanet) {
|
||||
mainPlanet.resources.metal += giftNotification.resources.metal
|
||||
mainPlanet.resources.crystal += giftNotification.resources.crystal
|
||||
mainPlanet.resources.deuterium += giftNotification.resources.deuterium
|
||||
mainPlanet.resources.darkMatter += giftNotification.resources.darkMatter
|
||||
}
|
||||
}
|
||||
|
||||
// 更新NPC对玩家的关系
|
||||
if (!npc.relations) {
|
||||
npc.relations = {}
|
||||
}
|
||||
|
||||
const npcRelation = getOrCreateRelation(npc.relations, npc.id, player.id)
|
||||
npc.relations[player.id] = updateReputation(
|
||||
npcRelation,
|
||||
giftNotification.expectedReputationGain,
|
||||
DET.GiftResources,
|
||||
t('diplomacy.reports.giftedResourcesToPlayer', locale)
|
||||
)
|
||||
|
||||
// 也更新玩家对NPC的关系(收到礼物会增加好感)
|
||||
if (!player.diplomaticRelations) {
|
||||
player.diplomaticRelations = {}
|
||||
}
|
||||
|
||||
const playerRelation = getOrCreateRelation(player.diplomaticRelations, player.id, npc.id)
|
||||
player.diplomaticRelations[npc.id] = updateReputation(
|
||||
playerRelation,
|
||||
giftNotification.expectedReputationGain,
|
||||
DET.GiftResources,
|
||||
t('diplomacy.reports.receivedGiftFromNpc', locale, { npcName: npc.name })
|
||||
)
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
player,
|
||||
npc,
|
||||
DET.GiftResources,
|
||||
giftNotification.expectedReputationGain,
|
||||
t('diplomacy.reports.acceptedGiftFromNpc', locale, {
|
||||
npcName: npc.name,
|
||||
metal: giftNotification.resources.metal.toString(),
|
||||
crystal: giftNotification.resources.crystal.toString(),
|
||||
deuterium: giftNotification.resources.deuterium.toString()
|
||||
})
|
||||
)
|
||||
|
||||
// 移除礼物通知
|
||||
if (player.giftNotifications) {
|
||||
player.giftNotifications = player.giftNotifications.filter(n => n.id !== giftNotification.id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 玩家拒绝NPC的礼物
|
||||
* @param player 玩家
|
||||
* @param npc NPC
|
||||
* @param giftNotification 礼物通知
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const rejectNPCGift = (player: Player, npc: NPC, giftNotification: GiftNotification, locale: Locale): void => {
|
||||
const { GIFT_ACCEPTANCE_CONFIG } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 拒绝礼物会降低好感度
|
||||
if (!npc.relations) {
|
||||
npc.relations = {}
|
||||
}
|
||||
|
||||
const npcRelation = getOrCreateRelation(npc.relations, npc.id, player.id)
|
||||
npc.relations[player.id] = updateReputation(
|
||||
npcRelation,
|
||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||
DET.GiftResources,
|
||||
t('diplomacy.reports.playerRejectedGift', locale)
|
||||
)
|
||||
|
||||
// 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
player,
|
||||
npc,
|
||||
DET.GiftResources,
|
||||
GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY,
|
||||
t('diplomacy.reports.rejectedGiftFromNpc', locale, {
|
||||
npcName: npc.name,
|
||||
reputation: GIFT_ACCEPTANCE_CONFIG.REJECTION_REPUTATION_PENALTY.toString()
|
||||
})
|
||||
)
|
||||
|
||||
// 移除礼物通知
|
||||
if (player.giftNotifications) {
|
||||
player.giftNotifications = player.giftNotifications.filter(n => n.id !== giftNotification.id)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理NPC被彻底消灭(所有星球被摧毁)
|
||||
* @param eliminatedNpc 被消灭的NPC
|
||||
* @param player 玩家
|
||||
* @param allNpcs 所有NPC列表
|
||||
* @param locale 语言代码
|
||||
*/
|
||||
export const handleNPCElimination = (eliminatedNpc: NPC, player: Player, allNpcs: NPC[], locale: Locale): void => {
|
||||
const { HOSTILE_THRESHOLD } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 1. 将玩家对该NPC的关系设为最低(敌对状态)
|
||||
if (!player.diplomaticRelations) {
|
||||
player.diplomaticRelations = {}
|
||||
}
|
||||
|
||||
const relation = getOrCreateRelation(player.diplomaticRelations, player.id, eliminatedNpc.id)
|
||||
const now = Date.now()
|
||||
|
||||
player.diplomaticRelations[eliminatedNpc.id] = {
|
||||
...relation,
|
||||
reputation: HOSTILE_THRESHOLD, // 设为敌对阈值
|
||||
status: RS.Hostile,
|
||||
lastUpdated: now,
|
||||
history: [
|
||||
...(relation.history || []),
|
||||
{
|
||||
timestamp: now,
|
||||
change: HOSTILE_THRESHOLD - relation.reputation,
|
||||
reason: DET.DestroyPlanet,
|
||||
details: t('diplomacy.reports.npcEliminated', locale, { npcName: eliminatedNpc.name })
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
// 2. 生成外交报告
|
||||
generateDiplomaticReport(
|
||||
player,
|
||||
eliminatedNpc,
|
||||
DET.DestroyPlanet,
|
||||
HOSTILE_THRESHOLD,
|
||||
t('diplomacy.reports.npcEliminatedMessage', locale, { npcName: eliminatedNpc.name }),
|
||||
'diplomacy.reports.npcEliminatedMessage',
|
||||
{ npcName: eliminatedNpc.name }
|
||||
)
|
||||
|
||||
// 3. 从所有其他NPC的盟友列表中移除被消灭的NPC
|
||||
allNpcs.forEach(npc => {
|
||||
if (npc.id !== eliminatedNpc.id && npc.allies && npc.allies.includes(eliminatedNpc.id)) {
|
||||
npc.allies = npc.allies.filter(allyId => allyId !== eliminatedNpc.id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查并处理被消灭的NPC(所有星球都被摧毁的NPC)
|
||||
* @param allNpcs 所有NPC列表
|
||||
* @param player 玩家
|
||||
* @param locale 语言代码
|
||||
* @returns 被消灭的NPC ID列表
|
||||
*/
|
||||
export const checkAndHandleEliminatedNPCs = (allNpcs: NPC[], player: Player, locale: Locale): string[] => {
|
||||
const eliminatedNpcIds: string[] = []
|
||||
|
||||
allNpcs.forEach(npc => {
|
||||
// 检查NPC是否还有星球
|
||||
if (!npc.planets || npc.planets.length === 0) {
|
||||
// NPC被彻底消灭
|
||||
handleNPCElimination(npc, player, allNpcs, locale)
|
||||
eliminatedNpcIds.push(npc.id)
|
||||
}
|
||||
})
|
||||
|
||||
return eliminatedNpcIds
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
import type { FleetMission, Planet, Resources, Fleet, BattleResult, SpyReport, Player, Officer, DebrisField } from '@/types/game'
|
||||
import { ShipType, DefenseType, MissionType, BuildingType, OfficerType } from '@/types/game'
|
||||
import type { FleetMission, Planet, Resources, Fleet, BattleResult, SpyReport, Player, Officer, DebrisField, NPC } from '@/types/game'
|
||||
import type { Locale } from '@/locales'
|
||||
import { ShipType, DefenseType, MissionType, BuildingType, OfficerType, TechnologyType } from '@/types/game'
|
||||
import { FLEET_STORAGE_CONFIG } from '@/config/gameConfig'
|
||||
import * as battleLogic from './battleLogic'
|
||||
import * as moonLogic from './moonLogic'
|
||||
import * as moonValidation from './moonValidation'
|
||||
import * as diplomaticLogic from './diplomaticLogic'
|
||||
|
||||
/**
|
||||
* 计算两个星球之间的距离
|
||||
@@ -34,9 +36,10 @@ export const calculateDistance = (
|
||||
|
||||
/**
|
||||
* 计算飞行时间
|
||||
* 平衡后的时间倍率,确保游戏节奏合理
|
||||
*/
|
||||
export const calculateFlightTime = (distance: number, minSpeed: number): number => {
|
||||
return Math.max(10, Math.floor((distance * 10000) / minSpeed)) // 至少10秒
|
||||
return Math.max(10, Math.floor((distance * 50) / minSpeed)) // 至少10秒
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,15 +73,45 @@ export const createFleetMission = (
|
||||
/**
|
||||
* 处理运输任务到达
|
||||
*/
|
||||
export const processTransportArrival = (mission: FleetMission, targetPlanet: Planet | undefined): void => {
|
||||
export const processTransportArrival = (
|
||||
mission: FleetMission,
|
||||
targetPlanet: Planet | undefined,
|
||||
player?: Player,
|
||||
allNpcs?: NPC[],
|
||||
locale: Locale = 'zh-CN'
|
||||
): { success: boolean; reputationGain?: number } => {
|
||||
// 检查是否是赠送任务
|
||||
if (mission.isGift && mission.giftTargetNpcId && player && allNpcs) {
|
||||
const targetNpc = allNpcs.find(n => n.id === mission.giftTargetNpcId)
|
||||
if (targetNpc) {
|
||||
const giftResult = diplomaticLogic.handleGiftArrival(mission, player, targetNpc, locale)
|
||||
mission.status = 'returning'
|
||||
|
||||
// 如果礼物被拒绝,资源返还给玩家
|
||||
if (!giftResult.accepted) {
|
||||
// 资源保留在cargo中,返回时会退还给玩家
|
||||
return { success: false, reputationGain: undefined }
|
||||
}
|
||||
|
||||
// 礼物被接受,清空货物
|
||||
mission.cargo = { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 }
|
||||
return { success: true, reputationGain: giftResult.reputationGain }
|
||||
}
|
||||
}
|
||||
|
||||
// 正常运输任务
|
||||
if (targetPlanet) {
|
||||
targetPlanet.resources.metal += mission.cargo.metal
|
||||
targetPlanet.resources.crystal += mission.cargo.crystal
|
||||
targetPlanet.resources.deuterium += mission.cargo.deuterium
|
||||
targetPlanet.resources.darkMatter += mission.cargo.darkMatter
|
||||
mission.status = 'returning'
|
||||
mission.cargo = { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 }
|
||||
return { success: true }
|
||||
}
|
||||
mission.status = 'returning'
|
||||
mission.cargo = { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 }
|
||||
return { success: false }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,7 +136,9 @@ export const processAttackArrival = async (
|
||||
targetPlanet.defense,
|
||||
targetPlanet.resources,
|
||||
attacker.officers,
|
||||
defender?.officers || ({} as Record<OfficerType, Officer>)
|
||||
defender?.officers || ({} as Record<OfficerType, Officer>),
|
||||
attacker.technologies,
|
||||
defender?.technologies || ({} as Record<TechnologyType, number>)
|
||||
)
|
||||
|
||||
// 更新战斗报告ID
|
||||
@@ -177,13 +212,134 @@ export const processAttackArrival = async (
|
||||
return { battleResult, moon, debrisField }
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理NPC攻击玩家星球
|
||||
* 专门用于NPC作为攻击方的情况
|
||||
*/
|
||||
export const processNPCAttackArrival = async (
|
||||
npc: NPC,
|
||||
mission: FleetMission,
|
||||
targetPlanet: Planet,
|
||||
defender: Player,
|
||||
allPlanets: Planet[]
|
||||
): Promise<{ battleResult: BattleResult; moon: Planet | null; debrisField: DebrisField | null } | null> => {
|
||||
// 执行战斗(使用 Worker 进行异步计算)
|
||||
const battleResult = await battleLogic.simulateBattle(
|
||||
mission.fleet, // NPC舰队
|
||||
targetPlanet.fleet, // 玩家舰队
|
||||
targetPlanet.defense, // 玩家防御
|
||||
targetPlanet.resources, // 玩家资源
|
||||
{} as Record<OfficerType, Officer>, // NPC没有军官系统
|
||||
defender.officers || ({} as Record<OfficerType, Officer>), // 玩家军官
|
||||
npc.technologies, // NPC科技等级
|
||||
defender.technologies // 玩家科技等级
|
||||
)
|
||||
|
||||
// 更新战斗报告ID和参与者信息
|
||||
battleResult.id = `battle_${Date.now()}`
|
||||
battleResult.attackerId = npc.id
|
||||
battleResult.defenderId = defender.id
|
||||
battleResult.attackerPlanetId = mission.originPlanetId
|
||||
battleResult.defenderPlanetId = targetPlanet.id
|
||||
battleResult.timestamp = Date.now()
|
||||
|
||||
// 如果NPC获胜,掠夺的资源给NPC的起始星球
|
||||
if (battleResult.winner === 'attacker' && battleResult.plunder) {
|
||||
const npcOriginPlanet = npc.planets.find(p => p.id === mission.originPlanetId)
|
||||
if (npcOriginPlanet) {
|
||||
// NPC获得掠夺的资源(当舰队返回时)
|
||||
mission.cargo = battleResult.plunder
|
||||
}
|
||||
}
|
||||
|
||||
// 更新NPC舰队 - 计算幸存舰船
|
||||
const survivingFleet: Partial<Fleet> = {}
|
||||
Object.entries(mission.fleet).forEach(([shipType, initialCount]) => {
|
||||
const lost = battleResult.attackerLosses[shipType as ShipType] || 0
|
||||
const surviving = initialCount - lost
|
||||
if (surviving > 0) {
|
||||
survivingFleet[shipType as ShipType] = surviving
|
||||
}
|
||||
})
|
||||
mission.fleet = survivingFleet
|
||||
|
||||
// 更新玩家星球舰队和防御
|
||||
Object.entries(battleResult.defenderLosses.fleet).forEach(([shipType, lost]) => {
|
||||
targetPlanet.fleet[shipType as ShipType] = Math.max(0, (targetPlanet.fleet[shipType as ShipType] || 0) - lost)
|
||||
})
|
||||
|
||||
Object.entries(battleResult.defenderLosses.defense).forEach(([defenseType, lost]) => {
|
||||
targetPlanet.defense[defenseType as DefenseType] = Math.max(0, (targetPlanet.defense[defenseType as DefenseType] || 0) - lost)
|
||||
})
|
||||
|
||||
// 防御设施修复(70%概率)
|
||||
const defenseBeforeBattle: Partial<Record<DefenseType, number>> = { ...targetPlanet.defense }
|
||||
Object.entries(battleResult.defenderLosses.defense).forEach(([defenseType, lost]) => {
|
||||
defenseBeforeBattle[defenseType as DefenseType] = (defenseBeforeBattle[defenseType as DefenseType] || 0) + lost
|
||||
})
|
||||
targetPlanet.defense = battleLogic.repairDefense(defenseBeforeBattle, targetPlanet.defense) as Record<DefenseType, number>
|
||||
|
||||
// 扣除玩家星球被掠夺的资源
|
||||
if (battleResult.plunder) {
|
||||
targetPlanet.resources.metal = Math.max(0, targetPlanet.resources.metal - battleResult.plunder.metal)
|
||||
targetPlanet.resources.crystal = Math.max(0, targetPlanet.resources.crystal - battleResult.plunder.crystal)
|
||||
targetPlanet.resources.deuterium = Math.max(0, targetPlanet.resources.deuterium - battleResult.plunder.deuterium)
|
||||
}
|
||||
|
||||
mission.status = 'returning'
|
||||
|
||||
// 尝试生成月球(如果该位置还没有月球)
|
||||
let moon: Planet | null = null
|
||||
const moonCheck = moonValidation.canCreateMoon(allPlanets, targetPlanet.position, battleResult.debrisField)
|
||||
if (moonCheck.canCreate && moonCheck.chance) {
|
||||
if (moonValidation.shouldGenerateMoon(moonCheck.chance)) {
|
||||
moon = moonLogic.tryGenerateMoon(battleResult.debrisField, targetPlanet.position, targetPlanet.id, targetPlanet.ownerId || 'unknown')
|
||||
}
|
||||
}
|
||||
|
||||
// 创建残骸场(如果有残骸)
|
||||
let debrisField: DebrisField | null = null
|
||||
const totalDebris = battleResult.debrisField.metal + battleResult.debrisField.crystal
|
||||
if (totalDebris > 0) {
|
||||
debrisField = {
|
||||
id: `debris_${targetPlanet.position.galaxy}_${targetPlanet.position.system}_${targetPlanet.position.position}`,
|
||||
position: targetPlanet.position,
|
||||
resources: {
|
||||
metal: battleResult.debrisField.metal,
|
||||
crystal: battleResult.debrisField.crystal
|
||||
},
|
||||
createdAt: Date.now()
|
||||
}
|
||||
}
|
||||
return { battleResult, moon, debrisField }
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算玩家最大星球数量
|
||||
* 基于天体物理学技术等级
|
||||
*/
|
||||
export const calculateMaxPlanets = (astrophysicsLevel: number): number => {
|
||||
// 基础1个星球(主星) + 每级天体物理学增加1个殖民地槽位
|
||||
return 1 + astrophysicsLevel
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查玩家是否可以殖民新星球
|
||||
*/
|
||||
export const canColonize = (player: Player): boolean => {
|
||||
const astrophysicsLevel = player.technologies[TechnologyType.Astrophysics] || 0
|
||||
const maxPlanets = calculateMaxPlanets(astrophysicsLevel)
|
||||
const currentPlanets = player.planets.length
|
||||
return currentPlanets < maxPlanets
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理殖民任务到达
|
||||
*/
|
||||
export const processColonizeArrival = (
|
||||
mission: FleetMission,
|
||||
targetPlanet: Planet | undefined,
|
||||
playerId: string,
|
||||
player: Player,
|
||||
colonyNameTemplate: string = 'Colony'
|
||||
): Planet | null => {
|
||||
if (targetPlanet) {
|
||||
@@ -192,11 +348,18 @@ export const processColonizeArrival = (
|
||||
return null
|
||||
}
|
||||
|
||||
// 检查殖民地槽位限制
|
||||
if (!canColonize(player)) {
|
||||
// 超出殖民地数量限制,殖民船返回
|
||||
mission.status = 'returning'
|
||||
return null
|
||||
}
|
||||
|
||||
// 创建新殖民地
|
||||
const newPlanet: Planet = {
|
||||
id: `planet_${Date.now()}`,
|
||||
name: `${colonyNameTemplate} ${mission.targetPosition.galaxy}:${mission.targetPosition.system}:${mission.targetPosition.position}`,
|
||||
ownerId: playerId,
|
||||
ownerId: player.id,
|
||||
position: mission.targetPosition,
|
||||
resources: { metal: 500, crystal: 500, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
buildings: {} as Record<BuildingType, number>,
|
||||
@@ -205,11 +368,15 @@ export const processColonizeArrival = (
|
||||
[ShipType.HeavyFighter]: 0,
|
||||
[ShipType.Cruiser]: 0,
|
||||
[ShipType.Battleship]: 0,
|
||||
[ShipType.Battlecruiser]: 0,
|
||||
[ShipType.Bomber]: 0,
|
||||
[ShipType.Destroyer]: 0,
|
||||
[ShipType.SmallCargo]: 0,
|
||||
[ShipType.LargeCargo]: 0,
|
||||
[ShipType.ColonyShip]: 0,
|
||||
[ShipType.Recycler]: 0,
|
||||
[ShipType.EspionageProbe]: 0,
|
||||
[ShipType.SolarSatellite]: 0,
|
||||
[ShipType.DarkMatterHarvester]: 0,
|
||||
[ShipType.Deathstar]: 0
|
||||
},
|
||||
@@ -222,6 +389,8 @@ export const processColonizeArrival = (
|
||||
[DefenseType.PlasmaTurret]: 0,
|
||||
[DefenseType.SmallShieldDome]: 0,
|
||||
[DefenseType.LargeShieldDome]: 0,
|
||||
[DefenseType.AntiBallisticMissile]: 0,
|
||||
[DefenseType.InterplanetaryMissile]: 0,
|
||||
[DefenseType.PlanetaryShield]: 0
|
||||
},
|
||||
buildQueue: [],
|
||||
@@ -242,27 +411,105 @@ export const processColonizeArrival = (
|
||||
return newPlanet
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算间谍侦查信息可见度
|
||||
* 根据双方间谍技术等级差异决定显示哪些信息
|
||||
*/
|
||||
export const calculateSpyVisibility = (
|
||||
attackerSpyLevel: number,
|
||||
defenderSpyLevel: number,
|
||||
spyProbeCount: number
|
||||
): {
|
||||
showFleet: boolean
|
||||
showDefense: boolean
|
||||
showBuildings: boolean
|
||||
showTechnologies: boolean
|
||||
} => {
|
||||
// 技术等级差异 (考虑间谍探测器数量加成)
|
||||
const levelDiff = attackerSpyLevel - defenderSpyLevel + Math.floor(spyProbeCount / 5)
|
||||
|
||||
return {
|
||||
showFleet: levelDiff >= -1, // Level 2: Resources + fleet
|
||||
showDefense: levelDiff >= 1, // Level 4: Resources + fleet + defense
|
||||
showBuildings: levelDiff >= 3, // Level 6: Resources + fleet + defense + buildings
|
||||
showTechnologies: levelDiff >= 5 // Level 8: Resources + fleet + defense + buildings + technologies
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算间谍侦查被发现概率
|
||||
*/
|
||||
export const calculateSpyDetectionChance = (attackerSpyLevel: number, defenderSpyLevel: number, spyProbeCount: number): number => {
|
||||
// 基础被发现概率
|
||||
let baseChance = 0.25
|
||||
|
||||
// 技术等级差异影响
|
||||
const levelDiff = defenderSpyLevel - attackerSpyLevel
|
||||
if (levelDiff > 0) {
|
||||
baseChance += levelDiff * 0.1 // 防守方技术高,增加被发现概率
|
||||
} else {
|
||||
baseChance += levelDiff * 0.05 // 攻击方技术高,减少被发现概率
|
||||
}
|
||||
|
||||
// 间谍探测器数量影响
|
||||
baseChance -= spyProbeCount * 0.01 // 每个探测器降低1%被发现概率
|
||||
|
||||
// 限制在 1% - 99% 之间
|
||||
return Math.max(0.01, Math.min(0.99, baseChance))
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理间谍任务到达
|
||||
*/
|
||||
export const processSpyArrival = (mission: FleetMission, targetPlanet: Planet | undefined, playerId: string): SpyReport | null => {
|
||||
export const processSpyArrival = (
|
||||
mission: FleetMission,
|
||||
targetPlanet: Planet | undefined,
|
||||
attacker: Player,
|
||||
defender: Player | null,
|
||||
allNpcs?: NPC[],
|
||||
locale: Locale = 'zh-CN'
|
||||
): SpyReport | null => {
|
||||
if (!targetPlanet) {
|
||||
mission.status = 'returning'
|
||||
return null
|
||||
}
|
||||
|
||||
// 获取间谍技术等级
|
||||
const attackerSpyLevel = attacker.technologies[TechnologyType.EspionageTechnology] || 0
|
||||
const defenderSpyLevel = defender?.technologies[TechnologyType.EspionageTechnology] || 0
|
||||
const spyProbeCount = mission.fleet[ShipType.EspionageProbe] || 0
|
||||
|
||||
// 计算信息可见度
|
||||
const visibility = calculateSpyVisibility(attackerSpyLevel, defenderSpyLevel, spyProbeCount)
|
||||
|
||||
// 计算被发现概率
|
||||
const detectionChance = calculateSpyDetectionChance(attackerSpyLevel, defenderSpyLevel, spyProbeCount)
|
||||
|
||||
// 判断是否被发现
|
||||
const wasDetected = Math.random() < detectionChance
|
||||
|
||||
const spyReport: SpyReport = {
|
||||
id: `spy_${Date.now()}`,
|
||||
timestamp: Date.now(),
|
||||
spyId: playerId,
|
||||
spyId: attacker.id,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
targetPlanetName: targetPlanet.name,
|
||||
targetPosition: { ...targetPlanet.position },
|
||||
targetPlayerId: targetPlanet.ownerId || 'unknown',
|
||||
resources: { ...targetPlanet.resources },
|
||||
fleet: { ...targetPlanet.fleet },
|
||||
defense: { ...targetPlanet.defense },
|
||||
buildings: { ...targetPlanet.buildings },
|
||||
technologies: {},
|
||||
detectionChance: 0.3
|
||||
resources: { ...targetPlanet.resources }, // 资源信息始终可见
|
||||
fleet: visibility.showFleet ? { ...targetPlanet.fleet } : undefined,
|
||||
defense: visibility.showDefense ? { ...targetPlanet.defense } : undefined,
|
||||
buildings: visibility.showBuildings ? { ...targetPlanet.buildings } : undefined,
|
||||
technologies: visibility.showTechnologies && defender ? { ...defender.technologies } : undefined,
|
||||
detectionChance
|
||||
}
|
||||
|
||||
// 如果目标是NPC星球,调用外交逻辑
|
||||
if (allNpcs && targetPlanet.ownerId) {
|
||||
const targetNpc = allNpcs.find(npc => npc.planets.some(p => p.id === targetPlanet.id))
|
||||
if (targetNpc) {
|
||||
diplomaticLogic.handleSpyReputation(attacker, targetNpc, wasDetected, locale)
|
||||
}
|
||||
}
|
||||
|
||||
mission.status = 'returning'
|
||||
@@ -291,7 +538,10 @@ export const processDeployArrival = (mission: FleetMission, targetPlanet: Planet
|
||||
*/
|
||||
export const processRecycleArrival = (
|
||||
mission: FleetMission,
|
||||
debrisField: DebrisField | undefined
|
||||
debrisField: DebrisField | undefined,
|
||||
player?: Player,
|
||||
allNpcs?: NPC[],
|
||||
locale: Locale = 'zh-CN'
|
||||
): { collectedResources: Pick<Resources, 'metal' | 'crystal'>; remainingDebris: Pick<Resources, 'metal' | 'crystal'> | null } | null => {
|
||||
if (!debrisField) {
|
||||
mission.status = 'returning'
|
||||
@@ -313,6 +563,12 @@ export const processRecycleArrival = (
|
||||
const totalDebris = debrisField.resources.metal + debrisField.resources.crystal
|
||||
const collectedAmount = Math.min(totalDebris, availableCapacity)
|
||||
|
||||
// 防止除零:如果残骸为0,直接返回
|
||||
if (totalDebris === 0) {
|
||||
mission.status = 'returning'
|
||||
return null
|
||||
}
|
||||
|
||||
// 按比例收集金属和晶体
|
||||
const metalRatio = debrisField.resources.metal / totalDebris
|
||||
const crystalRatio = debrisField.resources.crystal / totalDebris
|
||||
@@ -330,6 +586,11 @@ export const processRecycleArrival = (
|
||||
|
||||
mission.status = 'returning'
|
||||
|
||||
// 检查是否在NPC星球位置回收残骸,如果是则降低好感度
|
||||
if (player && allNpcs && collectedAmount > 0) {
|
||||
diplomaticLogic.handleDebrisRecycleReputation(player, debrisField.position, allNpcs, locale)
|
||||
}
|
||||
|
||||
return {
|
||||
collectedResources: {
|
||||
metal: collectedMetal,
|
||||
@@ -348,11 +609,7 @@ export const processRecycleArrival = (
|
||||
/**
|
||||
* 计算行星毁灭概率
|
||||
*/
|
||||
export const calculateDestructionChance = (
|
||||
deathstarCount: number,
|
||||
planetaryShieldCount: number,
|
||||
planetDefensePower: number
|
||||
): number => {
|
||||
export const calculateDestructionChance = (deathstarCount: number, planetaryShieldCount: number, planetDefensePower: number): number => {
|
||||
// 基础摧毁概率:每艘死星 10%
|
||||
let baseChance = deathstarCount * 10
|
||||
|
||||
@@ -372,10 +629,7 @@ export const calculateDestructionChance = (
|
||||
/**
|
||||
* 计算星球总防御力量
|
||||
*/
|
||||
export const calculatePlanetDefensePower = (
|
||||
fleet: Partial<Fleet>,
|
||||
defense: Partial<Record<DefenseType, number>>
|
||||
): number => {
|
||||
export const calculatePlanetDefensePower = (fleet: Partial<Fleet>, defense: Partial<Record<DefenseType, number>>): number => {
|
||||
let totalPower = 0
|
||||
|
||||
// 计算舰队力量
|
||||
@@ -463,7 +717,9 @@ export const updateFleetMissions = async (
|
||||
debrisFields: Map<string, DebrisField>,
|
||||
attacker: Player,
|
||||
defender: Player | null,
|
||||
now: number
|
||||
now: number,
|
||||
allNpcs?: NPC[],
|
||||
locale?: Locale
|
||||
): Promise<{
|
||||
completedMissions: string[]
|
||||
battleReports: BattleResult[]
|
||||
@@ -499,7 +755,7 @@ export const updateFleetMissions = async (
|
||||
|
||||
switch (mission.missionType) {
|
||||
case MissionType.Transport:
|
||||
processTransportArrival(mission, targetPlanet)
|
||||
processTransportArrival(mission, targetPlanet, attacker, allNpcs)
|
||||
break
|
||||
|
||||
case MissionType.Attack: {
|
||||
@@ -513,14 +769,31 @@ export const updateFleetMissions = async (
|
||||
planets.set(moonKey, attackResult.moon)
|
||||
}
|
||||
if (attackResult.debrisField) {
|
||||
// 检查该位置是否已存在残骸场
|
||||
const existingDebris = debrisFields.get(attackResult.debrisField.id)
|
||||
if (existingDebris) {
|
||||
// 累加残骸资源
|
||||
const updatedDebris: DebrisField = {
|
||||
...existingDebris,
|
||||
resources: {
|
||||
metal: existingDebris.resources.metal + attackResult.debrisField.resources.metal,
|
||||
crystal: existingDebris.resources.crystal + attackResult.debrisField.resources.crystal
|
||||
}
|
||||
}
|
||||
debrisFields.set(attackResult.debrisField.id, updatedDebris)
|
||||
updatedDebrisFields.push(updatedDebris)
|
||||
} else {
|
||||
// 新建残骸场
|
||||
debrisFields.set(attackResult.debrisField.id, attackResult.debrisField)
|
||||
newDebrisFields.push(attackResult.debrisField)
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case MissionType.Colonize:
|
||||
const newColony = processColonizeArrival(mission, targetPlanet, attacker.id)
|
||||
const newColony = processColonizeArrival(mission, targetPlanet, attacker)
|
||||
if (newColony) {
|
||||
newColonies.push(newColony)
|
||||
planets.set(targetKey, newColony)
|
||||
@@ -528,7 +801,7 @@ export const updateFleetMissions = async (
|
||||
break
|
||||
|
||||
case MissionType.Spy:
|
||||
const spyReport = processSpyArrival(mission, targetPlanet, attacker.id)
|
||||
const spyReport = processSpyArrival(mission, targetPlanet, attacker, defender)
|
||||
if (spyReport) {
|
||||
spyReports.push(spyReport)
|
||||
}
|
||||
@@ -544,7 +817,7 @@ export const updateFleetMissions = async (
|
||||
case MissionType.Recycle:
|
||||
const debrisId = `debris_${mission.targetPosition.galaxy}_${mission.targetPosition.system}_${mission.targetPosition.position}`
|
||||
const debrisField = debrisFields.get(debrisId)
|
||||
const recycleResult = processRecycleArrival(mission, debrisField)
|
||||
const recycleResult = processRecycleArrival(mission, debrisField, attacker, allNpcs)
|
||||
if (recycleResult) {
|
||||
if (recycleResult.remainingDebris) {
|
||||
// 更新残骸场
|
||||
@@ -567,6 +840,15 @@ export const updateFleetMissions = async (
|
||||
if (destroyResult && destroyResult.success && destroyResult.planetId) {
|
||||
// 星球被摧毁
|
||||
destroyedPlanetIds.push(destroyResult.planetId)
|
||||
|
||||
// 处理外交关系(如果目标是NPC星球)
|
||||
if (targetPlanet && targetPlanet.ownerId && allNpcs && locale) {
|
||||
const planetOwner = allNpcs.find(npc => npc.id === targetPlanet.ownerId)
|
||||
if (planetOwner) {
|
||||
diplomaticLogic.handlePlanetDestructionReputation(attacker, targetPlanet, planetOwner, allNpcs, locale)
|
||||
}
|
||||
}
|
||||
|
||||
planets.delete(targetKey)
|
||||
}
|
||||
break
|
||||
@@ -582,7 +864,17 @@ export const updateFleetMissions = async (
|
||||
}
|
||||
}
|
||||
|
||||
return { completedMissions, battleReports, spyReports, newColonies, newMoons, newDebrisFields, updatedDebrisFields, removedDebrisFieldIds, destroyedPlanetIds }
|
||||
return {
|
||||
completedMissions,
|
||||
battleReports,
|
||||
spyReports,
|
||||
newColonies,
|
||||
newMoons,
|
||||
newDebrisFields,
|
||||
updatedDebrisFields,
|
||||
removedDebrisFieldIds,
|
||||
destroyedPlanetIds
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -30,10 +30,7 @@ export const calculateFleetStorageUsage = (fleet: Fleet): number => {
|
||||
* @param technologies 玩家的科技等级
|
||||
* @returns 最大舰队仓储容量
|
||||
*/
|
||||
export const calculateMaxFleetStorage = (
|
||||
planet: Planet,
|
||||
technologies: Record<TechnologyType, number>
|
||||
): number => {
|
||||
export const calculateMaxFleetStorage = (planet: Planet, technologies: Record<TechnologyType, number>): number => {
|
||||
// 1. 基础仓储
|
||||
let maxStorage = FLEET_STORAGE_CONFIG.baseStorage
|
||||
|
||||
@@ -42,7 +39,12 @@ export const calculateMaxFleetStorage = (
|
||||
const shipyardBonus = BUILDINGS[BuildingType.Shipyard].fleetStorageBonus || 0
|
||||
maxStorage += shipyardLevel * shipyardBonus
|
||||
|
||||
// 3. 计算机技术全局加成
|
||||
// 3. 机库建筑加成(每个星球独立)
|
||||
const hangarLevel = planet.buildings[BuildingType.Hangar] || 0
|
||||
const hangarBonus = BUILDINGS[BuildingType.Hangar].fleetStorageBonus || 0
|
||||
maxStorage += hangarLevel * hangarBonus
|
||||
|
||||
// 4. 计算机技术全局加成
|
||||
const computerTechLevel = technologies[TechnologyType.ComputerTechnology] || 0
|
||||
const computerTechBonus = TECHNOLOGIES[TechnologyType.ComputerTechnology].fleetStorageBonus || 0
|
||||
maxStorage += computerTechLevel * computerTechBonus
|
||||
@@ -78,16 +80,16 @@ export const hasEnoughFleetStorage = (
|
||||
* @param technologies 玩家的科技等级
|
||||
* @returns 最大可建造数量
|
||||
*/
|
||||
export const getMaxBuildableShips = (
|
||||
planet: Planet,
|
||||
shipType: ShipType,
|
||||
technologies: Record<TechnologyType, number>
|
||||
): number => {
|
||||
export const getMaxBuildableShips = (planet: Planet, shipType: ShipType, technologies: Record<TechnologyType, number>): number => {
|
||||
const currentUsage = calculateFleetStorageUsage(planet.fleet)
|
||||
const maxStorage = calculateMaxFleetStorage(planet, technologies)
|
||||
const availableStorage = maxStorage - currentUsage
|
||||
const shipStorageUsage = SHIPS[shipType].storageUsage
|
||||
|
||||
if (shipStorageUsage === 0) return Number.MAX_SAFE_INTEGER
|
||||
|
||||
// 如果当前已经超限(舰队返回等情况),则不允许建造新舰船
|
||||
if (availableStorage <= 0) return 0
|
||||
|
||||
return Math.floor(availableStorage / shipStorageUsage)
|
||||
}
|
||||
|
||||
@@ -19,8 +19,17 @@ export const initializePlayer = (playerId: string, playerName: string = 'Command
|
||||
officers: {} as Record<OfficerType, Officer>,
|
||||
researchQueue: [],
|
||||
fleetMissions: [],
|
||||
missileAttacks: [],
|
||||
battleReports: [],
|
||||
spyReports: [],
|
||||
spiedNotifications: [],
|
||||
npcActivityNotifications: [],
|
||||
missionReports: [],
|
||||
incomingFleetAlerts: [],
|
||||
giftNotifications: [],
|
||||
giftRejectedNotifications: [],
|
||||
diplomaticRelations: {},
|
||||
diplomaticReports: [],
|
||||
points: 0
|
||||
}
|
||||
|
||||
@@ -91,7 +100,8 @@ export const generatePositionKey = (galaxy: number, system: number, position: nu
|
||||
*/
|
||||
export const processGameUpdate = (
|
||||
player: Player,
|
||||
now: number
|
||||
now: number,
|
||||
gameSpeed: number = 1
|
||||
): {
|
||||
updatedResearchQueue: BuildQueueItem[]
|
||||
} => {
|
||||
@@ -105,7 +115,7 @@ export const processGameUpdate = (
|
||||
|
||||
// 更新所有星球资源(直接同步计算,避免 Worker 通信开销)
|
||||
player.planets.forEach(planet => {
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses)
|
||||
resourceLogic.updatePlanetResources(planet, now, bonuses, gameSpeed)
|
||||
})
|
||||
|
||||
// 更新所有星球其他状态
|
||||
|
||||
196
src/logic/missileLogic.ts
Normal file
196
src/logic/missileLogic.ts
Normal file
@@ -0,0 +1,196 @@
|
||||
/**
|
||||
* 导弹系统逻辑
|
||||
* 处理星际导弹攻击、射程计算、拦截等
|
||||
*/
|
||||
|
||||
import type { Planet, MissileAttack, DefenseType, TechnologyType, Position } from '@/types/game'
|
||||
import { DefenseType as DefenseTypes } from '@/types/game'
|
||||
|
||||
/**
|
||||
* 计算导弹射程(基于脉冲引擎等级)
|
||||
* 射程 = 5 * impulseDriveLevel - 1(系统距离)
|
||||
*/
|
||||
export const calculateMissileRange = (impulseDriveLevel: number): number => {
|
||||
if (impulseDriveLevel === 0) return 0
|
||||
return 5 * impulseDriveLevel - 1
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个位置之间的系统距离
|
||||
*/
|
||||
export const calculateSystemDistance = (from: Position, to: Position): number => {
|
||||
// 如果在不同银河系,距离无限大
|
||||
if (from.galaxy !== to.galaxy) {
|
||||
return Infinity
|
||||
}
|
||||
|
||||
// 同一银河系内的系统距离
|
||||
return Math.abs(from.system - to.system)
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查目标是否在射程内
|
||||
*/
|
||||
export const isTargetInRange = (originPosition: Position, targetPosition: Position, impulseDriveLevel: number): boolean => {
|
||||
const range = calculateMissileRange(impulseDriveLevel)
|
||||
const distance = calculateSystemDistance(originPosition, targetPosition)
|
||||
return distance <= range
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算导弹飞行时间(秒)
|
||||
* 基础飞行时间: 30秒 + 60秒/系统距离
|
||||
*/
|
||||
export const calculateMissileFlightTime = (distance: number): number => {
|
||||
return 30 + distance * 60
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建导弹攻击任务
|
||||
*/
|
||||
export const createMissileAttack = (
|
||||
playerId: string,
|
||||
originPlanet: Planet,
|
||||
targetPosition: Position,
|
||||
targetPlanetId: string | undefined,
|
||||
missileCount: number
|
||||
): MissileAttack => {
|
||||
const now = Date.now()
|
||||
const distance = calculateSystemDistance(originPlanet.position, targetPosition)
|
||||
const flightTime = calculateMissileFlightTime(distance) * 1000 // 转换为毫秒
|
||||
|
||||
return {
|
||||
id: `missile_${now}_${playerId}`,
|
||||
playerId,
|
||||
originPlanetId: originPlanet.id,
|
||||
targetPosition,
|
||||
targetPlanetId,
|
||||
missileCount,
|
||||
launchTime: now,
|
||||
arrivalTime: now + flightTime,
|
||||
status: 'flying'
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证导弹发射条件
|
||||
*/
|
||||
export const validateMissileLaunch = (
|
||||
originPlanet: Planet,
|
||||
targetPosition: Position,
|
||||
missileCount: number,
|
||||
technologies: Partial<Record<TechnologyType, number>>
|
||||
): {
|
||||
valid: boolean
|
||||
reason?: string
|
||||
} => {
|
||||
// 检查是否有足够的星际导弹
|
||||
const availableMissiles = originPlanet.defense[DefenseTypes.InterplanetaryMissile] || 0
|
||||
if (availableMissiles < missileCount) {
|
||||
return { valid: false, reason: 'errors.insufficientMissiles' }
|
||||
}
|
||||
|
||||
// 检查发射数量
|
||||
if (missileCount <= 0) {
|
||||
return { valid: false, reason: 'errors.invalidMissileCount' }
|
||||
}
|
||||
|
||||
// 检查射程
|
||||
const impulseDriveLevel = technologies['impulseDrive'] || 0
|
||||
if (!isTargetInRange(originPlanet.position, targetPosition, impulseDriveLevel)) {
|
||||
return { valid: false, reason: 'errors.targetOutOfRange' }
|
||||
}
|
||||
|
||||
// 不能攻击自己的星球
|
||||
if (
|
||||
originPlanet.position.galaxy === targetPosition.galaxy &&
|
||||
originPlanet.position.system === targetPosition.system &&
|
||||
originPlanet.position.position === targetPosition.position
|
||||
) {
|
||||
return { valid: false, reason: 'errors.cannotAttackOwnPlanet' }
|
||||
}
|
||||
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行导弹发射(扣除导弹)
|
||||
*/
|
||||
export const executeMissileLaunch = (planet: Planet, missileCount: number): void => {
|
||||
const currentMissiles = planet.defense[DefenseTypes.InterplanetaryMissile] || 0
|
||||
planet.defense[DefenseTypes.InterplanetaryMissile] = currentMissiles - missileCount
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算导弹攻击结果(考虑拦截)
|
||||
* @returns 实际命中的导弹数量
|
||||
*/
|
||||
export const calculateMissileImpact = (
|
||||
attackingMissiles: number,
|
||||
defenderPlanet: Planet
|
||||
): {
|
||||
missileHits: number
|
||||
missileIntercepted: number
|
||||
defenseLosses: Partial<Record<DefenseType, number>>
|
||||
} => {
|
||||
const antiBallisticMissiles = defenderPlanet.defense[DefenseTypes.AntiBallisticMissile] || 0
|
||||
|
||||
// 反弹道导弹拦截(1:1)
|
||||
const intercepted = Math.min(attackingMissiles, antiBallisticMissiles)
|
||||
const missileHits = attackingMissiles - intercepted
|
||||
|
||||
// 计算防御损失
|
||||
const defenseLosses: Partial<Record<DefenseType, number>> = {}
|
||||
|
||||
// 消耗的反弹道导弹
|
||||
if (intercepted > 0) {
|
||||
defenseLosses[DefenseTypes.AntiBallisticMissile] = intercepted
|
||||
}
|
||||
|
||||
// 如果有导弹命中,随机摧毁防御设施
|
||||
if (missileHits > 0) {
|
||||
const defenseTypes = Object.keys(defenderPlanet.defense) as DefenseType[]
|
||||
const availableDefenses = defenseTypes.filter(type => {
|
||||
// 不能摧毁护盾罩和行星护盾
|
||||
if (type === DefenseTypes.SmallShieldDome || type === DefenseTypes.LargeShieldDome || type === DefenseTypes.PlanetaryShield) {
|
||||
return false
|
||||
}
|
||||
return (defenderPlanet.defense[type] || 0) > 0
|
||||
})
|
||||
|
||||
// 每枚导弹可以摧毁一个防御设施
|
||||
for (let i = 0; i < missileHits && availableDefenses.length > 0; i++) {
|
||||
const randomIndex = Math.floor(Math.random() * availableDefenses.length)
|
||||
const targetDefense = availableDefenses[randomIndex]
|
||||
|
||||
if (targetDefense) {
|
||||
if (!defenseLosses[targetDefense]) {
|
||||
defenseLosses[targetDefense] = 0
|
||||
}
|
||||
defenseLosses[targetDefense]!++
|
||||
|
||||
// 如果该类型防御全部摧毁,从可用列表中移除
|
||||
const remaining = (defenderPlanet.defense[targetDefense] || 0) - (defenseLosses[targetDefense] || 0)
|
||||
if (remaining <= 0) {
|
||||
availableDefenses.splice(randomIndex, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
missileHits,
|
||||
missileIntercepted: intercepted,
|
||||
defenseLosses
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用导弹攻击结果到星球
|
||||
*/
|
||||
export const applyMissileAttackResult = (planet: Planet, defenseLosses: Partial<Record<DefenseType, number>>): void => {
|
||||
for (const [defenseType, lossCount] of Object.entries(defenseLosses)) {
|
||||
const currentCount = planet.defense[defenseType as DefenseType] || 0
|
||||
planet.defense[defenseType as DefenseType] = Math.max(0, currentCount - lossCount)
|
||||
}
|
||||
}
|
||||
@@ -62,11 +62,15 @@ export const tryGenerateMoon = (
|
||||
[ShipType.HeavyFighter]: 0,
|
||||
[ShipType.Cruiser]: 0,
|
||||
[ShipType.Battleship]: 0,
|
||||
[ShipType.Battlecruiser]: 0,
|
||||
[ShipType.Bomber]: 0,
|
||||
[ShipType.Destroyer]: 0,
|
||||
[ShipType.SmallCargo]: 0,
|
||||
[ShipType.LargeCargo]: 0,
|
||||
[ShipType.ColonyShip]: 0,
|
||||
[ShipType.Recycler]: 0,
|
||||
[ShipType.EspionageProbe]: 0,
|
||||
[ShipType.SolarSatellite]: 0,
|
||||
[ShipType.DarkMatterHarvester]: 0,
|
||||
[ShipType.Deathstar]: 0
|
||||
},
|
||||
@@ -79,6 +83,8 @@ export const tryGenerateMoon = (
|
||||
[DefenseType.PlasmaTurret]: 0,
|
||||
[DefenseType.SmallShieldDome]: 0,
|
||||
[DefenseType.LargeShieldDome]: 0,
|
||||
[DefenseType.AntiBallisticMissile]: 0,
|
||||
[DefenseType.InterplanetaryMissile]: 0,
|
||||
[DefenseType.PlanetaryShield]: 0
|
||||
},
|
||||
buildQueue: [],
|
||||
|
||||
1061
src/logic/npcBehaviorLogic.ts
Normal file
1061
src/logic/npcBehaviorLogic.ts
Normal file
@@ -0,0 +1,1061 @@
|
||||
import type { NPC, Planet, Player, FleetMission, SpyReport, SpiedNotification, IncomingFleetAlert, Fleet, DebrisField } from '@/types/game'
|
||||
import { MissionType, ShipType, TechnologyType, RelationStatus } from '@/types/game'
|
||||
import * as fleetLogic from './fleetLogic'
|
||||
import * as diplomaticLogic from './diplomaticLogic'
|
||||
import { DIPLOMATIC_CONFIG } from '@/config/gameConfig'
|
||||
|
||||
/**
|
||||
* NPC行为决策系统
|
||||
*
|
||||
* 流程:
|
||||
* 1. NPC定期侦查玩家星球
|
||||
* 2. 玩家收到"被侦查"通知
|
||||
* 3. 基于侦查结果,NPC决定是否攻击
|
||||
* 4. NPC发起攻击,玩家收到实时警告
|
||||
* 5. NPC检测并回收自己星球附近的残骸
|
||||
* 6. NPC被攻击后会做出防御性反应或反击
|
||||
*/
|
||||
|
||||
// 动态行为配置接口
|
||||
export interface DynamicBehaviorConfig {
|
||||
spyInterval: number
|
||||
attackInterval: number
|
||||
attackProbability: number
|
||||
minSpyProbes: number
|
||||
attackFleetSizeRatio: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据玩家积分计算动态NPC行为配置
|
||||
* 积分越高,NPC越激进
|
||||
*/
|
||||
export const calculateDynamicBehavior = (playerPoints: number): DynamicBehaviorConfig => {
|
||||
if (playerPoints < 1000) {
|
||||
// 新手阶段:NPC很温和
|
||||
return {
|
||||
spyInterval: 2400, // 40分钟侦查一次
|
||||
attackInterval: 4800, // 80分钟攻击一次
|
||||
attackProbability: 0.15, // 15%概率攻击
|
||||
minSpyProbes: 1,
|
||||
attackFleetSizeRatio: 0.3 // 只派30%舰队
|
||||
}
|
||||
} else if (playerPoints < 5000) {
|
||||
// 初级阶段:NPC稍微激进
|
||||
return {
|
||||
spyInterval: 1800, // 30分钟侦查一次
|
||||
attackInterval: 3600, // 60分钟攻击一次
|
||||
attackProbability: 0.25, // 25%概率攻击
|
||||
minSpyProbes: 2,
|
||||
attackFleetSizeRatio: 0.5 // 派50%舰队
|
||||
}
|
||||
} else if (playerPoints < 20000) {
|
||||
// 中级阶段:NPC比较激进
|
||||
return {
|
||||
spyInterval: 1200, // 20分钟侦查一次
|
||||
attackInterval: 2400, // 40分钟攻击一次
|
||||
attackProbability: 0.4, // 40%概率攻击
|
||||
minSpyProbes: 3,
|
||||
attackFleetSizeRatio: 0.7 // 派70%舰队
|
||||
}
|
||||
} else if (playerPoints < 50000) {
|
||||
// 高级阶段:NPC很激进
|
||||
return {
|
||||
spyInterval: 900, // 15分钟侦查一次
|
||||
attackInterval: 1800, // 30分钟攻击一次
|
||||
attackProbability: 0.55, // 55%概率攻击
|
||||
minSpyProbes: 4,
|
||||
attackFleetSizeRatio: 0.85 // 派85%舰队
|
||||
}
|
||||
} else {
|
||||
// 专家阶段:NPC非常激进
|
||||
return {
|
||||
spyInterval: 600, // 10分钟侦查一次
|
||||
attackInterval: 1200, // 20分钟攻击一次
|
||||
attackProbability: 0.7, // 70%概率攻击
|
||||
minSpyProbes: 5,
|
||||
attackFleetSizeRatio: 0.95 // 派95%舰队
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查NPC是否应该侦查玩家
|
||||
*/
|
||||
export const shouldNPCSpyPlayer = (npc: NPC, player: Player, currentTime: number, config: DynamicBehaviorConfig): boolean => {
|
||||
const lastSpyTime = npc.lastSpyTime || 0
|
||||
|
||||
// 检查是否达到侦查间隔
|
||||
if (currentTime - lastSpyTime < config.spyInterval * 1000) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查外交关系 - 根据关系状态调整侦查概率
|
||||
const relation = npc.relations?.[player.id]
|
||||
if (relation) {
|
||||
if (relation.status === RelationStatus.Friendly) {
|
||||
// 友好NPC侦查频率降低到50%
|
||||
return Math.random() < 0.5
|
||||
}
|
||||
if (relation.status === RelationStatus.Hostile) {
|
||||
// 敌对NPC必定侦查
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查NPC是否应该攻击玩家
|
||||
*/
|
||||
export const shouldNPCAttackPlayer = (npc: NPC, player: Player, currentTime: number, config: DynamicBehaviorConfig): boolean => {
|
||||
const lastAttackTime = npc.lastAttackTime || 0
|
||||
|
||||
// 检查是否达到攻击间隔
|
||||
if (currentTime - lastAttackTime < config.attackInterval * 1000) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查外交关系
|
||||
const relation = npc.relations?.[player.id]
|
||||
if (relation) {
|
||||
if (relation.status === RelationStatus.Friendly) {
|
||||
// 友好NPC不攻击玩家
|
||||
return false
|
||||
}
|
||||
if (relation.status === RelationStatus.Hostile) {
|
||||
// 敌对NPC攻击概率翻倍
|
||||
return Math.random() < config.attackProbability * 2.0
|
||||
}
|
||||
}
|
||||
|
||||
// 中立或无关系:正常概率
|
||||
return Math.random() < config.attackProbability
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查NPC是否应该赠送资源给玩家
|
||||
*/
|
||||
export const shouldNPCGiftPlayer = (npc: NPC, player: Player, currentTime: number): boolean => {
|
||||
const { NPC_GIFT_CONFIG } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 检查功能是否启用
|
||||
if (!NPC_GIFT_CONFIG.ENABLED) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查上次赠送时间
|
||||
const lastGiftTime = (npc as any).lastGiftTime || 0
|
||||
if (currentTime - lastGiftTime < NPC_GIFT_CONFIG.CHECK_INTERVAL * 1000) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查NPC对玩家的好感度
|
||||
const relation = npc.relations?.[player.id]
|
||||
if (!relation || relation.reputation < NPC_GIFT_CONFIG.MIN_REPUTATION) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 随机概率
|
||||
return Math.random() < NPC_GIFT_CONFIG.GIFT_PROBABILITY
|
||||
}
|
||||
|
||||
/**
|
||||
* NPC向玩家赠送资源
|
||||
*/
|
||||
export const giftResourcesToPlayer = (npc: NPC, player: Player): void => {
|
||||
const { NPC_GIFT_CONFIG } = DIPLOMATIC_CONFIG
|
||||
|
||||
// 随机生成赠送资源量
|
||||
const giftResources = {
|
||||
metal:
|
||||
Math.floor(Math.random() * (NPC_GIFT_CONFIG.GIFT_AMOUNT.METAL.max - NPC_GIFT_CONFIG.GIFT_AMOUNT.METAL.min + 1)) +
|
||||
NPC_GIFT_CONFIG.GIFT_AMOUNT.METAL.min,
|
||||
crystal:
|
||||
Math.floor(Math.random() * (NPC_GIFT_CONFIG.GIFT_AMOUNT.CRYSTAL.max - NPC_GIFT_CONFIG.GIFT_AMOUNT.CRYSTAL.min + 1)) +
|
||||
NPC_GIFT_CONFIG.GIFT_AMOUNT.CRYSTAL.min,
|
||||
deuterium:
|
||||
Math.floor(Math.random() * (NPC_GIFT_CONFIG.GIFT_AMOUNT.DEUTERIUM.max - NPC_GIFT_CONFIG.GIFT_AMOUNT.DEUTERIUM.min + 1)) +
|
||||
NPC_GIFT_CONFIG.GIFT_AMOUNT.DEUTERIUM.min,
|
||||
darkMatter: 0,
|
||||
energy: 0
|
||||
}
|
||||
|
||||
// 处理赠送
|
||||
diplomaticLogic.handleNPCGiftToPlayer(npc, player, giftResources)
|
||||
|
||||
// 更新上次赠送时间
|
||||
;(npc as any).lastGiftTime = Date.now()
|
||||
}
|
||||
|
||||
/**
|
||||
* 选择NPC的最佳攻击来源星球
|
||||
*/
|
||||
const selectBestNPCPlanet = (npc: NPC, targetPosition: { galaxy: number; system: number; position: number }): Planet | null => {
|
||||
if (npc.planets.length === 0) return null
|
||||
|
||||
// 选择距离最近且有舰队的星球
|
||||
let bestPlanet: Planet | null = null
|
||||
let minDistance = Infinity
|
||||
|
||||
for (const planet of npc.planets) {
|
||||
const distance = fleetLogic.calculateDistance(planet.position, targetPosition)
|
||||
const hasFleet = Object.values(planet.fleet).some(count => (count || 0) > 0)
|
||||
|
||||
if (hasFleet && distance < minDistance) {
|
||||
minDistance = distance
|
||||
bestPlanet = planet
|
||||
}
|
||||
}
|
||||
|
||||
return bestPlanet
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建NPC侦查任务
|
||||
*/
|
||||
export const createNPCSpyMission = (
|
||||
npc: NPC,
|
||||
targetPlanet: Planet,
|
||||
_planets: Planet[],
|
||||
config: DynamicBehaviorConfig
|
||||
): FleetMission | null => {
|
||||
// 选择NPC的最佳星球作为起点
|
||||
const npcPlanet = selectBestNPCPlanet(npc, targetPlanet.position)
|
||||
if (!npcPlanet) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 检查NPC是否有足够的间谍探测器
|
||||
const spyProbes = npcPlanet.fleet[ShipType.EspionageProbe] || 0
|
||||
if (spyProbes < config.minSpyProbes) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 创建侦查舰队
|
||||
const fleet: Partial<Fleet> = {
|
||||
[ShipType.EspionageProbe]: config.minSpyProbes
|
||||
}
|
||||
|
||||
// 从NPC星球扣除舰队
|
||||
npcPlanet.fleet[ShipType.EspionageProbe] = (npcPlanet.fleet[ShipType.EspionageProbe] || 0) - config.minSpyProbes
|
||||
|
||||
// 计算飞行时间
|
||||
const distance = fleetLogic.calculateDistance(npcPlanet.position, targetPlanet.position)
|
||||
const spyProbeSpeed = 100000000 // 间谍探测器速度
|
||||
const flightTime = fleetLogic.calculateFlightTime(distance, spyProbeSpeed)
|
||||
|
||||
const now = Date.now()
|
||||
const mission: FleetMission = {
|
||||
id: `npc-spy-${npc.id}-${now}`,
|
||||
playerId: npc.id,
|
||||
npcId: npc.id,
|
||||
isHostile: true,
|
||||
originPlanetId: npcPlanet.id,
|
||||
targetPosition: targetPlanet.position,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
missionType: MissionType.Spy,
|
||||
fleet,
|
||||
cargo: { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
departureTime: now,
|
||||
arrivalTime: now + flightTime * 1000,
|
||||
status: 'outbound'
|
||||
}
|
||||
|
||||
// 更新NPC的上次侦查时间
|
||||
npc.lastSpyTime = now
|
||||
|
||||
// 添加到NPC任务列表
|
||||
if (!npc.fleetMissions) {
|
||||
npc.fleetMissions = []
|
||||
}
|
||||
npc.fleetMissions.push(mission)
|
||||
|
||||
return mission
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理NPC侦查到达
|
||||
* 返回:被侦查通知(给玩家)和侦查报告(给NPC)
|
||||
*/
|
||||
export const processNPCSpyArrival = (
|
||||
npc: NPC,
|
||||
mission: FleetMission,
|
||||
targetPlanet: Planet,
|
||||
player: Player
|
||||
): { spiedNotification: SpiedNotification; spyReport: SpyReport } => {
|
||||
// 计算侦查等级(基于NPC的间谍科技)
|
||||
const npcSpyTech = npc.technologies[TechnologyType.EspionageTechnology] || 0
|
||||
const playerSpyTech = player.technologies[TechnologyType.EspionageTechnology] || 0
|
||||
const spyProbeCount = mission.fleet[ShipType.EspionageProbe] || 0
|
||||
|
||||
// 计算被发现的概率
|
||||
const detectionChance = Math.max(0, Math.min(100, 50 + (playerSpyTech - npcSpyTech) * 10 - spyProbeCount * 5))
|
||||
const detected = Math.random() * 100 < detectionChance
|
||||
|
||||
// 创建NPC的侦查报告
|
||||
const spyReport: SpyReport = {
|
||||
id: `npc-spy-report-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
spyId: npc.id,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
targetPlanetName: targetPlanet.name,
|
||||
targetPosition: targetPlanet.position,
|
||||
targetPlayerId: player.id,
|
||||
resources: { ...targetPlanet.resources },
|
||||
fleet: npcSpyTech >= 2 ? { ...targetPlanet.fleet } : undefined,
|
||||
defense: npcSpyTech >= 4 ? { ...targetPlanet.defense } : undefined,
|
||||
buildings: npcSpyTech >= 6 ? { ...targetPlanet.buildings } : undefined,
|
||||
technologies: npcSpyTech >= 8 ? { ...player.technologies } : undefined,
|
||||
detectionChance
|
||||
}
|
||||
|
||||
// 保存到NPC的侦查报告
|
||||
if (!npc.playerSpyReports) {
|
||||
npc.playerSpyReports = {}
|
||||
}
|
||||
npc.playerSpyReports[targetPlanet.id] = spyReport
|
||||
|
||||
// 创建被侦查通知(给玩家)
|
||||
const spiedNotification: SpiedNotification = {
|
||||
id: `spied-${mission.id}`,
|
||||
timestamp: Date.now(),
|
||||
npcId: npc.id,
|
||||
npcName: npc.name,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
targetPlanetName: targetPlanet.name,
|
||||
detectionSuccess: detected,
|
||||
read: false
|
||||
}
|
||||
|
||||
// 舰队返回
|
||||
mission.status = 'returning'
|
||||
mission.returnTime = Date.now() + (mission.arrivalTime - mission.departureTime)
|
||||
|
||||
return { spiedNotification, spyReport }
|
||||
}
|
||||
|
||||
/**
|
||||
* 决定NPC攻击舰队组成
|
||||
* 基于侦查报告和NPC实力
|
||||
*/
|
||||
const decideAttackFleet = (_npc: NPC, npcPlanet: Planet, _spyReport: SpyReport, config: DynamicBehaviorConfig): Partial<Fleet> | null => {
|
||||
// 简单策略:派出一定比例的可用舰队
|
||||
const attackFleet: Partial<Fleet> = {}
|
||||
let hasShips = false
|
||||
|
||||
// 优先派出战斗舰船
|
||||
const combatShips = [
|
||||
ShipType.LightFighter,
|
||||
ShipType.HeavyFighter,
|
||||
ShipType.Cruiser,
|
||||
ShipType.Battleship,
|
||||
ShipType.Bomber,
|
||||
ShipType.Destroyer,
|
||||
ShipType.Battlecruiser,
|
||||
ShipType.Deathstar
|
||||
]
|
||||
|
||||
for (const shipType of combatShips) {
|
||||
const available = npcPlanet.fleet[shipType] || 0
|
||||
if (available > 0) {
|
||||
const sendCount = Math.floor(available * config.attackFleetSizeRatio)
|
||||
if (sendCount > 0) {
|
||||
attackFleet[shipType] = sendCount
|
||||
hasShips = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasShips ? attackFleet : null
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建NPC攻击任务
|
||||
*/
|
||||
export const createNPCAttackMission = (
|
||||
npc: NPC,
|
||||
targetPlanet: Planet,
|
||||
spyReport: SpyReport,
|
||||
config: DynamicBehaviorConfig
|
||||
): FleetMission | null => {
|
||||
// 选择NPC的最佳星球作为起点
|
||||
const npcPlanet = selectBestNPCPlanet(npc, targetPlanet.position)
|
||||
if (!npcPlanet) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 决定攻击舰队
|
||||
const attackFleet = decideAttackFleet(npc, npcPlanet, spyReport, config)
|
||||
if (!attackFleet) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 从NPC星球扣除舰队
|
||||
for (const [shipType, count] of Object.entries(attackFleet)) {
|
||||
npcPlanet.fleet[shipType as ShipType] = (npcPlanet.fleet[shipType as ShipType] || 0) - (count as number)
|
||||
}
|
||||
|
||||
// 计算飞行时间
|
||||
const distance = fleetLogic.calculateDistance(npcPlanet.position, targetPlanet.position)
|
||||
// 找出舰队中最慢的船速
|
||||
let minSpeed = Infinity
|
||||
for (const _shipType of Object.keys(attackFleet)) {
|
||||
// 这里简化处理,实际应该从SHIPS配置中获取速度
|
||||
const baseSpeed = 10000 // 简化
|
||||
minSpeed = Math.min(minSpeed, baseSpeed)
|
||||
}
|
||||
const flightTime = fleetLogic.calculateFlightTime(distance, minSpeed)
|
||||
|
||||
const now = Date.now()
|
||||
const mission: FleetMission = {
|
||||
id: `npc-attack-${npc.id}-${now}`,
|
||||
playerId: npc.id,
|
||||
npcId: npc.id,
|
||||
isHostile: true,
|
||||
originPlanetId: npcPlanet.id,
|
||||
targetPosition: targetPlanet.position,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
missionType: MissionType.Attack,
|
||||
fleet: attackFleet,
|
||||
cargo: { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
departureTime: now,
|
||||
arrivalTime: now + flightTime * 1000,
|
||||
status: 'outbound'
|
||||
}
|
||||
|
||||
// 更新NPC的上次攻击时间
|
||||
npc.lastAttackTime = now
|
||||
|
||||
// 添加到NPC任务列表
|
||||
if (!npc.fleetMissions) {
|
||||
npc.fleetMissions = []
|
||||
}
|
||||
npc.fleetMissions.push(mission)
|
||||
|
||||
return mission
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建或更新即将到来的舰队警告
|
||||
*/
|
||||
export const createIncomingFleetAlert = (mission: FleetMission, npc: NPC, targetPlanet: Planet): IncomingFleetAlert => {
|
||||
const fleetSize = Object.values(mission.fleet).reduce((sum, count) => sum + (count || 0), 0)
|
||||
|
||||
return {
|
||||
id: mission.id,
|
||||
npcId: npc.id,
|
||||
npcName: npc.name,
|
||||
missionType: mission.missionType,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
targetPlanetName: targetPlanet.name,
|
||||
arrivalTime: mission.arrivalTime,
|
||||
fleetSize,
|
||||
read: false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新玩家的即将到来的舰队警告
|
||||
* 删除已到达或已返回的任务警告
|
||||
*/
|
||||
export const updateIncomingFleetAlerts = (player: Player, currentTime: number): void => {
|
||||
if (!player.incomingFleetAlerts) {
|
||||
player.incomingFleetAlerts = []
|
||||
}
|
||||
|
||||
// 删除已过期的警告(舰队已到达)
|
||||
player.incomingFleetAlerts = player.incomingFleetAlerts.filter(alert => alert.arrivalTime > currentTime)
|
||||
}
|
||||
|
||||
/**
|
||||
* NPC主动行为主更新函数
|
||||
* 应该在游戏循环中定期调用
|
||||
*/
|
||||
export const updateNPCBehavior = (
|
||||
npc: NPC,
|
||||
player: Player,
|
||||
allPlanets: Planet[],
|
||||
debrisFields: Record<string, DebrisField>,
|
||||
currentTime: number
|
||||
): void => {
|
||||
// 根据玩家积分计算动态行为配置
|
||||
const config = calculateDynamicBehavior(player.points)
|
||||
|
||||
// 1. 检查并回收附近的残骸(优先级最高)
|
||||
const nearbyDebris = findNearbyDebris(npc, debrisFields)
|
||||
if (nearbyDebris.length > 0) {
|
||||
// 检查是否已经有正在执行的回收任务
|
||||
const activeRecycleMissions = npc.fleetMissions?.filter(m => m.missionType === MissionType.Recycle && m.status === 'outbound') || []
|
||||
const activeDebrisIds = new Set(activeRecycleMissions.map(m => m.debrisFieldId).filter(Boolean))
|
||||
|
||||
// 找到还没有被回收的残骸
|
||||
const availableDebris = nearbyDebris.filter(d => !activeDebrisIds.has(d.id))
|
||||
|
||||
if (availableDebris.length > 0) {
|
||||
// 随机选择一个残骸场进行回收
|
||||
const targetDebris = availableDebris[Math.floor(Math.random() * availableDebris.length)]
|
||||
if (targetDebris) {
|
||||
createNPCRecycleMission(npc, targetDebris, player, allPlanets)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 检查是否应该反击(优先于普通攻击)
|
||||
if (shouldNPCRevenge(npc, currentTime)) {
|
||||
const revengeMission = createNPCRevengeMission(npc, allPlanets, config)
|
||||
if (revengeMission) {
|
||||
// 找到目标星球创建警告
|
||||
const targetPlanet = allPlanets.find(p => p.id === revengeMission.targetPlanetId)
|
||||
if (targetPlanet) {
|
||||
const alert = createIncomingFleetAlert(revengeMission, npc, targetPlanet)
|
||||
if (!player.incomingFleetAlerts) {
|
||||
player.incomingFleetAlerts = []
|
||||
}
|
||||
player.incomingFleetAlerts.push(alert)
|
||||
}
|
||||
// 反击后跳过普通攻击
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 检查是否应该侦查玩家
|
||||
if (shouldNPCSpyPlayer(npc, player, currentTime, config)) {
|
||||
// 随机选择一个玩家星球进行侦查
|
||||
const playerPlanets = allPlanets.filter(p => p.ownerId === player.id)
|
||||
if (playerPlanets.length > 0) {
|
||||
const targetPlanet = playerPlanets[Math.floor(Math.random() * playerPlanets.length)]
|
||||
if (!targetPlanet) {
|
||||
return
|
||||
}
|
||||
|
||||
const spyMission = createNPCSpyMission(npc, targetPlanet, allPlanets, config)
|
||||
|
||||
if (spyMission) {
|
||||
// 创建即将到来的舰队警告
|
||||
const alert = createIncomingFleetAlert(spyMission, npc, targetPlanet)
|
||||
if (!player.incomingFleetAlerts) {
|
||||
player.incomingFleetAlerts = []
|
||||
}
|
||||
player.incomingFleetAlerts.push(alert)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 检查是否应该攻击玩家
|
||||
if (shouldNPCAttackPlayer(npc, player, currentTime, config)) {
|
||||
// 检查是否有最近的侦查报告
|
||||
if (npc.playerSpyReports && Object.keys(npc.playerSpyReports).length > 0) {
|
||||
// 选择一个侦查过的星球进行攻击
|
||||
const spyReports = Object.values(npc.playerSpyReports)
|
||||
const recentReport = spyReports[Math.floor(Math.random() * spyReports.length)]
|
||||
|
||||
// 确保找到了侦查报告
|
||||
if (!recentReport) {
|
||||
return
|
||||
}
|
||||
|
||||
// 找到目标星球
|
||||
const targetPlanet = allPlanets.find(p => p.id === recentReport.targetPlanetId)
|
||||
if (targetPlanet) {
|
||||
const attackMission = createNPCAttackMission(npc, targetPlanet, recentReport, config)
|
||||
|
||||
if (attackMission) {
|
||||
// 创建即将到来的舰队警告
|
||||
const alert = createIncomingFleetAlert(attackMission, npc, targetPlanet)
|
||||
if (!player.incomingFleetAlerts) {
|
||||
player.incomingFleetAlerts = []
|
||||
}
|
||||
player.incomingFleetAlerts.push(alert)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 检查是否应该赠送资源给玩家(仅友好NPC)
|
||||
if (shouldNPCGiftPlayer(npc, player, currentTime)) {
|
||||
giftResourcesToPlayer(npc, player)
|
||||
}
|
||||
|
||||
// 6. 更新即将到来的舰队警告(删除过期的)
|
||||
updateIncomingFleetAlerts(player, currentTime)
|
||||
}
|
||||
|
||||
// ========== 测试辅助函数 ==========
|
||||
|
||||
/**
|
||||
* 测试函数:强制NPC立即侦查玩家
|
||||
* 用于开发和测试
|
||||
*/
|
||||
export const forceNPCSpyPlayer = (npc: NPC, player: Player, allPlanets: Planet[], targetPlanetIndex = 0): FleetMission | null => {
|
||||
const config = calculateDynamicBehavior(player.points)
|
||||
|
||||
// 选择目标星球
|
||||
const playerPlanets = allPlanets.filter(p => p.ownerId === player.id)
|
||||
if (playerPlanets.length === 0) {
|
||||
console.error('[Test] No player planets found')
|
||||
return null
|
||||
}
|
||||
|
||||
const targetPlanet = playerPlanets[targetPlanetIndex] || playerPlanets[0]
|
||||
if (!targetPlanet) {
|
||||
console.error('[Test] Target planet not found')
|
||||
return null
|
||||
}
|
||||
|
||||
// 创建侦查任务
|
||||
const spyMission = createNPCSpyMission(npc, targetPlanet, allPlanets, config)
|
||||
|
||||
if (spyMission) {
|
||||
// 创建即将到来的舰队警告
|
||||
const alert = createIncomingFleetAlert(spyMission, npc, targetPlanet)
|
||||
if (!player.incomingFleetAlerts) {
|
||||
player.incomingFleetAlerts = []
|
||||
}
|
||||
player.incomingFleetAlerts.push(alert)
|
||||
} else {
|
||||
console.error('[Test] Failed to create spy mission - NPC may not have spy probes')
|
||||
}
|
||||
|
||||
return spyMission
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试函数:强制NPC立即攻击玩家
|
||||
* 需要先有侦查报告
|
||||
*/
|
||||
export const forceNPCAttackPlayer = (npc: NPC, player: Player, allPlanets: Planet[], targetPlanetIndex = 0): FleetMission | null => {
|
||||
const config = calculateDynamicBehavior(player.points)
|
||||
|
||||
// 检查是否有侦查报告
|
||||
if (!npc.playerSpyReports || Object.keys(npc.playerSpyReports).length === 0) {
|
||||
console.error('[Test] No spy reports available - NPC must spy first!')
|
||||
return null
|
||||
}
|
||||
|
||||
// 选择目标星球
|
||||
const playerPlanets = allPlanets.filter(p => p.ownerId === player.id)
|
||||
if (playerPlanets.length === 0) {
|
||||
console.error('[Test] No player planets found')
|
||||
return null
|
||||
}
|
||||
|
||||
const targetPlanet = playerPlanets[targetPlanetIndex] || playerPlanets[0]
|
||||
if (!targetPlanet) {
|
||||
console.error('[Test] Target planet not found')
|
||||
return null
|
||||
}
|
||||
|
||||
// 获取该星球的侦查报告
|
||||
const spyReport = npc.playerSpyReports[targetPlanet.id]
|
||||
if (!spyReport) {
|
||||
console.error(`[Test] No spy report for ${targetPlanet.name} - spy this planet first!`)
|
||||
return null
|
||||
}
|
||||
|
||||
// 创建攻击任务
|
||||
const attackMission = createNPCAttackMission(npc, targetPlanet, spyReport, config)
|
||||
|
||||
if (attackMission) {
|
||||
// 创建即将到来的舰队警告
|
||||
const alert = createIncomingFleetAlert(attackMission, npc, targetPlanet)
|
||||
if (!player.incomingFleetAlerts) {
|
||||
player.incomingFleetAlerts = []
|
||||
}
|
||||
player.incomingFleetAlerts.push(alert)
|
||||
} else {
|
||||
console.error('[Test] Failed to create attack mission - NPC may not have ships')
|
||||
}
|
||||
|
||||
return attackMission
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试函数:强制NPC先侦查再攻击
|
||||
* 一步到位的测试函数
|
||||
*/
|
||||
export const forceNPCSpyAndAttack = (
|
||||
npc: NPC,
|
||||
player: Player,
|
||||
allPlanets: Planet[],
|
||||
targetPlanetIndex = 0
|
||||
): { spyMission: FleetMission | null; attackMission: FleetMission | null } => {
|
||||
// 1. 先侦查
|
||||
const spyMission = forceNPCSpyPlayer(npc, player, allPlanets, targetPlanetIndex)
|
||||
|
||||
if (!spyMission) {
|
||||
return { spyMission: null, attackMission: null }
|
||||
}
|
||||
|
||||
// 2. 模拟侦查到达,立即生成侦查报告
|
||||
const playerPlanets = allPlanets.filter(p => p.ownerId === player.id)
|
||||
const targetPlanet = playerPlanets[targetPlanetIndex] || playerPlanets[0]
|
||||
if (!targetPlanet) {
|
||||
console.error('[Test] Target planet not found')
|
||||
return { spyMission, attackMission: null }
|
||||
}
|
||||
|
||||
const { spyReport, spiedNotification } = processNPCSpyArrival(npc, spyMission, targetPlanet, player)
|
||||
|
||||
// 保存侦查报告到NPC
|
||||
if (!npc.playerSpyReports) {
|
||||
npc.playerSpyReports = {}
|
||||
}
|
||||
npc.playerSpyReports[targetPlanet.id] = spyReport
|
||||
|
||||
// 添加被侦查通知给玩家
|
||||
if (!player.spiedNotifications) {
|
||||
player.spiedNotifications = []
|
||||
}
|
||||
player.spiedNotifications.push(spiedNotification)
|
||||
|
||||
// 3. 立即发起攻击
|
||||
const attackMission = forceNPCAttackPlayer(npc, player, allPlanets, targetPlanetIndex)
|
||||
|
||||
return { spyMission, attackMission }
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试函数:加速舰队任务到达时间
|
||||
* 将任务的到达时间设置为现在+指定秒数
|
||||
*/
|
||||
export const accelerateNPCMission = (npc: NPC, missionId: string, arriveInSeconds = 5, player?: Player): boolean => {
|
||||
if (!npc.fleetMissions) {
|
||||
console.error('[Test] NPC has no fleet missions')
|
||||
return false
|
||||
}
|
||||
|
||||
const mission = npc.fleetMissions.find(m => m.id === missionId)
|
||||
if (!mission) {
|
||||
console.error('[Test] Mission not found')
|
||||
return false
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
const flightTime = arriveInSeconds * 1000 // 飞行时间(毫秒)
|
||||
|
||||
// 同时修改 departureTime 和 arrivalTime,保持飞行时间为指定秒数
|
||||
mission.departureTime = now
|
||||
mission.arrivalTime = now + flightTime
|
||||
|
||||
// 同时更新对应的 IncomingFleetAlert
|
||||
if (player && player.incomingFleetAlerts) {
|
||||
const alert = player.incomingFleetAlerts.find(a => a.id === missionId)
|
||||
if (alert) {
|
||||
alert.arrivalTime = mission.arrivalTime
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试函数:加速所有NPC舰队任务
|
||||
*/
|
||||
export const accelerateAllNPCMissions = (npc: NPC, arriveInSeconds = 5, player?: Player): number => {
|
||||
if (!npc.fleetMissions) {
|
||||
console.error('[Test] NPC has no fleet missions')
|
||||
return 0
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
const flightTime = arriveInSeconds * 1000
|
||||
let count = 0
|
||||
|
||||
npc.fleetMissions.forEach(mission => {
|
||||
if (mission.status === 'outbound') {
|
||||
// 同时修改 departureTime 和 arrivalTime
|
||||
mission.departureTime = now
|
||||
mission.arrivalTime = now + flightTime
|
||||
|
||||
// 同时更新对应的 IncomingFleetAlert
|
||||
if (player && player.incomingFleetAlerts) {
|
||||
const alert = player.incomingFleetAlerts.find(a => a.id === mission.id)
|
||||
if (alert) {
|
||||
alert.arrivalTime = mission.arrivalTime
|
||||
}
|
||||
}
|
||||
|
||||
count++
|
||||
} else if (mission.status === 'returning' && mission.returnTime) {
|
||||
// 对于返回任务,保持原来的逻辑
|
||||
mission.returnTime = now + flightTime
|
||||
count++
|
||||
}
|
||||
})
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查NPC星球附近是否有残骸场
|
||||
* 返回NPC可以回收的残骸场列表
|
||||
* NPC会主动寻找同一星系内的残骸进行回收
|
||||
*/
|
||||
export const findNearbyDebris = (npc: NPC, debrisFields: Record<string, DebrisField>): DebrisField[] => {
|
||||
const nearbyDebris: DebrisField[] = []
|
||||
|
||||
for (const debris of Object.values(debrisFields)) {
|
||||
// 检查残骸是否在NPC的星球附近(同一星系内)
|
||||
for (const npcPlanet of npc.planets) {
|
||||
if (debris.position.galaxy === npcPlanet.position.galaxy && debris.position.system === npcPlanet.position.system) {
|
||||
// 检查残骸是否有足够资源值得回收(至少1000金属或水晶)
|
||||
if (debris.resources.metal > 1000 || debris.resources.crystal > 1000) {
|
||||
// 计算距离,确保不会太远(最多在同一星系内)
|
||||
const distance = Math.abs(debris.position.position - npcPlanet.position.position)
|
||||
if (distance <= 15) {
|
||||
// 同一星系内最多15个位置
|
||||
nearbyDebris.push(debris)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nearbyDebris
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建NPC回收残骸任务
|
||||
*/
|
||||
export const createNPCRecycleMission = (npc: NPC, debris: DebrisField, player: Player, allPlanets: Planet[]): FleetMission | null => {
|
||||
// 找到离残骸最近的NPC星球
|
||||
let closestPlanet: Planet | null = null
|
||||
let minDistance = Infinity
|
||||
|
||||
for (const npcPlanet of npc.planets) {
|
||||
if (npcPlanet.position.galaxy === debris.position.galaxy && npcPlanet.position.system === debris.position.system) {
|
||||
const distance = Math.abs(npcPlanet.position.position - debris.position.position)
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance
|
||||
closestPlanet = npcPlanet
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!closestPlanet) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 检查NPC是否有回收船
|
||||
const recyclers = closestPlanet.fleet[ShipType.Recycler] || 0
|
||||
if (recyclers === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 计算需要多少回收船(每艘回收船容量20000)
|
||||
const totalDebris = debris.resources.metal + debris.resources.crystal
|
||||
const recyclersNeeded = Math.min(Math.ceil(totalDebris / 20000), recyclers)
|
||||
|
||||
// 创建回收舰队
|
||||
const fleet: Partial<Fleet> = {
|
||||
[ShipType.Recycler]: recyclersNeeded
|
||||
}
|
||||
|
||||
// 从NPC星球扣除舰队
|
||||
closestPlanet.fleet[ShipType.Recycler] = recyclers - recyclersNeeded
|
||||
|
||||
// 计算飞行时间
|
||||
const distance = fleetLogic.calculateDistance(closestPlanet.position, debris.position)
|
||||
const recyclerSpeed = 2000 // 回收船基础速度
|
||||
const flightTime = fleetLogic.calculateFlightTime(distance, recyclerSpeed)
|
||||
|
||||
const now = Date.now()
|
||||
const mission: FleetMission = {
|
||||
id: `npc-recycle-${npc.id}-${now}`,
|
||||
playerId: npc.id,
|
||||
npcId: npc.id,
|
||||
isHostile: false,
|
||||
originPlanetId: closestPlanet.id,
|
||||
targetPosition: debris.position,
|
||||
debrisFieldId: debris.id,
|
||||
missionType: MissionType.Recycle,
|
||||
fleet,
|
||||
cargo: { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
departureTime: now,
|
||||
arrivalTime: now + flightTime * 1000,
|
||||
status: 'outbound'
|
||||
}
|
||||
|
||||
// 添加到NPC任务列表
|
||||
if (!npc.fleetMissions) {
|
||||
npc.fleetMissions = []
|
||||
}
|
||||
npc.fleetMissions.push(mission)
|
||||
|
||||
// 检查残骸位置是否有玩家星球,如果有则发送警告
|
||||
const playerPlanetAtDebris = allPlanets.find(
|
||||
p =>
|
||||
p.ownerId === player.id &&
|
||||
p.position.galaxy === debris.position.galaxy &&
|
||||
p.position.system === debris.position.system &&
|
||||
p.position.position === debris.position.position
|
||||
)
|
||||
|
||||
if (playerPlanetAtDebris) {
|
||||
// 创建即将到来的舰队警告(非敌对)
|
||||
const alert = createIncomingFleetAlert(mission, npc, playerPlanetAtDebris)
|
||||
if (!player.incomingFleetAlerts) {
|
||||
player.incomingFleetAlerts = []
|
||||
}
|
||||
player.incomingFleetAlerts.push(alert)
|
||||
|
||||
// 创建NPC活动通知
|
||||
if (!player.npcActivityNotifications) {
|
||||
player.npcActivityNotifications = []
|
||||
}
|
||||
player.npcActivityNotifications.push({
|
||||
id: `npc-activity-${mission.id}`,
|
||||
timestamp: now,
|
||||
npcId: npc.id,
|
||||
npcName: npc.name,
|
||||
activityType: 'recycle',
|
||||
targetPosition: debris.position,
|
||||
targetPlanetId: playerPlanetAtDebris.id,
|
||||
targetPlanetName: playerPlanetAtDebris.name,
|
||||
arrivalTime: mission.arrivalTime,
|
||||
read: false
|
||||
})
|
||||
}
|
||||
|
||||
return mission
|
||||
}
|
||||
|
||||
/**
|
||||
* NPC被攻击后的反应
|
||||
* 记录攻击者,并根据情况决定是否反击或加强防御
|
||||
*/
|
||||
export const handleNPCAttacked = (npc: NPC, attackerId: string, attackerPlanetId: string | undefined): void => {
|
||||
// 初始化被攻击记录
|
||||
if (!npc.attackedBy) {
|
||||
npc.attackedBy = {}
|
||||
}
|
||||
|
||||
// 记录攻击者和被攻击次数
|
||||
if (!npc.attackedBy[attackerId]) {
|
||||
npc.attackedBy[attackerId] = {
|
||||
count: 0,
|
||||
lastAttackTime: 0,
|
||||
planetId: attackerPlanetId
|
||||
}
|
||||
}
|
||||
npc.attackedBy[attackerId].count++
|
||||
npc.attackedBy[attackerId].lastAttackTime = Date.now()
|
||||
if (attackerPlanetId) {
|
||||
npc.attackedBy[attackerId].planetId = attackerPlanetId
|
||||
}
|
||||
|
||||
// 设置警戒状态(被攻击后1小时内保持警戒)
|
||||
npc.alertUntil = Date.now() + 3600 * 1000
|
||||
|
||||
// 如果被同一个玩家攻击超过3次,标记为高优先级反击目标
|
||||
if (npc.attackedBy[attackerId].count >= 3) {
|
||||
npc.revengeTarget = attackerId
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查NPC是否应该反击
|
||||
*/
|
||||
export const shouldNPCRevenge = (npc: NPC, currentTime: number): boolean => {
|
||||
// 如果没有复仇目标,不反击
|
||||
if (!npc.revengeTarget || !npc.attackedBy) {
|
||||
return false
|
||||
}
|
||||
|
||||
const attackRecord = npc.attackedBy[npc.revengeTarget]
|
||||
if (!attackRecord) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 被攻击后24小时内可以反击
|
||||
const timeSinceLastAttack = currentTime - attackRecord.lastAttackTime
|
||||
if (timeSinceLastAttack > 24 * 3600 * 1000) {
|
||||
return false
|
||||
}
|
||||
|
||||
// 至少等待10分钟后再反击(给NPC时间准备)
|
||||
if (timeSinceLastAttack < 600 * 1000) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建NPC反击任务
|
||||
*/
|
||||
export const createNPCRevengeMission = (npc: NPC, allPlanets: Planet[], config: DynamicBehaviorConfig): FleetMission | null => {
|
||||
if (!npc.revengeTarget || !npc.attackedBy) {
|
||||
return null
|
||||
}
|
||||
|
||||
const attackRecord = npc.attackedBy[npc.revengeTarget]
|
||||
if (!attackRecord || !attackRecord.planetId) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 找到攻击者的星球
|
||||
const targetPlanet = allPlanets.find(p => p.id === attackRecord.planetId)
|
||||
if (!targetPlanet) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 选择NPC的最佳星球作为起点
|
||||
const npcPlanet = selectBestNPCPlanet(npc, targetPlanet.position)
|
||||
if (!npcPlanet) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 反击时派出更多舰队(比正常攻击多50%)
|
||||
const revengeFleet = decideAttackFleet(npc, npcPlanet, {} as SpyReport, {
|
||||
...config,
|
||||
attackFleetSizeRatio: Math.min(1.0, config.attackFleetSizeRatio * 1.5)
|
||||
})
|
||||
|
||||
if (!revengeFleet) {
|
||||
return null
|
||||
}
|
||||
|
||||
// 从NPC星球扣除舰队
|
||||
for (const [shipType, count] of Object.entries(revengeFleet)) {
|
||||
npcPlanet.fleet[shipType as ShipType] = (npcPlanet.fleet[shipType as ShipType] || 0) - (count as number)
|
||||
}
|
||||
|
||||
// 计算飞行时间
|
||||
const distance = fleetLogic.calculateDistance(npcPlanet.position, targetPlanet.position)
|
||||
let minSpeed = Infinity
|
||||
for (const _shipType of Object.keys(revengeFleet)) {
|
||||
const baseSpeed = 10000
|
||||
minSpeed = Math.min(minSpeed, baseSpeed)
|
||||
}
|
||||
const flightTime = fleetLogic.calculateFlightTime(distance, minSpeed)
|
||||
|
||||
const now = Date.now()
|
||||
const mission: FleetMission = {
|
||||
id: `npc-revenge-${npc.id}-${now}`,
|
||||
playerId: npc.id,
|
||||
npcId: npc.id,
|
||||
isHostile: true,
|
||||
originPlanetId: npcPlanet.id,
|
||||
targetPosition: targetPlanet.position,
|
||||
targetPlanetId: targetPlanet.id,
|
||||
missionType: MissionType.Attack,
|
||||
fleet: revengeFleet,
|
||||
cargo: { metal: 0, crystal: 0, deuterium: 0, darkMatter: 0, energy: 0 },
|
||||
departureTime: now,
|
||||
arrivalTime: now + flightTime * 1000,
|
||||
status: 'outbound'
|
||||
}
|
||||
|
||||
// 添加到NPC任务列表
|
||||
if (!npc.fleetMissions) {
|
||||
npc.fleetMissions = []
|
||||
}
|
||||
npc.fleetMissions.push(mission)
|
||||
|
||||
// 清除复仇目标(已经反击)
|
||||
npc.revengeTarget = undefined
|
||||
|
||||
return mission
|
||||
}
|
||||
586
src/logic/npcGrowthLogic.ts
Normal file
586
src/logic/npcGrowthLogic.ts
Normal file
@@ -0,0 +1,586 @@
|
||||
import type { NPC, Planet, Player } from '@/types/game'
|
||||
import { TechnologyType, BuildingType, ShipType } from '@/types/game'
|
||||
import { BUILDINGS, SHIPS, TECHNOLOGIES } from '@/config/gameConfig'
|
||||
import * as buildingLogic from './buildingLogic'
|
||||
import * as researchLogic from './researchLogic'
|
||||
|
||||
/**
|
||||
* NPC成长系统
|
||||
*
|
||||
* 策略说明:
|
||||
* - Easy: NPC实力保持在玩家平均实力的60%左右,被动成长
|
||||
* - Medium: NPC实力保持在玩家平均实力的80%左右,半主动成长
|
||||
* - Hard: NPC实力保持在玩家平均实力的100-120%,主动成长
|
||||
*/
|
||||
|
||||
// 简化的游戏状态接口(用于NPC成长系统)
|
||||
export interface NPCGrowthGameState {
|
||||
planets: Planet[] // 所有星球(包括玩家和NPC的)
|
||||
player: Player // 玩家数据
|
||||
npcs: NPC[] // 所有NPC
|
||||
}
|
||||
|
||||
// NPC成长配置(旧版,保留用于兼容)
|
||||
export const NPC_GROWTH_CONFIG = {
|
||||
easy: {
|
||||
powerRatio: 0.6, // 实力比例(相对玩家)
|
||||
checkInterval: 300, // 检查间隔(秒) - 5分钟
|
||||
resourceGrowthRate: 0.5, // 资源增长速率系数
|
||||
buildingGrowthSpeed: 0.5, // 建筑升级速度系数
|
||||
techGrowthSpeed: 0.5 // 科技研究速度系数
|
||||
},
|
||||
medium: {
|
||||
powerRatio: 0.8,
|
||||
checkInterval: 180, // 3分钟
|
||||
resourceGrowthRate: 0.8,
|
||||
buildingGrowthSpeed: 0.8,
|
||||
techGrowthSpeed: 0.8
|
||||
},
|
||||
hard: {
|
||||
powerRatio: 1.1,
|
||||
checkInterval: 120, // 2分钟
|
||||
resourceGrowthRate: 1.2,
|
||||
buildingGrowthSpeed: 1.0,
|
||||
techGrowthSpeed: 1.0
|
||||
}
|
||||
} as const
|
||||
|
||||
// 动态难度配置(基于玩家积分)
|
||||
export interface DynamicDifficultyConfig {
|
||||
powerRatio: number
|
||||
checkInterval: number
|
||||
resourceGrowthRate: number
|
||||
buildingGrowthSpeed: number
|
||||
techGrowthSpeed: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据玩家积分计算动态难度配置
|
||||
*/
|
||||
export const calculateDynamicDifficulty = (playerPoints: number): DynamicDifficultyConfig => {
|
||||
// 积分区间和对应的难度参数
|
||||
if (playerPoints < 1000) {
|
||||
// 新手期:0-1,000分
|
||||
// NPC保持30-50%实力,给予充分发展空间,但资源增长速度加快
|
||||
const ratio = 0.3 + (playerPoints / 1000) * 0.2
|
||||
return {
|
||||
powerRatio: ratio,
|
||||
checkInterval: 300, // 5分钟
|
||||
resourceGrowthRate: 0.8, // 从0.4提升到0.8,确保NPC有足够资源发育
|
||||
buildingGrowthSpeed: 0.6, // 从0.4提升到0.6
|
||||
techGrowthSpeed: 0.6 // 从0.4提升到0.6
|
||||
}
|
||||
} else if (playerPoints < 5000) {
|
||||
// 初级期:1,000-5,000分
|
||||
// NPC保持50-70%实力,逐渐增加挑战
|
||||
const ratio = 0.5 + ((playerPoints - 1000) / 4000) * 0.2
|
||||
return {
|
||||
powerRatio: ratio,
|
||||
checkInterval: 240, // 4分钟
|
||||
resourceGrowthRate: 1.0, // 从0.6提升到1.0,与玩家资源产出相当
|
||||
buildingGrowthSpeed: 0.8, // 从0.6提升到0.8
|
||||
techGrowthSpeed: 0.8 // 从0.6提升到0.8
|
||||
}
|
||||
} else if (playerPoints < 20000) {
|
||||
// 中级期:5,000-20,000分
|
||||
// NPC保持70-90%实力,持续挑战
|
||||
const ratio = 0.7 + ((playerPoints - 5000) / 15000) * 0.2
|
||||
return {
|
||||
powerRatio: ratio,
|
||||
checkInterval: 180, // 3分钟
|
||||
resourceGrowthRate: 0.8,
|
||||
buildingGrowthSpeed: 0.8,
|
||||
techGrowthSpeed: 0.8
|
||||
}
|
||||
} else if (playerPoints < 50000) {
|
||||
// 高级期:20,000-50,000分
|
||||
// NPC保持90-110%实力,与玩家势均力敌
|
||||
const ratio = 0.9 + ((playerPoints - 20000) / 30000) * 0.2
|
||||
return {
|
||||
powerRatio: ratio,
|
||||
checkInterval: 150, // 2.5分钟
|
||||
resourceGrowthRate: 1.0,
|
||||
buildingGrowthSpeed: 1.0,
|
||||
techGrowthSpeed: 1.0
|
||||
}
|
||||
} else {
|
||||
// 专家期:50,000+分
|
||||
// NPC保持110-130%实力,超越玩家
|
||||
const ratio = Math.min(1.3, 1.1 + ((playerPoints - 50000) / 50000) * 0.2)
|
||||
return {
|
||||
powerRatio: ratio,
|
||||
checkInterval: 120, // 2分钟
|
||||
resourceGrowthRate: 1.2,
|
||||
buildingGrowthSpeed: 1.2,
|
||||
techGrowthSpeed: 1.2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算玩家平均实力
|
||||
*/
|
||||
export const calculatePlayerAveragePower = (
|
||||
gameState: NPCGrowthGameState
|
||||
): {
|
||||
avgBuildingLevel: number
|
||||
avgTechLevel: number
|
||||
totalFleetPower: number
|
||||
totalResources: number
|
||||
} => {
|
||||
// 筛选出玩家的星球
|
||||
const playerPlanets = gameState.planets.filter(p => p.ownerId === gameState.player.id)
|
||||
|
||||
if (playerPlanets.length === 0) {
|
||||
return {
|
||||
avgBuildingLevel: 0,
|
||||
avgTechLevel: 0,
|
||||
totalFleetPower: 0,
|
||||
totalResources: 0
|
||||
}
|
||||
}
|
||||
|
||||
// 计算平均建筑等级
|
||||
let totalBuildingLevels = 0
|
||||
let buildingCount = 0
|
||||
playerPlanets.forEach(planet => {
|
||||
Object.values(planet.buildings).forEach(level => {
|
||||
totalBuildingLevels += level
|
||||
buildingCount++
|
||||
})
|
||||
})
|
||||
|
||||
// 计算平均科技等级
|
||||
const techLevels = Object.values(gameState.player.technologies)
|
||||
const avgTechLevel = techLevels.length > 0 ? techLevels.reduce((sum, level) => sum + level, 0) / techLevels.length : 0
|
||||
|
||||
// 计算总舰队战力
|
||||
let totalFleetPower = 0
|
||||
playerPlanets.forEach(planet => {
|
||||
Object.entries(planet.fleet).forEach(([shipType, count]) => {
|
||||
const shipConfig = SHIPS[shipType as ShipType]
|
||||
const power = shipConfig.attack + shipConfig.shield + shipConfig.armor / 10
|
||||
totalFleetPower += power * (count as number)
|
||||
})
|
||||
})
|
||||
|
||||
// 计算总资源
|
||||
const totalResources = playerPlanets.reduce(
|
||||
(sum, planet) => sum + planet.resources.metal + planet.resources.crystal + planet.resources.deuterium,
|
||||
0
|
||||
)
|
||||
|
||||
return {
|
||||
avgBuildingLevel: buildingCount > 0 ? totalBuildingLevels / buildingCount : 0,
|
||||
avgTechLevel,
|
||||
totalFleetPower,
|
||||
totalResources
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算NPC当前实力
|
||||
*/
|
||||
export const calculateNPCPower = (
|
||||
npc: NPC
|
||||
): {
|
||||
avgBuildingLevel: number
|
||||
avgTechLevel: number
|
||||
totalFleetPower: number
|
||||
totalResources: number
|
||||
} => {
|
||||
// 计算平均建筑等级
|
||||
let totalBuildingLevels = 0
|
||||
let buildingCount = 0
|
||||
npc.planets.forEach(planet => {
|
||||
Object.values(planet.buildings).forEach(level => {
|
||||
totalBuildingLevels += level
|
||||
buildingCount++
|
||||
})
|
||||
})
|
||||
|
||||
// 计算平均科技等级
|
||||
const techLevels = Object.values(npc.technologies)
|
||||
const avgTechLevel = techLevels.length > 0 ? techLevels.reduce((sum, level) => sum + level, 0) / techLevels.length : 0
|
||||
|
||||
// 计算总舰队战力
|
||||
let totalFleetPower = 0
|
||||
npc.planets.forEach(planet => {
|
||||
Object.entries(planet.fleet).forEach(([shipType, count]) => {
|
||||
const shipConfig = SHIPS[shipType as ShipType]
|
||||
const power = shipConfig.attack + shipConfig.shield + shipConfig.armor / 10
|
||||
totalFleetPower += power * (count as number)
|
||||
})
|
||||
})
|
||||
|
||||
// 计算总资源
|
||||
const totalResources = npc.planets.reduce(
|
||||
(sum, planet) => sum + planet.resources.metal + planet.resources.crystal + planet.resources.deuterium,
|
||||
0
|
||||
)
|
||||
|
||||
return {
|
||||
avgBuildingLevel: buildingCount > 0 ? totalBuildingLevels / buildingCount : 0,
|
||||
avgTechLevel,
|
||||
totalFleetPower,
|
||||
totalResources
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动升级NPC建筑
|
||||
*/
|
||||
export const autoUpgradeNPCBuildings = (npc: NPC): void => {
|
||||
const planet = npc.planets[0]
|
||||
if (!planet) return
|
||||
|
||||
// 优先级队列:资源建筑 > 设施建筑 > 其他
|
||||
const priorityBuildings: BuildingType[] = [
|
||||
BuildingType.MetalMine,
|
||||
BuildingType.CrystalMine,
|
||||
BuildingType.DeuteriumSynthesizer,
|
||||
BuildingType.SolarPlant,
|
||||
BuildingType.RoboticsFactory,
|
||||
BuildingType.Shipyard,
|
||||
BuildingType.ResearchLab,
|
||||
BuildingType.MetalStorage,
|
||||
BuildingType.CrystalStorage,
|
||||
BuildingType.DeuteriumTank,
|
||||
BuildingType.DarkMatterCollector
|
||||
]
|
||||
|
||||
// 尝试升级建筑
|
||||
for (const buildingType of priorityBuildings) {
|
||||
const currentLevel = planet.buildings[buildingType] || 0
|
||||
const targetLevel = currentLevel + 1
|
||||
|
||||
// 检查是否达到最大等级
|
||||
const buildingConfig = BUILDINGS[buildingType]
|
||||
if (buildingConfig.maxLevel && currentLevel >= buildingConfig.maxLevel) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 计算升级成本
|
||||
const cost = buildingLogic.calculateBuildingCost(buildingType, targetLevel)
|
||||
|
||||
// 检查资源是否足够
|
||||
if (
|
||||
planet.resources.metal >= cost.metal &&
|
||||
planet.resources.crystal >= cost.crystal &&
|
||||
planet.resources.deuterium >= cost.deuterium &&
|
||||
planet.resources.darkMatter >= cost.darkMatter
|
||||
) {
|
||||
// 扣除资源
|
||||
planet.resources.metal -= cost.metal
|
||||
planet.resources.crystal -= cost.crystal
|
||||
planet.resources.deuterium -= cost.deuterium
|
||||
planet.resources.darkMatter -= cost.darkMatter
|
||||
|
||||
// 直接升级(NPC不需要等待建造时间)
|
||||
planet.buildings[buildingType] = targetLevel
|
||||
|
||||
// 每次只升级一个建筑,避免一次性消耗太多资源
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动研究NPC科技
|
||||
*/
|
||||
export const autoResearchNPCTechnologies = (npc: NPC): void => {
|
||||
const planet = npc.planets[0]
|
||||
if (!planet) return
|
||||
|
||||
// 优先级队列:战斗科技 > 驱动科技 > 其他
|
||||
const priorityTechs: TechnologyType[] = [
|
||||
TechnologyType.EnergyTechnology,
|
||||
TechnologyType.ComputerTechnology,
|
||||
TechnologyType.WeaponsTechnology,
|
||||
TechnologyType.ShieldingTechnology,
|
||||
TechnologyType.ArmourTechnology,
|
||||
TechnologyType.CombustionDrive,
|
||||
TechnologyType.ImpulseDrive,
|
||||
TechnologyType.HyperspaceDrive,
|
||||
TechnologyType.LaserTechnology,
|
||||
TechnologyType.IonTechnology,
|
||||
TechnologyType.PlasmaTechnology,
|
||||
TechnologyType.Astrophysics,
|
||||
TechnologyType.EspionageTechnology
|
||||
]
|
||||
|
||||
// 尝试研究科技
|
||||
for (const techType of priorityTechs) {
|
||||
const currentLevel = npc.technologies[techType] || 0
|
||||
const targetLevel = currentLevel + 1
|
||||
|
||||
// 检查是否达到最大等级
|
||||
const techConfig = TECHNOLOGIES[techType]
|
||||
if (techConfig.maxLevel && currentLevel >= techConfig.maxLevel) {
|
||||
continue
|
||||
}
|
||||
|
||||
// 计算研究成本
|
||||
const cost = researchLogic.calculateTechnologyCost(techType, targetLevel)
|
||||
|
||||
// 检查资源是否足够
|
||||
if (
|
||||
planet.resources.metal >= cost.metal &&
|
||||
planet.resources.crystal >= cost.crystal &&
|
||||
planet.resources.deuterium >= cost.deuterium &&
|
||||
planet.resources.darkMatter >= cost.darkMatter
|
||||
) {
|
||||
// 扣除资源
|
||||
planet.resources.metal -= cost.metal
|
||||
planet.resources.crystal -= cost.crystal
|
||||
planet.resources.deuterium -= cost.deuterium
|
||||
planet.resources.darkMatter -= cost.darkMatter
|
||||
|
||||
// 直接升级(NPC不需要等待研究时间)
|
||||
npc.technologies[techType] = targetLevel
|
||||
|
||||
// 每次只研究一个科技
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动建造NPC舰队
|
||||
*/
|
||||
export const autoBuildNPCFleet = (npc: NPC): void => {
|
||||
const planet = npc.planets[0]
|
||||
if (!planet) return
|
||||
|
||||
// 根据难度决定舰队组成
|
||||
const fleetComposition: { shipType: ShipType; priority: number }[] = [
|
||||
{ shipType: ShipType.LightFighter, priority: 1 },
|
||||
{ shipType: ShipType.HeavyFighter, priority: 2 },
|
||||
{ shipType: ShipType.Cruiser, priority: 3 },
|
||||
{ shipType: ShipType.Battleship, priority: 4 },
|
||||
{ shipType: ShipType.SmallCargo, priority: 5 },
|
||||
{ shipType: ShipType.LargeCargo, priority: 6 },
|
||||
{ shipType: ShipType.Recycler, priority: 7 },
|
||||
{ shipType: ShipType.EspionageProbe, priority: 8 }
|
||||
]
|
||||
|
||||
// 按优先级排序
|
||||
fleetComposition.sort((a, b) => a.priority - b.priority)
|
||||
|
||||
// 尝试建造舰船
|
||||
for (const { shipType } of fleetComposition) {
|
||||
const shipConfig = SHIPS[shipType]
|
||||
|
||||
// 检查建造需求
|
||||
const canBuild = Object.entries(shipConfig.requirements || {}).every(([reqType, reqLevel]) => {
|
||||
if (reqType in BuildingType) {
|
||||
return (planet.buildings[reqType as BuildingType] || 0) >= reqLevel
|
||||
}
|
||||
if (reqType in TechnologyType) {
|
||||
return (npc.technologies[reqType as TechnologyType] || 0) >= reqLevel
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
if (!canBuild) continue
|
||||
|
||||
// 根据难度和当前资源决定建造数量
|
||||
const maxAffordable = Math.floor(
|
||||
Math.min(
|
||||
planet.resources.metal / shipConfig.cost.metal,
|
||||
planet.resources.crystal / shipConfig.cost.crystal,
|
||||
planet.resources.deuterium / shipConfig.cost.deuterium,
|
||||
shipConfig.cost.darkMatter > 0 ? planet.resources.darkMatter / shipConfig.cost.darkMatter : Infinity
|
||||
)
|
||||
)
|
||||
|
||||
// 建造数量:简单1-5艘,中等5-10艘,困难10-20艘
|
||||
const buildCount = Math.min(maxAffordable, npc.difficulty === 'easy' ? 5 : npc.difficulty === 'medium' ? 10 : 20)
|
||||
|
||||
if (buildCount > 0) {
|
||||
// 扣除资源
|
||||
planet.resources.metal -= shipConfig.cost.metal * buildCount
|
||||
planet.resources.crystal -= shipConfig.cost.crystal * buildCount
|
||||
planet.resources.deuterium -= shipConfig.cost.deuterium * buildCount
|
||||
planet.resources.darkMatter -= shipConfig.cost.darkMatter * buildCount
|
||||
|
||||
// 添加舰船
|
||||
planet.fleet[shipType] = (planet.fleet[shipType] || 0) + buildCount
|
||||
|
||||
// 建造一批后退出
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 为NPC生成资源(模拟资源生产)
|
||||
*/
|
||||
export const generateNPCResources = (npc: NPC, deltaSeconds: number, config: DynamicDifficultyConfig): void => {
|
||||
const planet = npc.planets[0]
|
||||
if (!planet) return
|
||||
|
||||
// 基于建筑等级计算资源产量
|
||||
const metalMineLevel = planet.buildings[BuildingType.MetalMine] || 0
|
||||
const crystalMineLevel = planet.buildings[BuildingType.CrystalMine] || 0
|
||||
const deuteriumLevel = planet.buildings[BuildingType.DeuteriumSynthesizer] || 0
|
||||
const darkMatterLevel = planet.buildings[BuildingType.DarkMatterCollector] || 0
|
||||
|
||||
// 简化的资源产量计算(每秒产量)
|
||||
const metalProduction = 30 * metalMineLevel * Math.pow(1.1, metalMineLevel) * config.resourceGrowthRate
|
||||
const crystalProduction = 20 * crystalMineLevel * Math.pow(1.1, crystalMineLevel) * config.resourceGrowthRate
|
||||
const deuteriumProduction = 10 * deuteriumLevel * Math.pow(1.1, deuteriumLevel) * config.resourceGrowthRate
|
||||
const darkMatterProduction = ((25 * darkMatterLevel * Math.pow(1.5, darkMatterLevel)) / 3600) * config.resourceGrowthRate
|
||||
|
||||
// 增加资源
|
||||
planet.resources.metal += metalProduction * deltaSeconds
|
||||
planet.resources.crystal += crystalProduction * deltaSeconds
|
||||
planet.resources.deuterium += deuteriumProduction * deltaSeconds
|
||||
planet.resources.darkMatter += darkMatterProduction * deltaSeconds
|
||||
|
||||
// 确保不超过存储上限
|
||||
const metalStorage = planet.buildings[BuildingType.MetalStorage] || 0
|
||||
const crystalStorage = planet.buildings[BuildingType.CrystalStorage] || 0
|
||||
const deuteriumStorage = planet.buildings[BuildingType.DeuteriumTank] || 0
|
||||
const darkMatterStorage = planet.buildings[BuildingType.DarkMatterTank] || 0
|
||||
|
||||
planet.resources.metal = Math.min(planet.resources.metal, 10000 * Math.pow(2, metalStorage))
|
||||
planet.resources.crystal = Math.min(planet.resources.crystal, 10000 * Math.pow(2, crystalStorage))
|
||||
planet.resources.deuterium = Math.min(planet.resources.deuterium, 10000 * Math.pow(2, deuteriumStorage))
|
||||
planet.resources.darkMatter = Math.min(planet.resources.darkMatter, 1000 * Math.pow(2, darkMatterStorage))
|
||||
}
|
||||
|
||||
/**
|
||||
* 主NPC成长更新函数
|
||||
* 应该在游戏循环中定期调用
|
||||
*/
|
||||
export const updateNPCGrowth = (npc: NPC, gameState: NPCGrowthGameState, deltaSeconds: number): void => {
|
||||
// 使用动态难度(基于玩家积分)而不是固定难度
|
||||
const config = calculateDynamicDifficulty(gameState.player.points)
|
||||
|
||||
// 1. 持续生成资源
|
||||
generateNPCResources(npc, deltaSeconds, config)
|
||||
|
||||
// 2. 定期评估并调整实力(使用静态计数器或时间戳)
|
||||
const now = Date.now()
|
||||
const lastGrowthCheck = (npc as any).lastGrowthCheck || 0
|
||||
|
||||
if (now - lastGrowthCheck >= config.checkInterval * 1000) {
|
||||
;(npc as any).lastGrowthCheck = now
|
||||
|
||||
// 计算玩家平均实力
|
||||
const playerPower = calculatePlayerAveragePower(gameState)
|
||||
const npcPower = calculateNPCPower(npc)
|
||||
|
||||
// 计算目标实力
|
||||
const targetBuildingLevel = playerPower.avgBuildingLevel * config.powerRatio
|
||||
const targetTechLevel = playerPower.avgTechLevel * config.powerRatio
|
||||
const targetFleetPower = playerPower.totalFleetPower * config.powerRatio
|
||||
|
||||
// 3. 如果实力不足,进行升级
|
||||
if (npcPower.avgBuildingLevel < targetBuildingLevel) {
|
||||
autoUpgradeNPCBuildings(npc)
|
||||
}
|
||||
|
||||
if (npcPower.avgTechLevel < targetTechLevel) {
|
||||
autoResearchNPCTechnologies(npc)
|
||||
}
|
||||
|
||||
if (npcPower.totalFleetPower < targetFleetPower) {
|
||||
autoBuildNPCFleet(npc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化NPC时设置合理的起始实力
|
||||
*/
|
||||
export const initializeNPCStartingPower = (
|
||||
npc: NPC,
|
||||
playerPower: {
|
||||
avgBuildingLevel: number
|
||||
avgTechLevel: number
|
||||
totalFleetPower: number
|
||||
totalResources: number
|
||||
}
|
||||
): void => {
|
||||
const config = NPC_GROWTH_CONFIG[npc.difficulty]
|
||||
const planet = npc.planets[0]
|
||||
if (!planet) return
|
||||
|
||||
// 设置起始建筑等级(基于玩家实力)
|
||||
const targetBuildingLevel = Math.max(5, Math.floor(playerPower.avgBuildingLevel * config.powerRatio))
|
||||
|
||||
// 设置资源建筑
|
||||
planet.buildings[BuildingType.MetalMine] = targetBuildingLevel
|
||||
planet.buildings[BuildingType.CrystalMine] = Math.floor(targetBuildingLevel * 0.8)
|
||||
planet.buildings[BuildingType.DeuteriumSynthesizer] = Math.floor(targetBuildingLevel * 0.6)
|
||||
planet.buildings[BuildingType.SolarPlant] = targetBuildingLevel + 2
|
||||
|
||||
// 设置设施建筑
|
||||
planet.buildings[BuildingType.RoboticsFactory] = Math.floor(targetBuildingLevel * 0.5)
|
||||
planet.buildings[BuildingType.Shipyard] = Math.floor(targetBuildingLevel * 0.4)
|
||||
planet.buildings[BuildingType.ResearchLab] = Math.floor(targetBuildingLevel * 0.4)
|
||||
|
||||
// 设置仓储
|
||||
planet.buildings[BuildingType.MetalStorage] = Math.floor(targetBuildingLevel * 0.3)
|
||||
planet.buildings[BuildingType.CrystalStorage] = Math.floor(targetBuildingLevel * 0.3)
|
||||
planet.buildings[BuildingType.DeuteriumTank] = Math.floor(targetBuildingLevel * 0.3)
|
||||
|
||||
// 设置起始科技等级
|
||||
const targetTechLevel = Math.max(3, Math.floor(playerPower.avgTechLevel * config.powerRatio))
|
||||
|
||||
npc.technologies[TechnologyType.EnergyTechnology] = targetTechLevel
|
||||
npc.technologies[TechnologyType.ComputerTechnology] = Math.floor(targetTechLevel * 0.8)
|
||||
npc.technologies[TechnologyType.WeaponsTechnology] = Math.floor(targetTechLevel * 0.7)
|
||||
npc.technologies[TechnologyType.ShieldingTechnology] = Math.floor(targetTechLevel * 0.7)
|
||||
npc.technologies[TechnologyType.ArmourTechnology] = Math.floor(targetTechLevel * 0.7)
|
||||
npc.technologies[TechnologyType.CombustionDrive] = Math.floor(targetTechLevel * 0.6)
|
||||
|
||||
// 给予起始资源
|
||||
planet.resources.metal = 100000 * config.powerRatio
|
||||
planet.resources.crystal = 50000 * config.powerRatio
|
||||
planet.resources.deuterium = 20000 * config.powerRatio
|
||||
planet.resources.darkMatter = 1000 * config.powerRatio
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化NPC外交关系网络
|
||||
* 为每个NPC随机分配盟友和敌人
|
||||
*/
|
||||
export const initializeNPCDiplomacy = (npcs: NPC[]): void => {
|
||||
// 确保所有NPC都有空的外交字段
|
||||
npcs.forEach(npc => {
|
||||
if (!npc.allies) npc.allies = []
|
||||
if (!npc.enemies) npc.enemies = []
|
||||
if (!npc.relations) npc.relations = {}
|
||||
})
|
||||
|
||||
// 为每个NPC随机分配1-2个盟友
|
||||
npcs.forEach(npc => {
|
||||
// 获取还未建立关系的潜在盟友
|
||||
const potentialAllies = npcs.filter(n => n.id !== npc.id && !npc.allies!.includes(n.id) && !n.allies!.includes(npc.id))
|
||||
|
||||
if (potentialAllies.length === 0) return
|
||||
|
||||
// 随机选择1-2个盟友
|
||||
const allyCount = Math.min(Math.floor(Math.random() * 2) + 1, potentialAllies.length)
|
||||
|
||||
for (let i = 0; i < allyCount; i++) {
|
||||
if (potentialAllies.length === 0) break
|
||||
|
||||
const allyIndex = Math.floor(Math.random() * potentialAllies.length)
|
||||
const ally = potentialAllies.splice(allyIndex, 1)[0]
|
||||
|
||||
if (!ally) continue
|
||||
|
||||
// 建立双向盟友关系
|
||||
if (!npc.allies!.includes(ally.id)) {
|
||||
npc.allies!.push(ally.id)
|
||||
}
|
||||
if (!ally.allies!.includes(npc.id)) {
|
||||
ally.allies!.push(npc.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -24,11 +24,15 @@ export const createInitialPlanet = (playerId: string, planetName: string = 'Home
|
||||
[ShipType.HeavyFighter]: 0,
|
||||
[ShipType.Cruiser]: 0,
|
||||
[ShipType.Battleship]: 0,
|
||||
[ShipType.Battlecruiser]: 0,
|
||||
[ShipType.Bomber]: 0,
|
||||
[ShipType.Destroyer]: 0,
|
||||
[ShipType.SmallCargo]: 0,
|
||||
[ShipType.LargeCargo]: 0,
|
||||
[ShipType.ColonyShip]: 0,
|
||||
[ShipType.Recycler]: 0,
|
||||
[ShipType.EspionageProbe]: 0,
|
||||
[ShipType.SolarSatellite]: 0,
|
||||
[ShipType.DarkMatterHarvester]: 0,
|
||||
[ShipType.Deathstar]: 0
|
||||
},
|
||||
@@ -41,6 +45,8 @@ export const createInitialPlanet = (playerId: string, planetName: string = 'Home
|
||||
[DefenseType.PlasmaTurret]: 0,
|
||||
[DefenseType.SmallShieldDome]: 0,
|
||||
[DefenseType.LargeShieldDome]: 0,
|
||||
[DefenseType.AntiBallisticMissile]: 0,
|
||||
[DefenseType.InterplanetaryMissile]: 0,
|
||||
[DefenseType.PlanetaryShield]: 0
|
||||
},
|
||||
buildQueue: [],
|
||||
@@ -84,11 +90,15 @@ export const createNPCPlanet = (
|
||||
[ShipType.HeavyFighter]: Math.floor(Math.random() * 20),
|
||||
[ShipType.Cruiser]: Math.floor(Math.random() * 10),
|
||||
[ShipType.Battleship]: Math.floor(Math.random() * 5),
|
||||
[ShipType.Battlecruiser]: Math.floor(Math.random() * 3),
|
||||
[ShipType.Bomber]: Math.floor(Math.random() * 2),
|
||||
[ShipType.Destroyer]: Math.floor(Math.random() * 2),
|
||||
[ShipType.SmallCargo]: Math.floor(Math.random() * 10),
|
||||
[ShipType.LargeCargo]: Math.floor(Math.random() * 5),
|
||||
[ShipType.ColonyShip]: 0,
|
||||
[ShipType.Recycler]: 0,
|
||||
[ShipType.EspionageProbe]: 0,
|
||||
[ShipType.SolarSatellite]: Math.floor(Math.random() * 20),
|
||||
[ShipType.DarkMatterHarvester]: 0,
|
||||
[ShipType.Deathstar]: 0
|
||||
},
|
||||
@@ -101,6 +111,8 @@ export const createNPCPlanet = (
|
||||
[DefenseType.PlasmaTurret]: Math.floor(Math.random() * 5),
|
||||
[DefenseType.SmallShieldDome]: Math.random() > 0.5 ? 1 : 0,
|
||||
[DefenseType.LargeShieldDome]: Math.random() > 0.8 ? 1 : 0,
|
||||
[DefenseType.AntiBallisticMissile]: Math.floor(Math.random() * 3),
|
||||
[DefenseType.InterplanetaryMissile]: Math.floor(Math.random() * 2),
|
||||
[DefenseType.PlanetaryShield]: 0
|
||||
},
|
||||
buildQueue: [],
|
||||
@@ -157,11 +169,15 @@ export const createMoon = (
|
||||
[ShipType.HeavyFighter]: 0,
|
||||
[ShipType.Cruiser]: 0,
|
||||
[ShipType.Battleship]: 0,
|
||||
[ShipType.Battlecruiser]: 0,
|
||||
[ShipType.Bomber]: 0,
|
||||
[ShipType.Destroyer]: 0,
|
||||
[ShipType.SmallCargo]: 0,
|
||||
[ShipType.LargeCargo]: 0,
|
||||
[ShipType.ColonyShip]: 0,
|
||||
[ShipType.Recycler]: 0,
|
||||
[ShipType.EspionageProbe]: 0,
|
||||
[ShipType.SolarSatellite]: 0,
|
||||
[ShipType.DarkMatterHarvester]: 0,
|
||||
[ShipType.Deathstar]: 0
|
||||
},
|
||||
@@ -174,6 +190,8 @@ export const createMoon = (
|
||||
[DefenseType.PlasmaTurret]: 0,
|
||||
[DefenseType.SmallShieldDome]: 0,
|
||||
[DefenseType.LargeShieldDome]: 0,
|
||||
[DefenseType.AntiBallisticMissile]: 0,
|
||||
[DefenseType.InterplanetaryMissile]: 0,
|
||||
[DefenseType.PlanetaryShield]: 0
|
||||
},
|
||||
buildQueue: [],
|
||||
|
||||
@@ -3,6 +3,9 @@ import { TechnologyType, BuildingType } from '@/types/game'
|
||||
import { TECHNOLOGIES } from '@/config/gameConfig'
|
||||
import * as pointsLogic from './pointsLogic'
|
||||
|
||||
// 用于生成唯一ID的计数器
|
||||
let researchQueueIdCounter = 0
|
||||
|
||||
/**
|
||||
* 计算科技研究成本
|
||||
*/
|
||||
@@ -20,12 +23,31 @@ export const calculateTechnologyCost = (techType: TechnologyType, targetLevel: n
|
||||
|
||||
/**
|
||||
* 计算科技研究时间
|
||||
* @param techType 科技类型
|
||||
* @param currentLevel 当前等级
|
||||
* @param researchSpeedBonus 军官等提供的研究速度加成百分比
|
||||
* @param researchLabLevel 研究实验室等级
|
||||
* @param energyTechLevel 能源技术等级
|
||||
*/
|
||||
export const calculateTechnologyTime = (techType: TechnologyType, currentLevel: number, researchSpeedBonus: number = 0): number => {
|
||||
export const calculateTechnologyTime = (
|
||||
techType: TechnologyType,
|
||||
currentLevel: number,
|
||||
researchSpeedBonus: number = 0,
|
||||
researchLabLevel: number = 1,
|
||||
energyTechLevel: number = 0
|
||||
): number => {
|
||||
const config = TECHNOLOGIES[techType]
|
||||
const baseTime = config.baseTime * Math.pow(config.costMultiplier, currentLevel)
|
||||
|
||||
// 研究实验室和能源技术的加速:研究时间 / (研究实验室等级 × (1 + 能源技术等级))
|
||||
// 研究实验室等级至少为1,防止除以0
|
||||
const labLevel = Math.max(1, researchLabLevel)
|
||||
const techSpeedDivisor = labLevel * (1 + energyTechLevel)
|
||||
|
||||
// 军官等的百分比加成
|
||||
const speedMultiplier = 1 - researchSpeedBonus / 100
|
||||
return Math.floor(baseTime * speedMultiplier)
|
||||
|
||||
return Math.floor((baseTime / techSpeedDivisor) * speedMultiplier)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,8 +80,9 @@ export const checkTechnologyRequirements = (
|
||||
*/
|
||||
export const createResearchQueueItem = (techType: TechnologyType, targetLevel: number, researchTime: number): BuildQueueItem => {
|
||||
const now = Date.now()
|
||||
researchQueueIdCounter++
|
||||
return {
|
||||
id: `research_${now}`,
|
||||
id: `research_${now}_${researchQueueIdCounter}`,
|
||||
type: 'technology',
|
||||
itemType: techType,
|
||||
targetLevel,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Planet, Resources, BuildQueueItem, Officer } from '@/types/game'
|
||||
import { TechnologyType, OfficerType } from '@/types/game'
|
||||
import { TechnologyType, OfficerType, BuildingType } from '@/types/game'
|
||||
import * as researchLogic from './researchLogic'
|
||||
import * as resourceLogic from './resourceLogic'
|
||||
import * as publicLogic from './publicLogic'
|
||||
@@ -21,6 +21,12 @@ export const validateTechnologyResearch = (
|
||||
const targetLevel = currentLevel + 1
|
||||
const cost = researchLogic.calculateTechnologyCost(techType, targetLevel)
|
||||
|
||||
// 检查队列中是否已存在该科技的研究任务
|
||||
const existingQueueItem = researchQueue.find(item => item.type === 'technology' && item.itemType === techType)
|
||||
if (existingQueueItem) {
|
||||
return { valid: false, reason: 'errors.technologyAlreadyInQueue' }
|
||||
}
|
||||
|
||||
// 检查研究队列是否已满
|
||||
const maxQueue = publicLogic.getMaxResearchQueue(technologies)
|
||||
if (researchQueue.length >= maxQueue) {
|
||||
@@ -47,14 +53,20 @@ export const executeTechnologyResearch = (
|
||||
planet: Planet,
|
||||
techType: TechnologyType,
|
||||
currentLevel: number,
|
||||
officers: Record<OfficerType, Officer>
|
||||
officers: Record<OfficerType, Officer>,
|
||||
technologies: Partial<Record<TechnologyType, number>>
|
||||
): { queueItem: BuildQueueItem } => {
|
||||
const targetLevel = currentLevel + 1
|
||||
const cost = researchLogic.calculateTechnologyCost(techType, targetLevel)
|
||||
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
const time = researchLogic.calculateTechnologyTime(techType, currentLevel, bonuses.researchSpeedBonus)
|
||||
|
||||
// 获取研究实验室等级和能源技术等级
|
||||
const researchLabLevel = planet.buildings[BuildingType.ResearchLab] || 1
|
||||
const energyTechLevel = technologies[TechnologyType.EnergyTechnology] || 0
|
||||
|
||||
const time = researchLogic.calculateTechnologyTime(techType, currentLevel, bonuses.researchSpeedBonus, researchLabLevel, energyTechLevel)
|
||||
|
||||
// 扣除资源
|
||||
resourceLogic.deductResources(planet.resources, cost)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { Planet, Resources } from '@/types/game'
|
||||
import { BuildingType } from '@/types/game'
|
||||
import type { Planet, Resources, Officer } from '@/types/game'
|
||||
import { BuildingType, OfficerType } from '@/types/game'
|
||||
import * as officerLogic from './officerLogic'
|
||||
import { OFFICERS } from '@/config/gameConfig'
|
||||
|
||||
/**
|
||||
* 计算电量产出
|
||||
@@ -11,10 +13,20 @@ export const calculateEnergyProduction = (
|
||||
}
|
||||
): number => {
|
||||
const solarPlantLevel = planet.buildings[BuildingType.SolarPlant] || 0
|
||||
const fusionReactorLevel = planet.buildings[BuildingType.FusionReactor] || 0
|
||||
const solarSatelliteCount = planet.fleet.solarSatellite || 0
|
||||
const energyBonus = 1 + (bonuses.energyProductionBonus || 0) / 100
|
||||
|
||||
// 太阳能电站每级产出:50 * 1.1^等级
|
||||
return solarPlantLevel * 50 * Math.pow(1.1, solarPlantLevel) * energyBonus
|
||||
const solarPlantProduction = solarPlantLevel * 50 * Math.pow(1.1, solarPlantLevel)
|
||||
|
||||
// 核聚变反应堆每级产出:150 * 1.15^等级(消耗重氢)
|
||||
const fusionReactorProduction = fusionReactorLevel * 150 * Math.pow(1.15, fusionReactorLevel)
|
||||
|
||||
// 太阳能卫星每个产出:50点能量
|
||||
const solarSatelliteProduction = solarSatelliteCount * 50
|
||||
|
||||
return (solarPlantProduction + fusionReactorProduction + solarSatelliteProduction) * energyBonus
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,17 +88,18 @@ export const calculateResourceCapacity = (planet: Planet, storageCapacityBonus:
|
||||
const metalStorageLevel = planet.buildings[BuildingType.MetalStorage] || 0
|
||||
const crystalStorageLevel = planet.buildings[BuildingType.CrystalStorage] || 0
|
||||
const deuteriumTankLevel = planet.buildings[BuildingType.DeuteriumTank] || 0
|
||||
const darkMatterCollectorLevel = planet.buildings[BuildingType.DarkMatterCollector] || 0
|
||||
const darkMatterTankLevel = planet.buildings[BuildingType.DarkMatterTank] || 0
|
||||
const solarPlantLevel = planet.buildings[BuildingType.SolarPlant] || 0
|
||||
|
||||
const bonus = 1 + (storageCapacityBonus || 0) / 100
|
||||
|
||||
const baseCapacity = 10000
|
||||
const darkMatterBaseCapacity = 1000 // 暗物质基础容量较小
|
||||
return {
|
||||
metal: baseCapacity * Math.pow(2, metalStorageLevel) * bonus,
|
||||
crystal: baseCapacity * Math.pow(2, crystalStorageLevel) * bonus,
|
||||
deuterium: baseCapacity * Math.pow(2, deuteriumTankLevel) * bonus,
|
||||
darkMatter: 1000 + darkMatterCollectorLevel * 100, // 暗物质容量较小
|
||||
darkMatter: darkMatterBaseCapacity * Math.pow(2, darkMatterTankLevel) * bonus,
|
||||
energy: 1000 + solarPlantLevel * 500 // 能量容量基于太阳能电站等级
|
||||
}
|
||||
}
|
||||
@@ -102,23 +115,27 @@ export const updatePlanetResources = (
|
||||
darkMatterProductionBonus: number
|
||||
energyProductionBonus: number
|
||||
storageCapacityBonus: number
|
||||
}
|
||||
},
|
||||
gameSpeed: number = 1
|
||||
): void => {
|
||||
const timeDiff = (now - planet.lastUpdate) / 1000 // 转换为秒
|
||||
|
||||
// 应用游戏速度到时间差(游戏速度影响资源产出速率)
|
||||
const effectiveTimeDiff = timeDiff * gameSpeed
|
||||
|
||||
// 计算能量消耗(每小时)
|
||||
const energyConsumption = calculateEnergyConsumption(planet)
|
||||
|
||||
// 先增加能量产出
|
||||
const energyProduction = calculateEnergyProduction(planet, { energyProductionBonus: bonuses.energyProductionBonus })
|
||||
planet.resources.energy += (energyProduction * timeDiff) / 3600
|
||||
planet.resources.energy += (energyProduction * effectiveTimeDiff) / 3600
|
||||
|
||||
// 限制能量上限
|
||||
const capacity = calculateResourceCapacity(planet, bonuses.storageCapacityBonus)
|
||||
planet.resources.energy = Math.min(planet.resources.energy, capacity.energy)
|
||||
|
||||
// 扣除能量消耗
|
||||
planet.resources.energy -= (energyConsumption * timeDiff) / 3600
|
||||
planet.resources.energy -= (energyConsumption * effectiveTimeDiff) / 3600
|
||||
|
||||
// 能量不能为负数,最低为0
|
||||
planet.resources.energy = Math.max(0, planet.resources.energy)
|
||||
@@ -130,11 +147,11 @@ export const updatePlanetResources = (
|
||||
energyProductionBonus: bonuses.energyProductionBonus
|
||||
})
|
||||
|
||||
// 更新资源(转换为每秒产量)
|
||||
planet.resources.metal += (production.metal * timeDiff) / 3600
|
||||
planet.resources.crystal += (production.crystal * timeDiff) / 3600
|
||||
planet.resources.deuterium += (production.deuterium * timeDiff) / 3600
|
||||
planet.resources.darkMatter += (production.darkMatter * timeDiff) / 3600
|
||||
// 更新资源(转换为每秒产量,应用游戏速度)
|
||||
planet.resources.metal += (production.metal * effectiveTimeDiff) / 3600
|
||||
planet.resources.crystal += (production.crystal * effectiveTimeDiff) / 3600
|
||||
planet.resources.deuterium += (production.deuterium * effectiveTimeDiff) / 3600
|
||||
planet.resources.darkMatter += (production.darkMatter * effectiveTimeDiff) / 3600
|
||||
|
||||
// 限制资源上限
|
||||
planet.resources.metal = Math.min(planet.resources.metal, capacity.metal)
|
||||
@@ -194,12 +211,20 @@ export interface ProductionDetail {
|
||||
buildingName: string // 建筑名称(用于显示)
|
||||
bonuses: ProductionBonus[] // 加成列表
|
||||
finalProduction: number // 最终产量
|
||||
sources?: ProductionSource[] // 多个产量来源(用于能量)
|
||||
}
|
||||
|
||||
export interface ProductionSource {
|
||||
name: string // 来源名称
|
||||
level: number // 等级或数量
|
||||
production: number // 产量
|
||||
}
|
||||
|
||||
export interface ProductionBonus {
|
||||
name: string // 加成名称
|
||||
value: number // 加成百分比或固定值
|
||||
type: 'percentage' | 'multiplier' // 百分比加成或倍率
|
||||
percentage: number // 加成百分比
|
||||
value: number // 实际增加的产量
|
||||
source: 'technology' | 'officer' | 'other' // 加成来源类型
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,11 +248,8 @@ export interface ConsumptionDetail {
|
||||
*/
|
||||
export const calculateProductionBreakdown = (
|
||||
planet: Planet,
|
||||
bonuses: {
|
||||
resourceProductionBonus: number
|
||||
darkMatterProductionBonus: number
|
||||
energyProductionBonus: number
|
||||
}
|
||||
officers: Record<OfficerType, Officer>,
|
||||
currentTime: number
|
||||
): ProductionBreakdown => {
|
||||
const metalMineLevel = planet.buildings[BuildingType.MetalMine] || 0
|
||||
const crystalMineLevel = planet.buildings[BuildingType.CrystalMine] || 0
|
||||
@@ -238,86 +260,180 @@ export const calculateProductionBreakdown = (
|
||||
const hasEnergy = planet.resources.energy > 0
|
||||
const productionEfficiency = hasEnergy ? 1 : 0
|
||||
|
||||
// 收集每个军官的加成信息
|
||||
const activeOfficerBonuses: Array<{
|
||||
type: OfficerType
|
||||
name: string
|
||||
resourceBonus: number
|
||||
darkMatterBonus: number
|
||||
energyBonus: number
|
||||
}> = []
|
||||
|
||||
Object.values(officers).forEach(officer => {
|
||||
if (officerLogic.isOfficerActive(officer, currentTime)) {
|
||||
const config = OFFICERS[officer.type]
|
||||
activeOfficerBonuses.push({
|
||||
type: officer.type,
|
||||
name: config.name,
|
||||
resourceBonus: config.benefits.resourceProductionBonus || 0,
|
||||
darkMatterBonus: config.benefits.darkMatterProductionBonus || 0,
|
||||
energyBonus: config.benefits.energyProductionBonus || 0
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// 计算总加成
|
||||
const totalResourceBonus = activeOfficerBonuses.reduce((sum, officer) => sum + officer.resourceBonus, 0)
|
||||
const totalDarkMatterBonus = activeOfficerBonuses.reduce((sum, officer) => sum + officer.darkMatterBonus, 0)
|
||||
const totalEnergyBonus = activeOfficerBonuses.reduce((sum, officer) => sum + officer.energyBonus, 0)
|
||||
|
||||
// 金属矿产量
|
||||
const metalBase = metalMineLevel * 1500 * Math.pow(1.5, metalMineLevel)
|
||||
const metalBonuses: ProductionBonus[] = []
|
||||
if (bonuses.resourceProductionBonus > 0) {
|
||||
|
||||
// 为每个激活的军官添加加成项
|
||||
activeOfficerBonuses.forEach(officer => {
|
||||
if (officer.resourceBonus > 0) {
|
||||
const bonusValue = metalBase * (officer.resourceBonus / 100)
|
||||
metalBonuses.push({
|
||||
name: 'officers.resourceBonus',
|
||||
value: bonuses.resourceProductionBonus,
|
||||
type: 'percentage'
|
||||
name: `officers.${officer.type}`,
|
||||
percentage: officer.resourceBonus,
|
||||
value: bonusValue,
|
||||
source: 'officer'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (!hasEnergy) {
|
||||
metalBonuses.push({
|
||||
name: 'resources.noEnergy',
|
||||
value: -100,
|
||||
type: 'percentage'
|
||||
percentage: -100,
|
||||
value: -metalBase * (1 + totalResourceBonus / 100),
|
||||
source: 'other'
|
||||
})
|
||||
}
|
||||
const metalFinal = metalBase * (1 + bonuses.resourceProductionBonus / 100) * productionEfficiency
|
||||
|
||||
const metalFinal = metalBase * (1 + totalResourceBonus / 100) * productionEfficiency
|
||||
|
||||
// 晶体矿产量
|
||||
const crystalBase = crystalMineLevel * 1000 * Math.pow(1.5, crystalMineLevel)
|
||||
const crystalBonuses: ProductionBonus[] = []
|
||||
if (bonuses.resourceProductionBonus > 0) {
|
||||
|
||||
activeOfficerBonuses.forEach(officer => {
|
||||
if (officer.resourceBonus > 0) {
|
||||
const bonusValue = crystalBase * (officer.resourceBonus / 100)
|
||||
crystalBonuses.push({
|
||||
name: 'officers.resourceBonus',
|
||||
value: bonuses.resourceProductionBonus,
|
||||
type: 'percentage'
|
||||
name: `officers.${officer.type}`,
|
||||
percentage: officer.resourceBonus,
|
||||
value: bonusValue,
|
||||
source: 'officer'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (!hasEnergy) {
|
||||
crystalBonuses.push({
|
||||
name: 'resources.noEnergy',
|
||||
value: -100,
|
||||
type: 'percentage'
|
||||
percentage: -100,
|
||||
value: -crystalBase * (1 + totalResourceBonus / 100),
|
||||
source: 'other'
|
||||
})
|
||||
}
|
||||
const crystalFinal = crystalBase * (1 + bonuses.resourceProductionBonus / 100) * productionEfficiency
|
||||
|
||||
const crystalFinal = crystalBase * (1 + totalResourceBonus / 100) * productionEfficiency
|
||||
|
||||
// 重氢合成器产量
|
||||
const deuteriumBase = deuteriumSynthesizerLevel * 500 * Math.pow(1.5, deuteriumSynthesizerLevel)
|
||||
const deuteriumBonuses: ProductionBonus[] = []
|
||||
if (bonuses.resourceProductionBonus > 0) {
|
||||
|
||||
activeOfficerBonuses.forEach(officer => {
|
||||
if (officer.resourceBonus > 0) {
|
||||
const bonusValue = deuteriumBase * (officer.resourceBonus / 100)
|
||||
deuteriumBonuses.push({
|
||||
name: 'officers.resourceBonus',
|
||||
value: bonuses.resourceProductionBonus,
|
||||
type: 'percentage'
|
||||
name: `officers.${officer.type}`,
|
||||
percentage: officer.resourceBonus,
|
||||
value: bonusValue,
|
||||
source: 'officer'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
if (!hasEnergy) {
|
||||
deuteriumBonuses.push({
|
||||
name: 'resources.noEnergy',
|
||||
value: -100,
|
||||
type: 'percentage'
|
||||
percentage: -100,
|
||||
value: -deuteriumBase * (1 + totalResourceBonus / 100),
|
||||
source: 'other'
|
||||
})
|
||||
}
|
||||
const deuteriumFinal = deuteriumBase * (1 + bonuses.resourceProductionBonus / 100) * productionEfficiency
|
||||
|
||||
const deuteriumFinal = deuteriumBase * (1 + totalResourceBonus / 100) * productionEfficiency
|
||||
|
||||
// 暗物质收集器产量
|
||||
const darkMatterBase = darkMatterCollectorLevel * 25 * Math.pow(1.5, darkMatterCollectorLevel)
|
||||
const darkMatterBonuses: ProductionBonus[] = []
|
||||
if (bonuses.darkMatterProductionBonus > 0) {
|
||||
darkMatterBonuses.push({
|
||||
name: 'officers.darkMatterBonus',
|
||||
value: bonuses.darkMatterProductionBonus,
|
||||
type: 'percentage'
|
||||
})
|
||||
}
|
||||
const darkMatterFinal = darkMatterBase * (1 + bonuses.darkMatterProductionBonus / 100)
|
||||
|
||||
// 太阳能电站产量
|
||||
const energyBase = solarPlantLevel * 50 * Math.pow(1.1, solarPlantLevel)
|
||||
const energyBonuses: ProductionBonus[] = []
|
||||
if (bonuses.energyProductionBonus > 0) {
|
||||
energyBonuses.push({
|
||||
name: 'officers.energyBonus',
|
||||
value: bonuses.energyProductionBonus,
|
||||
type: 'percentage'
|
||||
activeOfficerBonuses.forEach(officer => {
|
||||
if (officer.darkMatterBonus > 0) {
|
||||
const bonusValue = darkMatterBase * (officer.darkMatterBonus / 100)
|
||||
darkMatterBonuses.push({
|
||||
name: `officers.${officer.type}`,
|
||||
percentage: officer.darkMatterBonus,
|
||||
value: bonusValue,
|
||||
source: 'officer'
|
||||
})
|
||||
}
|
||||
const energyFinal = energyBase * (1 + bonuses.energyProductionBonus / 100)
|
||||
})
|
||||
|
||||
const darkMatterFinal = darkMatterBase * (1 + totalDarkMatterBonus / 100)
|
||||
|
||||
// 能量产量(包含多个来源)
|
||||
const fusionReactorLevel = planet.buildings[BuildingType.FusionReactor] || 0
|
||||
const solarSatelliteCount = planet.fleet.solarSatellite || 0
|
||||
|
||||
const solarPlantProduction = solarPlantLevel * 50 * Math.pow(1.1, solarPlantLevel)
|
||||
const fusionReactorProduction = fusionReactorLevel * 150 * Math.pow(1.15, fusionReactorLevel)
|
||||
const solarSatelliteProduction = solarSatelliteCount * 50
|
||||
|
||||
const energyBase = solarPlantProduction + fusionReactorProduction + solarSatelliteProduction
|
||||
|
||||
const energySources: ProductionSource[] = []
|
||||
if (solarPlantLevel > 0) {
|
||||
energySources.push({
|
||||
name: 'buildings.solarPlant',
|
||||
level: solarPlantLevel,
|
||||
production: solarPlantProduction
|
||||
})
|
||||
}
|
||||
if (fusionReactorLevel > 0) {
|
||||
energySources.push({
|
||||
name: 'buildings.fusionReactor',
|
||||
level: fusionReactorLevel,
|
||||
production: fusionReactorProduction
|
||||
})
|
||||
}
|
||||
if (solarSatelliteCount > 0) {
|
||||
energySources.push({
|
||||
name: 'ships.solarSatellite',
|
||||
level: solarSatelliteCount,
|
||||
production: solarSatelliteProduction
|
||||
})
|
||||
}
|
||||
|
||||
const energyBonuses: ProductionBonus[] = []
|
||||
activeOfficerBonuses.forEach(officer => {
|
||||
if (officer.energyBonus > 0) {
|
||||
const bonusValue = energyBase * (officer.energyBonus / 100)
|
||||
energyBonuses.push({
|
||||
name: `officers.${officer.type}`,
|
||||
percentage: officer.energyBonus,
|
||||
value: bonusValue,
|
||||
source: 'officer'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
const energyFinal = energyBase * (1 + totalEnergyBonus / 100)
|
||||
|
||||
return {
|
||||
metal: {
|
||||
@@ -353,7 +469,8 @@ export const calculateProductionBreakdown = (
|
||||
buildingLevel: solarPlantLevel,
|
||||
buildingName: 'buildings.solarPlant',
|
||||
bonuses: energyBonuses,
|
||||
finalProduction: energyFinal
|
||||
finalProduction: energyFinal,
|
||||
sources: energySources
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@ import type { Resources, BuildQueueItem, Fleet } from '@/types/game'
|
||||
import { ShipType, DefenseType, BuildingType, TechnologyType } from '@/types/game'
|
||||
import { SHIPS, DEFENSES } from '@/config/gameConfig'
|
||||
|
||||
// 用于生成唯一ID的计数器
|
||||
let shipQueueIdCounter = 0
|
||||
|
||||
/**
|
||||
* 计算舰船建造成本
|
||||
*/
|
||||
@@ -32,22 +35,56 @@ export const calculateDefenseCost = (defenseType: DefenseType, quantity: number)
|
||||
|
||||
/**
|
||||
* 计算舰船建造时间
|
||||
* @param shipType 舰船类型
|
||||
* @param quantity 数量
|
||||
* @param buildingSpeedBonus 指挥官等提供的速度加成百分比
|
||||
* @param roboticsFactoryLevel 机器人工厂等级
|
||||
* @param naniteFactoryLevel 纳米工厂等级
|
||||
*/
|
||||
export const calculateShipBuildTime = (shipType: ShipType, quantity: number, buildingSpeedBonus: number = 0): number => {
|
||||
export const calculateShipBuildTime = (
|
||||
shipType: ShipType,
|
||||
quantity: number,
|
||||
buildingSpeedBonus: number = 0,
|
||||
roboticsFactoryLevel: number = 0,
|
||||
naniteFactoryLevel: number = 0
|
||||
): number => {
|
||||
const config = SHIPS[shipType]
|
||||
const baseTime = config.buildTime * quantity
|
||||
|
||||
// 机器人工厂和纳米工厂的加速:建造时间 / (1 + 机器人工厂等级 + 纳米工厂等级 × 2)
|
||||
const factorySpeedDivisor = 1 + roboticsFactoryLevel + naniteFactoryLevel * 2
|
||||
|
||||
// 指挥官等的百分比加成
|
||||
const speedMultiplier = 1 - buildingSpeedBonus / 100
|
||||
return Math.floor(baseTime * speedMultiplier)
|
||||
|
||||
return Math.floor((baseTime / factorySpeedDivisor) * speedMultiplier)
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算防御设施建造时间
|
||||
* @param defenseType 防御类型
|
||||
* @param quantity 数量
|
||||
* @param buildingSpeedBonus 指挥官等提供的速度加成百分比
|
||||
* @param roboticsFactoryLevel 机器人工厂等级
|
||||
* @param naniteFactoryLevel 纳米工厂等级
|
||||
*/
|
||||
export const calculateDefenseBuildTime = (defenseType: DefenseType, quantity: number, buildingSpeedBonus: number = 0): number => {
|
||||
export const calculateDefenseBuildTime = (
|
||||
defenseType: DefenseType,
|
||||
quantity: number,
|
||||
buildingSpeedBonus: number = 0,
|
||||
roboticsFactoryLevel: number = 0,
|
||||
naniteFactoryLevel: number = 0
|
||||
): number => {
|
||||
const config = DEFENSES[defenseType]
|
||||
const baseTime = config.buildTime * quantity
|
||||
|
||||
// 机器人工厂和纳米工厂的加速:建造时间 / (1 + 机器人工厂等级 + 纳米工厂等级 × 2)
|
||||
const factorySpeedDivisor = 1 + roboticsFactoryLevel + naniteFactoryLevel * 2
|
||||
|
||||
// 指挥官等的百分比加成
|
||||
const speedMultiplier = 1 - buildingSpeedBonus / 100
|
||||
return Math.floor(baseTime * speedMultiplier)
|
||||
|
||||
return Math.floor((baseTime / factorySpeedDivisor) * speedMultiplier)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,13 +156,52 @@ export const checkShieldDomeLimit = (
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算导弹发射井容量
|
||||
*/
|
||||
export const calculateMissileSiloCapacity = (buildings: Partial<Record<BuildingType, number>>): number => {
|
||||
const siloLevel = buildings[BuildingType.MissileSilo] || 0
|
||||
return siloLevel * 10 // 每级存储10枚导弹
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当前导弹总数
|
||||
*/
|
||||
export const calculateCurrentMissileCount = (defense: Partial<Record<DefenseType, number>>): number => {
|
||||
const interplanetaryMissiles = defense[DefenseType.InterplanetaryMissile] || 0
|
||||
const antiBallisticMissiles = defense[DefenseType.AntiBallisticMissile] || 0
|
||||
return interplanetaryMissiles + antiBallisticMissiles
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查导弹容量限制
|
||||
*/
|
||||
export const checkMissileSiloLimit = (
|
||||
defenseType: DefenseType,
|
||||
currentDefense: Partial<Record<DefenseType, number>>,
|
||||
buildings: Partial<Record<BuildingType, number>>,
|
||||
quantity: number
|
||||
): boolean => {
|
||||
// 只对导弹类型进行检查
|
||||
if (defenseType !== DefenseType.InterplanetaryMissile && defenseType !== DefenseType.AntiBallisticMissile) {
|
||||
return true
|
||||
}
|
||||
|
||||
const maxCapacity = calculateMissileSiloCapacity(buildings)
|
||||
const currentCount = calculateCurrentMissileCount(currentDefense)
|
||||
const newCount = currentCount + quantity
|
||||
|
||||
return newCount <= maxCapacity
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建舰船建造队列项
|
||||
*/
|
||||
export const createShipQueueItem = (shipType: ShipType, quantity: number, buildTime: number): BuildQueueItem => {
|
||||
const now = Date.now()
|
||||
shipQueueIdCounter++
|
||||
return {
|
||||
id: `ship_${now}`,
|
||||
id: `ship_${now}_${shipQueueIdCounter}`,
|
||||
type: 'ship',
|
||||
itemType: shipType,
|
||||
quantity,
|
||||
@@ -139,8 +215,9 @@ export const createShipQueueItem = (shipType: ShipType, quantity: number, buildT
|
||||
*/
|
||||
export const createDefenseQueueItem = (defenseType: DefenseType, quantity: number, buildTime: number): BuildQueueItem => {
|
||||
const now = Date.now()
|
||||
shipQueueIdCounter++
|
||||
return {
|
||||
id: `defense_${now}`,
|
||||
id: `defense_${now}_${shipQueueIdCounter}`,
|
||||
type: 'defense',
|
||||
itemType: defenseType,
|
||||
quantity,
|
||||
@@ -168,11 +245,7 @@ export const checkFleetAvailable = (currentFleet: Partial<Fleet>, requiredFleet:
|
||||
* @param cargo 携带的货物(可选)
|
||||
* @returns 总燃料消耗(重氢)
|
||||
*/
|
||||
export const calculateFleetFuelConsumption = (
|
||||
fleet: Partial<Fleet>,
|
||||
fuelConsumptionReduction: number = 0,
|
||||
cargo?: Resources
|
||||
): number => {
|
||||
export const calculateFleetFuelConsumption = (fleet: Partial<Fleet>, fuelConsumptionReduction: number = 0, cargo?: Resources): number => {
|
||||
// 计算舰船基础燃料消耗
|
||||
let baseFuelNeeded = 0
|
||||
for (const [shipType, count] of Object.entries(fleet)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Planet, Resources, BuildQueueItem, Fleet, Officer } from '@/types/game'
|
||||
import { ShipType, DefenseType, TechnologyType, OfficerType } from '@/types/game'
|
||||
import { ShipType, DefenseType, TechnologyType, OfficerType, BuildingType } from '@/types/game'
|
||||
import * as shipLogic from './shipLogic'
|
||||
import * as resourceLogic from './resourceLogic'
|
||||
import * as officerLogic from './officerLogic'
|
||||
@@ -51,7 +51,18 @@ export const executeShipBuild = (
|
||||
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
const buildTime = shipLogic.calculateShipBuildTime(shipType, quantity, bonuses.buildingSpeedBonus)
|
||||
|
||||
// 获取机器人工厂和纳米工厂等级
|
||||
const roboticsFactoryLevel = planet.buildings[BuildingType.RoboticsFactory] || 0
|
||||
const naniteFactoryLevel = planet.buildings[BuildingType.NaniteFactory] || 0
|
||||
|
||||
const buildTime = shipLogic.calculateShipBuildTime(
|
||||
shipType,
|
||||
quantity,
|
||||
bonuses.buildingSpeedBonus,
|
||||
roboticsFactoryLevel,
|
||||
naniteFactoryLevel
|
||||
)
|
||||
|
||||
// 扣除资源
|
||||
resourceLogic.deductResources(planet.resources, totalCost)
|
||||
@@ -89,6 +100,11 @@ export const validateDefenseBuild = (
|
||||
return { valid: false, reason: 'errors.shieldDomeLimit' }
|
||||
}
|
||||
|
||||
// 导弹发射井容量限制
|
||||
if (!shipLogic.checkMissileSiloLimit(defenseType, planet.defense, planet.buildings, quantity)) {
|
||||
return { valid: false, reason: 'errors.missileSiloLimit' }
|
||||
}
|
||||
|
||||
return { valid: true }
|
||||
}
|
||||
|
||||
@@ -105,7 +121,18 @@ export const executeDefenseBuild = (
|
||||
|
||||
// 计算军官加成
|
||||
const bonuses = officerLogic.calculateActiveBonuses(officers, Date.now())
|
||||
const buildTime = shipLogic.calculateDefenseBuildTime(defenseType, quantity, bonuses.buildingSpeedBonus)
|
||||
|
||||
// 获取机器人工厂和纳米工厂等级
|
||||
const roboticsFactoryLevel = planet.buildings[BuildingType.RoboticsFactory] || 0
|
||||
const naniteFactoryLevel = planet.buildings[BuildingType.NaniteFactory] || 0
|
||||
|
||||
const buildTime = shipLogic.calculateDefenseBuildTime(
|
||||
defenseType,
|
||||
quantity,
|
||||
bonuses.buildingSpeedBonus,
|
||||
roboticsFactoryLevel,
|
||||
naniteFactoryLevel
|
||||
)
|
||||
|
||||
// 扣除资源
|
||||
resourceLogic.deductResources(planet.resources, totalCost)
|
||||
|
||||
@@ -13,20 +13,10 @@ const router = createRouter({
|
||||
{ path: '/battle-simulator', name: 'battle-simulator', component: () => import('@/views/BattleSimulatorView.vue') },
|
||||
{ path: '/messages', name: 'messages', component: () => import('@/views/MessagesView.vue') },
|
||||
{ path: '/galaxy', name: 'galaxy', component: () => import('@/views/GalaxyView.vue') },
|
||||
{ path: '/diplomacy', name: 'diplomacy', component: () => import('@/views/DiplomacyView.vue') },
|
||||
{ path: '/settings', name: 'settings', component: () => import('@/views/SettingsView.vue') },
|
||||
{
|
||||
path: '/gm',
|
||||
name: 'gm',
|
||||
component: () => import('@/views/GMView.vue'),
|
||||
beforeEnter: (_to, _from, next) => {
|
||||
// GM页面仅在开发模式下可访问
|
||||
if (import.meta.env.DEV) {
|
||||
next()
|
||||
} else {
|
||||
next('/')
|
||||
}
|
||||
}
|
||||
}
|
||||
{ path: '/gm', name: 'gm', component: () => import('@/views/GMView.vue') },
|
||||
{ path: '/:pathMatch(.*)*', name: 'not-found', component: () => import('@/views/NotFoundView.vue') }
|
||||
]
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import type { Planet, Player, BuildQueueItem, FleetMission, BattleResult, SpyReport, Officer } from '@/types/game'
|
||||
import type {
|
||||
Planet,
|
||||
Player,
|
||||
BuildQueueItem,
|
||||
FleetMission,
|
||||
BattleResult,
|
||||
SpyReport,
|
||||
Officer,
|
||||
SpiedNotification,
|
||||
NPCActivityNotification,
|
||||
IncomingFleetAlert,
|
||||
MissileAttack
|
||||
} from '@/types/game'
|
||||
import { TechnologyType, OfficerType } from '@/types/game'
|
||||
import type { Locale } from '@/locales'
|
||||
import pkg from '../../package.json'
|
||||
@@ -9,6 +21,7 @@ export const useGameStore = defineStore('game', {
|
||||
state: () => ({
|
||||
gameTime: Date.now(),
|
||||
isPaused: false,
|
||||
gameSpeed: 1,
|
||||
player: {
|
||||
id: 'player1',
|
||||
name: '',
|
||||
@@ -17,8 +30,18 @@ export const useGameStore = defineStore('game', {
|
||||
officers: {} as Record<OfficerType, Officer>,
|
||||
researchQueue: [] as BuildQueueItem[],
|
||||
fleetMissions: [] as FleetMission[],
|
||||
missileAttacks: [] as MissileAttack[],
|
||||
battleReports: [] as BattleResult[],
|
||||
spyReports: [] as SpyReport[]
|
||||
spyReports: [] as SpyReport[],
|
||||
spiedNotifications: [] as SpiedNotification[],
|
||||
npcActivityNotifications: [] as NPCActivityNotification[],
|
||||
missionReports: [],
|
||||
incomingFleetAlerts: [] as IncomingFleetAlert[],
|
||||
giftNotifications: [],
|
||||
giftRejectedNotifications: [],
|
||||
points: 0,
|
||||
isGMEnabled: false, // 明确设置 GM 模式默认为 false
|
||||
lastVersionCheckTime: 0 // 最后一次检查版本的时间戳,默认为0
|
||||
} as Player,
|
||||
currentPlanetId: '',
|
||||
isDark: '',
|
||||
|
||||
23
src/stores/npcStore.ts
Normal file
23
src/stores/npcStore.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import type { NPC } from '@/types/game'
|
||||
import pkg from '../../package.json'
|
||||
import { encryptData, decryptData } from '@/utils/crypto'
|
||||
|
||||
/**
|
||||
* NPC Store
|
||||
* 存储和管理所有NPC数据
|
||||
*/
|
||||
export const useNPCStore = defineStore('npc', {
|
||||
state: () => ({
|
||||
npcs: [] as NPC[],
|
||||
lastGrowthCheck: {} as Record<string, number> // npcId -> timestamp
|
||||
}),
|
||||
persist: {
|
||||
key: `${pkg.name}-npcs`,
|
||||
storage: localStorage,
|
||||
serializer: {
|
||||
serialize: state => encryptData(state),
|
||||
deserialize: value => decryptData(value)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -6,37 +6,38 @@
|
||||
:root {
|
||||
--radius: 0.625rem;
|
||||
|
||||
/* Light mode colors */
|
||||
--background: oklch(0.99 0 0);
|
||||
--foreground: oklch(0.129 0.042 264.695);
|
||||
--card: oklch(1 0 0);
|
||||
--card-foreground: oklch(0.129 0.042 264.695);
|
||||
--popover: oklch(1 0 0);
|
||||
--popover-foreground: oklch(0.129 0.042 264.695);
|
||||
--primary: oklch(0.208 0.042 265.755);
|
||||
--primary-foreground: oklch(0.984 0.003 247.858);
|
||||
--secondary: oklch(0.968 0.007 247.896);
|
||||
--secondary-foreground: oklch(0.208 0.042 265.755);
|
||||
--muted: oklch(0.968 0.007 247.896);
|
||||
--muted-foreground: oklch(0.554 0.046 257.417);
|
||||
--accent: oklch(0.968 0.007 247.896);
|
||||
--accent-foreground: oklch(0.208 0.042 265.755);
|
||||
--destructive: oklch(0.577 0.245 27.325);
|
||||
--border: oklch(0.929 0.013 255.508);
|
||||
--input: oklch(0.929 0.013 255.508);
|
||||
/* Light mode colors - 更护眼的暖色调配色 */
|
||||
--background: oklch(0.95 0.008 85);
|
||||
--foreground: oklch(0.3 0.02 85);
|
||||
--card: oklch(0.97 0.006 85);
|
||||
--card-foreground: oklch(0.3 0.02 85);
|
||||
--popover: oklch(0.97 0.006 85);
|
||||
--popover-foreground: oklch(0.3 0.02 85);
|
||||
--primary: oklch(0.35 0.03 240);
|
||||
--primary-foreground: oklch(0.98 0.005 85);
|
||||
--secondary: oklch(0.92 0.01 85);
|
||||
--secondary-foreground: oklch(0.3 0.02 85);
|
||||
--muted: oklch(0.92 0.01 85);
|
||||
--muted-foreground: oklch(0.5 0.02 85);
|
||||
--accent: oklch(0.92 0.01 85);
|
||||
--accent-foreground: oklch(0.3 0.02 85);
|
||||
--destructive: oklch(0.5 0.15 25);
|
||||
--destructive-foreground: oklch(0.98 0.005 85);
|
||||
--border: oklch(0.86 0.012 85);
|
||||
--input: oklch(0.86 0.012 85);
|
||||
--ring: oklch(0.704 0.04 256.788);
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
--chart-3: oklch(0.398 0.07 227.392);
|
||||
--chart-4: oklch(0.828 0.189 84.429);
|
||||
--chart-5: oklch(0.769 0.188 70.08);
|
||||
--sidebar: oklch(0.984 0.003 247.858);
|
||||
--sidebar-foreground: oklch(0.129 0.042 264.695);
|
||||
--sidebar-primary: oklch(0.208 0.042 265.755);
|
||||
--sidebar-primary-foreground: oklch(0.984 0.003 247.858);
|
||||
--sidebar-accent: oklch(0.968 0.007 247.896);
|
||||
--sidebar-accent-foreground: oklch(0.208 0.042 265.755);
|
||||
--sidebar-border: oklch(0.929 0.013 255.508);
|
||||
--sidebar: oklch(0.96 0.006 85);
|
||||
--sidebar-foreground: oklch(0.3 0.02 85);
|
||||
--sidebar-primary: oklch(0.35 0.03 240);
|
||||
--sidebar-primary-foreground: oklch(0.98 0.005 85);
|
||||
--sidebar-accent: oklch(0.92 0.01 85);
|
||||
--sidebar-accent-foreground: oklch(0.3 0.02 85);
|
||||
--sidebar-border: oklch(0.86 0.012 85);
|
||||
--sidebar-ring: oklch(0.704 0.04 256.788);
|
||||
}
|
||||
|
||||
@@ -94,6 +95,7 @@
|
||||
--color-accent: var(--accent);
|
||||
--color-accent-foreground: var(--accent-foreground);
|
||||
--color-destructive: var(--destructive);
|
||||
--color-destructive-foreground: var(--destructive-foreground);
|
||||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// 位置类型
|
||||
export interface Position {
|
||||
galaxy: number
|
||||
system: number
|
||||
position: number
|
||||
}
|
||||
|
||||
// 资源类型
|
||||
export interface Resources {
|
||||
metal: number
|
||||
@@ -13,14 +20,18 @@ export const BuildingType = {
|
||||
CrystalMine: 'crystalMine',
|
||||
DeuteriumSynthesizer: 'deuteriumSynthesizer',
|
||||
SolarPlant: 'solarPlant',
|
||||
FusionReactor: 'fusionReactor', // 核聚变反应堆
|
||||
RoboticsFactory: 'roboticsFactory',
|
||||
NaniteFactory: 'naniteFactory', // 纳米工厂
|
||||
Shipyard: 'shipyard',
|
||||
Hangar: 'hangar', // 机库
|
||||
ResearchLab: 'researchLab',
|
||||
MetalStorage: 'metalStorage',
|
||||
CrystalStorage: 'crystalStorage',
|
||||
DeuteriumTank: 'deuteriumTank',
|
||||
DarkMatterCollector: 'darkMatterCollector', // 暗物质收集器
|
||||
DarkMatterTank: 'darkMatterTank', // 暗物质储罐
|
||||
MissileSilo: 'missileSilo', // 导弹发射井
|
||||
Terraformer: 'terraformer', // 地形改造器
|
||||
// 月球专属建筑
|
||||
LunarBase: 'lunarBase', // 月球基地
|
||||
@@ -63,9 +74,15 @@ export const TechnologyType = {
|
||||
HyperspaceTechnology: 'hyperspaceTechnology',
|
||||
PlasmaTechnology: 'plasmaTechnology',
|
||||
ComputerTechnology: 'computerTechnology', // 计算机技术
|
||||
EspionageTechnology: 'espionageTechnology', // 间谍技术
|
||||
CombustionDrive: 'combustionDrive',
|
||||
ImpulseDrive: 'impulseDrive',
|
||||
HyperspaceDrive: 'hyperspaceDrive',
|
||||
WeaponsTechnology: 'weaponsTechnology', // 武器技术
|
||||
ShieldingTechnology: 'shieldingTechnology', // 护盾技术
|
||||
ArmourTechnology: 'armourTechnology', // 装甲技术
|
||||
Astrophysics: 'astrophysics', // 天体物理学
|
||||
GravitonTechnology: 'gravitonTechnology', // 引力技术
|
||||
DarkMatterTechnology: 'darkMatterTechnology', // 暗物质技术
|
||||
TerraformingTechnology: 'terraformingTechnology', // 地形改造技术
|
||||
PlanetDestructionTech: 'planetDestructionTech' // 行星毁灭技术
|
||||
@@ -103,6 +120,8 @@ export const DefenseType = {
|
||||
PlasmaTurret: 'plasmaTurret',
|
||||
SmallShieldDome: 'smallShieldDome',
|
||||
LargeShieldDome: 'largeShieldDome',
|
||||
AntiBallisticMissile: 'antiBallisticMissile', // 反弹道导弹
|
||||
InterplanetaryMissile: 'interplanetaryMissile', // 星际导弹
|
||||
PlanetaryShield: 'planetaryShield' // 行星护盾
|
||||
} as const
|
||||
|
||||
@@ -127,11 +146,15 @@ export const ShipType = {
|
||||
HeavyFighter: 'heavyFighter',
|
||||
Cruiser: 'cruiser',
|
||||
Battleship: 'battleship',
|
||||
Battlecruiser: 'battlecruiser', // 战列巡洋舰
|
||||
Bomber: 'bomber', // 轰炸机
|
||||
Destroyer: 'destroyer', // 驱逐舰
|
||||
SmallCargo: 'smallCargo',
|
||||
LargeCargo: 'largeCargo',
|
||||
ColonyShip: 'colonyShip',
|
||||
Recycler: 'recycler',
|
||||
EspionageProbe: 'espionageProbe',
|
||||
SolarSatellite: 'solarSatellite', // 太阳能卫星
|
||||
DarkMatterHarvester: 'darkMatterHarvester', // 暗物质采集船
|
||||
Deathstar: 'deathstar' // 死星
|
||||
} as const
|
||||
@@ -161,11 +184,15 @@ export interface Fleet {
|
||||
[ShipType.HeavyFighter]: number
|
||||
[ShipType.Cruiser]: number
|
||||
[ShipType.Battleship]: number
|
||||
[ShipType.Battlecruiser]: number
|
||||
[ShipType.Bomber]: number
|
||||
[ShipType.Destroyer]: number
|
||||
[ShipType.SmallCargo]: number
|
||||
[ShipType.LargeCargo]: number
|
||||
[ShipType.ColonyShip]: number
|
||||
[ShipType.Recycler]: number
|
||||
[ShipType.EspionageProbe]: number
|
||||
[ShipType.SolarSatellite]: number
|
||||
[ShipType.DarkMatterHarvester]: number
|
||||
[ShipType.Deathstar]: number
|
||||
}
|
||||
@@ -180,18 +207,76 @@ export const MissionType = {
|
||||
Expedition: 'expedition',
|
||||
HarvestDarkMatter: 'harvestDarkMatter', // 暗物质采集
|
||||
Recycle: 'recycle', // 回收残骸
|
||||
Destroy: 'destroy' // 行星毁灭
|
||||
Destroy: 'destroy', // 行星毁灭
|
||||
MissileAttack: 'missileAttack' // 导弹攻击
|
||||
} as const
|
||||
|
||||
export type MissionType = (typeof MissionType)[keyof typeof MissionType]
|
||||
|
||||
// 外交关系状态
|
||||
export const RelationStatus = {
|
||||
Hostile: 'hostile', // 敌对
|
||||
Neutral: 'neutral', // 中立
|
||||
Friendly: 'friendly' // 友好
|
||||
} as const
|
||||
|
||||
export type RelationStatus = (typeof RelationStatus)[keyof typeof RelationStatus]
|
||||
|
||||
// 外交事件类型
|
||||
export const DiplomaticEventType = {
|
||||
GiftResources: 'giftResources', // 赠送资源
|
||||
Attack: 'attack', // 攻击
|
||||
Spy: 'spy', // 侦查
|
||||
StealDebris: 'stealDebris', // 抢夺残骸
|
||||
AllyAttacked: 'allyAttacked', // 盟友被攻击
|
||||
DestroyPlanet: 'destroyPlanet' // 摧毁星球
|
||||
} as const
|
||||
|
||||
export type DiplomaticEventType = (typeof DiplomaticEventType)[keyof typeof DiplomaticEventType]
|
||||
|
||||
// 外交关系
|
||||
export interface DiplomaticRelation {
|
||||
fromId: string // 关系发起方(玩家或NPC ID)
|
||||
toId: string // 关系接收方(玩家或NPC ID)
|
||||
reputation: number // 好感度值 (-100 到 +100)
|
||||
status: RelationStatus // 关系状态
|
||||
lastUpdated: number // 最后更新时间戳
|
||||
history?: Array<{
|
||||
// 关系变化历史
|
||||
timestamp: number
|
||||
change: number
|
||||
reason: DiplomaticEventType
|
||||
details?: string
|
||||
}>
|
||||
}
|
||||
|
||||
// 外交报告(显示好感度变化通知)
|
||||
export interface DiplomaticReport {
|
||||
id: string
|
||||
timestamp: number
|
||||
npcId: string // NPC ID
|
||||
npcName: string // NPC名称
|
||||
eventType: DiplomaticEventType // 事件类型
|
||||
reputationChange: number // 好感度变化值
|
||||
newReputation: number // 新的好感度值
|
||||
oldStatus: RelationStatus // 旧的关系状态
|
||||
newStatus: RelationStatus // 新的关系状态
|
||||
message: string // 消息内容(已弃用,保留用于兼容性)
|
||||
messageKey?: string // 翻译键(如 'diplomacy.reports.youDestroyedNpcPlanet')
|
||||
messageParams?: Record<string, string | number> // 翻译参数(如 { npcName: 'NPC-1', planetName: '星球 1:1:8', reputation: -80 })
|
||||
read?: boolean // 已读状态
|
||||
}
|
||||
|
||||
// 舰队任务
|
||||
export interface FleetMission {
|
||||
id: string
|
||||
playerId: string
|
||||
playerId: string // 玩家ID,如果是NPC任务则为NPC ID
|
||||
npcId?: string // NPC ID(如果是NPC发起的任务)
|
||||
isHostile?: boolean // 是否是敌对任务(用于警告显示)
|
||||
originPlanetId: string
|
||||
targetPosition: { galaxy: number; system: number; position: number }
|
||||
targetPlanetId?: string
|
||||
debrisFieldId?: string // 残骸场ID(用于回收任务)
|
||||
missionType: MissionType
|
||||
fleet: Partial<Fleet>
|
||||
cargo: Resources
|
||||
@@ -199,6 +284,22 @@ export interface FleetMission {
|
||||
arrivalTime: number
|
||||
returnTime?: number
|
||||
status: 'outbound' | 'returning' | 'arrived'
|
||||
// 外交系统字段
|
||||
isGift?: boolean // 是否为赠送资源任务
|
||||
giftTargetNpcId?: string // 赠送目标NPC ID
|
||||
}
|
||||
|
||||
// 导弹攻击任务(不使用舰队系统)
|
||||
export interface MissileAttack {
|
||||
id: string
|
||||
playerId: string
|
||||
originPlanetId: string
|
||||
targetPosition: { galaxy: number; system: number; position: number }
|
||||
targetPlanetId?: string
|
||||
missileCount: number // 发射的星际导弹数量
|
||||
launchTime: number
|
||||
arrivalTime: number
|
||||
status: 'flying' | 'arrived' | 'intercepted'
|
||||
}
|
||||
|
||||
// 战斗结果
|
||||
@@ -247,6 +348,8 @@ export interface SpyReport {
|
||||
timestamp: number
|
||||
spyId: string
|
||||
targetPlanetId: string
|
||||
targetPlanetName: string // 目标星球名称
|
||||
targetPosition: Position // 目标星球坐标
|
||||
targetPlayerId: string
|
||||
resources: Resources
|
||||
fleet?: Partial<Fleet>
|
||||
@@ -257,6 +360,105 @@ export interface SpyReport {
|
||||
read?: boolean // 已读状态
|
||||
}
|
||||
|
||||
// 被侦查通知(玩家被NPC侦查时收到)
|
||||
export interface SpiedNotification {
|
||||
id: string
|
||||
timestamp: number
|
||||
npcId: string // 侦查者NPC ID
|
||||
npcName: string // 侦查者NPC名称
|
||||
targetPlanetId: string // 被侦查的星球ID
|
||||
targetPlanetName: string // 被侦查的星球名称
|
||||
detectionSuccess: boolean // 是否被发现
|
||||
read?: boolean
|
||||
}
|
||||
|
||||
// NPC活动通知(回收残骸等)
|
||||
export interface NPCActivityNotification {
|
||||
id: string
|
||||
timestamp: number
|
||||
npcId: string // NPC ID
|
||||
npcName: string // NPC名称
|
||||
activityType: 'recycle' // 活动类型
|
||||
targetPosition: Position // 目标位置
|
||||
targetPlanetId?: string // 目标星球ID(如果在玩家星球位置)
|
||||
targetPlanetName?: string // 目标星球名称
|
||||
arrivalTime: number // 到达时间
|
||||
read?: boolean
|
||||
}
|
||||
|
||||
// 即将到来的敌对舰队警告
|
||||
export interface IncomingFleetAlert {
|
||||
id: string // 对应的FleetMission ID
|
||||
npcId: string // NPC ID
|
||||
npcName: string // NPC名称
|
||||
missionType: MissionType // 任务类型(spy/attack)
|
||||
targetPlanetId: string // 目标星球ID
|
||||
targetPlanetName: string // 目标星球名称
|
||||
arrivalTime: number // 到达时间
|
||||
fleetSize: number // 舰队总数(用于显示规模)
|
||||
read?: boolean
|
||||
}
|
||||
|
||||
// 任务报告(运输、殖民、回收、部署、毁灭等任务的结果通知)
|
||||
export interface MissionReport {
|
||||
id: string
|
||||
timestamp: number
|
||||
missionType: MissionType
|
||||
originPlanetId: string
|
||||
originPlanetName: string
|
||||
targetPosition: { galaxy: number; system: number; position: number }
|
||||
targetPlanetId?: string
|
||||
targetPlanetName?: string
|
||||
success: boolean // 任务是否成功
|
||||
message: string // 任务结果描述
|
||||
// 任务特定的详细信息
|
||||
details?: {
|
||||
// 运输任务:运输的资源
|
||||
transportedResources?: Resources
|
||||
// 殖民任务:新星球信息
|
||||
newPlanetId?: string
|
||||
newPlanetName?: string
|
||||
// 回收任务:回收的资源
|
||||
recycledResources?: Pick<Resources, 'metal' | 'crystal'>
|
||||
remainingDebris?: Pick<Resources, 'metal' | 'crystal'>
|
||||
// 毁灭任务:摧毁的星球
|
||||
destroyedPlanetName?: string
|
||||
// 部署任务:部署的舰队
|
||||
deployedFleet?: Partial<Fleet>
|
||||
// 导弹攻击任务:导弹信息
|
||||
missileCount?: number
|
||||
missileHits?: number
|
||||
missileIntercepted?: number
|
||||
defenseLosses?: Partial<Record<DefenseType, number>>
|
||||
}
|
||||
read?: boolean
|
||||
}
|
||||
|
||||
// 礼物通知(NPC赠送礼物,等待玩家接受或拒绝)
|
||||
export interface GiftNotification {
|
||||
id: string
|
||||
timestamp: number
|
||||
fromNpcId: string // 赠送方NPC ID
|
||||
fromNpcName: string // 赠送方NPC名称
|
||||
resources: Resources // 赠送的资源
|
||||
currentReputation: number // 当前好感度
|
||||
expectedReputationGain: number // 预期好感度增加
|
||||
expiresAt: number // 过期时间(7天后自动拒绝)
|
||||
read?: boolean
|
||||
}
|
||||
|
||||
// 礼物被拒绝通知(玩家赠送礼物被NPC拒绝)
|
||||
export interface GiftRejectedNotification {
|
||||
id: string
|
||||
timestamp: number
|
||||
npcId: string // NPC ID
|
||||
npcName: string // NPC名称
|
||||
rejectedResources: Resources // 被拒绝的资源
|
||||
currentReputation: number // 当前好感度
|
||||
reason: string // 拒绝原因
|
||||
read?: boolean
|
||||
}
|
||||
|
||||
// 残骸场
|
||||
export interface DebrisField {
|
||||
id: string
|
||||
@@ -354,9 +556,24 @@ export interface Player {
|
||||
officers: Record<OfficerType, Officer>
|
||||
researchQueue: BuildQueueItem[]
|
||||
fleetMissions: FleetMission[]
|
||||
missileAttacks: MissileAttack[] // 导弹攻击任务
|
||||
battleReports: BattleResult[]
|
||||
spyReports: SpyReport[]
|
||||
spiedNotifications: SpiedNotification[] // 被侦查通知
|
||||
npcActivityNotifications: NPCActivityNotification[] // NPC活动通知(回收残骸等)
|
||||
missionReports: MissionReport[] // 任务报告(运输、殖民、回收等)
|
||||
incomingFleetAlerts: IncomingFleetAlert[] // 即将到来的敌对舰队警告
|
||||
giftNotifications: GiftNotification[] // 礼物通知(等待接受/拒绝)
|
||||
giftRejectedNotifications: GiftRejectedNotification[] // 礼物被拒绝通知
|
||||
points: number // 总积分(每1000资源=1分)
|
||||
isGMEnabled?: boolean // GM模式开关(默认false,通过秘籍激活)
|
||||
lastVersionCheckTime?: number // 最后一次自动检查版本的时间戳(被动检测)
|
||||
lastManualUpdateCheck?: number // 最后一次手动检查更新的时间戳(主动检测)
|
||||
// 外交系统字段
|
||||
diplomaticRelations?: Record<string, DiplomaticRelation> // 玩家对NPC的关系(key: npcId)
|
||||
diplomaticReports?: DiplomaticReport[] // 外交变化报告
|
||||
// 新手引导字段
|
||||
tutorialProgress?: TutorialProgress // 新手引导进度
|
||||
}
|
||||
|
||||
// 游戏状态
|
||||
@@ -384,4 +601,54 @@ export interface NPC {
|
||||
planets: Planet[]
|
||||
technologies: Record<TechnologyType, number>
|
||||
difficulty: 'easy' | 'medium' | 'hard'
|
||||
// 行为跟踪字段
|
||||
lastSpyTime?: number // 上次侦查玩家的时间
|
||||
lastAttackTime?: number // 上次攻击玩家的时间
|
||||
playerSpyReports?: Record<string, SpyReport> // 对玩家星球的侦查报告(key: planetId)
|
||||
fleetMissions?: FleetMission[] // NPC的舰队任务
|
||||
// 被攻击追踪
|
||||
attackedBy?: Record<
|
||||
string,
|
||||
{
|
||||
count: number // 被攻击次数
|
||||
lastAttackTime: number // 最后被攻击时间
|
||||
planetId?: string // 攻击者星球ID
|
||||
}
|
||||
>
|
||||
alertUntil?: number // 警戒状态持续到的时间戳
|
||||
revengeTarget?: string // 复仇目标玩家ID
|
||||
// 外交系统字段
|
||||
relations?: Record<string, DiplomaticRelation> // NPC对其他实体的关系(key: targetId)
|
||||
allies?: string[] // 盟友列表(NPC ID)
|
||||
enemies?: string[] // 敌人列表(NPC ID)
|
||||
}
|
||||
|
||||
// 新手引导系统
|
||||
export interface TutorialStep {
|
||||
id: string
|
||||
title: string // 标题
|
||||
content: string // 内容描述
|
||||
target?: string // 目标元素的选择器或ID
|
||||
placement?: 'top' | 'bottom' | 'left' | 'right' | 'center' // 提示框位置
|
||||
route?: string // 需要跳转的路由
|
||||
action?: 'click' | 'build' | 'research' | 'none' // 需要完成的操作类型
|
||||
actionTarget?: string // 操作目标(建筑ID、科技ID等)
|
||||
completionCheck?: () => boolean // 完成条件检查函数(运行时注入)
|
||||
canSkip?: boolean // 是否可跳过此步骤
|
||||
highlightPadding?: number // 高亮区域的padding
|
||||
}
|
||||
|
||||
export interface TutorialState {
|
||||
isActive: boolean // 引导是否激活
|
||||
currentStepIndex: number // 当前步骤索引
|
||||
completedSteps: string[] // 已完成的步骤ID列表
|
||||
skipped: boolean // 是否已跳过整个引导
|
||||
lastActiveTime?: number // 最后活跃时间
|
||||
}
|
||||
|
||||
export interface TutorialProgress {
|
||||
tutorialCompleted: boolean // 是否完成了整个引导
|
||||
completedStepIds: string[] // 已完成的步骤ID
|
||||
currentStep: string | null // 当前步骤ID
|
||||
skippedAt?: number // 跳过的时间戳
|
||||
}
|
||||
|
||||
@@ -120,7 +120,4 @@ export interface CalculateDebrisRequest extends WorkerRequestMessage {
|
||||
/**
|
||||
* 所有 Worker 请求类型
|
||||
*/
|
||||
export type WorkerRequest =
|
||||
| SimulateBattleRequest
|
||||
| CalculatePlunderRequest
|
||||
| CalculateDebrisRequest
|
||||
export type WorkerRequest = SimulateBattleRequest | CalculatePlunderRequest | CalculateDebrisRequest
|
||||
|
||||
@@ -342,6 +342,7 @@ export const simulateBattle = (
|
||||
} else if (defenderUnits.length === 0) {
|
||||
winner = 'attacker'
|
||||
} else {
|
||||
// OGame原版规则:6回合后双方都有剩余单位时判定为平局
|
||||
winner = 'draw'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
/**
|
||||
* 格式化数字为英文单位(K, M, B)
|
||||
* 格式化数字为英文单位(K, M, B, T, Q)
|
||||
* @param num 数字
|
||||
* @param decimals 小数位数,默认2
|
||||
* @returns 格式化后的字符串
|
||||
*/
|
||||
export const formatNumber = (num: number, decimals: number = 2): string => {
|
||||
if (num >= 1_000_000_000) {
|
||||
if (num >= 1_000_000_000_000_000) {
|
||||
return (num / 1_000_000_000_000_000).toFixed(decimals) + 'Q'
|
||||
} else if (num >= 1_000_000_000_000) {
|
||||
return (num / 1_000_000_000_000).toFixed(decimals) + 'T'
|
||||
} else if (num >= 1_000_000_000) {
|
||||
return (num / 1_000_000_000).toFixed(decimals) + 'B'
|
||||
} else if (num >= 1_000_000) {
|
||||
return (num / 1_000_000).toFixed(decimals) + 'M'
|
||||
@@ -27,22 +31,59 @@ export const getResourceColor = (current: number, max: number): string => {
|
||||
if (ratio >= 0.7) return 'text-yellow-600 dark:text-yellow-400'
|
||||
return ''
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间(秒转为天时分秒)
|
||||
* 格式化相对时间(用于显示"多久之前")
|
||||
* @param seconds 秒数
|
||||
* @returns 格式化后的时间字符串(例如 2d 05:30:15 或 05:30:15)
|
||||
* @param t 翻译函数
|
||||
* @returns 格式化后的相对时间字符串
|
||||
*/
|
||||
export const formatTime = (seconds: number): string => {
|
||||
export const formatRelativeTime = (seconds: number, t: (key: string) => string): string => {
|
||||
const days = Math.floor(seconds / 86400)
|
||||
const hours = Math.floor((seconds % 86400) / 3600)
|
||||
const minutes = Math.floor((seconds % 3600) / 60)
|
||||
const secs = Math.floor(seconds % 60)
|
||||
|
||||
if (days > 0) {
|
||||
return `${days}:${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
|
||||
return `${days}${t('time.days')}${hours}${t('time.hours')}`
|
||||
}
|
||||
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`
|
||||
if (hours > 0) {
|
||||
return `${hours}${t('time.hours')}${minutes}${t('time.minutes')}`
|
||||
}
|
||||
if (minutes > 0) {
|
||||
return `${minutes}${t('time.minutes')}`
|
||||
}
|
||||
return `${secs}${t('time.seconds')}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间(秒转为 年:天:时:分:秒)
|
||||
* @param seconds 秒数
|
||||
* @returns 格式化后的时间字符串
|
||||
* 例如:
|
||||
* 1:02:03:04:05
|
||||
* 02:03:04:05
|
||||
* 03:04:05
|
||||
*/
|
||||
export const formatTime = (seconds: number): string => {
|
||||
const YEAR = 365 * 86400
|
||||
const years = Math.floor(seconds / YEAR)
|
||||
seconds %= YEAR
|
||||
const days = Math.floor(seconds / 86400)
|
||||
seconds %= 86400
|
||||
const hours = Math.floor(seconds / 3600)
|
||||
seconds %= 3600
|
||||
const minutes = Math.floor(seconds / 60)
|
||||
const secs = Math.floor(seconds % 60)
|
||||
const h = hours.toString().padStart(2, '0')
|
||||
const m = minutes.toString().padStart(2, '0')
|
||||
const s = secs.toString().padStart(2, '0')
|
||||
if (years > 0) {
|
||||
return `${years}:${days}:${h}:${m}:${s}`
|
||||
}
|
||||
if (days > 0) {
|
||||
return `${days}:${h}:${m}:${s}`
|
||||
}
|
||||
return `${h}:${m}:${s}`
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user