diff --git a/.air.toml b/.air.toml index 19f54c2ac..8348c3591 100644 --- a/.air.toml +++ b/.air.toml @@ -15,7 +15,7 @@ full_bin = "APP_ENV=dev APP_USER=air ./tmp/main" # Watch these filename extensions. include_ext = ["go", "tpl", "tmpl", "html", "toml", "po", "conf"] # Ignore these filename extensions or directories. -exclude_dir = ["assets", "tmp", "vendor", "app/node_modules", "upload", "docs", "resources", ".idea"] +exclude_dir = ["assets", "tmp", "vendor", "app/node_modules", "upload", "docs", "resources", ".idea", "cmd"] # Watch these directories if you specified. include_dir = [] # Exclude files. @@ -33,7 +33,7 @@ delay = 1000 # ms # Stop running old binary when build errors occur. stop_on_error = true # Send Interrupt signal before killing process (windows does not support this feature) -send_interrupt = false +send_interrupt = true # Delay after sending Interrupt signal kill_delay = 500 # ms diff --git a/.cursor/mcp.json b/.cursor/mcp.json new file mode 100644 index 000000000..846943055 --- /dev/null +++ b/.cursor/mcp.json @@ -0,0 +1,13 @@ +{ + "mcpServers": { + "eslint": { + "command": "npx", + "args": ["@eslint/mcp@latest"], + "env": {} + }, + "context7": { + "command": "npx", + "args": ["-y", "@upstash/context7-mcp"] + } + } +} \ No newline at end of file diff --git a/.cursor/rules/backend.mdc b/.cursor/rules/backend.mdc new file mode 100644 index 000000000..27a215ad5 --- /dev/null +++ b/.cursor/rules/backend.mdc @@ -0,0 +1,56 @@ +--- +description: +globs: **/**/*.go +alwaysApply: false +--- +# Cursor Rules +You are an expert in Go, Gin, Gorm, Gen, Cosy (https://cosy.uozi.org/) with a deep understanding of best practices and performance optimization techniques in these technologies. + +## 1. Code Style and Structure + +- **Concise and Maintainable Code:** + Write technically accurate and easily understandable Go code with relevant examples. + +- **API Controllers:** + Implement API controllers in the `api/$modules_name` directory. + +- **Database Models:** + Define database table models in the `model/` folder. + +- **Query Simplification:** + Use [Gen](mdc:https:/cosy.uozi.org) to streamline query operations, reducing boilerplate code. + +- **Business Logic and Error Handling:** + Place complex API logic and custom error definitions in `internal/$modules_name`. Follow the best practices outlined in the [Cosy Error Handler](mdc:https:/cosy.uozi.org/error-handler). + +- **Routing:** + Register all application routes in the `router/` directory. + +- **Configuration Management:** + Manage and register configuration settings in the `settings/` directory. + +## 2. CRUD Operations + +- **Standardized Operations:** + Utilize [Cosy](mdc:https:/cosy.uozi.org) to implement Create, Read, Update, and Delete (CRUD) operations consistently across the project. + +## 3. Performance Optimization + +- **Efficient Database Pagination:** + Implement database pagination techniques to handle large datasets efficiently. + +- **Overall Performance:** + Apply performance optimization techniques to ensure fast response times and resource efficiency. + +## 4. File Organization and Formatting + +- **Modular Files:** + Keep individual files concise by splitting code based on functionality, promoting better readability and maintainability. + +- **Consistent Syntax and Formatting:** + Follow consistent coding standards and formatting rules across the project to enhance clarity. + +## 5. Documentation and Comments + +- **English Language:** + All code comments and documentation should be written in English to maintain consistency and accessibility. \ No newline at end of file diff --git a/.cursor/rules/frontend.mdc b/.cursor/rules/frontend.mdc new file mode 100644 index 000000000..43f215ee4 --- /dev/null +++ b/.cursor/rules/frontend.mdc @@ -0,0 +1,47 @@ +--- +description: +globs: app/**/*.tsx,app/**/*.vue,app/**/*.ts,app/**/*.js,app/**/*.json +alwaysApply: false +--- +You are an expert in TypeScript, Node.js, Vite, Vue.js, Vue Router, Pinia, VueUse, Ant Design Vue, and UnoCSS, with a deep understanding of best practices and performance optimization techniques in these technologies. + +Package manager: pnpm +- pnpm typecheck +   +    Code Style and Structure +    - Write concise, maintainable, and technically accurate TypeScript code with relevant examples. +    - Use functional and declarative programming patterns; avoid classes. +    - Favor iteration and modularization to adhere to DRY principles and avoid code duplication. +    - Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError). +    - Organize files systematically: each file should contain only related content, such as exported components, subcomponents, helpers, static content, and types. + - Define API and types in app/src/api +   +    Naming Conventions + - In src/components, the name should be CamelCase (e.g., app/src/components/ChatGPT/ChatGPT.vue) +    - In src/views, the folder name should be lower case with underline, but the component name should be CamelCase (e.g., app/src/views/system/About.vue) +    - Favor named exports for functions. +   +    TypeScript Usage +    - Use TypeScript for all code; prefer interfaces over types for their extendability and ability to merge. +   +    Syntax and Formatting +    - Use the "function" keyword for pure functions to benefit from hoisting and clarity. +    - Always use the Vue Composition API script setup style. + - Use Vue3.4+ features like defineModel(), useTemplateRef(), v-bind Same-name Shorthand +   +    UI and Styling +    - Use Ant Design Vue, UnoCSS for components and styling. +    - Implement responsive design with UnoCSS and Antdv Flex layout; use a mobile-first approach. +   +    Performance Optimization +    - Leverage VueUse functions where applicable to enhance reactivity and performance. +    - Wrap asynchronous components in Suspense with a fallback UI. +    - Use dynamic loading for non-critical components. +    - Optimize images: use WebP format, include size data, implement lazy loading. +    - Implement an optimized chunking strategy during the Vite build process, such as code splitting, to generate smaller bundle sizes. +   +    Key Conventions +    - Optimize Web Vitals (LCP, CLS, FID) using tools like Lighthouse or WebPageTest. + + Comments + - Always response in English diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 7aca31303..c41a9d0f7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,49 +1,38 @@ -FROM mcr.microsoft.com/devcontainers/base:jammy +FROM mcr.microsoft.com/devcontainers/base:noble # Combine installation steps for Nginx and Go to avoid repetitive update/cleanup commands RUN apt-get update && \ - apt-get install -y --no-install-recommends curl gnupg2 ca-certificates lsb-release ubuntu-keyring jq cloc && \ - \ - # Configure the Nginx repository - curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor > /usr/share/keyrings/nginx-archive-keyring.gpg && \ - echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/mainline/ubuntu $(lsb_release -cs) nginx" \ - > /etc/apt/sources.list.d/nginx.list && \ - printf "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \ - > /etc/apt/preferences.d/99nginx && \ - \ - # Update package information and install Nginx - apt-get update && \ - apt-get install -y --no-install-recommends nginx inotify-tools file && \ - \ - # Automatically retrieve the latest stable Go version and install it, - # download the appropriate binary based on system architecture (amd64 or arm64) - GO_VERSION=$(curl -sSL "https://golang.org/dl/?mode=json" | \ - jq -r 'map(select(.stable)) | .[0].version' | sed 's/^go//') && \ - ARCH=$(dpkg --print-architecture) && \ - if [ "$ARCH" = "arm64" ]; then \ - GO_ARCH=linux-arm64; \ - else \ - GO_ARCH=linux-amd64; \ - fi && \ - echo "Installing Go version: ${GO_VERSION} for architecture: ${GO_ARCH}" && \ - curl -sSL "https://golang.org/dl/go${GO_VERSION}.${GO_ARCH}.tar.gz" -o go.tar.gz && \ - rm -rf /usr/local/go && \ - tar -C /usr/local -xzf go.tar.gz && \ - rm go.tar.gz && \ - \ - # Remove jq and clean up to reduce image size - apt-get remove -y jq && \ - apt-get autoremove -y && \ - apt-get clean && \ - rm -rf /var/lib/apt/lists/* + apt-get install -y --no-install-recommends curl gnupg2 ca-certificates lsb-release ubuntu-keyring jq cloc software-properties-common && \ + \ + # Add PPA repository for nginx-extras + add-apt-repository -y ppa:ondrej/nginx && \ + \ + # Update package information and install Nginx-extras + apt-get update && \ + apt-get install -y --no-install-recommends nginx nginx-extras inotify-tools file && \ + \ + # Automatically retrieve the latest stable Go version and install it, + # download the appropriate binary based on system architecture (amd64 or arm64) + GO_VERSION=$(curl -sSL "https://golang.org/dl/?mode=json" | \ + jq -r 'map(select(.stable)) | .[0].version' | sed 's/^go//') && \ + ARCH=$(dpkg --print-architecture) && \ + if [ "$ARCH" = "arm64" ]; then \ + GO_ARCH=linux-arm64; \ + else \ + GO_ARCH=linux-amd64; \ + fi && \ + echo "Installing Go version: ${GO_VERSION} for architecture: ${GO_ARCH}" && \ + curl -sSL "https://golang.org/dl/go${GO_VERSION}.${GO_ARCH}.tar.gz" -o go.tar.gz && \ + rm -rf /usr/local/go && \ + tar -C /usr/local -xzf go.tar.gz && \ + rm go.tar.gz RUN cp -rp /etc/nginx /etc/nginx.orig # Set PATH to include Go installation and default go install binary location ENV PATH="/usr/local/go/bin:/root/go/bin:${PATH}" -# Install air with go install (requires Go 1.23 or higher) -RUN go install github.com/air-verse/air@latest +ENV NGINX_UI_WORKING_DIR=/var/run/ # set zsh as default shell RUN chsh -s $(which zsh) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index f3690edce..96a8284d7 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -11,7 +11,7 @@ "ghcr.io/devcontainers/features/common-utils:2": { "installOhMyZsh": true }, - "ghcr.io/devcontainers/features/node:1.6.1": {} + "ghcr.io/devcontainers/features/node:1.6.3": {} }, // Use 'forwardPorts' to make a list of ports inside the container available locally. @@ -28,8 +28,11 @@ "antfu.unocss", "github.copilot", "golang.go", + "ms-azuretools.vscode-docker", + "akino.i18n-gettext", + "github.vscode-github-actions", "vue.volar", - "ms-azuretools.vscode-docker" + "eamodio.gitlens" ] } }, diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 09e492ea9..8ea8aac94 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -7,6 +7,7 @@ services: - ../..:/workspaces:cached - ./go-path:/root/go - ./data/nginx:/etc/nginx + - /var/run/docker.sock:/var/run/docker.sock command: sleep infinity environment: - NGINX_UI_CERT_CA_DIR=https://pebble:14000/dir @@ -25,15 +26,38 @@ services: - nginx-ui networks: nginxui: - + nginx-ui-3: + image: nginx-ui-dev + container_name: nginx-ui-3 + environment: + - NGINX_UI_OFFICIAL_DOCKER=true + volumes: + - ../..:/workspaces:cached + - ./data/nginx-ui-3/nginx:/etc/nginx + - ./data/nginx-ui-3/nginx-ui:/etc/nginx-ui + - /var/run/docker.sock:/var/run/docker.sock + working_dir: /workspaces/nginx-ui + command: ./.devcontainer/node-supervisor.sh + depends_on: + - nginx-ui + networks: + nginxui: + nginx: + image: nginx-ui-dev + container_name: nginx + volumes: + - ./data/nginx-ui-3/nginx:/etc/nginx + command: sleep infinity + networks: + nginxui: pebble: image: ghcr.io/letsencrypt/pebble:latest volumes: - ./pebble-test:/test command: -config /test/config/pebble-config.json -strict -dnsserver challtestsrv:8053 ports: - - 14000:14000 # HTTPS ACME API - - 15000:15000 # HTTPS Management API + - 14000:14000 # HTTPS ACME API + - 15000:15000 # HTTPS Management API environment: - PEBBLE_VA_NOSLEEP=1 - PEBBLE_VA_ALWAYS_VALID=1 diff --git a/.devcontainer/init-nginx.sh b/.devcontainer/init-nginx.sh index 870807799..65f0aae05 100755 --- a/.devcontainer/init-nginx.sh +++ b/.devcontainer/init-nginx.sh @@ -1,6 +1,56 @@ +#!/bin/bash # init nginx config dir if [ "$(ls -A /etc/nginx)" = "" ]; then echo "Initialing Nginx config dir" cp -rp /etc/nginx.orig/* /etc/nginx/ echo "Initialed Nginx config dir" -fi \ No newline at end of file +fi + + +src_dir="/usr/share/nginx/modules-available" +dest_dir="/etc/nginx/modules-enabled" + +create_symlink() { + local module_name=$1 + local weight=$2 + + local target="$dest_dir/$weight-$module_name" + local source="$src_dir/$module_name" + + ln -sf "$source" "$target" + echo "Created symlink: $target -> $source" +} + +modules=( + "mod-http-ndk.conf 10" + "mod-http-auth-pam.conf 50" + "mod-http-cache-purge.conf 50" + "mod-http-dav-ext.conf 50" + "mod-http-echo.conf 50" + "mod-http-fancyindex.conf 50" + "mod-http-geoip.conf 50" + "mod-http-geoip2.conf 50" + "mod-http-headers-more-filter.conf 50" + "mod-http-image-filter.conf 50" + "mod-http-lua.conf 50" + "mod-http-perl.conf 50" + "mod-http-subs-filter.conf 50" + "mod-http-uploadprogress.conf 50" + "mod-http-upstream-fair.conf 50" + "mod-http-xslt-filter.conf 50" + "mod-mail.conf 50" + "mod-nchan.conf 50" + "mod-stream.conf 50" + "mod-stream-geoip.conf 70" + "mod-stream-geoip2.conf 70" +) + +for module in "${modules[@]}"; do + module_name=$(echo $module | awk '{print $1}') + weight=$(echo $module | awk '{print $2}') + + create_symlink "$module_name" "$weight" +done + +# start nginx +nginx diff --git a/.devcontainer/pebble-test/config/pebble-config.json b/.devcontainer/pebble-test/config/pebble-config.json index be398b8c7..a7603753c 100644 --- a/.devcontainer/pebble-test/config/pebble-config.json +++ b/.devcontainer/pebble-test/config/pebble-config.json @@ -20,7 +20,7 @@ }, "shortlived": { "description": "A short-lived cert profile, without actual enforcement", - "validityPeriod": 518400 + "validityPeriod": 7776000 } } } diff --git a/.devcontainer/start.sh b/.devcontainer/start.sh index 184b6a1ed..fd788472a 100755 --- a/.devcontainer/start.sh +++ b/.devcontainer/start.sh @@ -1,6 +1,9 @@ #!/bin/bash -# install zsh-autosuggestions +# install air +go install github.com/air-verse/air@latest + +install zsh-autosuggestions git clone https://github.com/zsh-users/zsh-autosuggestions ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions if ! grep -q "zsh-autosuggestions" ~/.zshrc; then diff --git a/.github/build/build_info.json b/.github/build/build_info.json index 07f13d17f..8befffd83 100644 --- a/.github/build/build_info.json +++ b/.github/build/build_info.json @@ -16,5 +16,10 @@ "darwin": { "amd64": {"arch": "o64", "name": "macos-64"}, "arm64": {"arch": "oa64", "name": "macos-arm64-v8a"} + }, + "windows": { + "386": {"arch": "i686", "name": "windows-32"}, + "amd64": {"arch": "x86_64", "name": "windows-64"}, + "arm64": {"arch": "aarch64", "name": "windows-arm64-v8a"} } } diff --git a/.github/renovate.json b/.github/renovate.json index 801fc2d96..03a48b3a4 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -27,11 +27,7 @@ "schedule": [ "after 2am and before 3am" ] - }, - { - "matchPackageNames": ["vue-tsc"], - "allowedVersions": "!/^2\\.2\\.0$/" } ], - "ignoreDeps": ["vue3-apexcharts"] + "ignoreDeps": ["vue3-apexcharts", "gorm.io/gorm", "gorm.io/plugin/dbresolver"] } diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dd517852d..2875cd47f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,7 @@ on: - 'weblate' paths: - "app/**/*.js" + - "app/**/*.ts" - "app/**/*.vue" - "app/src/language/**/*.po" - "app/i18n.json" @@ -69,7 +70,7 @@ jobs: - name: Build run: | - npx browserslist@latest --update-db + npx update-browserslist-db@latest pnpm build working-directory: app @@ -96,7 +97,7 @@ jobs: needs: build_app strategy: matrix: - goos: [ linux, darwin ] + goos: [ linux, darwin, windows ] goarch: [ amd64, 386, arm64 ] exclude: # Exclude i386 on darwin. @@ -140,7 +141,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: ^1.24.1 + go-version: ^1.24.4 cache: false - name: Setup environment @@ -150,12 +151,14 @@ jobs: export _ARCH=$(jq ".$GOOS[\"$GOARCH$GOARM\"].arch" -r < .github/build/build_info.json) export _ABI=$(jq ".$GOOS[\"$GOARCH$GOARM\"].abi // \"\"" -r < .github/build/build_info.json) export _ARTIFACT=nginx-ui-$GOOS-$GOARCH$(if [[ "$GOARM" ]]; then echo "v$GOARM"; fi) - echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, ABI: $_ABI, RELEASE_NAME: $_NAME, ARTIFACT_NAME: $_ARTIFACT" + export _BINARY=nginx-ui$(if [[ "$GOOS" == "windows" ]]; then echo ".exe"; fi) + echo "GOOS: $GOOS, GOARCH: $GOARCH, GOARM: $GOARM, ABI: $_ABI, RELEASE_NAME: $_NAME, ARTIFACT_NAME: $_ARTIFACT, BINARY_NAME: $_BINARY" echo "CACHE_NAME=$_NAME" >> $GITHUB_ENV echo "ARCH_NAME=$_ARCH" >> $GITHUB_ENV echo "ABI=$_ABI" >> $GITHUB_ENV echo "DIST=nginx-ui-$_NAME" >> $GITHUB_ENV echo "ARTIFACT=$_ARTIFACT" >> $GITHUB_ENV + echo "BINARY_NAME=$_BINARY" >> $GITHUB_ENV - name: Setup Go modules cache uses: actions/cache@v4 @@ -185,7 +188,7 @@ jobs: env: GOOS: linux GOARCH: amd64 - run: go generate + run: go generate cmd/version/generate.go - name: Install musl cross compiler if: env.GOOS == 'linux' @@ -213,20 +216,52 @@ jobs: echo "CC=${{ env.ARCH_NAME }}-clang" >> $GITHUB_ENV echo "CXX=${{ env.ARCH_NAME }}-clang++" >> $GITHUB_ENV echo "LD_FLAGS=-w" >> $GITHUB_ENV + + - name: Setup for Windows + if: env.GOOS == 'windows' + run: | + echo "LD_FLAGS=-w" >> $GITHUB_ENV + echo "CGO_ENABLED=1" >> $GITHUB_ENV + + # Install cross compilers based on architecture + sudo apt-get update + if [[ "$GOARCH" == "amd64" ]]; then + echo "Installing x86_64 Windows cross compiler" + sudo apt-get install -y gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 + echo "CC=x86_64-w64-mingw32-gcc" >> $GITHUB_ENV + echo "CXX=x86_64-w64-mingw32-g++" >> $GITHUB_ENV + elif [[ "$GOARCH" == "386" ]]; then + echo "Installing i686 Windows cross compiler" + sudo apt-get install -y gcc-mingw-w64-i686 g++-mingw-w64-i686 + echo "CC=i686-w64-mingw32-gcc" >> $GITHUB_ENV + echo "CXX=i686-w64-mingw32-g++" >> $GITHUB_ENV + elif [[ "$GOARCH" == "arm64" ]]; then + echo "Installing ARM64 Windows cross compiler" + # Ubuntu's apt repositories don't have mingw for ARM64 + # Use llvm-mingw project instead + mkdir -p $HOME/llvm-mingw + wget -q https://github.com/mstorsjo/llvm-mingw/releases/download/20231128/llvm-mingw-20231128-ucrt-ubuntu-20.04-x86_64.tar.xz + tar xf llvm-mingw-20231128-ucrt-ubuntu-20.04-x86_64.tar.xz -C $HOME/llvm-mingw --strip-components=1 + echo "PATH=$HOME/llvm-mingw/bin:$PATH" >> $GITHUB_ENV + echo "CC=aarch64-w64-mingw32-clang" >> $GITHUB_ENV + echo "CXX=aarch64-w64-mingw32-clang++" >> $GITHUB_ENV + else + echo "Unsupported Windows architecture: $GOARCH" + exit 1 + fi - name: Build run: | mkdir -p dist - go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o dist/nginx-ui -v main.go + go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o dist/$BINARY_NAME -v main.go - name: Archive backend artifacts uses: actions/upload-artifact@v4 with: name: ${{ env.ARTIFACT }} - path: dist/nginx-ui + path: dist/${{ env.BINARY_NAME }} - name: Prepare publish - if: github.event_name == 'release' run: | cp README*.md ./dist find dist -printf '%P\n' | tar -C dist --no-recursion -zcvf ${{ env.DIST }}.tar.gz -T - @@ -239,6 +274,30 @@ jobs: files: | ${{ env.DIST }}.tar.gz ${{ env.DIST }}.tar.gz.digest + + - name: Set up nodejs + uses: actions/setup-node@v4 + with: + node-version: current + + - name: Install dependencies + run: | + corepack enable + corepack prepare pnpm@latest --activate + + - name: Upload to R2 + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/dev' + uses: cloudflare/wrangler-action@v3 + env: + WRANGLER_LOG: debug + WRANGLER_LOG_SANITIZE: false + with: + accountId: ${{ secrets.CF_ACCOUNT_ID }} + apiToken: ${{ secrets.CF_R2_API_TOKEN }} + wranglerVersion: "4.21.1" + command: | + r2 object put nginx-ui-dev-build/${{ env.DIST }}.tar.gz --file ./${{ env.DIST }}.tar.gz --remote + r2 object put nginx-ui-dev-build/${{ env.DIST }}.tar.gz.digest --file ./${{ env.DIST }}.tar.gz.digest --remote docker-build: if: github.event_name != 'pull_request' @@ -260,6 +319,7 @@ jobs: type=schedule type=ref,event=branch type=semver,pattern={{version}} + type=semver,pattern={{raw}} type=sha type=raw,value=latest,enable=${{ github.event_name == 'release' && !github.event.release.prerelease }} @@ -269,7 +329,7 @@ jobs: path: ./dist - name: Prepare Artifacts - run: chmod +x ./dist/nginx-ui-*/nginx-ui + run: chmod +x ./dist/nginx-ui-*/nginx-ui* - name: Set up Docker Buildx id: buildx diff --git a/.github/workflows/documents.yml b/.github/workflows/documents.yml index 5ba557ee2..eead0402f 100644 --- a/.github/workflows/documents.yml +++ b/.github/workflows/documents.yml @@ -1,6 +1,7 @@ name: Build Documents on: + workflow_dispatch: push: branches: - '*' @@ -22,6 +23,12 @@ on: - "docs/.env*" - "docs/**/*.md" - ".github/workflows/doc*.yml" + release: + types: [published] + workflow_run: + workflows: ["Sync branch"] + types: + - completed jobs: build: @@ -33,7 +40,7 @@ jobs: - name: Set up nodejs uses: actions/setup-node@v4 with: - node-version: 21.x + node-version: 23.x - name: Install dependencies run: | @@ -52,8 +59,8 @@ jobs: name: dist path: docs/.vitepress/dist - - name: Deploy to server - if: github.event_name != 'pull_request' + - name: Deploy + if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main' || github.event_name == 'release' || (github.event_name == 'workflow_run' && github.event.workflow_run.conclusion == 'success')) uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ secrets.CF_API_TOKEN }} diff --git a/.github/workflows/sync-main-on-release.yml b/.github/workflows/sync-main-on-release.yml index 9da99d53b..9d0b05d73 100644 --- a/.github/workflows/sync-main-on-release.yml +++ b/.github/workflows/sync-main-on-release.yml @@ -16,6 +16,7 @@ jobs: fetch-depth: 0 ref: dev clean: false + token: ${{ secrets.PAT_TOKEN }} - name: Configure Git run: | diff --git a/.github/workflows/weblate-pull.yml b/.github/workflows/weblate-pull.yml index 3d3d66fb0..0e8779440 100644 --- a/.github/workflows/weblate-pull.yml +++ b/.github/workflows/weblate-pull.yml @@ -21,7 +21,7 @@ jobs: - name: Setup Python uses: actions/setup-python@v5 with: - python-version: '3.13.2' + python-version: '3.13.5' - name: Install wlc run: pip install wlc diff --git a/.github/workflows/weblate-sync.yml b/.github/workflows/weblate-sync.yml index 0cd094aad..11d086e17 100644 --- a/.github/workflows/weblate-sync.yml +++ b/.github/workflows/weblate-sync.yml @@ -51,7 +51,7 @@ jobs: - name: Setup python uses: actions/setup-python@v5 with: - python-version: '3.13.2' + python-version: '3.13.5' - name: Install wlc run: pip install wlc diff --git a/.gitignore b/.gitignore index 0c38fd5ef..99140d39f 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ internal/**/*.gen.go .devcontainer/go-path .devcontainer/data .devcontainer/casdoor.pem +.vscode/.i18n-gettext.secret diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..1040baec7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,38 @@ +{ + "i18n-gettext.localesConfig": { + "root": "app", + "type": "nested", + "basePath": "src/language", + "pattern": "${locale}/${domain}.po", + "defaultDomain": "app", + "sourceLanguage": "en" + }, + "i18n-gettext.translatorConfig": { + "onlyTranslateUntranslatedAndFuzzy": true, + "batch": { + "pageSize": 100 + } + }, + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.code-search": true, + "**/vendor": true, + "**/dist": true, + "**/build": true, + "**/out": true, + "**/tmp": true, + "**/.git": true, + "**/.DS_Store": true, + "**/database.db": true, + "**/.pnpm-store": true, + "**/nginx-ui": true + }, + "files.watcherExclude": { + "**/.git/objects/**": true, + "**/.git/subtree-cache/**": true, + "**/node_modules/*/**": true, + "**/tmp/**": true, + "**/.pnpm-store/**": true + } +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d44e62864..3e59b9359 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -2,7 +2,7 @@ "version": "2.0.0", "tasks": [ { - "label": "Start Backend", + "label": "[Go] Start Backend", "type": "shell", "command": "air", "isBackground": true, @@ -12,16 +12,17 @@ "problemMatcher": [] }, { - "label": "Start Frontend", + "label": "[App] Start Frontend", "type": "shell", "command": "cd app && pnpm dev", "isBackground": true, "presentation": { "panel": "new" - } + }, + "problemMatcher": [] }, { - "label": "Start Documentation", + "label": "[Docs] Start Documentation", "type": "shell", "command": "cd docs && pnpm docs:dev", "isBackground": true, @@ -31,12 +32,12 @@ "problemMatcher": [] }, { - "label": "Start All Services", + "label": "[All] Start All Services", "dependsOrder": "parallel", "dependsOn": [ - "Start Backend", - "Start Frontend", - "Start Documentation" + "[Go] Start Backend", + "[App] Start Frontend", + "[Docs] Start Documentation" ], "group": { "kind": "build", @@ -82,16 +83,16 @@ "problemMatcher": [] }, { - "label": "Go Generate", + "label": "[Go] Generate", "type": "shell", - "command": "./gen.sh", + "command": "go generate", "presentation": { "panel": "new" }, "problemMatcher": [] }, { - "label": "Bump Version", + "label": "[All] Bump Version", "type": "shell", "command": "./version.sh", "presentation": { diff --git a/Dockerfile b/Dockerfile index ca5a10efe..b21c5d627 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,6 +5,7 @@ ARG TARGETVARIANT EXPOSE 80 443 ENV NGINX_UI_OFFICIAL_DOCKER=true +ENV NGINX_UI_WORKING_DIR=/var/run/ # register nginx-ui service COPY resources/docker/nginx-ui.run /etc/s6-overlay/s6-rc.d/nginx-ui/run diff --git a/README-es.md b/README-es.md index 5aff39076..2d4534356 100644 --- a/README-es.md +++ b/README-es.md @@ -4,7 +4,7 @@ # Interfaz de usuario (UI) de Nginx -Otra UI web de Nginx, desarrollada por [0xJacky](https://jackyu.cn/) y [Hintay](https://blog.kugeek.com/). +Otra UI web de Nginx, desarrollada por [0xJacky](https://jackyu.cn/), [Hintay](https://blog.kugeek.com/) y [Akino](https://github.com/akinoccc). [![Build and Publish](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml/badge.svg)](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml) @@ -134,6 +134,7 @@ Para más información: [debian/conf/nginx.conf](https://salsa.debian.org/nginx- La UI de Nginx está disponible en las siguientes plataformas: - macOS 11 Big Sur y posterior (amd64 / arm64) +- Windows 10 y posterior (x86 /amd64 / arm64) - Linux 2.6.23 y posterior (x86 / amd64 / arm64 / armv5 / armv6 / armv7 / mips32 / mips64 / riscv64 / loongarch64) - Incluyendo pero no limitado a Debian 7 / 8, Ubuntu 12.04 / 14.04 y posterior, CentOS 6 / 7, Arch Linux - FreeBSD @@ -202,6 +203,7 @@ docker run -dit \ -v /mnt/user/appdata/nginx:/etc/nginx \ -v /mnt/user/appdata/nginx-ui:/etc/nginx-ui \ -v /var/www:/var/www \ + -v /var/run/docker.sock:/var/run/docker.sock \ -p 8080:80 -p 8443:443 \ uozi/nginx-ui:latest ``` @@ -247,7 +249,7 @@ go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/sett **Instalar and Actualizar** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ install +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ install ``` El puerto de escucha predeterminado es `9000` y el puerto de Desafío HTTP predeterminado es `9180`. Si hay un conflicto de puertos, modifique manualmente `/usr/local/etc/nginx-ui/app.ini`, @@ -256,13 +258,13 @@ luego use `systemctl restart nginx-ui` para recargar el servicio de UI de Nginx. **Eliminar UI Nginx UI, excepto los archivos de configuración y la base de datos** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ remove +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove ``` ### Uso avanzado ````shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ help +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ help ```` ## Ejemplo de configuración de proxy reverso de Nginx diff --git a/README-ja_JP.md b/README-ja_JP.md new file mode 100644 index 000000000..5cea40b24 --- /dev/null +++ b/README-ja_JP.md @@ -0,0 +1,390 @@ +
+ Nginx UI Logo +
+ +# Nginx UI + +もう一つのNginx Web UI [0xJacky](https://jackyu.cn/), [Hintay](https://blog.kugeek.com/), [Akino](https://github.com/akinoccc)によって開発されました。 + +[![DeepWiki](https://img.shields.io/badge/DeepWiki-0xJacky%2Fnginx--ui-blue.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==)](https://deepwiki.com/0xJacky/nginx-ui) + +[![Build and Publish](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml/badge.svg)](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml) +[![GitHub license](https://img.shields.io/github/license/0xJacky/nginx-ui?label=License&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") +[![Release Version](https://img.shields.io/github/release/0xJacky/nginx-ui?include_prereleases&label=Release&logo=github)](https://github.com/0xJacky/nginx-ui/releases/latest "Click to view the repo on Github") +[![GitHub Star](https://img.shields.io/github/stars/0xJacky/nginx-ui?label=Stars&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") +[![GitHub Fork](https://img.shields.io/github/forks/0xJacky/nginx-ui?label=Forks&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") +[![Repo Size](https://img.shields.io/github/repo-size/0xJacky/nginx-ui?label=Size&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") +[![GitHub Fork](https://img.shields.io/github/issues-closed-raw/0xJacky/nginx-ui?label=Closed%20Issue&logo=github)](https://github.com/0xJacky/nginx-ui/issues "Click to view the repo on Github") + +[![Docker Stars](https://img.shields.io/docker/stars/uozi/nginx-ui?label=Stars&logo=docker)](https://hub.docker.com/r/uozi/nginx-ui "Click to view the image on Docker Hub") +[![Docker Pulls](https://img.shields.io/docker/pulls/uozi/nginx-ui?label=Pulls&logo=docker)](https://hub.docker.com/r/uozi/nginx-ui "Click to view the image on Docker Hub") +[![Image Size](https://img.shields.io/docker/image-size/uozi/nginx-ui/latest?label=Image%20Size&logo=docker)](https://hub.docker.com/r/uozi/nginx-ui "Click to view the image on Docker Hub") + +[![Translated Status](https://weblate.nginxui.com/widget/nginx-ui/frontend/svg-badge.svg)](https://weblate.nginxui.com/engage/nginx-ui/) +[![Featured|HelloGitHub](https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=86f3a8f779934748a34fe6f1b5cd442f&claim_uid=MOFqadzAShCBeQj&theme=small)](https://hellogithub.com/repository/86f3a8f779934748a34fe6f1b5cd442f) + +## ドキュメント +公式ドキュメントは [nginxui.com](https://nginxui.com) を参照してください。 + +## スター推移 + +[![Stargazers over time](https://starchart.cc/0xJacky/nginx-ui.svg)](https://starchart.cc/0xJacky/nginx-ui) + +English | [Español](README-es.md) | [简体中文](README-zh_CN.md) | [繁體中文](README-zh_TW.md) | [Tiếng Việt](README-vi_VN.md) | [日本語](README-ja_JP.md) + +
+ 目次 +
    +
  1. + プロジェクトについて + +
  2. +
  3. + はじめに + +
  4. +
  5. + 手動ビルド + +
  6. +
  7. + Linux用スクリプト + +
  8. +
  9. Nginx リバースプロキシ設定例
  10. +
  11. 貢献方法
  12. +
  13. ライセンス
  14. +
+
+ +## プロジェクトについて + +![ダッシュボード](resources/screenshots/dashboard_en.png) + +### デモ +URL:[https://demo.nginxui.com](https://demo.nginxui.com) +- ユーザー名:admin +- パスワード:admin + +### 機能 + +- サーバーの CPU 使用率、メモリ使用率、ロードアベレージ、ディスク使用率 とかの指標をオンラインで見られるんやで。 +- 設定変更したら自動でバックアップ作ってくれて、バージョン比較&復元もできるんやわ。 +- クラスタ管理で複数ノードへのミラーリング操作もサポートしてるから、大規模環境でも楽勝や。 +- 暗号化した Nginx / Nginx UI の設定をエクスポートして、新環境へのデプロイ&復旧がサクッとできるで。 +- オンライン ChatGPT アシスタント(Deepseek-R1 のチェインオブソート表示付き)で設定の最適化や理解をサポートしてくれるんや。 +- MCP(Model Context Protocol)で AI エージェントが Nginx UI と連携できる特別インターフェースもあるから、自動化もバッチリや。 +- ワンクリックで Let’s Encrypt 証明書の発行&自動更新もしてくれるし。 +- 自社開発の **NgxConfigEditor**(ブロックエディタ)か、**Ace Code Editor**(LLM コード補完&シンタックスハイライト付き)で nginx 設定を直感的に編集でけるんや。 +- Nginx ログのオンライン閲覧機能もあるで。 +- Go と Vue で書かれとって、配布物は単一バイナリだからセットアップも簡単や。 +- 保存時に設定テスト→nginx 再読み込みまで自動でやってくれるで。 +- Web ターミナル +- ダークモード対応 +- レスポンシブデザイン + +### 多言語化 + +公式でサポートしてんのは: +- 英語 +- 簡体字中国語 +- 繁體字中国語 + + +非ネイティブの英語話者やから完璧ちゃうかもしれへんけど、気づいたことあったらフィードバックしてや! + +コミュニティのおかげで他の言語もいろいろ揃っとるで。翻訳に参加したい人は [Weblate](https://weblate.nginxui.com) 見てみてな。 + +### 主要技術 + +- [Go言語](https://go.dev) +- [Gin Web Framework](https://gin-gonic.com) +- [GORM](http://gorm.io) +- [Vue 3](https://v3.vuejs.org) +- [Vite](https://vitejs.dev) +- [TypeScript](https://www.typescriptlang.org/) +- [Ant Design Vue](https://antdv.com) +- [vue3-gettext](https://github.com/jshmrtn/vue3-gettext) +- [vue3-ace-editor](https://github.com/CarterLi/vue3-ace-editor) +- [Gonginx](https://github.com/tufanbarisyildirim/gonginx) +- [lego](https://github.com/go-acme/lego) + +## はじめに + +### 使用前の注意 + +Nginx UIはDebian系Webサーバ設定ファイルの標準に準拠します。 +作成されたサイト設定ファイルは、自動検出されたNginx設定フォルダ内の`sites-available`に配置されます。有効化されたサイトは`sites-enabled`にシンボリックリンクが作成されます。 + +非Debian系(Ubuntu以外)の場合は、以下のように`nginx.conf`をDebianスタイルに変更してください。 + +```nginx +http { + # ... + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} +``` + +詳細: [debian/conf/nginx.conf](https://salsa.debian.org/nginx-team/nginx/-/blob/master/debian/conf/nginx.conf#L59-L60) + +### インストール + +Nginx UIは以下のプラットフォームで利用可能です: + +- macOS 11 Big Sur and later (amd64 / arm64) +- Windows 10 and later (amd64 / arm64) +- Linux 2.6.23 and later (x86 / amd64 / arm64 / armv5 / armv6 / armv7 / mips32 / mips64 / riscv64 / loongarch64) + - Including but not limited to Debian 7 / 8, Ubuntu 12.04 / 14.04 and later, CentOS 6 / 7, Arch Linux +- FreeBSD +- OpenBSD +- Dragonfly BSD +- Openwrt + + +最新リリースは[リリースページ](https://github.com/0xJacky/nginx-ui/releases/latest)からダウンロード、または[Linux用インストールスクリプト](#script-for-linux)を利用 + + +### 使い方 + +初回起動後、ブラウザで`http://:`にアクセスし、初期設定を完了してください。 + +#### 実行ファイルから +**ターミナルでNginx UIを動かす** + +```shell +nginx-ui -config app.ini +``` +`Control+C`で終了します。 + +**バックグラウンドでNginx UIを動かす** + +```shell +nohup ./nginx-ui -config app.ini & +``` +以下のコマンドでNginx UIを停止する。 + +```shell +kill -9 $(ps -aux | grep nginx-ui | grep -v grep | awk '{print $2}') +``` + +#### Systemdで +[Linuxインストールスクリプト](#script-for-linux)を使うと、`nginx-ui`というsystemdサービスが作成されます。以下コマンドで操作可能: + +**起動** + +```shell +systemctl start nginx-ui +``` +**停止** + +```shell +systemctl stop nginx-ui +``` +**再起動** + +```shell +systemctl restart nginx-ui +``` + +#### Dockerで +公式イメージ [uozi/nginx-ui:latest](https://hub.docker.com/r/uozi/nginx-ui) はベースに公式 nginx イメージを利用しています。ホストの Nginx と置き換える形で利用可能です。 + +##### 注意 +1. 初回利用時は `/etc/nginx` にマッピングするボリュームが空であることを確認してください。 +2. 静的ファイルを配信する場合は、適切なディレクトリをマッピングしてください。 + +
+Dockerでデプロイ + +1. [Dockerをインストール](https://docs.docker.com/install/) + +2. 以下のように実行: + +```bash +docker run -dit \ + --name=nginx-ui \ + --restart=always \ + -e TZ=Asia/Shanghai \ + -v /mnt/user/appdata/nginx:/etc/nginx \ + -v /mnt/user/appdata/nginx-ui:/etc/nginx-ui \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -p 8080:80 -p 8443:443 \ + uozi/nginx-ui:latest +``` + +3. パネルには `[http://:8080/install](http://:8080/install)` でアクセスします。 +
+ +
+Docker-Composeでデプロイ + +1. [Docker-Composeをインストール](https://docs.docker.com/compose/install/) + +2. 以下内容の`docker-compose.yml`を作成: + +```yml +services: + nginx-ui: + stdin_open: true + tty: true + container_name: nginx-ui + restart: always + environment: + - TZ=Asia/Shanghai + volumes: + - '/mnt/user/appdata/nginx:/etc/nginx' + - '/mnt/user/appdata/nginx-ui:/etc/nginx-ui' + - '/var/www:/var/www' + - '/var/run/docker.sock:/var/run/docker.sock' + ports: + - 8080:80 + - 8443:443 + image: 'uozi/nginx-ui:latest' +``` + +3. コンテナの起動: +```bash +docker compose up -d +``` + +4. パネルには `[http://:8080/install](http://:8080/install)` でアクセスします。 + +
+ +## 手動ビルド + +公式ビルドがないプラットフォーム向けに、以下の手順でビルドできます。 + +### 前提条件 + +- Make + +- Golang 1.23+ + +- node.js 21+ + + ```shell + npx browserslist@latest --update-db + ``` + +### フロントエンドのビルド + +`app` ディレクトリで以下を実行: + +```shell +pnpm install +pnpm build +``` + +### バックエンドのビルド + +フロントエンドビルド後、プロジェクトルートで: + +```shell +go generate +go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/settings.buildTime=$(date +%s)'" -o nginx-ui -v main.go +``` + +## Linux用スクリプト + +### 基本的な使い方 + +**インストール & アップグレード** + +```shell +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ install +``` +デフォルトのリスニングポートは `9000`、HTTP チャレンジポートは `9180` です。 +競合する場合は `/usr/local/etc/nginx-ui/app.ini` を編集し、`systemctl restart nginx-ui` を実行してください。 + +**設定・DB を残してアンインストール** + +```shell +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove +``` + +### その他の使い方 + +````shell +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ help +```` + +## Nginx リバースプロキシ設定例 + +```nginx +server { + listen 80; + listen [::]:80; + + server_name ; + rewrite ^(.*)$ https://$host$1 permanent; +} + +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + listen 443 ssl; + listen [::]:443 ssl; + http2 on; + + server_name ; + + ssl_certificate /path/to/ssl_cert; + ssl_certificate_key /path/to/ssl_cert_key; + + location / { + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + proxy_pass http://127.0.0.1:9000/; + } +} +``` + +## 貢献方法 + +オープンソースコミュニティへの貢献は**大歓迎**です。 +改善提案がある場合はリポジトリをフォークし、プルリクエストを作成してください。 +Issueに「enhancement」タグをつけて提案することもできます。 +スターもよろしくお願いします! + +1. リポジトリをフォーク +2. フィーチャーブランチ作成 (`git checkout -b feature/AmazingFeature`) +3. 変更をコミット (`git commit -m 'Add some AmazingFeature'`) +4. ブランチをプッシュ (`git push origin feature/AmazingFeature`) +5. プルリクエストを作成 + +## ライセンス + +本プロジェクトは GNU Affero General Public License v3.0 に基づき配布されています。ライセンスの詳細は [LICENSE](LICENSE) ファイルをご覧ください。 diff --git a/README-vi_VN.md b/README-vi_VN.md index 934eb35f3..844f9b9f6 100644 --- a/README-vi_VN.md +++ b/README-vi_VN.md @@ -4,7 +4,7 @@ # Nginx UI -Yet another Nginx Web UI, được phát triển bởi [0xJacky](https://jackyu.cn/) và [Hintay](https://blog.kugeek.com/). +Yet another Nginx Web UI, được phát triển bởi [0xJacky](https://jackyu.cn/), [Hintay](https://blog.kugeek.com/) và [Akino](https://github.com/akinoccc). [![Build and Publish](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml/badge.svg)](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml) [![GitHub license](https://img.shields.io/github/license/0xJacky/nginx-ui?label=License&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") @@ -12,7 +12,7 @@ Yet another Nginx Web UI, được phát triển bởi [0xJacky](https://jackyu. [![GitHub Star](https://img.shields.io/github/stars/0xJacky/nginx-ui?label=Stars&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") [![GitHub Fork](https://img.shields.io/github/forks/0xJacky/nginx-ui?label=Forks&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") [![Repo Size](https://img.shields.io/github/repo-size/0xJacky/nginx-ui?label=Size&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") -[![GitHub Fork](https://img.shields.io/github/issues-closed-raw/0xJacky/nginx-ui?label=Closed%20Issue&logo=github)](https://github.com/0xJacky/nginx-ui/issue "Click to view the repo on Github") +[![GitHub Fork](https://img.shields.io/github/issues-closed-raw/0xJacky/nginx-ui?label=Closed%20Issue&logo=github)](https://github.com/0xJacky/nginx-ui/issues "Click to view the repo on Github") [![Docker Stars](https://img.shields.io/docker/stars/uozi/nginx-ui?label=Stars&logo=docker)](https://hub.docker.com/r/uozi/nginx-ui "Click to view the image on Docker Hub") [![Docker Pulls](https://img.shields.io/docker/pulls/uozi/nginx-ui?label=Pulls&logo=docker)](https://hub.docker.com/r/uozi/nginx-ui "Click to view the image on Docker Hub") @@ -148,6 +148,7 @@ http { Giao diện người dùng Nginx có sẵn trên các nền tảng sau: - macOS 11 Big Sur and later (amd64 / arm64) +- Windows 10 and later (x86 /amd64 / arm64) - Linux 2.6.23 và sau đó (x86 / amd64 / arm64 / armv5 / armv6 / armv7 / mips32 / mips64 / riscv64 / loongarch64) - Bao gồm nhưng không giới hạn Debian 7/8, Ubuntu 12.04/14.04 trở lên, CentOS 6/7, Arch Linux - FreeBSD @@ -220,6 +221,7 @@ docker run -dit \ -e TZ=Asia/Shanghai \ -v /mnt/user/appdata/nginx:/etc/nginx \ -v /mnt/user/appdata/nginx-ui:/etc/nginx-ui \ + -v /var/run/docker.sock:/var/run/docker.sock \ -p 8080:80 -p 8443:443 \ uozi/nginx-ui:latest ``` @@ -247,6 +249,7 @@ services: - '/mnt/user/appdata/nginx:/etc/nginx' - '/mnt/user/appdata/nginx-ui:/etc/nginx-ui' - '/var/www:/var/www' + - '/var/run/docker.sock:/var/run/docker.sock' ports: - 8080:80 - 8443:443 @@ -301,7 +304,7 @@ go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/sett **Cài đặt và nâng cấp** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ install +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ install ``` Port mặc định để truy cập UI là `9000`, port HTTP Challenge mặc định để xác thực SSL là `9180`. Nếu có xung đột port, vui lòng sửa đổi trong file `/usr/local/etc/nginx-ui/app.ini`, @@ -310,19 +313,19 @@ hãy nhớ restart nginx-ui bằng lệnh `systemctl restart nginx-ui` mỗi khi **Gỡ bỏ Nginx UI nhưng giữ lại các tệp cấu hình và cơ sở dữ liệu** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ remove +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove ``` **Gỡ bỏ Nginx UI đồng thời xoá các tệp cấu hình, cơ sở dữ liệu** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ remove --purge +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove --purge ``` ### Trợ giúp ````shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ help +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ help ```` ## Ví dụ về cấu hình Nginx Reverse Proxy diff --git a/README-zh_CN.md b/README-zh_CN.md index 17c908a1c..4f2b1e10f 100644 --- a/README-zh_CN.md +++ b/README-zh_CN.md @@ -6,7 +6,7 @@ Yet another Nginx Web UI -Nginx 网络管理界面,由 [0xJacky](https://jackyu.cn/) 与 [Hintay](https://blog.kugeek.com/) 开发。 +Nginx 网络管理界面,由 [0xJacky](https://jackyu.cn/)、[Hintay](https://blog.kugeek.com/) 和 [Akino](https://github.com/akinoccc) 开发。 [![Build and Publish](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml/badge.svg)](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml) @@ -73,9 +73,13 @@ Nginx 网络管理界面,由 [0xJacky](https://jackyu.cn/) 与 [Hintay](https ### 特色 - 在线查看服务器 CPU、内存、系统负载、磁盘使用率等指标 -- 在线 ChatGPT 助理 +- 配置修改后会自动备份,可以对比任意版本或恢复到任意版本 +- 支持镜像操作到多个集群节点,轻松管理多服务器环境 +- 导出加密的 Nginx / Nginx UI 配置,方便快速部署和恢复到新环境 +- 增强版在线 ChatGPT 助手,支持多种模型,包括显示 Deepseek-R1 的思考链,帮助您更好地理解和优化配置 +- MCP (Model Context Protocol) 让 AI 代理程式与 Nginx UI 互动,实现自动化配置管理和服务控制 - 一键申请和自动续签 Let's encrypt 证书 -- 在线编辑 Nginx 配置文件,编辑器支持 Nginx 配置语法高亮 +- 在线编辑 Nginx 配置文件,编辑器支持**大模型代码补全**和 Nginx 配置语法高亮 - 在线查看 Nginx 日志 - 使用 Go 和 Vue 开发,发行版本为单个可执行的二进制文件 - 保存配置后自动测试配置文件并重载 Nginx @@ -127,6 +131,7 @@ http { Nginx UI 可在以下平台中使用: - macOS 11 Big Sur 及之后版本(amd64 / arm64) +- Windows 10 及之后版本(x86 /amd64 / arm64) - Linux 2.6.23 及之后版本(x86 / amd64 / arm64 / armv5 / armv6 / armv7 / mips32 / mips64 / riscv64 / loongarch64) - 包括但不限于 Debian 7 / 8、Ubuntu 12.04 / 14.04 及后续版本、CentOS 6 / 7、Arch Linux - FreeBSD @@ -196,6 +201,7 @@ docker run -dit \ -e TZ=Asia/Shanghai \ -v /mnt/user/appdata/nginx:/etc/nginx \ -v /mnt/user/appdata/nginx-ui:/etc/nginx-ui \ + -v /var/run/docker.sock:/var/run/docker.sock \ -p 8080:80 -p 8443:443 \ uozi/nginx-ui:latest ``` @@ -236,39 +242,29 @@ go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/sett ## Linux 安装脚本 -### 基本用法 - -如果您在中国大陆,可能会遇到 GitHub 的网络问题。您可以通过以下命令设置代理服务器下载 Nginx UI,以加快下载速度。 - -```bash -export GH_PROXY=https://ghfast.top/ -``` - -当以上地址不可用时,请检视 [GitHub Proxy](https://ghproxy.link/) 获得最新地址,或根据实际情况选择其他代理。 - **安装或升级** ```shell -bash -c "$(curl -L ${GH_PROXY}https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ install +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ install ``` 一键安装脚本默认设置的监听端口为 `9000`,HTTP Challenge 端口默认为 `9180`,如果出现端口冲突请进入 `/usr/local/etc/nginx-ui/app.ini` 修改,并使用 `systemctl restart nginx-ui` 重启 Nginx UI 服务。 **卸载 Nginx UI 但保留配置和数据库文件** ```shell -bash -c "$(curl -L ${GH_PROXY}https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ remove +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove ``` **卸载 Nginx UI 不保留配置和数据库文件** ```shell -bash -c "$(curl -L ${GH_PROXY}https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ remove --purge +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove --purge ``` ### 更多用法 ````shell -bash -c "$(curl -L ${GH_PROXY}https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ help +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ help ```` ## Nginx 反向代理配置示例 diff --git a/README-zh_TW.md b/README-zh_TW.md index 5c95f9d13..c15939a73 100644 --- a/README-zh_TW.md +++ b/README-zh_TW.md @@ -6,7 +6,7 @@ Yet another Nginx Web UI -Nginx 網路管理介面,由 [0xJacky](https://jackyu.cn/) 與 [Hintay](https://blog.kugeek.com/) 開發。 +Nginx 網路管理介面,由 [0xJacky](https://jackyu.cn/)、[Hintay](https://blog.kugeek.com/) 和 [Akino](https://github.com/akinoccc) 開發。 [![Build and Publish](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml/badge.svg)](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml) @@ -75,9 +75,13 @@ Nginx 網路管理介面,由 [0xJacky](https://jackyu.cn/) 與 [Hintay](https: ### 特色 - 線上檢視伺服器 CPU、記憶體、系統負載、磁碟使用率等指標 -- 線上 ChatGPT 助理 +- 設定修改後會自動備份,可以對比任意版本或恢復到任意版本 +- 支援鏡像操作到多個叢集節點,輕鬆管理多伺服器環境 +- 匯出加密的 Nginx/NginxUI 設定,方便快速部署和恢復到新環境 +- 增強版線上 ChatGPT 助手,支援多種模型,包括顯示 Deepseek-R1 的思考鏈,幫助您更好地理解和最佳化設定 +- MCP (Model Context Protocol) 讓 AI 代理程式與 Nginx UI 互動,實現自動化設定管理和服務控制 - 一鍵申請和自動續簽 Let's encrypt 憑證 -- 線上編輯 Nginx 設定檔,編輯器支援 Nginx 設定語法醒目提示 +- 線上編輯 Nginx 設定檔,編輯器支援**大模型代碼補全**和 Nginx 設定語法醒目提示 - 線上檢視 Nginx 日誌 - 使用 Go 和 Vue 開發,發行版本為單個可執行檔案 - 儲存設定後自動測試設定檔並重新載入 Nginx @@ -111,7 +115,7 @@ Nginx 網路管理介面,由 [0xJacky](https://jackyu.cn/) 與 [Hintay](https: ### 使用前注意 -Nginx UI 遵循 Debian 的網頁伺服器設定檔標準。建立的網站設定檔將會放置於 Nginx 設定資料夾(自動檢測)下的 `sites-available` 中,啟用後的網站將會建立一份設定檔軟連結檔到 `sites-enabled` 資料夾。您可能需要提前調整設定檔的組織方式。 +Nginx UI 遵循 Debian 的網頁伺服器設定檔標準。建立的網站設定檔將會放置於 Nginx 設定資料夾(自動偵測)下的 `sites-available` 中,啟用後的網站將會建立一份設定檔軟連結檔到 `sites-enabled` 資料夾。您可能需要提前調整設定檔的組織方式。 對於非 Debian (及 Ubuntu) 作業系統,您可能需要將 `nginx.conf` 設定檔中的內容修改為如下所示的 Debian 風格。 @@ -130,6 +134,7 @@ http { Nginx UI 可在以下作業系統中使用: - macOS 11 Big Sur 及之後版本(amd64 / arm64) +- Windows 10 及之後版本(x86 /amd64 / arm64) - Linux 2.6.23 及之後版本(x86 / amd64 / arm64 / armv5 / armv6 / armv7 / mips32 / mips64 / riscv64 / loongarch64) - 包括但不限於 Debian 7 / 8、Ubuntu 12.04 / 14.04 及後續版本、CentOS 6 / 7、Arch Linux - FreeBSD @@ -141,7 +146,7 @@ Nginx UI 可在以下作業系統中使用: ### 使用方法 -第一次執行 Nginx UI 時,請在網頁瀏覽器中訪問 `http://:` 完成後續設定。 +第一次執行 Nginx UI 時,請在網頁瀏覽器中存取 `http://:` 完成後續設定。 #### 透過執行檔案執行 @@ -150,7 +155,7 @@ Nginx UI 可在以下作業系統中使用: ```shell nginx-ui -config app.ini ``` -在終端使用 `Control+C` 退出 Nginx UI。 +在終端使用 `Control+C` 結束 Nginx UI。 **在背景執行 Nginx UI** @@ -201,6 +206,7 @@ docker run -dit \ -e TZ=Asia/Shanghai \ -v /mnt/user/appdata/nginx:/etc/nginx \ -v /mnt/user/appdata/nginx-ui:/etc/nginx-ui \ + -v /var/run/docker.sock:/var/run/docker.sock \ -p 8080:80 -p 8443:443 \ uozi/nginx-ui:latest ``` @@ -246,7 +252,7 @@ go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/sett **安裝或升級** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ install +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ install ``` 一鍵安裝指令預設的監聽連接埠為 `9000`,HTTP Challenge 埠預設為 `9180`,如果出現連接埠衝突請修改 `/usr/local/etc/nginx-ui/app.ini`,並使用 `systemctl restart nginx-ui` 重啟 Nginx UI 守護行程。 @@ -254,13 +260,13 @@ bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/insta **解除安裝 Nginx UI 但保留設定和資料庫檔案** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ remove +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove ``` ### 更多用法 ````shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ help +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ help ```` ## Nginx 反向代理設定範例 diff --git a/README.md b/README.md index 01854d19c..d84ceb596 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,10 @@ # Nginx UI -Yet another Nginx Web UI, developed by [0xJacky](https://jackyu.cn/) and [Hintay](https://blog.kugeek.com/). +Yet another Nginx Web UI, developed by [0xJacky](https://jackyu.cn/), [Hintay](https://blog.kugeek.com/) and [Akino](https://github.com/akinoccc). + +[![DeepWiki](https://img.shields.io/badge/DeepWiki-0xJacky%2Fnginx--ui-blue.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAyCAYAAAAnWDnqAAAAAXNSR0IArs4c6QAAA05JREFUaEPtmUtyEzEQhtWTQyQLHNak2AB7ZnyXZMEjXMGeK/AIi+QuHrMnbChYY7MIh8g01fJoopFb0uhhEqqcbWTp06/uv1saEDv4O3n3dV60RfP947Mm9/SQc0ICFQgzfc4CYZoTPAswgSJCCUJUnAAoRHOAUOcATwbmVLWdGoH//PB8mnKqScAhsD0kYP3j/Yt5LPQe2KvcXmGvRHcDnpxfL2zOYJ1mFwrryWTz0advv1Ut4CJgf5uhDuDj5eUcAUoahrdY/56ebRWeraTjMt/00Sh3UDtjgHtQNHwcRGOC98BJEAEymycmYcWwOprTgcB6VZ5JK5TAJ+fXGLBm3FDAmn6oPPjR4rKCAoJCal2eAiQp2x0vxTPB3ALO2CRkwmDy5WohzBDwSEFKRwPbknEggCPB/imwrycgxX2NzoMCHhPkDwqYMr9tRcP5qNrMZHkVnOjRMWwLCcr8ohBVb1OMjxLwGCvjTikrsBOiA6fNyCrm8V1rP93iVPpwaE+gO0SsWmPiXB+jikdf6SizrT5qKasx5j8ABbHpFTx+vFXp9EnYQmLx02h1QTTrl6eDqxLnGjporxl3NL3agEvXdT0WmEost648sQOYAeJS9Q7bfUVoMGnjo4AZdUMQku50McDcMWcBPvr0SzbTAFDfvJqwLzgxwATnCgnp4wDl6Aa+Ax283gghmj+vj7feE2KBBRMW3FzOpLOADl0Isb5587h/U4gGvkt5v60Z1VLG8BhYjbzRwyQZemwAd6cCR5/XFWLYZRIMpX39AR0tjaGGiGzLVyhse5C9RKC6ai42ppWPKiBagOvaYk8lO7DajerabOZP46Lby5wKjw1HCRx7p9sVMOWGzb/vA1hwiWc6jm3MvQDTogQkiqIhJV0nBQBTU+3okKCFDy9WwferkHjtxib7t3xIUQtHxnIwtx4mpg26/HfwVNVDb4oI9RHmx5WGelRVlrtiw43zboCLaxv46AZeB3IlTkwouebTr1y2NjSpHz68WNFjHvupy3q8TFn3Hos2IAk4Ju5dCo8B3wP7VPr/FGaKiG+T+v+TQqIrOqMTL1VdWV1DdmcbO8KXBz6esmYWYKPwDL5b5FA1a0hwapHiom0r/cKaoqr+27/XcrS5UwSMbQAAAABJRU5ErkJggg==)](https://deepwiki.com/0xJacky/nginx-ui) +[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/0xJacky/nginx-ui) [![Build and Publish](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml/badge.svg)](https://github.com/0xJacky/nginx-ui/actions/workflows/build.yml) [![GitHub license](https://img.shields.io/github/license/0xJacky/nginx-ui?label=License&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") @@ -12,7 +15,7 @@ Yet another Nginx Web UI, developed by [0xJacky](https://jackyu.cn/) and [Hintay [![GitHub Star](https://img.shields.io/github/stars/0xJacky/nginx-ui?label=Stars&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") [![GitHub Fork](https://img.shields.io/github/forks/0xJacky/nginx-ui?label=Forks&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") [![Repo Size](https://img.shields.io/github/repo-size/0xJacky/nginx-ui?label=Size&logo=github)](https://github.com/0xJacky/nginx-ui "Click to view the repo on Github") -[![GitHub Fork](https://img.shields.io/github/issues-closed-raw/0xJacky/nginx-ui?label=Closed%20Issue&logo=github)](https://github.com/0xJacky/nginx-ui/issue "Click to view the repo on Github") +[![GitHub Fork](https://img.shields.io/github/issues-closed-raw/0xJacky/nginx-ui?label=Closed%20Issue&logo=github)](https://github.com/0xJacky/nginx-ui/issues "Click to view the repo on Github") [![Docker Stars](https://img.shields.io/docker/stars/uozi/nginx-ui?label=Stars&logo=docker)](https://hub.docker.com/r/uozi/nginx-ui "Click to view the image on Docker Hub") [![Docker Pulls](https://img.shields.io/docker/pulls/uozi/nginx-ui?label=Pulls&logo=docker)](https://hub.docker.com/r/uozi/nginx-ui "Click to view the image on Docker Hub") @@ -24,11 +27,25 @@ Yet another Nginx Web UI, developed by [0xJacky](https://jackyu.cn/) and [Hintay ## Documentation To check out docs, visit [nginxui.com](https://nginxui.com). +## Sponsor + +If you find this project helpful, please consider sponsoring us to support ongoing development and maintenance. + +[![GitHub Sponsors](https://img.shields.io/badge/GitHub-Sponsors-ea4aaa?style=for-the-badge&logo=github-sponsors&logoColor=white)](https://github.com/sponsors/nginxui) +[![Afdian](https://img.shields.io/badge/爱发电-Support-946ce6?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTEyIDJMMTMuMDkgOC4yNkwyMCA5TDEzLjA5IDE1Ljc0TDEyIDIyTDEwLjkxIDE1Ljc0TDQgOUwxMC45MSA4LjI2TDEyIDJaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K)](https://afdian.com/a/nginxui) + +Your support helps us: +- 🚀 Accelerate development of new features +- 🐛 Fix bugs and improve stability +- 📚 Enhance documentation and tutorials +- 🌐 Provide better community support +- 💻 Maintain infrastructure and demo servers + ## Stargazers over time [![Stargazers over time](https://starchart.cc/0xJacky/nginx-ui.svg)](https://starchart.cc/0xJacky/nginx-ui) -English | [Español](README-es.md) | [简体中文](README-zh_CN.md) | [繁體中文](README-zh_TW.md) | [Tiếng Việt](README-vi_VN.md) +English | [Español](README-es.md) | [简体中文](README-zh_CN.md) | [繁體中文](README-zh_TW.md) | [Tiếng Việt](README-vi_VN.md) | [日本語](README-ja_JP.md)
Table of Contents @@ -90,9 +107,13 @@ URL:[https://demo.nginxui.com](https://demo.nginxui.com) ### Features - Online statistics for server indicators such as CPU usage, memory usage, load average, and disk usage. -- Online ChatGPT Assistant +- Automatic configuration backup after changes, with version comparison and restore capabilities +- Cluster management supporting mirroring operations to multiple nodes, making multi-server environments easy to manage +- Export encrypted Nginx / Nginx UI configurations for quick deployment and recovery to new environments +- Enhanced online **ChatGPT** assistant supporting multiple models, including Deepseek-R1's chain-of-thought display to help you better understand and optimize configurations +- **MCP** (Model Context Protocol) provides special interfaces for AI agents to interact with Nginx UI, enabling automated configuration management and service control. - One-click deployment and automatic renewal Let's Encrypt certificates. -- Online editing websites configurations with our self-designed **NgxConfigEditor** which is a user-friendly block editor for nginx configurations or **Ace Code Editor** which supports highlighting nginx configuration syntax. +- Online editing websites configurations with our self-designed **NgxConfigEditor** which is a user-friendly block editor for nginx configurations or **Ace Code Editor** which supports **LLM Code Completion** and highlighting nginx configuration syntax. - Online view Nginx logs - Written in Go and Vue, distribution is a single executable binary. - Automatically test configuration file and reload nginx after saving configuration. @@ -108,7 +129,7 @@ We proudly offer official support for: - Simplified Chinese - Traditional Chinese -As non-native English speakers, we strive for accuracy, but we know there’s always room for improvement. If you spot any issues, we’d love your feedback! +As non-native English speakers, we strive for accuracy, but we know there's always room for improvement. If you spot any issues, we'd love your feedback! Thanks to our amazing community, additional languages are also available! Explore and contribute to translations on [Weblate](https://weblate.nginxui.com). @@ -149,6 +170,7 @@ For more information: [debian/conf/nginx.conf](https://salsa.debian.org/nginx-te Nginx UI is available on the following platforms: - macOS 11 Big Sur and later (amd64 / arm64) +- Windows 10 and later (amd64 / arm64) - Linux 2.6.23 and later (x86 / amd64 / arm64 / armv5 / armv6 / armv7 / mips32 / mips64 / riscv64 / loongarch64) - Including but not limited to Debian 7 / 8, Ubuntu 12.04 / 14.04 and later, CentOS 6 / 7, Arch Linux - FreeBSD @@ -224,6 +246,7 @@ docker run -dit \ -e TZ=Asia/Shanghai \ -v /mnt/user/appdata/nginx:/etc/nginx \ -v /mnt/user/appdata/nginx-ui:/etc/nginx-ui \ + -v /var/run/docker.sock:/var/run/docker.sock \ -p 8080:80 -p 8443:443 \ uozi/nginx-ui:latest ``` @@ -251,6 +274,7 @@ services: - '/mnt/user/appdata/nginx:/etc/nginx' - '/mnt/user/appdata/nginx-ui:/etc/nginx-ui' - '/var/www:/var/www' + - '/var/run/docker.sock:/var/run/docker.sock' ports: - 8080:80 - 8443:443 @@ -307,7 +331,7 @@ go build -tags=jsoniter -ldflags "$LD_FLAGS -X 'github.com/0xJacky/Nginx-UI/sett **Install and Upgrade** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ install +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ install ``` The default listening port is `9000`, and the default HTTP Challenge port is `9180`. If there is a port conflict, please modify `/usr/local/etc/nginx-ui/app.ini` manually, @@ -316,13 +340,13 @@ then use `systemctl restart nginx-ui` to reload the Nginx UI service. **Remove Nginx UI, except configuration and database files** ```shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ remove +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ remove ``` ### More Usage ````shell -bash -c "$(curl -L https://raw.githubusercontent.com/0xJacky/nginx-ui/main/install.sh)" @ help +bash -c "$(curl -L https://cloud.nginxui.com/install.sh)" @ help ```` ## Example of Nginx Reverse Proxy Configuration diff --git a/api/analytic/analytic.go b/api/analytic/analytic.go index ab00e95fc..40bd71616 100644 --- a/api/analytic/analytic.go +++ b/api/analytic/analytic.go @@ -8,6 +8,7 @@ import ( "github.com/0xJacky/Nginx-UI/internal/analytic" "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/kernel" "github.com/shirou/gopsutil/v4/cpu" "github.com/shirou/gopsutil/v4/host" "github.com/shirou/gopsutil/v4/load" @@ -91,7 +92,11 @@ func Analytic(c *gin.Context) { break } - time.Sleep(1 * time.Second) + select { + case <-kernel.Context.Done(): + return + case <-time.After(1 * time.Second): + } } } diff --git a/api/analytic/nodes.go b/api/analytic/nodes.go index ceccf8787..589f52994 100644 --- a/api/analytic/nodes.go +++ b/api/analytic/nodes.go @@ -6,6 +6,7 @@ import ( "github.com/0xJacky/Nginx-UI/internal/analytic" "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/kernel" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/uozi-tech/cosy/logger" @@ -36,7 +37,11 @@ func GetNodeStat(c *gin.Context) { break } - time.Sleep(10 * time.Second) + select { + case <-kernel.Context.Done(): + return + case <-time.After(10 * time.Second): + } } } @@ -65,6 +70,10 @@ func GetNodesAnalytic(c *gin.Context) { break } - time.Sleep(10 * time.Second) + select { + case <-kernel.Context.Done(): + return + case <-time.After(10 * time.Second): + } } } diff --git a/api/backup/auto_backup.go b/api/backup/auto_backup.go new file mode 100644 index 000000000..d9e31a20b --- /dev/null +++ b/api/backup/auto_backup.go @@ -0,0 +1,196 @@ +package backup + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/internal/backup" + "github.com/0xJacky/Nginx-UI/internal/cron" + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" + "github.com/uozi-tech/cosy/logger" +) + +// GetAutoBackupList retrieves a paginated list of auto backup configurations. +// This endpoint supports fuzzy search by backup name and filtering by backup type and enabled status. +// +// Query Parameters: +// - page: Page number for pagination +// - page_size: Number of items per page +// - name: Fuzzy search filter for backup name +// - backup_type: Filter by backup type (nginx_config/nginx_ui_config/both_config/custom_dir) +// - enabled: Filter by enabled status (true/false) +// +// Response: Paginated list of auto backup configurations +func GetAutoBackupList(c *gin.Context) { + cosy.Core[model.AutoBackup](c). + SetFussy("name"). + SetEqual("backup_type", "enabled", "storage_type", "last_backup_status"). + PagingList() +} + +// CreateAutoBackup creates a new auto backup configuration with comprehensive validation. +// This endpoint validates all required fields, path permissions, and S3 configuration. +// +// Request Body: AutoBackup model with required fields +// Response: Created auto backup configuration +func CreateAutoBackup(c *gin.Context) { + cosy.Core[model.AutoBackup](c).SetValidRules(gin.H{ + "name": "required", + "backup_type": "required", + "storage_type": "required", + "storage_path": "required", + "cron_expression": "required", + "enabled": "omitempty", + "backup_path": "omitempty", + "s3_endpoint": "omitempty", + "s3_access_key_id": "omitempty", + "s3_secret_access_key": "omitempty", + "s3_bucket": "omitempty", + "s3_region": "omitempty", + }).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AutoBackup]) { + // Validate backup configuration before creation + if err := backup.ValidateAutoBackupConfig(&ctx.Model); err != nil { + ctx.AbortWithError(err) + return + } + }).ExecutedHook(func(ctx *cosy.Ctx[model.AutoBackup]) { + // Register cron job only if the backup is enabled + if ctx.Model.Enabled { + if err := cron.AddAutoBackupJob(ctx.Model.ID, ctx.Model.CronExpression); err != nil { + ctx.AbortWithError(err) + return + } + } + }).Create() +} + +// GetAutoBackup retrieves a single auto backup configuration by ID. +// +// Path Parameters: +// - id: Auto backup configuration ID +// +// Response: Auto backup configuration details +func GetAutoBackup(c *gin.Context) { + cosy.Core[model.AutoBackup](c).Get() +} + +// ModifyAutoBackup updates an existing auto backup configuration with validation. +// This endpoint performs the same validation as creation for modified fields. +// +// Path Parameters: +// - id: Auto backup configuration ID +// +// Request Body: Partial AutoBackup model with fields to update +// Response: Updated auto backup configuration +func ModifyAutoBackup(c *gin.Context) { + cosy.Core[model.AutoBackup](c).SetValidRules(gin.H{ + "name": "omitempty", + "backup_type": "omitempty", + "storage_type": "omitempty", + "storage_path": "omitempty", + "cron_expression": "omitempty", + "backup_path": "omitempty", + "enabled": "omitempty", + "s3_endpoint": "omitempty", + "s3_access_key_id": "omitempty", + "s3_secret_access_key": "omitempty", + "s3_bucket": "omitempty", + "s3_region": "omitempty", + }).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AutoBackup]) { + // Validate backup configuration before modification + if err := backup.ValidateAutoBackupConfig(&ctx.Model); err != nil { + ctx.AbortWithError(err) + return + } + }).ExecutedHook(func(ctx *cosy.Ctx[model.AutoBackup]) { + // Update cron job based on enabled status + if ctx.Model.Enabled { + if err := cron.UpdateAutoBackupJob(ctx.Model.ID, ctx.Model.CronExpression); err != nil { + ctx.AbortWithError(err) + return + } + } else { + if err := cron.RemoveAutoBackupJob(ctx.Model.ID); err != nil { + ctx.AbortWithError(err) + return + } + } + }).Modify() +} + +// DestroyAutoBackup deletes an auto backup configuration and removes its cron job. +// This endpoint ensures proper cleanup of both database records and scheduled tasks. +// +// Path Parameters: +// - id: Auto backup configuration ID +// +// Response: Success confirmation +func DestroyAutoBackup(c *gin.Context) { + cosy.Core[model.AutoBackup](c).BeforeExecuteHook(func(ctx *cosy.Ctx[model.AutoBackup]) { + // Remove cron job before deleting the backup task + if err := cron.RemoveAutoBackupJob(ctx.Model.ID); err != nil { + logger.Errorf("Failed to remove auto backup job %d: %v", ctx.Model.ID, err) + } + }).Destroy() +} + +// TestS3Connection tests the S3 connection for auto backup configuration. +// This endpoint allows users to verify their S3 settings before saving the configuration. +// +// Request Body: AutoBackup model with S3 configuration +// Response: Success confirmation or error details +func TestS3Connection(c *gin.Context) { + var autoBackup model.AutoBackup + if !cosy.BindAndValid(c, &autoBackup) { + return + } + + // Validate S3 configuration + if err := backup.ValidateS3Config(&autoBackup); err != nil { + cosy.ErrHandler(c, err) + return + } + + // Test S3 connection + if err := backup.TestS3ConnectionForConfig(&autoBackup); err != nil { + cosy.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{"message": "S3 connection test successful"}) +} + +// RestoreAutoBackup restores a soft-deleted auto backup configuration. +// This endpoint restores the backup configuration and re-registers the cron job if enabled. +// +// Path Parameters: +// - id: Auto backup configuration ID to restore +// +// Response: Success confirmation +func RestoreAutoBackup(c *gin.Context) { + var autoBackup model.AutoBackup + if err := c.ShouldBindUri(&autoBackup); err != nil { + cosy.ErrHandler(c, err) + return + } + + // Restore the backup configuration + if err := backup.RestoreAutoBackup(autoBackup.ID); err != nil { + cosy.ErrHandler(c, err) + return + } + + // Get the restored backup configuration to check if it's enabled + restoredBackup, err := backup.GetAutoBackupByID(autoBackup.ID) + if err != nil { + logger.Errorf("Failed to get restored auto backup %d: %v", autoBackup.ID, err) + } else if restoredBackup.Enabled { + // Register cron job if the backup is enabled + if err := cron.AddAutoBackupJob(restoredBackup.ID, restoredBackup.CronExpression); err != nil { + logger.Errorf("Failed to add auto backup job %d after restore: %v", restoredBackup.ID, err) + } + } + + c.JSON(http.StatusOK, gin.H{"message": "Auto backup restored successfully"}) +} diff --git a/api/system/backup.go b/api/backup/backup.go similarity index 98% rename from api/system/backup.go rename to api/backup/backup.go index 0c90a2965..95dad259e 100644 --- a/api/system/backup.go +++ b/api/backup/backup.go @@ -1,4 +1,4 @@ -package system +package backup import ( "bytes" diff --git a/api/system/backup_test.go b/api/backup/backup_test.go similarity index 99% rename from api/system/backup_test.go rename to api/backup/backup_test.go index eb678733a..2b54cab6e 100644 --- a/api/system/backup_test.go +++ b/api/backup/backup_test.go @@ -1,4 +1,4 @@ -package system +package backup import ( "bytes" diff --git a/api/system/restore.go b/api/backup/restore.go similarity index 98% rename from api/system/restore.go rename to api/backup/restore.go index 50ff619b5..0c4cf80ac 100644 --- a/api/system/restore.go +++ b/api/backup/restore.go @@ -1,4 +1,4 @@ -package system +package backup import ( "encoding/base64" @@ -8,10 +8,10 @@ import ( "strings" "time" + "code.pfad.fr/risefront" "github.com/0xJacky/Nginx-UI/internal/backup" "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/gin-gonic/gin" - "github.com/jpillora/overseer" "github.com/uozi-tech/cosy" ) @@ -123,7 +123,7 @@ func RestoreBackup(c *gin.Context) { go func() { time.Sleep(2 * time.Second) // gracefully restart - overseer.Restart() + risefront.Restart() }() } diff --git a/api/backup/router.go b/api/backup/router.go new file mode 100644 index 000000000..332152ba4 --- /dev/null +++ b/api/backup/router.go @@ -0,0 +1,21 @@ +package backup + +import ( + "github.com/0xJacky/Nginx-UI/internal/middleware" + "github.com/gin-gonic/gin" +) + +func InitRouter(r *gin.RouterGroup) { + r.GET("/backup", CreateBackup) + r.POST("/restore", middleware.EncryptedForm(), RestoreBackup) +} + +func InitAutoBackupRouter(r *gin.RouterGroup) { + r.GET("/auto_backup", GetAutoBackupList) + r.POST("/auto_backup", CreateAutoBackup) + r.GET("/auto_backup/:id", GetAutoBackup) + r.POST("/auto_backup/:id", ModifyAutoBackup) + r.DELETE("/auto_backup/:id", DestroyAutoBackup) + r.PATCH("/auto_backup/:id", RestoreAutoBackup) + r.POST("/auto_backup/test_s3", TestS3Connection) +} diff --git a/api/certificate/certificate.go b/api/certificate/certificate.go index 23518da22..8a62d7cf7 100644 --- a/api/certificate/certificate.go +++ b/api/certificate/certificate.go @@ -57,21 +57,25 @@ func Transformer(certModel *model.Cert) (certificate *APICertificate) { } func GetCertList(c *gin.Context) { - cosy.Core[model.Cert](c).SetFussy("name", "domain").SetTransformer(func(m *model.Cert) any { - - info, _ := cert.GetCertInfo(m.SSLCertificatePath) - - return APICertificate{ - Cert: m, - CertificateInfo: info, - } - }).PagingList() + cosy.Core[model.Cert](c).SetFussy("name", "domain"). + SetTransformer(func(m *model.Cert) any { + info, _ := cert.GetCertInfo(m.SSLCertificatePath) + return APICertificate{ + Cert: m, + CertificateInfo: info, + } + }).PagingList() } func GetCert(c *gin.Context) { q := query.Cert - certModel, err := q.FirstByID(cast.ToUint64(c.Param("id"))) + id := cast.ToUint64(c.Param("id")) + if contextId, ok := c.Get("id"); ok { + id = cast.ToUint64(contextId) + } + + certModel, err := q.FirstByID(id) if err != nil { cosy.ErrHandler(c, err) @@ -81,118 +85,134 @@ func GetCert(c *gin.Context) { c.JSON(http.StatusOK, Transformer(certModel)) } -type certJson struct { - Name string `json:"name" binding:"required"` - SSLCertificatePath string `json:"ssl_certificate_path" binding:"required,certificate_path"` - SSLCertificateKeyPath string `json:"ssl_certificate_key_path" binding:"required,privatekey_path"` - SSLCertificate string `json:"ssl_certificate" binding:"omitempty,certificate"` - SSLCertificateKey string `json:"ssl_certificate_key" binding:"omitempty,privatekey"` - KeyType certcrypto.KeyType `json:"key_type" binding:"omitempty,auto_cert_key_type"` - ChallengeMethod string `json:"challenge_method"` - DnsCredentialID uint64 `json:"dns_credential_id"` - ACMEUserID uint64 `json:"acme_user_id"` - SyncNodeIds []uint64 `json:"sync_node_ids"` -} - func AddCert(c *gin.Context) { - var json certJson - - if !cosy.BindAndValid(c, &json) { - return - } - - certModel := &model.Cert{ - Name: json.Name, - SSLCertificatePath: json.SSLCertificatePath, - SSLCertificateKeyPath: json.SSLCertificateKeyPath, - KeyType: json.KeyType, - ChallengeMethod: json.ChallengeMethod, - DnsCredentialID: json.DnsCredentialID, - ACMEUserID: json.ACMEUserID, - SyncNodeIds: json.SyncNodeIds, - } - - err := certModel.Insert() - if err != nil { - cosy.ErrHandler(c, err) - return - } - - content := &cert.Content{ - SSLCertificatePath: json.SSLCertificatePath, - SSLCertificateKeyPath: json.SSLCertificateKeyPath, - SSLCertificate: json.SSLCertificate, - SSLCertificateKey: json.SSLCertificateKey, - } - - err = content.WriteFile() - if err != nil { - cosy.ErrHandler(c, err) - return - } - - err = cert.SyncToRemoteServer(certModel) - if err != nil { - notification.Error("Sync Certificate Error", err.Error(), nil) - return - } - - c.JSON(http.StatusOK, Transformer(certModel)) + cosy.Core[model.Cert](c). + SetValidRules(gin.H{ + "name": "omitempty", + "ssl_certificate_path": "required,certificate_path", + "ssl_certificate_key_path": "required,privatekey_path", + "ssl_certificate": "omitempty,certificate", + "ssl_certificate_key": "omitempty,privatekey", + "key_type": "omitempty,auto_cert_key_type", + "challenge_method": "omitempty,oneof=http01 dns01", + "dns_credential_id": "omitempty", + "acme_user_id": "omitempty", + "sync_node_ids": "omitempty", + "must_staple": "omitempty", + "lego_disable_cname_support": "omitempty", + "revoke_old": "omitempty", + }). + BeforeExecuteHook(func(ctx *cosy.Ctx[model.Cert]) { + sslCertificate := cast.ToString(ctx.Payload["ssl_certificate"]) + // Detect and set certificate type + if sslCertificate != "" { + keyType, err := cert.GetKeyType(sslCertificate) + if err == nil && keyType != "" { + // Set KeyType based on certificate type + switch keyType { + case "2048": + ctx.Model.KeyType = certcrypto.RSA2048 + case "3072": + ctx.Model.KeyType = certcrypto.RSA3072 + case "4096": + ctx.Model.KeyType = certcrypto.RSA4096 + case "P256": + ctx.Model.KeyType = certcrypto.EC256 + case "P384": + ctx.Model.KeyType = certcrypto.EC384 + } + } + } + }). + ExecutedHook(func(ctx *cosy.Ctx[model.Cert]) { + sslCertificate := cast.ToString(ctx.Payload["ssl_certificate"]) + sslCertificateKey := cast.ToString(ctx.Payload["ssl_certificate_key"]) + if sslCertificate != "" && sslCertificateKey != "" { + content := &cert.Content{ + SSLCertificatePath: ctx.Model.SSLCertificatePath, + SSLCertificateKeyPath: ctx.Model.SSLCertificateKeyPath, + SSLCertificate: sslCertificate, + SSLCertificateKey: sslCertificateKey, + } + err := content.WriteFile() + if err != nil { + ctx.AbortWithError(err) + return + } + } + err := cert.SyncToRemoteServer(&ctx.Model) + if err != nil { + notification.Error("Sync Certificate Error", err.Error(), nil) + return + } + ctx.Context.Set("id", ctx.Model.ID) + }). + SetNextHandler(GetCert). + Create() } func ModifyCert(c *gin.Context) { - id := cast.ToUint64(c.Param("id")) - - var json certJson - - if !cosy.BindAndValid(c, &json) { - return - } - - q := query.Cert - - certModel, err := q.FirstByID(id) - if err != nil { - cosy.ErrHandler(c, err) - return - } - - err = certModel.Updates(&model.Cert{ - Name: json.Name, - SSLCertificatePath: json.SSLCertificatePath, - SSLCertificateKeyPath: json.SSLCertificateKeyPath, - ChallengeMethod: json.ChallengeMethod, - KeyType: json.KeyType, - DnsCredentialID: json.DnsCredentialID, - ACMEUserID: json.ACMEUserID, - SyncNodeIds: json.SyncNodeIds, - }) - - if err != nil { - cosy.ErrHandler(c, err) - return - } - - content := &cert.Content{ - SSLCertificatePath: json.SSLCertificatePath, - SSLCertificateKeyPath: json.SSLCertificateKeyPath, - SSLCertificate: json.SSLCertificate, - SSLCertificateKey: json.SSLCertificateKey, - } - - err = content.WriteFile() - if err != nil { - cosy.ErrHandler(c, err) - return - } - - err = cert.SyncToRemoteServer(certModel) - if err != nil { - notification.Error("Sync Certificate Error", err.Error(), nil) - return - } - - GetCert(c) + cosy.Core[model.Cert](c). + SetValidRules(gin.H{ + "name": "omitempty", + "ssl_certificate_path": "required,certificate_path", + "ssl_certificate_key_path": "required,privatekey_path", + "ssl_certificate": "omitempty,certificate", + "ssl_certificate_key": "omitempty,privatekey", + "key_type": "omitempty,auto_cert_key_type", + "challenge_method": "omitempty,oneof=http01 dns01", + "dns_credential_id": "omitempty", + "acme_user_id": "omitempty", + "sync_node_ids": "omitempty", + "must_staple": "omitempty", + "lego_disable_cname_support": "omitempty", + "revoke_old": "omitempty", + }). + BeforeExecuteHook(func(ctx *cosy.Ctx[model.Cert]) { + sslCertificate := cast.ToString(ctx.Payload["ssl_certificate"]) + // Detect and set certificate type + if sslCertificate != "" { + keyType, err := cert.GetKeyType(sslCertificate) + if err == nil && keyType != "" { + // Set KeyType based on certificate type + switch keyType { + case "2048": + ctx.Model.KeyType = certcrypto.RSA2048 + case "3072": + ctx.Model.KeyType = certcrypto.RSA3072 + case "4096": + ctx.Model.KeyType = certcrypto.RSA4096 + case "P256": + ctx.Model.KeyType = certcrypto.EC256 + case "P384": + ctx.Model.KeyType = certcrypto.EC384 + } + } + } + }). + ExecutedHook(func(ctx *cosy.Ctx[model.Cert]) { + sslCertificate := cast.ToString(ctx.Payload["ssl_certificate"]) + sslCertificateKey := cast.ToString(ctx.Payload["ssl_certificate_key"]) + + content := &cert.Content{ + SSLCertificatePath: ctx.Model.SSLCertificatePath, + SSLCertificateKeyPath: ctx.Model.SSLCertificateKeyPath, + SSLCertificate: sslCertificate, + SSLCertificateKey: sslCertificateKey, + } + err := content.WriteFile() + if err != nil { + ctx.AbortWithError(err) + return + } + err = cert.SyncToRemoteServer(&ctx.Model) + if err != nil { + notification.Error("Sync Certificate Error", err.Error(), nil) + return + } + }). + SetNextHandler(GetCert). + Modify() } func RemoveCert(c *gin.Context) { diff --git a/api/certificate/issue.go b/api/certificate/issue.go index c20b20cd7..adc3f0da8 100644 --- a/api/certificate/issue.go +++ b/api/certificate/issue.go @@ -4,6 +4,8 @@ import ( "net/http" "github.com/0xJacky/Nginx-UI/internal/cert" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/translation" "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" @@ -24,28 +26,7 @@ type IssueCertResponse struct { Message string `json:"message"` SSLCertificate string `json:"ssl_certificate,omitempty"` SSLCertificateKey string `json:"ssl_certificate_key,omitempty"` - KeyType certcrypto.KeyType `json:"key_type"` -} - -func handleIssueCertLogChan(conn *websocket.Conn, log *cert.Logger, logChan chan string) { - defer func() { - if err := recover(); err != nil { - logger.Error(err) - } - }() - - for logString := range logChan { - log.Info(logString) - - err := conn.WriteJSON(IssueCertResponse{ - Status: Info, - Message: logString, - }) - if err != nil { - logger.Error(err) - return - } - } + KeyType certcrypto.KeyType `json:"key_type,omitempty"` } func IssueCert(c *gin.Context) { @@ -63,9 +44,7 @@ func IssueCert(c *gin.Context) { return } - defer func(ws *websocket.Conn) { - _ = ws.Close() - }(ws) + defer ws.Close() // read payload := &cert.ConfigPayload{} @@ -82,6 +61,8 @@ func IssueCert(c *gin.Context) { return } + payload.CertID = certModel.ID + if certModel.SSLCertificatePath != "" { certInfo, _ := cert.GetCertInfo(certModel.SSLCertificatePath) if certInfo != nil { @@ -90,29 +71,18 @@ func IssueCert(c *gin.Context) { } } - logChan := make(chan string, 1) - errChan := make(chan error, 1) - - log := &cert.Logger{} + log := cert.NewLogger() log.SetCertModel(&certModel) + log.SetWebSocket(ws) + defer log.Close() - go cert.IssueCert(payload, logChan, errChan) - - go handleIssueCertLogChan(ws, log, logChan) - - // block, until errChan closes - for err = range errChan { + err = cert.IssueCert(payload, log) + if err != nil { log.Error(err) - // Save logs to db - log.Exit() - err = ws.WriteJSON(IssueCertResponse{ + _ = ws.WriteJSON(IssueCertResponse{ Status: Error, Message: err.Error(), }) - if err != nil { - logger.Error(err) - return - } return } @@ -130,6 +100,7 @@ func IssueCert(c *gin.Context) { MustStaple: payload.MustStaple, LegoDisableCNAMESupport: payload.LegoDisableCNAMESupport, Log: log.ToString(), + RevokeOld: payload.RevokeOld, })).FirstOrCreate() if err != nil { logger.Error(err) @@ -139,19 +110,17 @@ func IssueCert(c *gin.Context) { }) return } - - // Save logs to db - log.Exit() - err = ws.WriteJSON(IssueCertResponse{ Status: Success, - Message: "Issued certificate successfully", + Message: translation.C("[Nginx UI] Issued certificate successfully").ToString(), SSLCertificate: payload.GetCertificatePath(), SSLCertificateKey: payload.GetCertificateKeyPath(), KeyType: payload.GetKeyType(), }) if err != nil { - logger.Error(err) + if helper.IsUnexpectedWebsocketError(err) { + logger.Error(err) + } return } } diff --git a/api/certificate/revoke.go b/api/certificate/revoke.go new file mode 100644 index 000000000..d33e03189 --- /dev/null +++ b/api/certificate/revoke.go @@ -0,0 +1,132 @@ +package certificate + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/internal/cert" + "github.com/0xJacky/Nginx-UI/internal/translation" + "github.com/0xJacky/Nginx-UI/query" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "github.com/spf13/cast" + "github.com/uozi-tech/cosy/logger" +) + +type RevokeCertResponse struct { + Status string `json:"status"` + *translation.Container +} + +func handleRevokeCertLogChan(conn *websocket.Conn, logChan chan string) { + defer func() { + if err := recover(); err != nil { + logger.Error(err) + } + }() + + for logString := range logChan { + err := conn.WriteJSON(RevokeCertResponse{ + Status: Info, + Container: translation.C(logString), + }) + if err != nil { + logger.Error(err) + return + } + } +} + +// RevokeCert handles certificate revocation through websocket connection +func RevokeCert(c *gin.Context) { + id := cast.ToUint64(c.Param("id")) + + var upGrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + } + + // upgrade http to websocket + ws, err := upGrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + logger.Error(err) + return + } + + defer func(ws *websocket.Conn) { + _ = ws.Close() + }(ws) + + // Get certificate from database + certQuery := query.Cert + certModel, err := certQuery.FirstByID(id) + if err != nil { + logger.Error(err) + _ = ws.WriteJSON(RevokeCertResponse{ + Status: Error, + Container: translation.C("Certificate not found: %{error}", map[string]any{ + "error": err.Error(), + }), + }) + return + } + + // Create payload for revocation + payload := &cert.ConfigPayload{ + CertID: id, + ServerName: certModel.Domains, + ChallengeMethod: certModel.ChallengeMethod, + DNSCredentialID: certModel.DnsCredentialID, + ACMEUserID: certModel.ACMEUserID, + KeyType: certModel.KeyType, + Resource: certModel.Resource, + } + + logChan := make(chan string, 1) + errChan := make(chan error, 1) + + certLogger := cert.NewLogger() + certLogger.SetWebSocket(ws) + defer certLogger.Close() + + go cert.RevokeCert(payload, certLogger, logChan, errChan) + + go handleRevokeCertLogChan(ws, logChan) + + // block, until errChan closes + for err = range errChan { + logger.Error(err) + err = ws.WriteJSON(RevokeCertResponse{ + Status: Error, + Container: translation.C("Failed to revoke certificate: %{error}", map[string]any{ + "error": err.Error(), + }), + }) + if err != nil { + logger.Error(err) + return + } + } + + // Update certificate status in database + err = certModel.Remove() + if err != nil { + logger.Error(err) + _ = ws.WriteJSON(RevokeCertResponse{ + Status: Error, + Container: translation.C("Failed to delete certificate from database: %{error}", map[string]any{ + "error": err.Error(), + }), + }) + return + } + + err = ws.WriteJSON(RevokeCertResponse{ + Status: Success, + Container: translation.C("Certificate revoked successfully"), + }) + if err != nil { + logger.Error(err) + return + } +} diff --git a/api/certificate/router.go b/api/certificate/router.go index f81294833..6491f8b7a 100644 --- a/api/certificate/router.go +++ b/api/certificate/router.go @@ -23,6 +23,7 @@ func InitCertificateRouter(r *gin.RouterGroup) { func InitCertificateWebSocketRouter(r *gin.RouterGroup) { r.GET("domain/:name/cert", IssueCert) + r.GET("certs/:id/revoke", RevokeCert) } func InitAcmeUserRouter(r *gin.RouterGroup) { diff --git a/api/cluster/environment.go b/api/cluster/environment.go index 9181b74ad..b78a95f3e 100644 --- a/api/cluster/environment.go +++ b/api/cluster/environment.go @@ -1,14 +1,9 @@ package cluster import ( - "crypto/sha256" - "encoding/hex" - "encoding/json" - "io" + "context" "net/http" - "time" - "github.com/0xJacky/Nginx-UI/api" "github.com/0xJacky/Nginx-UI/internal/analytic" "github.com/0xJacky/Nginx-UI/internal/cluster" "github.com/0xJacky/Nginx-UI/model" @@ -47,86 +42,16 @@ func GetEnvironmentList(c *gin.Context) { core.SetTransformer(func(m *model.Environment) any { return analytic.GetNode(m) - }).PagingList() -} - -func GetAllEnabledEnvironment(c *gin.Context) { - api.SetSSEHeaders(c) - notify := c.Writer.CloseNotify() - - interval := 10 - - type respEnvironment struct { - *model.Environment - Status bool `json:"status"` - } - - f := func() (any, bool) { - return cosy.Core[model.Environment](c). - SetFussy("name"). - SetTransformer(func(m *model.Environment) any { - resp := respEnvironment{ - Environment: m, - Status: analytic.GetNode(m).Status, - } - return resp - }).ListAllData() - } - - getHash := func(data any) string { - bytes, _ := json.Marshal(data) - hash := sha256.New() - hash.Write(bytes) - hashSum := hash.Sum(nil) - return hex.EncodeToString(hashSum) - } - - dataHash := "" - - { - data, ok := f() - if !ok { - return - } + }) - c.Stream(func(w io.Writer) bool { - c.SSEvent("message", data) - dataHash = getHash(data) - return false - }) + data, ok := core.ListAllData() + if !ok { + return } - for { - select { - case <-time.After(time.Duration(interval) * time.Second): - data, ok := f() - if !ok { - return - } - // if data is not changed, send heartbeat - if dataHash == getHash(data) { - c.Stream(func(w io.Writer) bool { - c.SSEvent("heartbeat", "") - return false - }) - return - } - - dataHash = getHash(data) - - c.Stream(func(w io.Writer) bool { - c.SSEvent("message", data) - return false - }) - case <-time.After(30 * time.Second): - c.Stream(func(w io.Writer) bool { - c.SSEvent("heartbeat", "") - return false - }) - case <-notify: - return - } - } + c.JSON(http.StatusOK, model.DataList{ + Data: data, + }) } func AddEnvironment(c *gin.Context) { @@ -165,7 +90,8 @@ func LoadEnvironmentFromSettings(c *gin.Context) { return } - cluster.RegisterPredefinedNodes() + ctx := context.Background() + cluster.RegisterPredefinedNodes(ctx) go analytic.RestartRetrieveNodesStatus() diff --git a/api/cluster/group.go b/api/cluster/group.go new file mode 100644 index 000000000..4c1f92ea7 --- /dev/null +++ b/api/cluster/group.go @@ -0,0 +1,84 @@ +package cluster + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" + "gorm.io/gorm" +) + +func GetGroup(c *gin.Context) { + cosy.Core[model.EnvGroup](c).Get() +} + +func GetGroupList(c *gin.Context) { + cosy.Core[model.EnvGroup](c).GormScope(func(tx *gorm.DB) *gorm.DB { + return tx.Order("order_id ASC") + }).PagingList() +} + +func ReloadNginx(c *gin.Context) { + var json struct { + NodeIDs []uint64 `json:"node_ids" binding:"required"` + } + + if !cosy.BindAndValid(c, &json) { + return + } + + go syncReload(json.NodeIDs) + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} + +func RestartNginx(c *gin.Context) { + var json struct { + NodeIDs []uint64 `json:"node_ids" binding:"required"` + } + + if !cosy.BindAndValid(c, &json) { + return + } + + go syncRestart(json.NodeIDs) + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} + +func AddGroup(c *gin.Context) { + cosy.Core[model.EnvGroup](c). + SetValidRules(gin.H{ + "name": "required", + "sync_node_ids": "omitempty", + "post_sync_action": "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx, + }). + Create() +} + +func ModifyGroup(c *gin.Context) { + cosy.Core[model.EnvGroup](c). + SetValidRules(gin.H{ + "name": "required", + "sync_node_ids": "omitempty", + "post_sync_action": "omitempty,oneof=" + model.PostSyncActionNone + " " + model.PostSyncActionReloadNginx, + }). + Modify() +} + +func DeleteGroup(c *gin.Context) { + cosy.Core[model.EnvGroup](c).Destroy() +} + +func RecoverGroup(c *gin.Context) { + cosy.Core[model.EnvGroup](c).Recover() +} + +func UpdateGroupsOrder(c *gin.Context) { + cosy.Core[model.EnvGroup](c).UpdateOrder() +} diff --git a/api/cluster/nginx.go b/api/cluster/nginx.go new file mode 100644 index 000000000..7befcfc80 --- /dev/null +++ b/api/cluster/nginx.go @@ -0,0 +1,126 @@ +package cluster + +import ( + "net/http" + "runtime" + "sync" + + "github.com/0xJacky/Nginx-UI/internal/notification" + "github.com/0xJacky/Nginx-UI/model" + "github.com/0xJacky/Nginx-UI/query" + "github.com/go-resty/resty/v2" + "github.com/uozi-tech/cosy/logger" +) + +type syncResult struct { + Node string `json:"node"` + Resp string `json:"resp"` +} + +// syncReload handle reload nginx on remote nodes +func syncReload(nodeIDs []uint64) { + if len(nodeIDs) == 0 { + return + } + + e := query.Environment + nodes, err := e.Where(e.ID.In(nodeIDs...)).Find() + if err != nil { + logger.Error("Failed to get environment nodes:", err) + return + } + + wg := &sync.WaitGroup{} + wg.Add(len(nodes)) + + for _, node := range nodes { + go func(node *model.Environment) { + defer func() { + if err := recover(); err != nil { + buf := make([]byte, 1024) + runtime.Stack(buf, false) + logger.Errorf("%s\n%s", err, buf) + } + }() + defer wg.Done() + + client := resty.New() + client.SetBaseURL(node.URL) + resp, err := client.R(). + SetHeader("X-Node-Secret", node.Token). + Post("/api/nginx/reload") + if err != nil { + notification.Error("Reload Remote Nginx Error", "", err.Error()) + return + } + if resp.StatusCode() != http.StatusOK { + notification.Error("Reload Remote Nginx Error", + "Reload Nginx on %{node} failed, response: %{resp}", syncResult{ + Node: node.Name, + Resp: resp.String(), + }) + return + } + notification.Success("Reload Remote Nginx Success", + "Reload Nginx on %{node} successfully", syncResult{ + Node: node.Name, + }) + }(node) + } + + wg.Wait() +} + +// syncRestart handle restart nginx on remote nodes +func syncRestart(nodeIDs []uint64) { + if len(nodeIDs) == 0 { + return + } + + e := query.Environment + nodes, err := e.Where(e.ID.In(nodeIDs...)).Find() + if err != nil { + logger.Error("Failed to get environment nodes:", err) + return + } + + wg := &sync.WaitGroup{} + wg.Add(len(nodes)) + + for _, node := range nodes { + go func(node *model.Environment) { + defer func() { + if err := recover(); err != nil { + buf := make([]byte, 1024) + runtime.Stack(buf, false) + logger.Errorf("%s\n%s", err, buf) + } + }() + defer wg.Done() + + client := resty.New() + client.SetBaseURL(node.URL) + resp, err := client.R(). + SetHeader("X-Node-Secret", node.Token). + Post("/api/nginx/restart") + if err != nil { + notification.Error("Restart Remote Nginx Error", "", err.Error()) + return + } + if resp.StatusCode() != http.StatusOK { + notification.Error("Restart Remote Nginx Error", + "Restart Nginx on %{node} failed, response: %{resp}", syncResult{ + Node: node.Name, + Resp: resp.String(), + }) + return + } + notification.Success("Restart Remote Nginx Success", + "Restart Nginx on %{node} successfully", syncResult{ + Node: node.Name, + }) + }(node) + } + + wg.Wait() +} diff --git a/api/cluster/node.go b/api/cluster/node.go index 399bbec10..82796823f 100644 --- a/api/cluster/node.go +++ b/api/cluster/node.go @@ -3,13 +3,10 @@ package cluster import ( "net/http" - analytic2 "github.com/0xJacky/Nginx-UI/internal/analytic" - "github.com/0xJacky/Nginx-UI/internal/upgrader" + "github.com/0xJacky/Nginx-UI/internal/analytic" "github.com/0xJacky/Nginx-UI/internal/version" - "github.com/dustin/go-humanize" "github.com/gin-gonic/gin" "github.com/shirou/gopsutil/v4/cpu" - "github.com/shirou/gopsutil/v4/disk" "github.com/uozi-tech/cosy" ) @@ -21,27 +18,27 @@ func GetCurrentNode(c *gin.Context) { return } - runtimeInfo, err := upgrader.GetRuntimeInfo() + runtimeInfo, err := version.GetRuntimeInfo() if err != nil { cosy.ErrHandler(c, err) return } cpuInfo, _ := cpu.Info() - memory, _ := analytic2.GetMemoryStat() + memory, _ := analytic.GetMemoryStat() ver := version.GetVersionInfo() - diskUsage, _ := disk.Usage(".") + diskUsage, _ := analytic.GetDiskStat() - nodeInfo := analytic2.NodeInfo{ + nodeInfo := analytic.NodeInfo{ NodeRuntimeInfo: runtimeInfo, CPUNum: len(cpuInfo), MemoryTotal: memory.Total, - DiskTotal: humanize.Bytes(diskUsage.Total), + DiskTotal: diskUsage.Total, Version: ver.Version, } - stat := analytic2.GetNodeStat() + stat := analytic.GetNodeStat() - c.JSON(http.StatusOK, analytic2.Node{ + c.JSON(http.StatusOK, analytic.Node{ NodeInfo: nodeInfo, NodeStat: stat, }) diff --git a/api/cluster/router.go b/api/cluster/router.go index ee4a5608b..fd1c706c4 100644 --- a/api/cluster/router.go +++ b/api/cluster/router.go @@ -5,7 +5,7 @@ import "github.com/gin-gonic/gin" func InitRouter(r *gin.RouterGroup) { // Environment r.GET("environments", GetEnvironmentList) - r.GET("environments/enabled", GetAllEnabledEnvironment) + r.GET("environments/enabled", GetAllEnabledEnvironmentWS) r.POST("environments/load_from_settings", LoadEnvironmentFromSettings) envGroup := r.Group("environments") { @@ -16,4 +16,15 @@ func InitRouter(r *gin.RouterGroup) { } // Node r.GET("node", GetCurrentNode) + + r.POST("environments/reload_nginx", ReloadNginx) + r.POST("environments/restart_nginx", RestartNginx) + + r.GET("env_groups", GetGroupList) + r.GET("env_groups/:id", GetGroup) + r.POST("env_groups", AddGroup) + r.POST("env_groups/:id", ModifyGroup) + r.DELETE("env_groups/:id", DeleteGroup) + r.POST("env_groups/:id/recover", RecoverGroup) + r.POST("env_groups/order", UpdateGroupsOrder) } diff --git a/api/cluster/websocket.go b/api/cluster/websocket.go new file mode 100644 index 000000000..1a87f02bf --- /dev/null +++ b/api/cluster/websocket.go @@ -0,0 +1,293 @@ +package cluster + +import ( + "context" + "crypto/sha256" + "encoding/hex" + "encoding/json" + "net/http" + "sync" + "time" + + "github.com/0xJacky/Nginx-UI/internal/analytic" + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "github.com/uozi-tech/cosy/logger" +) + +// WebSocketMessage represents the structure of messages sent to the client +type WebSocketMessage struct { + Event string `json:"event"` + Data interface{} `json:"data"` +} + +// Client represents a WebSocket client connection for cluster environment monitoring +type Client struct { + conn *websocket.Conn + send chan WebSocketMessage + ctx context.Context + cancel context.CancelFunc + mutex sync.RWMutex +} + +// Hub maintains the set of active clients and broadcasts messages to them +type Hub struct { + clients map[*Client]bool + broadcast chan WebSocketMessage + register chan *Client + unregister chan *Client + mutex sync.RWMutex +} + +var ( + hub *Hub + hubOnce sync.Once +) + +// GetHub returns the singleton hub instance +func GetHub() *Hub { + hubOnce.Do(func() { + hub = &Hub{ + clients: make(map[*Client]bool), + broadcast: make(chan WebSocketMessage, 256), + register: make(chan *Client), + unregister: make(chan *Client), + } + go hub.run() + }) + return hub +} + +// run handles the main hub loop +func (h *Hub) run() { + for { + select { + case client := <-h.register: + h.mutex.Lock() + h.clients[client] = true + h.mutex.Unlock() + logger.Debug("Cluster environment client connected, total clients:", len(h.clients)) + + case client := <-h.unregister: + h.mutex.Lock() + if _, ok := h.clients[client]; ok { + delete(h.clients, client) + close(client.send) + } + h.mutex.Unlock() + logger.Debug("Cluster environment client disconnected, total clients:", len(h.clients)) + + case message := <-h.broadcast: + h.mutex.RLock() + for client := range h.clients { + select { + case client.send <- message: + default: + close(client.send) + delete(h.clients, client) + } + } + h.mutex.RUnlock() + } + } +} + +// BroadcastMessage sends a message to all connected clients +func (h *Hub) BroadcastMessage(event string, data any) { + message := WebSocketMessage{ + Event: event, + Data: data, + } + select { + case h.broadcast <- message: + default: + logger.Warn("Cluster environment broadcast channel full, message dropped") + } +} + +// WebSocket upgrader configuration +var upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + ReadBufferSize: 1024, + WriteBufferSize: 1024, +} + +type respEnvironment struct { + *model.Environment + Status bool `json:"status"` +} + +// GetAllEnabledEnvironmentWS handles WebSocket connections for real-time environment monitoring +func GetAllEnabledEnvironmentWS(c *gin.Context) { + ws, err := upgrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + logger.Error("Failed to upgrade connection:", err) + return + } + defer ws.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + client := &Client{ + conn: ws, + send: make(chan WebSocketMessage, 256), + ctx: ctx, + cancel: cancel, + } + + hub := GetHub() + hub.register <- client + + // Start goroutines for handling environment monitoring + go client.handleEnvironmentMonitoring() + + // Start write and read pumps + go client.writePump() + client.readPump() +} + +// handleEnvironmentMonitoring monitors environment status and sends updates +func (c *Client) handleEnvironmentMonitoring() { + interval := 10 * time.Second + heartbeatInterval := 30 * time.Second + + getEnvironmentData := func() (interface{}, bool) { + // Query environments directly from database + var environments []model.Environment + err := model.UseDB().Where("enabled = ?", true).Find(&environments).Error + if err != nil { + logger.Error("Failed to query environments:", err) + return nil, false + } + + // Transform environments to response format + var result []respEnvironment + for _, env := range environments { + result = append(result, respEnvironment{ + Environment: &env, + Status: analytic.GetNode(&env).Status, + }) + } + + return result, true + } + + getHash := func(data interface{}) string { + bytes, _ := json.Marshal(data) + hash := sha256.New() + hash.Write(bytes) + hashSum := hash.Sum(nil) + return hex.EncodeToString(hashSum) + } + + var dataHash string + + // Send initial data + data, ok := getEnvironmentData() + if ok { + dataHash = getHash(data) + c.sendMessage("message", data) + } + + ticker := time.NewTicker(interval) + heartbeatTicker := time.NewTicker(heartbeatInterval) + defer ticker.Stop() + defer heartbeatTicker.Stop() + + for { + select { + case <-ticker.C: + data, ok := getEnvironmentData() + if !ok { + return + } + + newHash := getHash(data) + if dataHash != newHash { + dataHash = newHash + c.sendMessage("message", data) + } + + case <-heartbeatTicker.C: + c.sendMessage("heartbeat", "") + + case <-c.ctx.Done(): + return + } + } +} + +// sendMessage sends a message to the client +func (c *Client) sendMessage(event string, data any) { + message := WebSocketMessage{ + Event: event, + Data: data, + } + + select { + case c.send <- message: + default: + logger.Warn("Client send channel full, message dropped") + } +} + +// writePump pumps messages from the hub to the websocket connection +func (c *Client) writePump() { + ticker := time.NewTicker(54 * time.Second) + defer ticker.Stop() + + for { + select { + case message, ok := <-c.send: + c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) + if !ok { + c.conn.WriteMessage(websocket.CloseMessage, []byte{}) + return + } + + if err := c.conn.WriteJSON(message); err != nil { + logger.Error("Error writing message to websocket:", err) + return + } + + case <-ticker.C: + c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) + if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil { + return + } + + case <-c.ctx.Done(): + return + } + } +} + +// readPump pumps messages from the websocket connection to the hub +func (c *Client) readPump() { + defer func() { + hub := GetHub() + hub.unregister <- c + c.conn.Close() + c.cancel() + }() + + c.conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + c.conn.SetPongHandler(func(string) error { + c.conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + return nil + }) + + for { + _, _, err := c.conn.ReadMessage() + if err != nil { + if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { + logger.Error("Websocket error:", err) + } + break + } + } +} diff --git a/api/config/add.go b/api/config/add.go index 0a2f00b2c..e693fdd38 100644 --- a/api/config/add.go +++ b/api/config/add.go @@ -12,7 +12,6 @@ import ( "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" - "github.com/sashabaranov/go-openai" "github.com/uozi-tech/cosy" ) @@ -28,8 +27,13 @@ func AddConfig(c *gin.Context) { name := json.Name content := json.Content - dir := nginx.GetConfPath(json.BaseDir) - path := filepath.Join(dir, json.Name) + + // Decode paths from URL encoding + decodedBaseDir := helper.UnescapeURL(json.BaseDir) + decodedName := helper.UnescapeURL(name) + + dir := nginx.GetConfPath(decodedBaseDir) + path := filepath.Join(dir, decodedName) if !helper.IsUnderDirectory(path, nginx.GetConfPath()) { c.JSON(http.StatusForbidden, gin.H{ "message": "filepath is not under the nginx conf path", @@ -59,11 +63,9 @@ func AddConfig(c *gin.Context) { return } - output := nginx.Reload() - if nginx.GetLogLevel(output) >= nginx.Warn { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) + res := nginx.Control(nginx.Reload) + if res.IsError() { + res.RespError(c) return } @@ -94,10 +96,9 @@ func AddConfig(c *gin.Context) { } c.JSON(http.StatusOK, config.Config{ - Name: name, - Content: content, - ChatGPTMessages: make([]openai.ChatCompletionMessage, 0), - FilePath: path, - ModifiedAt: time.Now(), + Name: name, + Content: content, + FilePath: path, + ModifiedAt: time.Now(), }) } diff --git a/api/config/delete.go b/api/config/delete.go new file mode 100644 index 000000000..56483e427 --- /dev/null +++ b/api/config/delete.go @@ -0,0 +1,75 @@ +package config + +import ( + "net/http" + "os" + + "github.com/0xJacky/Nginx-UI/internal/config" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" +) + +// DeleteConfig handles the deletion of configuration files or directories +func DeleteConfig(c *gin.Context) { + var json struct { + BasePath string `json:"base_path"` + Name string `json:"name" binding:"required"` + SyncNodeIds []uint64 `json:"sync_node_ids" gorm:"serializer:json"` + } + if !cosy.BindAndValid(c, &json) { + return + } + + // Decode paths from URL encoding + decodedBasePath := helper.UnescapeURL(json.BasePath) + decodedName := helper.UnescapeURL(json.Name) + + fullPath := nginx.GetConfPath(decodedBasePath, decodedName) + + // Check if path is under nginx config directory + if err := config.ValidateDeletePath(fullPath); err != nil { + cosy.ErrHandler(c, err) + return + } + + // Check if trying to delete protected paths + if config.IsProtectedPath(fullPath, decodedName) { + cosy.ErrHandler(c, config.ErrCannotDeleteProtectedPath) + return + } + + // Check if file/directory exists + stat, err := config.CheckFileExists(fullPath) + if err != nil { + cosy.ErrHandler(c, err) + return + } + + // Delete the file or directory + err = os.RemoveAll(fullPath) + if err != nil { + cosy.ErrHandler(c, err) + return + } + + // Clean up database records + if err := config.CleanupDatabaseRecords(fullPath, stat.IsDir()); err != nil { + cosy.ErrHandler(c, err) + return + } + + // Sync deletion to remote servers if configured + if len(json.SyncNodeIds) > 0 { + err = config.SyncDeleteOnRemoteServer(fullPath, json.SyncNodeIds) + if err != nil { + cosy.ErrHandler(c, err) + return + } + } + + c.JSON(http.StatusOK, gin.H{ + "message": "deleted successfully", + }) +} diff --git a/api/config/get.go b/api/config/get.go index 5d47bf95a..c74c667d2 100644 --- a/api/config/get.go +++ b/api/config/get.go @@ -10,18 +10,11 @@ import ( "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" - "github.com/sashabaranov/go-openai" "github.com/uozi-tech/cosy" ) -type APIConfigResp struct { - config.Config - SyncNodeIds []uint64 `json:"sync_node_ids" gorm:"serializer:json"` - SyncOverwrite bool `json:"sync_overwrite"` -} - func GetConfig(c *gin.Context) { - relativePath := c.Param("path") + relativePath := helper.UnescapeURL(c.Param("path")) absPath := nginx.GetConfPath(relativePath) if !helper.IsUnderDirectory(absPath, nginx.GetConfPath()) { @@ -42,33 +35,20 @@ func GetConfig(c *gin.Context) { cosy.ErrHandler(c, err) return } - q := query.Config - g := query.ChatGPTLog - chatgpt, err := g.Where(g.Name.Eq(absPath)).FirstOrCreate() - if err != nil { - cosy.ErrHandler(c, err) - return - } - - if chatgpt.Content == nil { - chatgpt.Content = make([]openai.ChatCompletionMessage, 0) - } + q := query.Config cfg, err := q.Where(q.Filepath.Eq(absPath)).FirstOrInit() if err != nil { cosy.ErrHandler(c, err) return } - c.JSON(http.StatusOK, APIConfigResp{ - Config: config.Config{ - Name: stat.Name(), - Content: string(content), - ChatGPTMessages: chatgpt.Content, - FilePath: absPath, - ModifiedAt: stat.ModTime(), - Dir: filepath.Dir(relativePath), - }, + c.JSON(http.StatusOK, config.Config{ + Name: stat.Name(), + Content: string(content), + FilePath: absPath, + ModifiedAt: stat.ModTime(), + Dir: filepath.Dir(relativePath), SyncNodeIds: cfg.SyncNodeIds, SyncOverwrite: cfg.SyncOverwrite, }) diff --git a/api/config/history.go b/api/config/history.go new file mode 100644 index 000000000..83083d6fe --- /dev/null +++ b/api/config/history.go @@ -0,0 +1,13 @@ +package config + +import ( + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" +) + +func GetConfigHistory(c *gin.Context) { + cosy.Core[model.ConfigBackup](c). + SetEqual("filepath"). + PagingList() +} diff --git a/api/config/list.go b/api/config/list.go index a8a08797e..b23909807 100644 --- a/api/config/list.go +++ b/api/config/list.go @@ -6,65 +6,34 @@ import ( "strings" "github.com/0xJacky/Nginx-UI/internal/config" - "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/gin-gonic/gin" "github.com/uozi-tech/cosy" - "github.com/uozi-tech/cosy/logger" ) func GetConfigs(c *gin.Context) { name := c.Query("name") sortBy := c.Query("sort_by") order := c.DefaultQuery("order", "desc") - dir := c.DefaultQuery("dir", "/") - configFiles, err := os.ReadDir(nginx.GetConfPath(dir)) - if err != nil { - cosy.ErrHandler(c, err) - return - } - - configs := make([]config.Config, 0) - - for i := range configFiles { - file := configFiles[i] - fileInfo, _ := file.Info() + // Get directory parameter + encodedDir := c.DefaultQuery("dir", "/") - if name != "" && !strings.Contains(file.Name(), name) { - continue - } + // Handle cases where the path might be encoded multiple times + dir := helper.UnescapeURL(encodedDir) - switch mode := fileInfo.Mode(); { - case mode.IsRegular(): // regular file, not a hidden file - if "." == file.Name()[0:1] { - continue - } - case mode&os.ModeSymlink != 0: // is a symbol - var targetPath string - targetPath, err = os.Readlink(nginx.GetConfPath(dir, file.Name())) - if err != nil { - logger.Error("Read Symlink Error", targetPath, err) - continue - } - - var targetInfo os.FileInfo - targetInfo, err = os.Stat(targetPath) - if err != nil { - logger.Error("Stat Error", targetPath, err) - continue - } - // hide the file if it's target file is a directory - if targetInfo.IsDir() { - continue - } - } + // Ensure the directory path format is correct + dir = strings.TrimSpace(dir) + if dir != "/" && strings.HasSuffix(dir, "/") { + dir = strings.TrimSuffix(dir, "/") + } - configs = append(configs, config.Config{ - Name: file.Name(), - ModifiedAt: fileInfo.ModTime(), - Size: fileInfo.Size(), - IsDir: fileInfo.IsDir(), - }) + configs, err := config.GetConfigList(dir, func(file os.FileInfo) bool { + return name == "" || strings.Contains(file.Name(), name) + }) + if err != nil { + cosy.ErrHandler(c, err) + return } configs = config.Sort(sortBy, order, configs) diff --git a/api/config/mkdir.go b/api/config/mkdir.go index 54cba6fdb..a7e4d2a1e 100644 --- a/api/config/mkdir.go +++ b/api/config/mkdir.go @@ -18,7 +18,13 @@ func Mkdir(c *gin.Context) { if !cosy.BindAndValid(c, &json) { return } - fullPath := nginx.GetConfPath(json.BasePath, json.FolderName) + + // Ensure paths are properly URL unescaped + decodedBasePath := helper.UnescapeURL(json.BasePath) + + decodedFolderName := helper.UnescapeURL(json.FolderName) + + fullPath := nginx.GetConfPath(decodedBasePath, decodedFolderName) if !helper.IsUnderDirectory(fullPath, nginx.GetConfPath()) { c.JSON(http.StatusForbidden, gin.H{ "message": "You are not allowed to create a folder " + diff --git a/api/config/modify.go b/api/config/modify.go index e2eda895e..f6876f479 100644 --- a/api/config/modify.go +++ b/api/config/modify.go @@ -2,7 +2,6 @@ package config import ( "net/http" - "os" "path/filepath" "time" @@ -12,7 +11,6 @@ import ( "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" - "github.com/sashabaranov/go-openai" "github.com/uozi-tech/cosy" "gorm.io/gen/field" ) @@ -22,7 +20,8 @@ type EditConfigJson struct { } func EditConfig(c *gin.Context) { - relativePath := c.Param("path") + relativePath := helper.UnescapeURL(c.Param("path")) + var json struct { Content string `json:"content"` SyncOverwrite bool `json:"sync_overwrite"` @@ -40,30 +39,15 @@ func EditConfig(c *gin.Context) { return } - content := json.Content - origContent, err := os.ReadFile(absPath) - if err != nil { - cosy.ErrHandler(c, err) - return - } - - if content != "" && content != string(origContent) { - err = os.WriteFile(absPath, []byte(content), 0644) - if err != nil { - cosy.ErrHandler(c, err) - return - } - } - q := query.Config cfg, err := q.Assign(field.Attrs(&model.Config{ - Name: filepath.Base(absPath), + Filepath: absPath, })).Where(q.Filepath.Eq(absPath)).FirstOrCreate() if err != nil { - cosy.ErrHandler(c, err) return } + // Update database record _, err = q.Where(q.Filepath.Eq(absPath)). Select(q.SyncNodeIds, q.SyncOverwrite). Updates(&model.Config{ @@ -71,45 +55,26 @@ func EditConfig(c *gin.Context) { SyncOverwrite: json.SyncOverwrite, }) if err != nil { - cosy.ErrHandler(c, err) return } - // use the new values cfg.SyncNodeIds = json.SyncNodeIds cfg.SyncOverwrite = json.SyncOverwrite - g := query.ChatGPTLog - err = config.SyncToRemoteServer(cfg) - if err != nil { - cosy.ErrHandler(c, err) - return - } - - output := nginx.Reload() - if nginx.GetLogLevel(output) >= nginx.Warn { - c.JSON(http.StatusInternalServerError, gin.H{ - "message": output, - }) - return - } - - chatgpt, err := g.Where(g.Name.Eq(absPath)).FirstOrCreate() + content := json.Content + err = config.Save(absPath, content, cfg) if err != nil { cosy.ErrHandler(c, err) return } - if chatgpt.Content == nil { - chatgpt.Content = make([]openai.ChatCompletionMessage, 0) - } - c.JSON(http.StatusOK, config.Config{ - Name: filepath.Base(absPath), - Content: content, - ChatGPTMessages: chatgpt.Content, - FilePath: absPath, - ModifiedAt: time.Now(), - Dir: filepath.Dir(relativePath), + Name: filepath.Base(absPath), + Content: content, + FilePath: absPath, + ModifiedAt: time.Now(), + Dir: filepath.Dir(relativePath), + SyncNodeIds: cfg.SyncNodeIds, + SyncOverwrite: cfg.SyncOverwrite, }) } diff --git a/api/config/rename.go b/api/config/rename.go index 34b9ca3af..6515956d0 100644 --- a/api/config/rename.go +++ b/api/config/rename.go @@ -2,6 +2,7 @@ package config import ( "net/http" + "net/url" "os" "path/filepath" "strings" @@ -32,8 +33,20 @@ func Rename(c *gin.Context) { }) return } - origFullPath := nginx.GetConfPath(json.BasePath, json.OrigName) - newFullPath := nginx.GetConfPath(json.BasePath, json.NewName) + + // Decode paths from URL encoding + decodedBasePath := helper.UnescapeURL(json.BasePath) + + decodedOrigName := helper.UnescapeURL(json.OrigName) + + decodedNewName, err := url.QueryUnescape(json.NewName) + if err != nil { + cosy.ErrHandler(c, err) + return + } + + origFullPath := nginx.GetConfPath(decodedBasePath, decodedOrigName) + newFullPath := nginx.GetConfPath(decodedBasePath, decodedNewName) if !helper.IsUnderDirectory(origFullPath, nginx.GetConfPath()) || !helper.IsUnderDirectory(newFullPath, nginx.GetConfPath()) { c.JSON(http.StatusForbidden, gin.H{ @@ -89,6 +102,12 @@ func Rename(c *gin.Context) { return } + b := query.ConfigBackup + _, _ = b.Where(b.FilePath.Eq(origFullPath)).Updates(map[string]interface{}{ + "filepath": newFullPath, + "name": json.NewName, + }) + if len(json.SyncNodeIds) > 0 { err = config.SyncRenameOnRemoteServer(origFullPath, newFullPath, json.SyncNodeIds) if err != nil { diff --git a/api/config/router.go b/api/config/router.go index 2d9b9d0f5..ff1ae4c53 100644 --- a/api/config/router.go +++ b/api/config/router.go @@ -17,5 +17,8 @@ func InitRouter(r *gin.RouterGroup) { { o.POST("config_mkdir", Mkdir) o.POST("config_rename", Rename) + o.POST("config_delete", DeleteConfig) } + + r.GET("config_histories", GetConfigHistory) } diff --git a/api/event/router.go b/api/event/router.go new file mode 100644 index 000000000..977330709 --- /dev/null +++ b/api/event/router.go @@ -0,0 +1,8 @@ +package event + +import "github.com/gin-gonic/gin" + +// InitRouter registers the WebSocket event bus route +func InitRouter(r *gin.RouterGroup) { + r.GET("events", EventBus) +} diff --git a/api/event/websocket.go b/api/event/websocket.go new file mode 100644 index 000000000..247268493 --- /dev/null +++ b/api/event/websocket.go @@ -0,0 +1,296 @@ +package event + +import ( + "context" + "encoding/json" + "net/http" + "sync" + "time" + + "github.com/0xJacky/Nginx-UI/internal/cache" + "github.com/0xJacky/Nginx-UI/internal/cert" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/kernel" + "github.com/0xJacky/Nginx-UI/internal/notification" + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "github.com/uozi-tech/cosy/logger" +) + +// WebSocketMessage represents the structure of messages sent to the client +type WebSocketMessage struct { + Event string `json:"event"` + Data interface{} `json:"data"` +} + +// Client represents a WebSocket client connection +type Client struct { + conn *websocket.Conn + send chan WebSocketMessage + ctx context.Context + cancel context.CancelFunc + mutex sync.RWMutex +} + +// Hub maintains the set of active clients and broadcasts messages to them +type Hub struct { + clients map[*Client]bool + broadcast chan WebSocketMessage + register chan *Client + unregister chan *Client + mutex sync.RWMutex +} + +var ( + hub *Hub + hubOnce sync.Once +) + +// GetHub returns the singleton hub instance +func GetHub() *Hub { + hubOnce.Do(func() { + hub = &Hub{ + clients: make(map[*Client]bool), + broadcast: make(chan WebSocketMessage, 256), + register: make(chan *Client), + unregister: make(chan *Client), + } + go hub.run() + }) + return hub +} + +// run handles the main hub loop +func (h *Hub) run() { + for { + select { + case client := <-h.register: + h.mutex.Lock() + h.clients[client] = true + h.mutex.Unlock() + logger.Debug("Client connected, total clients:", len(h.clients)) + + case client := <-h.unregister: + h.mutex.Lock() + if _, ok := h.clients[client]; ok { + delete(h.clients, client) + close(client.send) + } + h.mutex.Unlock() + logger.Debug("Client disconnected, total clients:", len(h.clients)) + + case message := <-h.broadcast: + h.mutex.RLock() + for client := range h.clients { + select { + case client.send <- message: + default: + close(client.send) + delete(h.clients, client) + } + } + h.mutex.RUnlock() + } + } +} + +// BroadcastMessage sends a message to all connected clients +func (h *Hub) BroadcastMessage(event string, data interface{}) { + message := WebSocketMessage{ + Event: event, + Data: data, + } + select { + case h.broadcast <- message: + default: + logger.Warn("Broadcast channel full, message dropped") + } +} + +// WebSocket upgrader configuration +var upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + ReadBufferSize: 1024, + WriteBufferSize: 1024, +} + +// EventBus handles the main WebSocket connection for the event bus +func EventBus(c *gin.Context) { + ws, err := upgrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + logger.Error("Failed to upgrade connection:", err) + return + } + defer ws.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + client := &Client{ + conn: ws, + send: make(chan WebSocketMessage, 256), + ctx: ctx, + cancel: cancel, + } + + hub := GetHub() + hub.register <- client + + // Start goroutines for handling subscriptions + go client.handleNotifications() + go client.handleProcessingStatus() + go client.handleNginxLogStatus() + + // Start write and read pumps + go client.writePump() + client.readPump() +} + +// handleNotifications subscribes to notification events +func (c *Client) handleNotifications() { + evtChan := make(chan *model.Notification, 10) + wsManager := notification.GetWebSocketManager() + wsManager.Subscribe(evtChan) + + defer func() { + wsManager.Unsubscribe(evtChan) + }() + + for { + select { + case n := <-evtChan: + hub.BroadcastMessage("notification", n) + case <-c.ctx.Done(): + return + } + } +} + +// handleProcessingStatus subscribes to processing status events +func (c *Client) handleProcessingStatus() { + indexScanning := cache.SubscribeScanningStatus() + defer cache.UnsubscribeScanningStatus(indexScanning) + + autoCert := cert.SubscribeProcessingStatus() + defer cert.UnsubscribeProcessingStatus(autoCert) + + status := struct { + IndexScanning bool `json:"index_scanning"` + AutoCertProcessing bool `json:"auto_cert_processing"` + }{ + IndexScanning: false, + AutoCertProcessing: false, + } + + for { + select { + case indexStatus, ok := <-indexScanning: + if !ok { + return + } + status.IndexScanning = indexStatus + // Send processing status event + hub.BroadcastMessage("processing_status", status) + // Also send nginx log status event for backward compatibility + hub.BroadcastMessage("nginx_log_status", gin.H{ + "scanning": indexStatus, + }) + + case certStatus, ok := <-autoCert: + if !ok { + return + } + status.AutoCertProcessing = certStatus + hub.BroadcastMessage("processing_status", status) + + case <-c.ctx.Done(): + return + } + } +} + +// handleNginxLogStatus subscribes to nginx log scanning status events +// Note: This uses the same cache.SubscribeScanningStatus as handleProcessingStatus +// but sends different event types for different purposes +func (c *Client) handleNginxLogStatus() { + // We don't need a separate subscription here since handleProcessingStatus + // already handles the index scanning status. This function is kept for + // potential future nginx-specific log status that might be different + // from the general index scanning status. + + // For now, this is handled by handleProcessingStatus + <-c.ctx.Done() +} + +// writePump pumps messages from the hub to the websocket connection +func (c *Client) writePump() { + ticker := time.NewTicker(30 * time.Second) + defer func() { + ticker.Stop() + c.conn.Close() + }() + + for { + select { + case message, ok := <-c.send: + c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) + if !ok { + c.conn.WriteMessage(websocket.CloseMessage, []byte{}) + return + } + + if err := c.conn.WriteJSON(message); err != nil { + logger.Error("Failed to write message:", err) + if helper.IsUnexpectedWebsocketError(err) { + return + } + } + + case <-ticker.C: + c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) + if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil { + logger.Error("Failed to write ping:", err) + return + } + + case <-c.ctx.Done(): + return + + case <-kernel.Context.Done(): + return + } + } +} + +// readPump pumps messages from the websocket connection to the hub +func (c *Client) readPump() { + defer func() { + hub := GetHub() + hub.unregister <- c + c.conn.Close() + c.cancel() + }() + + c.conn.SetReadLimit(512) + c.conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + c.conn.SetPongHandler(func(string) error { + c.conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + return nil + }) + + for { + var msg json.RawMessage + err := c.conn.ReadJSON(&msg) + if err != nil { + if helper.IsUnexpectedWebsocketError(err) { + logger.Error("Unexpected WebSocket error:", err) + } + break + } + // Handle incoming messages if needed + // For now, this is a one-way communication (server to client) + } +} diff --git a/api/external_notify/external_notify.go b/api/external_notify/external_notify.go new file mode 100644 index 000000000..b5d97bbbb --- /dev/null +++ b/api/external_notify/external_notify.go @@ -0,0 +1,13 @@ +package external_notify + +import ( + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" +) + +func InitRouter(r *gin.RouterGroup) { + c := cosy.Api[model.ExternalNotify]("/external_notifies") + + c.InitRouter(r) +} diff --git a/api/nginx/control.go b/api/nginx/control.go index f6b492a7e..975fa4dea 100644 --- a/api/nginx/control.go +++ b/api/nginx/control.go @@ -1,28 +1,27 @@ package nginx import ( + "net/http" + "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/gin-gonic/gin" - "net/http" - "os" ) +// Reload reloads the nginx func Reload(c *gin.Context) { - output := nginx.Reload() - c.JSON(http.StatusOK, gin.H{ - "message": output, - "level": nginx.GetLogLevel(output), - }) + nginx.Control(nginx.Reload).Resp(c) } -func Test(c *gin.Context) { - output := nginx.TestConf() +// TestConfig tests the nginx config +func TestConfig(c *gin.Context) { + lastResult := nginx.Control(nginx.TestConfig) c.JSON(http.StatusOK, gin.H{ - "message": output, - "level": nginx.GetLogLevel(output), + "message": lastResult.GetOutput(), + "level": lastResult.GetLevel(), }) } +// Restart restarts the nginx func Restart(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "message": "ok", @@ -30,18 +29,15 @@ func Restart(c *gin.Context) { go nginx.Restart() } +// Status returns the status of the nginx func Status(c *gin.Context) { - pidPath := nginx.GetPIDPath() - lastOutput := nginx.GetLastOutput() + lastResult := nginx.GetLastResult() - running := true - if fileInfo, err := os.Stat(pidPath); err != nil || fileInfo.Size() == 0 { // fileInfo.Size() == 0 no process id - running = false - } + running := nginx.IsRunning() c.JSON(http.StatusOK, gin.H{ "running": running, - "message": lastOutput, - "level": nginx.GetLogLevel(lastOutput), + "message": lastResult.GetOutput(), + "level": lastResult.GetLevel(), }) } diff --git a/api/nginx/modules.go b/api/nginx/modules.go new file mode 100644 index 000000000..ab344df42 --- /dev/null +++ b/api/nginx/modules.go @@ -0,0 +1,17 @@ +package nginx + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/gin-gonic/gin" +) + +func GetModules(c *gin.Context) { + modules := nginx.GetModules() + modulesList := make([]*nginx.Module, 0, modules.Len()) + for _, module := range modules.AllFromFront() { + modulesList = append(modulesList, module) + } + c.JSON(http.StatusOK, modulesList) +} diff --git a/api/nginx/performance.go b/api/nginx/performance.go new file mode 100644 index 000000000..ecac4628e --- /dev/null +++ b/api/nginx/performance.go @@ -0,0 +1,36 @@ +package nginx + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/internal/performance" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" +) + +// GetPerformanceSettings retrieves current Nginx performance settings +func GetPerformanceSettings(c *gin.Context) { + // Get Nginx worker configuration info + perfInfo, err := performance.GetNginxWorkerConfigInfo() + if err != nil { + cosy.ErrHandler(c, err) + return + } + c.JSON(http.StatusOK, perfInfo) +} + +// UpdatePerformanceSettings updates Nginx performance settings +func UpdatePerformanceSettings(c *gin.Context) { + var perfOpt performance.PerfOpt + if !cosy.BindAndValid(c, &perfOpt) { + return + } + + err := performance.UpdatePerfOpt(&perfOpt) + if err != nil { + cosy.ErrHandler(c, err) + return + } + + GetPerformanceSettings(c) +} diff --git a/api/nginx/router.go b/api/nginx/router.go index d7c2e798d..436f4d16e 100644 --- a/api/nginx/router.go +++ b/api/nginx/router.go @@ -11,8 +11,23 @@ func InitRouter(r *gin.RouterGroup) { r.POST("ngx/format_code", FormatNginxConfig) r.POST("nginx/reload", Reload) r.POST("nginx/restart", Restart) - r.POST("nginx/test", Test) + r.POST("nginx/test", TestConfig) r.GET("nginx/status", Status) + // Get detailed Nginx status information, including connection count, process information, etc. (Issue #850) + r.GET("nginx/detail_status", GetDetailStatus) + // Use SSE to push detailed Nginx status information + // Use WebSocket to push detailed Nginx status information + r.GET("nginx/detail_status/ws", StreamDetailStatusWS) + // Get stub_status module status + r.GET("nginx/stub_status", CheckStubStatus) + // Enable or disable stub_status module + r.POST("nginx/stub_status", ToggleStubStatus) r.POST("nginx_log", nginx_log.GetNginxLogPage) r.GET("nginx/directives", GetDirectives) + + // Performance optimization endpoints + r.GET("nginx/performance", GetPerformanceSettings) + r.POST("nginx/performance", UpdatePerformanceSettings) + + r.GET("nginx/modules", GetModules) } diff --git a/api/nginx/status.go b/api/nginx/status.go new file mode 100644 index 000000000..8feeee7ad --- /dev/null +++ b/api/nginx/status.go @@ -0,0 +1,87 @@ +// Implementation of GetDetailedStatus API +// This feature is designed to address Issue #850, providing Nginx load monitoring functionality similar to BT Panel +// Returns detailed Nginx status information, including request statistics, connections, worker processes, and other data +package nginx + +import ( + "net/http" + "strings" + + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/internal/performance" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" +) + +// NginxPerformanceInfo stores Nginx performance-related information +type NginxPerformanceInfo struct { + // Basic status information + performance.StubStatusData + + // Process-related information + performance.NginxProcessInfo + + // Configuration information + performance.NginxConfigInfo +} + +// GetDetailStatus retrieves detailed Nginx status information +func GetDetailStatus(c *gin.Context) { + response := performance.GetPerformanceData() + c.JSON(http.StatusOK, response) +} + +// CheckStubStatus gets Nginx stub_status module status +func CheckStubStatus(c *gin.Context) { + stubStatus := performance.GetStubStatus() + + c.JSON(http.StatusOK, stubStatus) +} + +// ToggleStubStatus enables or disables stub_status module +func ToggleStubStatus(c *gin.Context) { + var json struct { + Enable bool `json:"enable"` + } + + if !cosy.BindAndValid(c, &json) { + return + } + + stubStatus := performance.GetStubStatus() + + // If current status matches desired status, no action needed + if stubStatus.Enabled == json.Enable { + c.JSON(http.StatusOK, stubStatus) + return + } + + var err error + if json.Enable { + err = performance.EnableStubStatus() + } else { + err = performance.DisableStubStatus() + } + + if err != nil { + cosy.ErrHandler(c, err) + return + } + + // Reload Nginx configuration + reloadOutput, err := nginx.Reload() + if err != nil { + cosy.ErrHandler(c, err) + return + } + if len(reloadOutput) > 0 && (strings.Contains(strings.ToLower(reloadOutput), "error") || + strings.Contains(strings.ToLower(reloadOutput), "failed")) { + cosy.ErrHandler(c, cosy.WrapErrorWithParams(nginx.ErrReloadFailed, reloadOutput)) + return + } + + // Check status after operation + newStubStatus := performance.GetStubStatus() + + c.JSON(http.StatusOK, newStubStatus) +} diff --git a/api/nginx/websocket.go b/api/nginx/websocket.go new file mode 100644 index 000000000..daafa2e9a --- /dev/null +++ b/api/nginx/websocket.go @@ -0,0 +1,227 @@ +package nginx + +import ( + "context" + "net/http" + "sync" + "time" + + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/kernel" + "github.com/0xJacky/Nginx-UI/internal/performance" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "github.com/uozi-tech/cosy/logger" +) + +// NginxPerformanceClient represents a WebSocket client for Nginx performance monitoring +type NginxPerformanceClient struct { + conn *websocket.Conn + send chan interface{} + ctx context.Context + cancel context.CancelFunc + mutex sync.RWMutex +} + +// NginxPerformanceHub manages WebSocket connections for Nginx performance monitoring +type NginxPerformanceHub struct { + clients map[*NginxPerformanceClient]bool + register chan *NginxPerformanceClient + unregister chan *NginxPerformanceClient + mutex sync.RWMutex + ticker *time.Ticker +} + +var ( + performanceHub *NginxPerformanceHub + performanceHubOnce sync.Once +) + +// GetNginxPerformanceHub returns the singleton hub instance +func GetNginxPerformanceHub() *NginxPerformanceHub { + performanceHubOnce.Do(func() { + performanceHub = &NginxPerformanceHub{ + clients: make(map[*NginxPerformanceClient]bool), + register: make(chan *NginxPerformanceClient), + unregister: make(chan *NginxPerformanceClient), + ticker: time.NewTicker(5 * time.Second), + } + go performanceHub.run() + }) + return performanceHub +} + +// run handles the main hub loop +func (h *NginxPerformanceHub) run() { + defer h.ticker.Stop() + + for { + select { + case client := <-h.register: + h.mutex.Lock() + h.clients[client] = true + h.mutex.Unlock() + logger.Debug("Nginx performance client connected, total clients:", len(h.clients)) + + // Send initial data to the new client + go h.sendPerformanceDataToClient(client) + + case client := <-h.unregister: + h.mutex.Lock() + if _, ok := h.clients[client]; ok { + delete(h.clients, client) + close(client.send) + } + h.mutex.Unlock() + logger.Debug("Nginx performance client disconnected, total clients:", len(h.clients)) + + case <-h.ticker.C: + // Send performance data to all connected clients + h.broadcastPerformanceData() + + case <-kernel.Context.Done(): + // Shutdown all clients + h.mutex.Lock() + for client := range h.clients { + close(client.send) + delete(h.clients, client) + } + h.mutex.Unlock() + return + } + } +} + +// sendPerformanceDataToClient sends performance data to a specific client +func (h *NginxPerformanceHub) sendPerformanceDataToClient(client *NginxPerformanceClient) { + response := performance.GetPerformanceData() + + select { + case client.send <- response: + default: + // Channel is full, remove client + h.unregister <- client + } +} + +// broadcastPerformanceData sends performance data to all connected clients +func (h *NginxPerformanceHub) broadcastPerformanceData() { + response := performance.GetPerformanceData() + + h.mutex.RLock() + for client := range h.clients { + select { + case client.send <- response: + default: + // Channel is full, remove client + close(client.send) + delete(h.clients, client) + } + } + h.mutex.RUnlock() +} + +// WebSocket upgrader configuration +var nginxPerformanceUpgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + ReadBufferSize: 1024, + WriteBufferSize: 1024, +} + +// StreamDetailStatusWS handles WebSocket connection for Nginx performance monitoring +func StreamDetailStatusWS(c *gin.Context) { + ws, err := nginxPerformanceUpgrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + logger.Error("Failed to upgrade connection:", err) + return + } + defer ws.Close() + + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + client := &NginxPerformanceClient{ + conn: ws, + send: make(chan interface{}, 256), + ctx: ctx, + cancel: cancel, + } + + hub := GetNginxPerformanceHub() + hub.register <- client + + // Start write and read pumps + go client.writePump() + client.readPump() +} + +// writePump pumps messages from the hub to the websocket connection +func (c *NginxPerformanceClient) writePump() { + ticker := time.NewTicker(30 * time.Second) + defer func() { + ticker.Stop() + c.conn.Close() + }() + + for { + select { + case message, ok := <-c.send: + c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) + if !ok { + c.conn.WriteMessage(websocket.CloseMessage, []byte{}) + return + } + + if err := c.conn.WriteJSON(message); err != nil { + logger.Error("Failed to write message:", err) + if helper.IsUnexpectedWebsocketError(err) { + return + } + } + + case <-ticker.C: + c.conn.SetWriteDeadline(time.Now().Add(10 * time.Second)) + if err := c.conn.WriteMessage(websocket.PingMessage, nil); err != nil { + logger.Error("Failed to write ping:", err) + return + } + + case <-c.ctx.Done(): + return + + case <-kernel.Context.Done(): + return + } + } +} + +// readPump pumps messages from the websocket connection to the hub +func (c *NginxPerformanceClient) readPump() { + defer func() { + hub := GetNginxPerformanceHub() + hub.unregister <- c + c.conn.Close() + c.cancel() + }() + + c.conn.SetReadLimit(512) + c.conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + c.conn.SetPongHandler(func(string) error { + c.conn.SetReadDeadline(time.Now().Add(60 * time.Second)) + return nil + }) + + for { + _, _, err := c.conn.ReadMessage() + if err != nil { + if helper.IsUnexpectedWebsocketError(err) { + logger.Error("Unexpected WebSocket error:", err) + } + break + } + // Handle incoming messages if needed + // For now, this is a one-way communication (server to client) + } +} diff --git a/api/nginx_log/nginx_log.go b/api/nginx_log/nginx_log.go index 192a12af7..6ba90dfcc 100644 --- a/api/nginx_log/nginx_log.go +++ b/api/nginx_log/nginx_log.go @@ -1,40 +1,39 @@ package nginx_log import ( - "encoding/json" - "github.com/0xJacky/Nginx-UI/internal/helper" - "github.com/0xJacky/Nginx-UI/internal/nginx" + "io" + "net/http" + "os" + "strings" + "github.com/0xJacky/Nginx-UI/internal/nginx_log" + "github.com/0xJacky/Nginx-UI/internal/translation" "github.com/gin-gonic/gin" - "github.com/gorilla/websocket" - "github.com/hpcloud/tail" "github.com/pkg/errors" "github.com/spf13/cast" "github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy/logger" - "io" - "net/http" - "os" - "strings" ) const ( + // PageSize defines the size of log chunks returned by the API PageSize = 128 * 1024 ) +// controlStruct represents the request parameters for getting log content type controlStruct struct { - Type string `json:"type"` - ConfName string `json:"conf_name"` - ServerIdx int `json:"server_idx"` - DirectiveIdx int `json:"directive_idx"` + Type string `json:"type"` // Type of log: "access" or "error" + LogPath string `json:"log_path"` // Path to the log file } +// nginxLogPageResp represents the response format for log content type nginxLogPageResp struct { - Content string `json:"content"` - Page int64 `json:"page"` - Error string `json:"error,omitempty"` + Content string `json:"content"` // Log content + Page int64 `json:"page"` // Current page number + Error *translation.Container `json:"error,omitempty"` // Error message if any } +// GetNginxLogPage handles retrieving a page of log content from a log file func GetNginxLogPage(c *gin.Context) { page := cast.ToInt64(c.Query("page")) if page < 0 { @@ -49,7 +48,7 @@ func GetNginxLogPage(c *gin.Context) { logPath, err := getLogPath(&control) if err != nil { c.JSON(http.StatusInternalServerError, nginxLogPageResp{ - Error: err.Error(), + Error: translation.C(err.Error()), }) logger.Error(err) return @@ -58,7 +57,7 @@ func GetNginxLogPage(c *gin.Context) { logFileStat, err := os.Stat(logPath) if err != nil { c.JSON(http.StatusInternalServerError, nginxLogPageResp{ - Error: err.Error(), + Error: translation.C(err.Error()), }) logger.Error(err) return @@ -66,9 +65,14 @@ func GetNginxLogPage(c *gin.Context) { if !logFileStat.Mode().IsRegular() { c.JSON(http.StatusInternalServerError, nginxLogPageResp{ - Error: "log file is not regular file", + Error: translation.C("Log file %{log_path} is not a regular file. "+ + "If you are using nginx-ui in docker container, please refer to "+ + "https://nginxui.com/zh_CN/guide/config-nginx-log.html for more information.", + map[string]any{ + "log_path": logPath, + }), }) - logger.Errorf("log file is not regular file: %s", logPath) + logger.Errorf("log file is not a regular file: %s", logPath) return } @@ -84,11 +88,12 @@ func GetNginxLogPage(c *gin.Context) { f, err := os.Open(logPath) if err != nil { c.JSON(http.StatusInternalServerError, nginxLogPageResp{ - Error: err.Error(), + Error: translation.C(err.Error()), }) logger.Error(err) return } + defer f.Close() totalPage := logFileStat.Size() / PageSize @@ -105,11 +110,11 @@ func GetNginxLogPage(c *gin.Context) { buf = make([]byte, PageSize) offset = (page - 1) * PageSize - // seek + // seek to the correct position in the file _, err = f.Seek(offset, io.SeekStart) if err != nil && err != io.EOF { c.JSON(http.StatusInternalServerError, nginxLogPageResp{ - Error: err.Error(), + Error: translation.C(err.Error()), }) logger.Error(err) return @@ -118,7 +123,7 @@ func GetNginxLogPage(c *gin.Context) { n, err := f.Read(buf) if err != nil && !errors.Is(err, io.EOF) { c.JSON(http.StatusInternalServerError, nginxLogPageResp{ - Error: err.Error(), + Error: translation.C(err.Error()), }) logger.Error(err) return @@ -130,200 +135,36 @@ func GetNginxLogPage(c *gin.Context) { }) } -func getLogPath(control *controlStruct) (logPath string, err error) { - switch control.Type { - case "site": - var config *nginx.NgxConfig - path := nginx.GetConfPath("sites-available", control.ConfName) - config, err = nginx.ParseNgxConfig(path) - if err != nil { - err = errors.Wrap(err, "error parsing ngx config") - return - } - - if control.ServerIdx >= len(config.Servers) { - err = nginx_log.ErrServerIdxOutOfRange - return - } - - if control.DirectiveIdx >= len(config.Servers[control.ServerIdx].Directives) { - err = nginx_log.ErrDirectiveIdxOutOfRange - return - } - - directive := config.Servers[control.ServerIdx].Directives[control.DirectiveIdx] - switch directive.Directive { - case "access_log", "error_log": - // ok - default: - err = nginx_log.ErrLogDirective - return - } - - if directive.Params == "" { - err = nginx_log.ErrDirectiveParamsIsEmpty - return - } - - // fix: access_log /var/log/test.log main; - p := strings.Split(directive.Params, " ") - if len(p) > 0 { - logPath = p[0] - } - - case "error": - path := nginx.GetErrorLogPath() - - if path == "" { - err = nginx_log.ErrErrorLogPathIsEmpty - return - } - - logPath = path - default: - path := nginx.GetAccessLogPath() - - if path == "" { - err = nginx_log.ErrAccessLogPathIsEmpty - return - } - - logPath = path - } - - // check if logPath is under one of the paths in LogDirWhiteList - if !nginx_log.IsLogPathUnderWhiteList(logPath) { - return "", nginx_log.ErrLogPathIsNotUnderTheLogDirWhiteList - } - return -} - -func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan chan error) { - defer func() { - if err := recover(); err != nil { - logger.Error(err) - return - } - }() - - control := <-controlChan +// GetLogList returns a list of Nginx log files +func GetLogList(c *gin.Context) { + filters := []func(*nginx_log.NginxLogCache) bool{} - for { - logPath, err := getLogPath(&control) - - if err != nil { - errChan <- err - return - } - - seek := tail.SeekInfo{ - Offset: 0, - Whence: io.SeekEnd, - } - - stat, err := os.Stat(logPath) - if os.IsNotExist(err) { - errChan <- errors.New("[error] log path not exists " + logPath) - return - } - - if !stat.Mode().IsRegular() { - errChan <- errors.New("[error] " + logPath + " is not a regular file. " + - "If you are using nginx-ui in docker container, please refer to " + - "https://nginxui.com/zh_CN/guide/config-nginx-log.html for more information.") - return - } - - // Create a tail - t, err := tail.TailFile(logPath, tail.Config{Follow: true, - ReOpen: true, Location: &seek}) - - if err != nil { - errChan <- errors.Wrap(err, "error tailing log") - return - } - - for { - var next = false - select { - case line := <-t.Lines: - // Print the text of each received line - if line == nil { - continue - } - - err = ws.WriteMessage(websocket.TextMessage, []byte(line.Text)) - if err != nil { - if helper.IsUnexpectedWebsocketError(err) { - errChan <- errors.Wrap(err, "error tailNginxLog write message") - } - return - } - case control = <-controlChan: - next = true - break - } - if next { - break - } - } + if logType := c.Query("type"); logType != "" { + filters = append(filters, func(entry *nginx_log.NginxLogCache) bool { + return entry.Type == logType + }) } -} - -func handleLogControl(ws *websocket.Conn, controlChan chan controlStruct, errChan chan error) { - defer func() { - if err := recover(); err != nil { - logger.Error(err) - return - } - }() - - for { - msgType, payload, err := ws.ReadMessage() - if err != nil && websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure) { - errChan <- errors.Wrap(err, "error handleLogControl read message") - return - } - if msgType != websocket.TextMessage { - errChan <- errors.New("error handleLogControl message type") - return - } - - var msg controlStruct - err = json.Unmarshal(payload, &msg) - if err != nil { - errChan <- errors.Wrap(err, "error ReadWsAndWritePty json.Unmarshal") - return - } - controlChan <- msg + if name := c.Query("name"); name != "" { + filters = append(filters, func(entry *nginx_log.NginxLogCache) bool { + return strings.Contains(entry.Name, name) + }) } -} -func Log(c *gin.Context) { - var upGrader = websocket.Upgrader{ - CheckOrigin: func(r *http.Request) bool { - return true - }, - } - // upgrade http to websocket - ws, err := upGrader.Upgrade(c.Writer, c.Request, nil) - if err != nil { - logger.Error(err) - return + if path := c.Query("path"); path != "" { + filters = append(filters, func(entry *nginx_log.NginxLogCache) bool { + return strings.Contains(entry.Path, path) + }) } - defer ws.Close() + data := nginx_log.GetAllLogs(filters...) - errChan := make(chan error, 1) - controlChan := make(chan controlStruct, 1) + orderBy := c.DefaultQuery("sort_by", "name") + sort := c.DefaultQuery("order", "desc") - go tailNginxLog(ws, controlChan, errChan) - go handleLogControl(ws, controlChan, errChan) + data = nginx_log.Sort(orderBy, sort, data) - if err = <-errChan; err != nil { - logger.Error(err) - _ = ws.WriteMessage(websocket.TextMessage, []byte(err.Error())) - return - } + c.JSON(http.StatusOK, gin.H{ + "data": data, + }) } diff --git a/api/nginx_log/router.go b/api/nginx_log/router.go index 59540a63b..93fe23d42 100644 --- a/api/nginx_log/router.go +++ b/api/nginx_log/router.go @@ -2,6 +2,8 @@ package nginx_log import "github.com/gin-gonic/gin" +// InitRouter registers all the nginx log related routes func InitRouter(r *gin.RouterGroup) { r.GET("nginx_log", Log) + r.GET("nginx_logs", GetLogList) } diff --git a/api/nginx_log/websocket.go b/api/nginx_log/websocket.go new file mode 100644 index 000000000..a49896d4a --- /dev/null +++ b/api/nginx_log/websocket.go @@ -0,0 +1,196 @@ +package nginx_log + +import ( + "encoding/json" + "io" + "net/http" + "os" + "runtime" + + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/internal/nginx_log" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "github.com/nxadm/tail" + "github.com/pkg/errors" + "github.com/uozi-tech/cosy/logger" +) + +// getLogPath resolves the log file path based on the provided control parameters +// It checks if the path is under the whitelist directories +func getLogPath(control *controlStruct) (logPath string, err error) { + // If direct log path is provided, use it + if control.LogPath != "" { + logPath = control.LogPath + // Check if logPath is under one of the paths in LogDirWhiteList + if !nginx_log.IsLogPathUnderWhiteList(logPath) { + return "", nginx_log.ErrLogPathIsNotUnderTheLogDirWhiteList + } + return + } + + // Otherwise, use default log path based on type + switch control.Type { + case "error": + path := nginx.GetErrorLogPath() + + if path == "" { + err = nginx_log.ErrErrorLogPathIsEmpty + return + } + + logPath = path + case "access": + fallthrough + default: + path := nginx.GetAccessLogPath() + + if path == "" { + err = nginx_log.ErrAccessLogPathIsEmpty + return + } + + logPath = path + } + + // check if logPath is under one of the paths in LogDirWhiteList + if !nginx_log.IsLogPathUnderWhiteList(logPath) { + return "", nginx_log.ErrLogPathIsNotUnderTheLogDirWhiteList + } + return +} + +// tailNginxLog tails the specified log file and sends each line to the websocket +func tailNginxLog(ws *websocket.Conn, controlChan chan controlStruct, errChan chan error) { + defer func() { + if err := recover(); err != nil { + buf := make([]byte, 1024) + runtime.Stack(buf, false) + logger.Errorf("%s\n%s", err, buf) + return + } + }() + + control := <-controlChan + + for { + logPath, err := getLogPath(&control) + + if err != nil { + errChan <- err + return + } + + seek := tail.SeekInfo{ + Offset: 0, + Whence: io.SeekEnd, + } + + stat, err := os.Stat(logPath) + if os.IsNotExist(err) { + errChan <- errors.New("[error] Log path does not exist: " + logPath) + return + } + + if !stat.Mode().IsRegular() { + errChan <- errors.Errorf("[error] %s is not a regular file. If you are using nginx-ui in docker container, please refer to https://nginxui.com/zh_CN/guide/config-nginx-log.html for more information.", logPath) + return + } + + // Create a tail + t, err := tail.TailFile(logPath, tail.Config{Follow: true, + ReOpen: true, Location: &seek}) + if err != nil { + errChan <- errors.Wrap(err, "error tailing log") + return + } + + for { + var next = false + select { + case line := <-t.Lines: + // Print the text of each received line + if line == nil { + continue + } + + err = ws.WriteMessage(websocket.TextMessage, []byte(line.Text)) + if err != nil { + if helper.IsUnexpectedWebsocketError(err) { + errChan <- errors.Wrap(err, "error tailNginxLog write message") + } + return + } + case control = <-controlChan: + next = true + break + } + if next { + break + } + } + } +} + +// handleLogControl processes websocket control messages +func handleLogControl(ws *websocket.Conn, controlChan chan controlStruct, errChan chan error) { + defer func() { + if err := recover(); err != nil { + buf := make([]byte, 1024) + runtime.Stack(buf, false) + logger.Errorf("%s\n%s", err, buf) + return + } + }() + + for { + msgType, payload, err := ws.ReadMessage() + if err != nil && websocket.IsUnexpectedCloseError(err, websocket.CloseNormalClosure) { + errChan <- errors.Wrap(err, "error handleLogControl read message") + return + } + + if msgType != websocket.TextMessage { + errChan <- errors.New("error handleLogControl message type") + return + } + + var msg controlStruct + err = json.Unmarshal(payload, &msg) + if err != nil { + errChan <- errors.Wrap(err, "error ReadWsAndWritePty json.Unmarshal") + return + } + controlChan <- msg + } +} + +// Log handles websocket connection for real-time log viewing +func Log(c *gin.Context) { + var upGrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + } + // upgrade http to websocket + ws, err := upGrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + logger.Error(err) + return + } + + defer ws.Close() + + errChan := make(chan error, 1) + controlChan := make(chan controlStruct, 1) + + go tailNginxLog(ws, controlChan, errChan) + go handleLogControl(ws, controlChan, errChan) + + if err = <-errChan; err != nil { + logger.Error(err) + _ = ws.WriteMessage(websocket.TextMessage, []byte(err.Error())) + return + } +} diff --git a/api/notification/live.go b/api/notification/live.go deleted file mode 100644 index 41a32b56c..000000000 --- a/api/notification/live.go +++ /dev/null @@ -1,43 +0,0 @@ -package notification - -import ( - "github.com/0xJacky/Nginx-UI/api" - "github.com/0xJacky/Nginx-UI/internal/notification" - "github.com/0xJacky/Nginx-UI/model" - "github.com/gin-gonic/gin" - "io" - "time" -) - -func Live(c *gin.Context) { - api.SetSSEHeaders(c) - - evtChan := make(chan *model.Notification) - - notification.SetClient(c, evtChan) - - notify := c.Writer.CloseNotify() - - c.Stream(func(w io.Writer) bool { - c.SSEvent("heartbeat", "") - return false - }) - - for { - select { - case n := <-evtChan: - c.Stream(func(w io.Writer) bool { - c.SSEvent("message", n) - return false - }) - case <-time.After(30 * time.Second): - c.Stream(func(w io.Writer) bool { - c.SSEvent("heartbeat", "") - return false - }) - case <-notify: - notification.RemoveClient(c) - return - } - } -} diff --git a/api/notification/notification.go b/api/notification/notification.go index c40d911d0..2ea2942ed 100644 --- a/api/notification/notification.go +++ b/api/notification/notification.go @@ -26,7 +26,9 @@ func Get(c *gin.Context) { } func GetList(c *gin.Context) { - cosy.Core[model.Notification](c).PagingList() + cosy.Core[model.Notification](c). + SetEqual("type"). + PagingList() } func Destroy(c *gin.Context) { diff --git a/api/notification/router.go b/api/notification/router.go index fc5caa295..87c3d166c 100644 --- a/api/notification/router.go +++ b/api/notification/router.go @@ -7,6 +7,4 @@ func InitRouter(r *gin.RouterGroup) { r.GET("notifications/:id", Get) r.DELETE("notifications/:id", Destroy) r.DELETE("notifications", DestroyAll) - - r.GET("notifications/live", Live) } diff --git a/api/openai/code_completion.go b/api/openai/code_completion.go new file mode 100644 index 000000000..4615529f8 --- /dev/null +++ b/api/openai/code_completion.go @@ -0,0 +1,82 @@ +package openai + +import ( + "net/http" + "sync" + "time" + + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/llm" + "github.com/0xJacky/Nginx-UI/settings" + "github.com/gin-gonic/gin" + "github.com/gorilla/websocket" + "github.com/uozi-tech/cosy" + "github.com/uozi-tech/cosy/logger" +) + +var mutex sync.Mutex + +// CodeCompletion handles code completion requests +func CodeCompletion(c *gin.Context) { + if !settings.OpenAISettings.EnableCodeCompletion { + cosy.ErrHandler(c, llm.ErrCodeCompletionNotEnabled) + return + } + + var upgrader = websocket.Upgrader{ + CheckOrigin: func(r *http.Request) bool { + return true + }, + } + ws, err := upgrader.Upgrade(c.Writer, c.Request, nil) + if err != nil { + cosy.ErrHandler(c, err) + return + } + defer ws.Close() + + for { + var codeCompletionRequest llm.CodeCompletionRequest + err := ws.ReadJSON(&codeCompletionRequest) + if err != nil { + if helper.IsUnexpectedWebsocketError(err) { + logger.Errorf("Error reading JSON: %v", err) + } + return + } + + codeCompletionRequest.UserID = api.CurrentUser(c).ID + + go func() { + start := time.Now() + completedCode, err := codeCompletionRequest.Send() + if err != nil { + logger.Errorf("Error sending code completion request: %v", err) + return + } + elapsed := time.Since(start) + + mutex.Lock() + defer mutex.Unlock() + + err = ws.WriteJSON(gin.H{ + "code": completedCode, + "request_id": codeCompletionRequest.RequestID, + "completion_ms": elapsed.Milliseconds(), + }) + if err != nil { + if helper.IsUnexpectedWebsocketError(err) { + logger.Errorf("Error writing JSON: %v", err) + } + return + } + }() + } +} + +func GetCodeCompletionEnabledStatus(c *gin.Context) { + c.JSON(http.StatusOK, gin.H{ + "enabled": settings.OpenAISettings.EnableCodeCompletion, + }) +} diff --git a/api/openai/openai.go b/api/openai/openai.go index db306bd78..2736e9bc6 100644 --- a/api/openai/openai.go +++ b/api/openai/openai.go @@ -4,15 +4,17 @@ import ( "context" "errors" "fmt" - "github.com/0xJacky/Nginx-UI/internal/chatbot" + "io" + "strings" + "time" + + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/llm" "github.com/0xJacky/Nginx-UI/settings" "github.com/gin-gonic/gin" "github.com/sashabaranov/go-openai" "github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy/logger" - "io" - "strings" - "time" ) const ChatGPTInitPrompt = `You are a assistant who can help users write and optimise the configurations of Nginx, @@ -41,16 +43,13 @@ func MakeChatCompletionRequest(c *gin.Context) { messages = append(messages, json.Messages...) if json.Filepath != "" { - messages = chatbot.ChatCompletionWithContext(json.Filepath, messages) + messages = llm.ChatCompletionWithContext(json.Filepath, messages) } // SSE server - c.Writer.Header().Set("Content-Type", "text/event-stream; charset=utf-8") - c.Writer.Header().Set("Cache-Control", "no-cache") - c.Writer.Header().Set("Connection", "keep-alive") - c.Writer.Header().Set("Access-Control-Allow-Origin", "*") + api.SetSSEHeaders(c) - openaiClient, err := chatbot.GetClient() + openaiClient, err := llm.GetClient() if err != nil { c.Stream(func(w io.Writer) bool { c.SSEvent("message", gin.H{ diff --git a/api/openai/record.go b/api/openai/record.go new file mode 100644 index 000000000..f624397e7 --- /dev/null +++ b/api/openai/record.go @@ -0,0 +1,31 @@ +package openai + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/query" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" +) + +func GetChatGPTRecord(c *gin.Context) { + absPath := c.Query("path") + + if !helper.IsUnderDirectory(absPath, nginx.GetConfPath()) { + c.JSON(http.StatusForbidden, gin.H{ + "message": "path is not under the nginx conf path", + }) + return + } + + g := query.ChatGPTLog + chatgpt, err := g.Where(g.Name.Eq(absPath)).FirstOrCreate() + if err != nil { + cosy.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, chatgpt) +} diff --git a/api/openai/router.go b/api/openai/router.go index d9ce13f06..b96d42919 100644 --- a/api/openai/router.go +++ b/api/openai/router.go @@ -2,8 +2,13 @@ package openai import "github.com/gin-gonic/gin" + func InitRouter(r *gin.RouterGroup) { // ChatGPT r.POST("chatgpt", MakeChatCompletionRequest) + r.GET("chatgpt/history", GetChatGPTRecord) r.POST("chatgpt_record", StoreChatGPTRecord) + // Code Completion + r.GET("code_completion", CodeCompletion) + r.GET("code_completion/enabled", GetCodeCompletionEnabledStatus) } diff --git a/api/pages/maintenance.go b/api/pages/maintenance.go new file mode 100644 index 000000000..0e97bcdeb --- /dev/null +++ b/api/pages/maintenance.go @@ -0,0 +1,78 @@ +package pages + +import ( + "embed" + "html/template" + "net/http" + "strings" + + "github.com/0xJacky/Nginx-UI/settings" + "github.com/gin-gonic/gin" +) + +//go:embed *.tmpl +var tmplFS embed.FS + +// MaintenancePageData maintenance page data structure +type MaintenancePageData struct { + Title string `json:"title"` + Message string `json:"message"` + Description string `json:"description"` + ICPNumber string `json:"icp_number"` + PublicSecurityNumber string `json:"public_security_number"` +} + +const ( + Title = "System Maintenance" + Message = "We are currently performing system maintenance to improve your experience." + Description = "Please check back later. Thank you for your understanding and patience." +) + +// MaintenancePage returns a maintenance page +func MaintenancePage(c *gin.Context) { + // Prepare template data + data := MaintenancePageData{ + Title: Title, + Message: Message, + Description: Description, + ICPNumber: settings.NodeSettings.ICPNumber, + PublicSecurityNumber: settings.NodeSettings.PublicSecurityNumber, + } + + // Check User-Agent + userAgent := c.GetHeader("User-Agent") + isBrowser := len(userAgent) > 0 && (contains(userAgent, "Mozilla") || + contains(userAgent, "Chrome") || + contains(userAgent, "Safari") || + contains(userAgent, "Edge") || + contains(userAgent, "Firefox") || + contains(userAgent, "Opera")) + + if !isBrowser { + c.JSON(http.StatusServiceUnavailable, data) + return + } + + // Parse template + tmpl, err := template.ParseFS(tmplFS, "maintenance.tmpl") + if err != nil { + c.String(http.StatusInternalServerError, "503 Service Unavailable") + return + } + + // Set content type + c.Header("Content-Type", "text/html; charset=utf-8") + c.Status(http.StatusServiceUnavailable) + + // Render template + err = tmpl.Execute(c.Writer, data) + if err != nil { + c.String(http.StatusInternalServerError, "503 Service Unavailable") + return + } +} + +// Helper function to check if a string contains a substring +func contains(s, substr string) bool { + return strings.Contains(s, substr) +} diff --git a/api/pages/maintenance.tmpl b/api/pages/maintenance.tmpl new file mode 100644 index 000000000..19483d152 --- /dev/null +++ b/api/pages/maintenance.tmpl @@ -0,0 +1,89 @@ + + + + + + Codestin Search App + + + +
+
+
🛠️
+

{{.Title}}

+

{{.Message}}

+

{{.Description}}

+ +
+
+ {{if .ICPNumber}} +

{{.ICPNumber}}

+ {{end}} + {{if .PublicSecurityNumber}} +

公安备案{{.PublicSecurityNumber}}

+ {{end}} +
+
+ + diff --git a/api/pages/router.go b/api/pages/router.go new file mode 100644 index 000000000..80696060f --- /dev/null +++ b/api/pages/router.go @@ -0,0 +1,11 @@ +package pages + +import ( + "github.com/gin-gonic/gin" +) + +// InitRouter initializes the pages routes +func InitRouter(r *gin.Engine) { + // Register maintenance page route + r.GET("/pages/maintenance", MaintenancePage) +} diff --git a/api/settings/settings.go b/api/settings/settings.go index c431bda89..03e82a948 100644 --- a/api/settings/settings.go +++ b/api/settings/settings.go @@ -3,14 +3,14 @@ package settings import ( "fmt" "net/http" - "time" + "code.pfad.fr/risefront" + "github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/cron" "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/system" "github.com/0xJacky/Nginx-UI/settings" "github.com/gin-gonic/gin" - "github.com/jpillora/overseer" "github.com/uozi-tech/cosy" cSettings "github.com/uozi-tech/cosy/settings" ) @@ -26,6 +26,7 @@ func GetSettings(c *gin.Context) { settings.NginxSettings.ErrorLogPath = nginx.GetErrorLogPath() settings.NginxSettings.ConfigDir = nginx.GetConfPath() settings.NginxSettings.PIDPath = nginx.GetPIDPath() + settings.NginxSettings.StubStatusPort = settings.NginxSettings.GetStubStatusPort() if settings.NginxSettings.ReloadCmd == "" { settings.NginxSettings.ReloadCmd = "nginx -s reload" @@ -72,6 +73,7 @@ func SaveSettings(c *gin.Context) { Node settings.Node `json:"node"` Openai settings.OpenAI `json:"openai"` Logrotate settings.Logrotate `json:"logrotate"` + Nginx settings.Nginx `json:"nginx"` } if !cosy.BindAndValid(c, &json) { @@ -84,9 +86,16 @@ func SaveSettings(c *gin.Context) { } // Validate SSL certificates if HTTPS is enabled - needRestart := false + needReloadCert := false + needRestartProgram := false if json.Server.EnableHTTPS != cSettings.ServerSettings.EnableHTTPS { - needRestart = true + needReloadCert = true + needRestartProgram = true + } + + if json.Server.SSLCert != cSettings.ServerSettings.SSLCert || + json.Server.SSLKey != cSettings.ServerSettings.SSLKey { + needReloadCert = true } if json.Server.EnableHTTPS { @@ -105,6 +114,7 @@ func SaveSettings(c *gin.Context) { cSettings.ProtectedFill(settings.NodeSettings, &json.Node) cSettings.ProtectedFill(settings.OpenAISettings, &json.Openai) cSettings.ProtectedFill(settings.LogrotateSettings, &json.Logrotate) + cSettings.ProtectedFill(settings.NginxSettings, &json.Nginx) err := settings.Save() if err != nil { @@ -112,12 +122,17 @@ func SaveSettings(c *gin.Context) { return } - if needRestart { + GetSettings(c) + + if needReloadCert { go func() { - time.Sleep(2 * time.Second) - overseer.Restart() + cert.ReloadServerTLSCertificate() }() } - GetSettings(c) + if needRestartProgram { + go func() { + risefront.Restart() + }() + } } diff --git a/api/sites/advance.go b/api/sites/advance.go index daeeaed30..dcfb5d10c 100644 --- a/api/sites/advance.go +++ b/api/sites/advance.go @@ -3,6 +3,7 @@ package sites import ( "net/http" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" @@ -18,7 +19,7 @@ func DomainEditByAdvancedMode(c *gin.Context) { return } - name := c.Param("name") + name := helper.UnescapeURL(c.Param("name")) path := nginx.GetConfPath("sites-available", name) s := query.Site diff --git a/api/sites/category.go b/api/sites/category.go deleted file mode 100644 index f141d3c0c..000000000 --- a/api/sites/category.go +++ /dev/null @@ -1,48 +0,0 @@ -package sites - -import ( - "github.com/0xJacky/Nginx-UI/model" - "github.com/gin-gonic/gin" - "github.com/uozi-tech/cosy" - "gorm.io/gorm" -) - -func GetCategory(c *gin.Context) { - cosy.Core[model.SiteCategory](c).Get() -} - -func GetCategoryList(c *gin.Context) { - cosy.Core[model.SiteCategory](c).GormScope(func(tx *gorm.DB) *gorm.DB { - return tx.Order("order_id ASC") - }).PagingList() -} - -func AddCategory(c *gin.Context) { - cosy.Core[model.SiteCategory](c). - SetValidRules(gin.H{ - "name": "required", - "sync_node_ids": "omitempty", - }). - Create() -} - -func ModifyCategory(c *gin.Context) { - cosy.Core[model.SiteCategory](c). - SetValidRules(gin.H{ - "name": "required", - "sync_node_ids": "omitempty", - }). - Modify() -} - -func DeleteCategory(c *gin.Context) { - cosy.Core[model.SiteCategory](c).Destroy() -} - -func RecoverCategory(c *gin.Context) { - cosy.Core[model.SiteCategory](c).Recover() -} - -func UpdateCategoriesOrder(c *gin.Context) { - cosy.Core[model.SiteCategory](c).UpdateOrder() -} diff --git a/api/sites/list.go b/api/sites/list.go index 6775517a8..09a0bc2dc 100644 --- a/api/sites/list.go +++ b/api/sites/list.go @@ -8,6 +8,7 @@ import ( "github.com/0xJacky/Nginx-UI/internal/config" "github.com/0xJacky/Nginx-UI/internal/nginx" + "github.com/0xJacky/Nginx-UI/internal/site" "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" @@ -18,27 +19,27 @@ import ( func GetSiteList(c *gin.Context) { name := c.Query("name") - enabled := c.Query("enabled") + status := c.Query("status") orderBy := c.Query("sort_by") sort := c.DefaultQuery("order", "desc") - querySiteCategoryId := cast.ToUint64(c.Query("site_category_id")) + queryEnvGroupId := cast.ToUint64(c.Query("env_group_id")) configFiles, err := os.ReadDir(nginx.GetConfPath("sites-available")) if err != nil { - cosy.ErrHandler(c, err) + cosy.ErrHandler(c, cosy.WrapErrorWithParams(site.ErrReadDirFailed, err.Error())) return } enabledConfig, err := os.ReadDir(nginx.GetConfPath("sites-enabled")) if err != nil { - cosy.ErrHandler(c, err) + cosy.ErrHandler(c, cosy.WrapErrorWithParams(site.ErrReadDirFailed, err.Error())) return } s := query.Site - sTx := s.Preload(s.SiteCategory) - if querySiteCategoryId != 0 { - sTx.Where(s.SiteCategoryID.Eq(querySiteCategoryId)) + sTx := s.Preload(s.EnvGroup) + if queryEnvGroupId != 0 { + sTx.Where(s.EnvGroupID.Eq(queryEnvGroupId)) } sites, err := sTx.Find() if err != nil { @@ -49,9 +50,23 @@ func GetSiteList(c *gin.Context) { return filepath.Base(item.Path), item }) - enabledConfigMap := make(map[string]bool) - for i := range enabledConfig { - enabledConfigMap[enabledConfig[i].Name()] = true + configStatusMap := make(map[string]config.ConfigStatus) + for _, site := range configFiles { + configStatusMap[site.Name()] = config.StatusDisabled + } + + // Check for enabled sites and maintenance mode sites + for _, enabledSite := range enabledConfig { + name := enabledSite.Name() + + // Check if this is a maintenance mode configuration + if strings.HasSuffix(name, site.MaintenanceSuffix) { + // Extract the original site name by removing maintenance suffix + originalName := strings.TrimSuffix(name, site.MaintenanceSuffix) + configStatusMap[originalName] = config.StatusMaintenance + } else { + configStatusMap[nginx.GetConfNameBySymlinkName(name)] = config.StatusEnabled + } } var configs []config.Config @@ -67,37 +82,47 @@ func GetSiteList(c *gin.Context) { continue } // status filter - if enabled != "" { - if enabled == "true" && !enabledConfigMap[file.Name()] { - continue - } - if enabled == "false" && enabledConfigMap[file.Name()] { - continue - } + if status != "" && configStatusMap[file.Name()] != config.ConfigStatus(status) { + continue } + var ( - siteCategoryId uint64 - siteCategory *model.SiteCategory + envGroupId uint64 + envGroup *model.EnvGroup ) if site, ok := sitesMap[file.Name()]; ok { - siteCategoryId = site.SiteCategoryID - siteCategory = site.SiteCategory + envGroupId = site.EnvGroupID + envGroup = site.EnvGroup } - // site category filter - if querySiteCategoryId != 0 && siteCategoryId != querySiteCategoryId { + // env group filter + if queryEnvGroupId != 0 && envGroupId != queryEnvGroupId { continue } + indexedSite := site.GetIndexedSite(file.Name()) + + // Convert site.ProxyTarget to config.ProxyTarget + var proxyTargets []config.ProxyTarget + for _, target := range indexedSite.ProxyTargets { + proxyTargets = append(proxyTargets, config.ProxyTarget{ + Host: target.Host, + Port: target.Port, + Type: target.Type, + }) + } + configs = append(configs, config.Config{ - Name: file.Name(), - ModifiedAt: fileInfo.ModTime(), - Size: fileInfo.Size(), - IsDir: fileInfo.IsDir(), - Enabled: enabledConfigMap[file.Name()], - SiteCategoryID: siteCategoryId, - SiteCategory: siteCategory, + Name: file.Name(), + ModifiedAt: fileInfo.ModTime(), + Size: fileInfo.Size(), + IsDir: fileInfo.IsDir(), + Status: configStatusMap[file.Name()], + EnvGroupID: envGroupId, + EnvGroup: envGroup, + Urls: indexedSite.Urls, + ProxyTargets: proxyTargets, }) } diff --git a/api/sites/router.go b/api/sites/router.go index 1b247b0e1..5b7a208f7 100644 --- a/api/sites/router.go +++ b/api/sites/router.go @@ -22,14 +22,6 @@ func InitRouter(r *gin.RouterGroup) { r.DELETE("sites/:name", DeleteSite) // duplicate site r.POST("sites/:name/duplicate", DuplicateSite) -} - -func InitCategoryRouter(r *gin.RouterGroup) { - r.GET("site_categories", GetCategoryList) - r.GET("site_categories/:id", GetCategory) - r.POST("site_categories", AddCategory) - r.POST("site_categories/:id", ModifyCategory) - r.DELETE("site_categories/:id", DeleteCategory) - r.POST("site_categories/:id/recover", RecoverCategory) - r.POST("site_categories/order", UpdateCategoriesOrder) + // enable maintenance mode for site + r.POST("sites/:name/maintenance", EnableMaintenanceSite) } diff --git a/api/sites/site.go b/api/sites/site.go index e6997c2f2..4b96990df 100644 --- a/api/sites/site.go +++ b/api/sites/site.go @@ -5,19 +5,19 @@ import ( "os" "github.com/0xJacky/Nginx-UI/internal/cert" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/site" "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" - "github.com/sashabaranov/go-openai" "github.com/uozi-tech/cosy" "github.com/uozi-tech/cosy/logger" "gorm.io/gorm/clause" ) func GetSite(c *gin.Context) { - name := c.Param("name") + name := helper.UnescapeURL(c.Param("name")) path := nginx.GetConfPath("sites-available", name) file, err := os.Stat(path) @@ -28,22 +28,6 @@ func GetSite(c *gin.Context) { return } - enabled := true - if _, err := os.Stat(nginx.GetConfPath("sites-enabled", name)); os.IsNotExist(err) { - enabled = false - } - - g := query.ChatGPTLog - chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() - if err != nil { - cosy.ErrHandler(c, err) - return - } - - if chatgpt.Content == nil { - chatgpt.Content = make([]openai.ChatCompletionMessage, 0) - } - s := query.Site siteModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate() if err != nil { @@ -63,15 +47,14 @@ func GetSite(c *gin.Context) { return } - c.JSON(http.StatusOK, Site{ - ModifiedAt: file.ModTime(), - Site: siteModel, - Enabled: enabled, - Name: name, - Config: string(origContent), - AutoCert: certModel.AutoCert == model.AutoCertEnabled, - ChatGPTMessages: chatgpt.Content, - Filepath: path, + c.JSON(http.StatusOK, site.Site{ + ModifiedAt: file.ModTime(), + Site: siteModel, + Name: name, + Config: string(origContent), + AutoCert: certModel.AutoCert == model.AutoCertEnabled, + Filepath: path, + Status: site.GetSiteStatus(name), }) return } @@ -96,35 +79,35 @@ func GetSite(c *gin.Context) { } } - c.JSON(http.StatusOK, Site{ - Site: siteModel, - ModifiedAt: file.ModTime(), - Enabled: enabled, - Name: name, - Config: nginxConfig.FmtCode(), - Tokenized: nginxConfig, - AutoCert: certModel.AutoCert == model.AutoCertEnabled, - CertInfo: certInfoMap, - ChatGPTMessages: chatgpt.Content, - Filepath: path, + c.JSON(http.StatusOK, site.Site{ + Site: siteModel, + ModifiedAt: file.ModTime(), + Name: name, + Config: nginxConfig.FmtCode(), + Tokenized: nginxConfig, + AutoCert: certModel.AutoCert == model.AutoCertEnabled, + CertInfo: certInfoMap, + Filepath: path, + Status: site.GetSiteStatus(name), }) } func SaveSite(c *gin.Context) { - name := c.Param("name") + name := helper.UnescapeURL(c.Param("name")) var json struct { - Content string `json:"content" binding:"required"` - SiteCategoryID uint64 `json:"site_category_id"` - SyncNodeIDs []uint64 `json:"sync_node_ids"` - Overwrite bool `json:"overwrite"` + Content string `json:"content" binding:"required"` + EnvGroupID uint64 `json:"env_group_id"` + SyncNodeIDs []uint64 `json:"sync_node_ids"` + Overwrite bool `json:"overwrite"` + PostAction string `json:"post_action"` } if !cosy.BindAndValid(c, &json) { return } - err := site.Save(name, json.Content, json.Overwrite, json.SiteCategoryID, json.SyncNodeIDs) + err := site.Save(name, json.Content, json.Overwrite, json.EnvGroupID, json.SyncNodeIDs, json.PostAction) if err != nil { cosy.ErrHandler(c, err) return @@ -134,7 +117,7 @@ func SaveSite(c *gin.Context) { } func RenameSite(c *gin.Context) { - oldName := c.Param("name") + oldName := helper.UnescapeURL(c.Param("name")) var json struct { NewName string `json:"new_name"` } @@ -154,7 +137,21 @@ func RenameSite(c *gin.Context) { } func EnableSite(c *gin.Context) { - err := site.Enable(c.Param("name")) + name := helper.UnescapeURL(c.Param("name")) + + // Check if the site is in maintenance mode, if yes, disable maintenance mode first + maintenanceConfigPath := nginx.GetConfPath("sites-enabled", name+site.MaintenanceSuffix) + if _, err := os.Stat(maintenanceConfigPath); err == nil { + // Site is in maintenance mode, disable it first + err := site.DisableMaintenance(name) + if err != nil { + cosy.ErrHandler(c, err) + return + } + } + + // Then enable the site normally + err := site.Enable(name) if err != nil { cosy.ErrHandler(c, err) return @@ -166,7 +163,21 @@ func EnableSite(c *gin.Context) { } func DisableSite(c *gin.Context) { - err := site.Disable(c.Param("name")) + name := helper.UnescapeURL(c.Param("name")) + + // Check if the site is in maintenance mode, if yes, disable maintenance mode first + maintenanceConfigPath := nginx.GetConfPath("sites-enabled", name+site.MaintenanceSuffix) + if _, err := os.Stat(maintenanceConfigPath); err == nil { + // Site is in maintenance mode, disable it first + err := site.DisableMaintenance(name) + if err != nil { + cosy.ErrHandler(c, err) + return + } + } + + // Then disable the site normally + err := site.Disable(name) if err != nil { cosy.ErrHandler(c, err) return @@ -178,7 +189,7 @@ func DisableSite(c *gin.Context) { } func DeleteSite(c *gin.Context) { - err := site.Delete(c.Param("name")) + err := site.Delete(helper.UnescapeURL(c.Param("name"))) if err != nil { cosy.ErrHandler(c, err) return @@ -191,7 +202,7 @@ func DeleteSite(c *gin.Context) { func BatchUpdateSites(c *gin.Context) { cosy.Core[model.Site](c).SetValidRules(gin.H{ - "site_category_id": "required", + "env_group_id": "required", }).SetItemKey("path"). BeforeExecuteHook(func(ctx *cosy.Ctx[model.Site]) { effectedPath := make([]string, len(ctx.BatchEffectedIDs)) @@ -214,3 +225,29 @@ func BatchUpdateSites(c *gin.Context) { ctx.BatchEffectedIDs = effectedPath }).BatchModify() } + +func EnableMaintenanceSite(c *gin.Context) { + name := helper.UnescapeURL(c.Param("name")) + + // If site is already enabled, disable the normal site first + enabledConfigPath := nginx.GetConfPath("sites-enabled", name) + if _, err := os.Stat(enabledConfigPath); err == nil { + // Site is already enabled, disable normal site first + err := site.Disable(name) + if err != nil { + cosy.ErrHandler(c, err) + return + } + } + + // Then enable maintenance mode + err := site.EnableMaintenance(name) + if err != nil { + cosy.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} diff --git a/api/sites/type.go b/api/sites/type.go deleted file mode 100644 index 4b8e3f118..000000000 --- a/api/sites/type.go +++ /dev/null @@ -1,22 +0,0 @@ -package sites - -import ( - "github.com/0xJacky/Nginx-UI/internal/cert" - "github.com/0xJacky/Nginx-UI/internal/nginx" - "github.com/0xJacky/Nginx-UI/model" - "github.com/sashabaranov/go-openai" - "time" -) - -type Site struct { - *model.Site - Name string `json:"name"` - ModifiedAt time.Time `json:"modified_at"` - Enabled bool `json:"enabled"` - Config string `json:"config"` - AutoCert bool `json:"auto_cert"` - ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"` - Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"` - CertInfo map[int][]*cert.Info `json:"cert_info,omitempty"` - Filepath string `json:"filepath"` -} diff --git a/api/streams/advance.go b/api/streams/advance.go index 9496f0b57..1693366ab 100644 --- a/api/streams/advance.go +++ b/api/streams/advance.go @@ -3,6 +3,7 @@ package streams import ( "net/http" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" @@ -18,7 +19,7 @@ func AdvancedEdit(c *gin.Context) { return } - name := c.Param("name") + name := helper.UnescapeURL(c.Param("name")) path := nginx.GetConfPath("streams-available", name) s := query.Stream diff --git a/api/streams/duplicate.go b/api/streams/duplicate.go index 2679e795c..86f07983e 100644 --- a/api/streams/duplicate.go +++ b/api/streams/duplicate.go @@ -11,7 +11,7 @@ import ( func Duplicate(c *gin.Context) { // Source name - name := c.Param("name") + name := helper.UnescapeURL(c.Param("name")) // Destination name var json struct { diff --git a/api/streams/router.go b/api/streams/router.go index 67fa43345..5a2987730 100644 --- a/api/streams/router.go +++ b/api/streams/router.go @@ -5,6 +5,7 @@ import "github.com/gin-gonic/gin" func InitRouter(r *gin.RouterGroup) { r.GET("streams", GetStreams) r.GET("streams/:name", GetStream) + r.PUT("streams", BatchUpdateStreams) r.POST("streams/:name", SaveStream) r.POST("streams/:name/rename", RenameStream) r.POST("streams/:name/enable", EnableStream) diff --git a/api/streams/streams.go b/api/streams/streams.go index 731993746..b34935000 100644 --- a/api/streams/streams.go +++ b/api/streams/streams.go @@ -3,71 +3,160 @@ package streams import ( "net/http" "os" + "path/filepath" "strings" "time" "github.com/0xJacky/Nginx-UI/internal/config" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/stream" + "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" "github.com/gin-gonic/gin" - "github.com/sashabaranov/go-openai" + "github.com/samber/lo" + "github.com/spf13/cast" "github.com/uozi-tech/cosy" + "gorm.io/gorm/clause" ) type Stream struct { - ModifiedAt time.Time `json:"modified_at"` - Advanced bool `json:"advanced"` - Enabled bool `json:"enabled"` - Name string `json:"name"` - Config string `json:"config"` - ChatGPTMessages []openai.ChatCompletionMessage `json:"chatgpt_messages,omitempty"` - Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"` - Filepath string `json:"filepath"` - SyncNodeIDs []uint64 `json:"sync_node_ids" gorm:"serializer:json"` + ModifiedAt time.Time `json:"modified_at"` + Advanced bool `json:"advanced"` + Status config.ConfigStatus `json:"status"` + Name string `json:"name"` + Config string `json:"config"` + Tokenized *nginx.NgxConfig `json:"tokenized,omitempty"` + Filepath string `json:"filepath"` + EnvGroupID uint64 `json:"env_group_id"` + EnvGroup *model.EnvGroup `json:"env_group,omitempty"` + SyncNodeIDs []uint64 `json:"sync_node_ids" gorm:"serializer:json"` + ProxyTargets []config.ProxyTarget `json:"proxy_targets,omitempty"` } func GetStreams(c *gin.Context) { name := c.Query("name") + status := c.Query("status") orderBy := c.Query("order_by") sort := c.DefaultQuery("sort", "desc") + queryEnvGroupId := cast.ToUint64(c.Query("env_group_id")) configFiles, err := os.ReadDir(nginx.GetConfPath("streams-available")) if err != nil { - cosy.ErrHandler(c, err) + cosy.ErrHandler(c, cosy.WrapErrorWithParams(stream.ErrReadDirFailed, err.Error())) return } enabledConfig, err := os.ReadDir(nginx.GetConfPath("streams-enabled")) if err != nil { - cosy.ErrHandler(c, err) + cosy.ErrHandler(c, cosy.WrapErrorWithParams(stream.ErrReadDirFailed, err.Error())) return } - enabledConfigMap := make(map[string]bool) + enabledConfigMap := make(map[string]config.ConfigStatus) + for _, file := range configFiles { + enabledConfigMap[file.Name()] = config.StatusDisabled + } for i := range enabledConfig { - enabledConfigMap[enabledConfig[i].Name()] = true + enabledConfigMap[nginx.GetConfNameBySymlinkName(enabledConfig[i].Name())] = config.StatusEnabled } var configs []config.Config + // Get all streams map for Node Group lookup + s := query.Stream + var streams []*model.Stream + if queryEnvGroupId != 0 { + streams, err = s.Where(s.EnvGroupID.Eq(queryEnvGroupId)).Find() + } else { + streams, err = s.Find() + } + if err != nil { + cosy.ErrHandler(c, err) + return + } + + // Retrieve Node Groups data + eg := query.EnvGroup + envGroups, err := eg.Find() + if err != nil { + cosy.ErrHandler(c, err) + return + } + // Create a map of Node Groups for quick lookup by ID + envGroupMap := lo.SliceToMap(envGroups, func(item *model.EnvGroup) (uint64, *model.EnvGroup) { + return item.ID, item + }) + + // Convert streams slice to map for efficient lookups + streamsMap := lo.SliceToMap(streams, func(item *model.Stream) (string, *model.Stream) { + // Associate each stream with its corresponding Node Group + if item.EnvGroupID > 0 { + item.EnvGroup = envGroupMap[item.EnvGroupID] + } + return filepath.Base(item.Path), item + }) + for i := range configFiles { file := configFiles[i] fileInfo, _ := file.Info() - if !file.IsDir() { - if name != "" && !strings.Contains(file.Name(), name) { - continue - } - configs = append(configs, config.Config{ - Name: file.Name(), - ModifiedAt: fileInfo.ModTime(), - Size: fileInfo.Size(), - IsDir: fileInfo.IsDir(), - Enabled: enabledConfigMap[file.Name()], + if file.IsDir() { + continue + } + + // Apply name filter if specified + if name != "" && !strings.Contains(file.Name(), name) { + continue + } + + // Apply enabled status filter if specified + if status != "" && enabledConfigMap[file.Name()] != config.ConfigStatus(status) { + continue + } + + var ( + envGroupId uint64 + envGroup *model.EnvGroup + ) + + // Lookup stream in the streams map to get Node Group info + if stream, ok := streamsMap[file.Name()]; ok { + envGroupId = stream.EnvGroupID + envGroup = stream.EnvGroup + } + + // Apply Node Group filter if specified + if queryEnvGroupId != 0 && envGroupId != queryEnvGroupId { + continue + } + + // Get indexed stream for proxy targets + indexedStream := stream.GetIndexedStream(file.Name()) + + // Convert stream.ProxyTarget to config.ProxyTarget + var proxyTargets []config.ProxyTarget + for _, target := range indexedStream.ProxyTargets { + proxyTargets = append(proxyTargets, config.ProxyTarget{ + Host: target.Host, + Port: target.Port, + Type: target.Type, }) } + + // Add the config to the result list after passing all filters + configs = append(configs, config.Config{ + Name: file.Name(), + ModifiedAt: fileInfo.ModTime(), + Size: fileInfo.Size(), + IsDir: fileInfo.IsDir(), + Status: enabledConfigMap[file.Name()], + EnvGroupID: envGroupId, + EnvGroup: envGroup, + ProxyTargets: proxyTargets, + }) } + // Sort the configs based on the provided sort parameters configs = config.Sort(orderBy, sort, configs) c.JSON(http.StatusOK, gin.H{ @@ -76,8 +165,9 @@ func GetStreams(c *gin.Context) { } func GetStream(c *gin.Context) { - name := c.Param("name") + name := helper.UnescapeURL(c.Param("name")) + // Get the absolute path to the stream configuration file path := nginx.GetConfPath("streams-available", name) file, err := os.Stat(path) if os.IsNotExist(err) { @@ -87,24 +177,13 @@ func GetStream(c *gin.Context) { return } - enabled := true - + // Check if the stream is enabled + status := config.StatusEnabled if _, err := os.Stat(nginx.GetConfPath("streams-enabled", name)); os.IsNotExist(err) { - enabled = false - } - - g := query.ChatGPTLog - chatgpt, err := g.Where(g.Name.Eq(path)).FirstOrCreate() - - if err != nil { - cosy.ErrHandler(c, err) - return - } - - if chatgpt.Content == nil { - chatgpt.Content = make([]openai.ChatCompletionMessage, 0) + status = config.StatusDisabled } + // Retrieve or create stream model from database s := query.Stream streamModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate() if err != nil { @@ -112,6 +191,7 @@ func GetStream(c *gin.Context) { return } + // For advanced mode, return the raw content if streamModel.Advanced { origContent, err := os.ReadFile(path) if err != nil { @@ -120,62 +200,96 @@ func GetStream(c *gin.Context) { } c.JSON(http.StatusOK, Stream{ - ModifiedAt: file.ModTime(), - Advanced: streamModel.Advanced, - Enabled: enabled, - Name: name, - Config: string(origContent), - ChatGPTMessages: chatgpt.Content, - Filepath: path, - SyncNodeIDs: streamModel.SyncNodeIDs, + ModifiedAt: file.ModTime(), + Advanced: streamModel.Advanced, + Status: status, + Name: name, + Config: string(origContent), + Filepath: path, + EnvGroupID: streamModel.EnvGroupID, + EnvGroup: streamModel.EnvGroup, + SyncNodeIDs: streamModel.SyncNodeIDs, }) return } + // For normal mode, parse and tokenize the configuration nginxConfig, err := nginx.ParseNgxConfig(path) - if err != nil { cosy.ErrHandler(c, err) return } c.JSON(http.StatusOK, Stream{ - ModifiedAt: file.ModTime(), - Advanced: streamModel.Advanced, - Enabled: enabled, - Name: name, - Config: nginxConfig.FmtCode(), - Tokenized: nginxConfig, - ChatGPTMessages: chatgpt.Content, - Filepath: path, - SyncNodeIDs: streamModel.SyncNodeIDs, + ModifiedAt: file.ModTime(), + Advanced: streamModel.Advanced, + Status: status, + Name: name, + Config: nginxConfig.FmtCode(), + Tokenized: nginxConfig, + Filepath: path, + EnvGroupID: streamModel.EnvGroupID, + EnvGroup: streamModel.EnvGroup, + SyncNodeIDs: streamModel.SyncNodeIDs, }) } func SaveStream(c *gin.Context) { - name := c.Param("name") + name := helper.UnescapeURL(c.Param("name")) var json struct { Content string `json:"content" binding:"required"` + EnvGroupID uint64 `json:"env_group_id"` SyncNodeIDs []uint64 `json:"sync_node_ids"` Overwrite bool `json:"overwrite"` + PostAction string `json:"post_action"` } + // Validate input JSON if !cosy.BindAndValid(c, &json) { return } - err := stream.Save(name, json.Content, json.Overwrite, json.SyncNodeIDs) + // Get stream from database or create if not exists + path := nginx.GetConfPath("streams-available", name) + s := query.Stream + streamModel, err := s.Where(s.Path.Eq(path)).FirstOrCreate() + if err != nil { + cosy.ErrHandler(c, err) + return + } + + // Update Node Group ID if provided + if json.EnvGroupID > 0 { + streamModel.EnvGroupID = json.EnvGroupID + } + + // Update synchronization node IDs if provided + if json.SyncNodeIDs != nil { + streamModel.SyncNodeIDs = json.SyncNodeIDs + } + + // Save the updated stream model to database + _, err = s.Where(s.ID.Eq(streamModel.ID)).Updates(streamModel) + if err != nil { + cosy.ErrHandler(c, err) + return + } + + // Save the stream configuration file + err = stream.Save(name, json.Content, json.Overwrite, json.SyncNodeIDs, json.PostAction) if err != nil { cosy.ErrHandler(c, err) return } + // Return the updated stream GetStream(c) } func EnableStream(c *gin.Context) { - err := stream.Enable(c.Param("name")) + // Enable the stream by creating a symlink in streams-enabled directory + err := stream.Enable(helper.UnescapeURL(c.Param("name"))) if err != nil { cosy.ErrHandler(c, err) return @@ -187,7 +301,8 @@ func EnableStream(c *gin.Context) { } func DisableStream(c *gin.Context) { - err := stream.Disable(c.Param("name")) + // Disable the stream by removing the symlink from streams-enabled directory + err := stream.Disable(helper.UnescapeURL(c.Param("name"))) if err != nil { cosy.ErrHandler(c, err) return @@ -199,7 +314,8 @@ func DisableStream(c *gin.Context) { } func DeleteStream(c *gin.Context) { - err := stream.Delete(c.Param("name")) + // Delete the stream configuration file and its symbolic link if exists + err := stream.Delete(helper.UnescapeURL(c.Param("name"))) if err != nil { cosy.ErrHandler(c, err) return @@ -211,14 +327,16 @@ func DeleteStream(c *gin.Context) { } func RenameStream(c *gin.Context) { - oldName := c.Param("name") + oldName := helper.UnescapeURL(c.Param("name")) var json struct { NewName string `json:"new_name"` } + // Validate input JSON if !cosy.BindAndValid(c, &json) { return } + // Rename the stream configuration file err := stream.Rename(oldName, json.NewName) if err != nil { cosy.ErrHandler(c, err) @@ -229,3 +347,29 @@ func RenameStream(c *gin.Context) { "message": "ok", }) } + +func BatchUpdateStreams(c *gin.Context) { + cosy.Core[model.Stream](c).SetValidRules(gin.H{ + "env_group_id": "required", + }).SetItemKey("path"). + BeforeExecuteHook(func(ctx *cosy.Ctx[model.Stream]) { + effectedPath := make([]string, len(ctx.BatchEffectedIDs)) + var streams []*model.Stream + for i, name := range ctx.BatchEffectedIDs { + path := nginx.GetConfPath("streams-available", name) + effectedPath[i] = path + streams = append(streams, &model.Stream{ + Path: path, + }) + } + s := query.Stream + err := s.Clauses(clause.OnConflict{ + DoNothing: true, + }).Create(streams...) + if err != nil { + ctx.AbortWithError(err) + return + } + ctx.BatchEffectedIDs = effectedPath + }).BatchModify() +} diff --git a/api/system/install.go b/api/system/install.go index ab07b3f8f..ebcd9dd28 100644 --- a/api/system/install.go +++ b/api/system/install.go @@ -4,7 +4,6 @@ import ( "net/http" "time" - "github.com/0xJacky/Nginx-UI/internal/kernel" "github.com/0xJacky/Nginx-UI/internal/system" "github.com/0xJacky/Nginx-UI/model" "github.com/0xJacky/Nginx-UI/query" @@ -25,7 +24,7 @@ func init() { } func installLockStatus() bool { - return settings.NodeSettings.SkipInstallation || "" != cSettings.AppSettings.JwtSecret + return settings.NodeSettings.SkipInstallation || cSettings.AppSettings.JwtSecret != "" } // Check if installation time limit (10 minutes) is exceeded @@ -50,8 +49,7 @@ func InstallLockCheck(c *gin.Context) { type InstallJson struct { Email string `json:"email" binding:"required,email"` Username string `json:"username" binding:"required,max=255"` - Password string `json:"password" binding:"required,max=255"` - Database string `json:"database"` + Password string `json:"password" binding:"required,max=20"` } func InstallNginxUI(c *gin.Context) { @@ -78,9 +76,6 @@ func InstallNginxUI(c *gin.Context) { cSettings.AppSettings.JwtSecret = uuid.New().String() settings.NodeSettings.Secret = uuid.New().String() settings.CertSettings.Email = json.Email - if "" != json.Database { - settings.DatabaseSettings.Name = json.Database - } err := settings.Save() if err != nil { @@ -88,13 +83,14 @@ func InstallNginxUI(c *gin.Context) { return } - // Init model - kernel.InitDatabase() - - pwd, _ := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost) + pwd, err := bcrypt.GenerateFromPassword([]byte(json.Password), bcrypt.DefaultCost) + if err != nil { + cosy.ErrHandler(c, err) + return + } u := query.User - err = u.Create(&model.User{ + _, err = u.Where(u.ID.Eq(1)).Updates(&model.User{ Name: json.Username, Password: string(pwd), }) diff --git a/api/system/port_scan.go b/api/system/port_scan.go new file mode 100644 index 000000000..071b458a5 --- /dev/null +++ b/api/system/port_scan.go @@ -0,0 +1,175 @@ +package system + +import ( + "fmt" + "net" + "os/exec" + "strconv" + "strings" + "time" + + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy/logger" +) + +type PortScanRequest struct { + StartPort int `json:"start_port" binding:"required,min=1,max=65535"` + EndPort int `json:"end_port" binding:"required,min=1,max=65535"` + Page int `json:"page" binding:"required,min=1"` + PageSize int `json:"page_size" binding:"required,min=1,max=1000"` +} + +type PortInfo struct { + Port int `json:"port"` + Status string `json:"status"` + Process string `json:"process"` +} + +type PortScanResponse struct { + Data []PortInfo `json:"data"` + Total int `json:"total"` + Page int `json:"page"` + PageSize int `json:"page_size"` +} + +func PortScan(c *gin.Context) { + var req PortScanRequest + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(400, gin.H{"message": err.Error()}) + return + } + + if req.StartPort > req.EndPort { + c.JSON(400, gin.H{"message": "Start port must be less than or equal to end port"}) + return + } + + // Calculate pagination + totalPorts := req.EndPort - req.StartPort + 1 + startIndex := (req.Page - 1) * req.PageSize + endIndex := startIndex + req.PageSize + + if startIndex >= totalPorts { + c.JSON(200, PortScanResponse{ + Data: []PortInfo{}, + Total: totalPorts, + Page: req.Page, + PageSize: req.PageSize, + }) + return + } + + if endIndex > totalPorts { + endIndex = totalPorts + } + + // Calculate actual port range for this page + actualStartPort := req.StartPort + startIndex + actualEndPort := req.StartPort + endIndex - 1 + + var ports []PortInfo + + // Get listening ports info + listeningPorts := getListeningPorts() + + // Scan ports in the current page range + for port := actualStartPort; port <= actualEndPort; port++ { + portInfo := PortInfo{ + Port: port, + Status: "closed", + Process: "", + } + + // Check if port is listening + if processInfo, exists := listeningPorts[port]; exists { + portInfo.Status = "listening" + portInfo.Process = processInfo + } else { + // Quick check if port is open but not in listening list + if isPortOpen(port) { + portInfo.Status = "open" + } + } + + ports = append(ports, portInfo) + } + + c.JSON(200, PortScanResponse{ + Data: ports, + Total: totalPorts, + Page: req.Page, + PageSize: req.PageSize, + }) +} + +func isPortOpen(port int) bool { + timeout := time.Millisecond * 100 + conn, err := net.DialTimeout("tcp", fmt.Sprintf("localhost:%d", port), timeout) + if err != nil { + return false + } + defer conn.Close() + return true +} + +func getListeningPorts() map[int]string { + ports := make(map[int]string) + + // Try netstat first + if cmd := exec.Command("netstat", "-tlnp"); cmd.Err == nil { + if output, err := cmd.Output(); err == nil { + lines := strings.Split(string(output), "\n") + for _, line := range lines { + if strings.Contains(line, "LISTEN") { + fields := strings.Fields(line) + if len(fields) >= 4 { + address := fields[3] + process := "" + if len(fields) >= 7 { + process = fields[6] + } + + // Extract port from address (format: 0.0.0.0:port or :::port) + if colonIndex := strings.LastIndex(address, ":"); colonIndex != -1 { + portStr := address[colonIndex+1:] + if port, err := strconv.Atoi(portStr); err == nil { + ports[port] = process + } + } + } + } + } + return ports + } + } + + // Fallback to ss command + if cmd := exec.Command("ss", "-tlnp"); cmd.Err == nil { + if output, err := cmd.Output(); err == nil { + lines := strings.Split(string(output), "\n") + for _, line := range lines { + if strings.Contains(line, "LISTEN") { + fields := strings.Fields(line) + if len(fields) >= 4 { + address := fields[3] + process := "" + if len(fields) >= 6 { + process = fields[5] + } + + // Extract port from address + if colonIndex := strings.LastIndex(address, ":"); colonIndex != -1 { + portStr := address[colonIndex+1:] + if port, err := strconv.Atoi(portStr); err == nil { + ports[port] = process + } + } + } + } + } + } + } + + logger.Debug("Found listening ports: %v", ports) + return ports +} diff --git a/api/system/router.go b/api/system/router.go index a22f66443..a52a05cab 100644 --- a/api/system/router.go +++ b/api/system/router.go @@ -5,6 +5,14 @@ import ( "github.com/gin-gonic/gin" ) +func authIfInstalled(ctx *gin.Context) { + if installLockStatus() || isInstallTimeoutExceeded() { + middleware.AuthRequired()(ctx) + } else { + ctx.Next() + } +} + func InitPublicRouter(r *gin.RouterGroup) { r.GET("install", InstallLockCheck) r.POST("install", middleware.EncryptedParams(), InstallNginxUI) @@ -14,28 +22,22 @@ func InitPublicRouter(r *gin.RouterGroup) { func InitPrivateRouter(r *gin.RouterGroup) { r.GET("upgrade/release", GetRelease) r.GET("upgrade/current", GetCurrentVersion) - r.GET("self_check", SelfCheck) - r.POST("self_check/:name/fix", SelfCheckFix) - // Backup endpoint only - r.GET("system/backup", CreateBackup) + r.POST("system/port_scan", PortScan) +} + +func InitSelfCheckRouter(r *gin.RouterGroup) { + g := r.Group("self_check", authIfInstalled) + g.GET("", middleware.Proxy(), SelfCheck) + g.POST("/:name/fix", middleware.Proxy(), SelfCheckFix) + g.GET("websocket", middleware.ProxyWs(), CheckWebSocket) + g.GET("timeout", middleware.Proxy(), TimeoutCheck) } func InitBackupRestoreRouter(r *gin.RouterGroup) { - r.POST("system/backup/restore", - func(ctx *gin.Context) { - // If system is installed, verify user authentication - if installLockStatus() { - middleware.AuthRequired()(ctx) - } else { - ctx.Next() - } - }, - middleware.EncryptedForm(), - RestoreBackup) + // Backup and restore routes moved to api/backup package } func InitWebSocketRouter(r *gin.RouterGroup) { r.GET("upgrade/perform", PerformCoreUpgrade) - r.GET("self_check/websocket", CheckWebSocket) } diff --git a/api/system/self_check.go b/api/system/self_check.go index cb4e434ba..d80d2a118 100644 --- a/api/system/self_check.go +++ b/api/system/self_check.go @@ -1,9 +1,12 @@ package system import ( + "net/http" + "github.com/gorilla/websocket" "github.com/uozi-tech/cosy/logger" - "net/http" + + "time" "github.com/0xJacky/Nginx-UI/internal/self_check" "github.com/gin-gonic/gin" @@ -39,3 +42,10 @@ func CheckWebSocket(c *gin.Context) { return } } + +func TimeoutCheck(c *gin.Context) { + time.Sleep(time.Minute) + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} diff --git a/api/system/upgrade.go b/api/system/upgrade.go index 16257aa72..f438d2cfc 100644 --- a/api/system/upgrade.go +++ b/api/system/upgrade.go @@ -2,11 +2,10 @@ package system import ( "net/http" - "os" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/upgrader" "github.com/0xJacky/Nginx-UI/internal/version" - "github.com/0xJacky/Nginx-UI/settings" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/uozi-tech/cosy" @@ -14,19 +13,19 @@ import ( ) func GetRelease(c *gin.Context) { - data, err := upgrader.GetRelease(c.Query("channel")) + data, err := version.GetRelease(c.Query("channel")) if err != nil { cosy.ErrHandler(c, err) return } - runtimeInfo, err := upgrader.GetRuntimeInfo() + runtimeInfo, err := version.GetRuntimeInfo() if err != nil { cosy.ErrHandler(c, err) return } type resp struct { - upgrader.TRelease - upgrader.RuntimeInfo + version.TRelease + version.RuntimeInfo } c.JSON(http.StatusOK, resp{ data, runtimeInfo, @@ -63,10 +62,7 @@ func PerformCoreUpgrade(c *gin.Context) { } defer ws.Close() - var control struct { - DryRun bool `json:"dry_run"` - Channel string `json:"channel"` - } + var control upgrader.Control err = ws.ReadJSON(&control) @@ -74,80 +70,9 @@ func PerformCoreUpgrade(c *gin.Context) { logger.Error(err) return } - - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusInfo, - Message: "Initialing core upgrader", - }) - - u, err := upgrader.NewUpgrader(control.Channel) - - if err != nil { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: "Initial core upgrader error", - }) - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: err.Error(), - }) - logger.Error(err) - return - } - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusInfo, - Message: "Downloading latest release", - }) - progressChan := make(chan float64) - defer close(progressChan) - go func() { - for progress := range progressChan { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusProgress, - Progress: progress, - }) - } - }() - - tarName, err := u.DownloadLatestRelease(progressChan) - if err != nil { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: "Download latest release error", - }) - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: err.Error(), - }) - logger.Error(err) - return - } - - defer func() { - _ = os.Remove(tarName) - _ = os.Remove(tarName + ".digest") - }() - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusInfo, - Message: "Performing core upgrade", - }) - // dry run - if control.DryRun || settings.NodeSettings.Demo { - return - } - - // bye, will restart nginx-ui in performCoreUpgrade - err = u.PerformCoreUpgrade(tarName) - if err != nil { - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: "Perform core upgrade error", - }) - _ = ws.WriteJSON(CoreUpgradeResp{ - Status: UpgradeStatusError, - Message: err.Error(), - }) - logger.Error(err) - return + if helper.InNginxUIOfficialDocker() && helper.DockerSocketExists() { + upgrader.DockerUpgrade(ws, &control) + } else { + upgrader.BinaryUpgrade(ws, &control) } } diff --git a/api/upstream/upstream.go b/api/upstream/upstream.go index 0cead0007..e6d40b4a4 100644 --- a/api/upstream/upstream.go +++ b/api/upstream/upstream.go @@ -1,15 +1,23 @@ package upstream import ( + "context" + "net/http" + "sync" + "time" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/upstream" "github.com/gin-gonic/gin" "github.com/gorilla/websocket" "github.com/uozi-tech/cosy/logger" - "net/http" - "time" ) +type wsMessage struct { + data interface{} + done chan error +} + func AvailabilityTest(c *gin.Context) { var upGrader = websocket.Upgrader{ CheckOrigin: func(r *http.Request) bool { @@ -25,24 +33,151 @@ func AvailabilityTest(c *gin.Context) { defer ws.Close() - var body []string + var currentTargets []string + var targetsMutex sync.RWMutex - err = ws.ReadJSON(&body) + // Use context to manage goroutine lifecycle + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() - if err != nil { - logger.Error(err) - return + // Use channel to serialize WebSocket write operations, avoiding concurrent conflicts + writeChan := make(chan wsMessage, 10) + testChan := make(chan bool, 1) // Immediate test signal + + // Create debouncer for test execution + testDebouncer := helper.NewDebouncer(300 * time.Millisecond) + + // WebSocket writer goroutine - serialize all write operations + go func() { + defer logger.Debug("WebSocket writer goroutine stopped") + for { + select { + case <-ctx.Done(): + return + case msg := <-writeChan: + err := ws.WriteJSON(msg.data) + if msg.done != nil { + msg.done <- err + close(msg.done) + } + if err != nil { + logger.Error("Failed to send WebSocket message:", err) + if helper.IsUnexpectedWebsocketError(err) { + cancel() // Cancel all goroutines + } + } + } + } + }() + + // Safe WebSocket write function + writeJSON := func(data interface{}) error { + done := make(chan error, 1) + msg := wsMessage{data: data, done: done} + + select { + case writeChan <- msg: + return <-done + case <-ctx.Done(): + return ctx.Err() + case <-time.After(5 * time.Second): // Prevent write blocking + return context.DeadlineExceeded + } } - for { - err = ws.WriteJSON(upstream.AvailabilityTest(body)) - if err != nil { - if helper.IsUnexpectedWebsocketError(err) { - logger.Error(err) + // Function to perform availability test + performTest := func() { + targetsMutex.RLock() + targets := make([]string, len(currentTargets)) + copy(targets, currentTargets) + targetsMutex.RUnlock() + + logger.Debug("Performing availability test for targets:", targets) + + if len(targets) > 0 { + logger.Debug("Starting upstream.AvailabilityTest...") + result := upstream.AvailabilityTest(targets) + logger.Debug("Test completed, results:", result) + + logger.Debug("Sending results via WebSocket...") + if err := writeJSON(result); err != nil { + logger.Error("Failed to send WebSocket message:", err) + if helper.IsUnexpectedWebsocketError(err) { + cancel() // Cancel all goroutines + } + } else { + logger.Debug("Results sent successfully") + } + } else { + logger.Debug("No targets to test") + // Send empty result even if no targets + emptyResult := make(map[string]interface{}) + if err := writeJSON(emptyResult); err != nil { + logger.Error("Failed to send empty result:", err) + } else { + logger.Debug("Empty result sent successfully") + } + } + } + + // Goroutine to handle incoming messages (target updates) + go func() { + defer logger.Debug("WebSocket reader goroutine stopped") + for { + select { + case <-ctx.Done(): + return + default: + } + + var newTargets []string + // Set read timeout to avoid blocking + ws.SetReadDeadline(time.Now().Add(30 * time.Second)) + err := ws.ReadJSON(&newTargets) + ws.SetReadDeadline(time.Time{}) // Clear deadline + + if err != nil { + if helper.IsUnexpectedWebsocketError(err) { + logger.Error(err) + } + cancel() // Cancel all goroutines + return } - break + + logger.Debug("Received targets from frontend:", newTargets) + + targetsMutex.Lock() + currentTargets = newTargets + targetsMutex.Unlock() + + // Use debouncer to trigger test execution + testDebouncer.Trigger(func() { + select { + case testChan <- true: + default: + } + }) } + }() - time.Sleep(10 * time.Second) + // Main testing loop + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + + logger.Debug("WebSocket connection established, waiting for messages...") + + for { + select { + case <-ctx.Done(): + testDebouncer.Stop() + logger.Debug("WebSocket connection closed") + return + case <-testChan: + // Debounce triggered test or first test + go performTest() // Execute asynchronously to avoid blocking main loop + case <-ticker.C: + // Periodic test execution + go performTest() // Execute asynchronously to avoid blocking main loop + } } } diff --git a/api/user/auth.go b/api/user/auth.go index e846451f9..4aaf36ac7 100644 --- a/api/user/auth.go +++ b/api/user/auth.go @@ -1,7 +1,6 @@ package user import ( - "errors" "math/rand/v2" "net/http" "sync" @@ -32,10 +31,10 @@ const ( ) type LoginResponse struct { - Message string `json:"message"` - Error string `json:"error,omitempty"` - Code int `json:"code"` - Token string `json:"token,omitempty"` + Message string `json:"message"` + Error string `json:"error,omitempty"` + Code int `json:"code"` + *user.AccessTokenPayload SecureSessionID string `json:"secure_session_id,omitempty"` } @@ -67,17 +66,10 @@ func Login(c *gin.Context) { u, err := user.Login(json.Name, json.Password) if err != nil { + user.BanIP(clientIP) random := time.Duration(rand.Int() % 10) time.Sleep(random * time.Second) - switch { - case errors.Is(err, user.ErrPasswordIncorrect): - c.JSON(http.StatusForbidden, user.ErrPasswordIncorrect) - case errors.Is(err, user.ErrUserBanned): - c.JSON(http.StatusForbidden, user.ErrUserBanned) - default: - cosy.ErrHandler(c, err) - } - user.BanIP(clientIP) + cosy.ErrHandler(c, err) return } @@ -95,10 +87,7 @@ func Login(c *gin.Context) { } if err = user.VerifyOTP(u, json.OTP, json.RecoveryCode); err != nil { - c.JSON(http.StatusForbidden, LoginResponse{ - Message: "Invalid 2FA or recovery code", - Code: Error2FACode, - }) + cosy.ErrHandler(c, err) user.BanIP(clientIP) return } @@ -110,19 +99,17 @@ func Login(c *gin.Context) { _, _ = b.Where(b.IP.Eq(clientIP)).Delete() logger.Info("[User Login]", u.Name) - token, err := user.GenerateJWT(u) + accessToken, err := user.GenerateJWT(u) if err != nil { - c.JSON(http.StatusInternalServerError, LoginResponse{ - Message: err.Error(), - }) + cosy.ErrHandler(c, err) return } c.JSON(http.StatusOK, LoginResponse{ - Code: LoginSuccess, - Message: "ok", - Token: token, - SecureSessionID: secureSessionID, + Code: LoginSuccess, + Message: "ok", + AccessTokenPayload: accessToken, + SecureSessionID: secureSessionID, }) } diff --git a/api/user/casdoor.go b/api/user/casdoor.go index 3b80bed4e..46a3ae412 100644 --- a/api/user/casdoor.go +++ b/api/user/casdoor.go @@ -81,8 +81,8 @@ func CasdoorCallback(c *gin.Context) { } c.JSON(http.StatusOK, LoginResponse{ - Message: "ok", - Token: userToken, + Message: "ok", + AccessTokenPayload: userToken, }) } diff --git a/api/user/current_user.go b/api/user/current_user.go new file mode 100644 index 000000000..f966633ab --- /dev/null +++ b/api/user/current_user.go @@ -0,0 +1,102 @@ +package user + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/model" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" + "golang.org/x/crypto/bcrypt" +) + +func GetCurrentUser(c *gin.Context) { + user := api.CurrentUser(c) + c.JSON(http.StatusOK, user) +} + +func UpdateCurrentUser(c *gin.Context) { + cosy.Core[model.User](c). + SetValidRules(gin.H{ + "name": "omitempty", + "language": "omitempty", + }). + Custom(func(c *cosy.Ctx[model.User]) { + user := api.CurrentUser(c.Context) + user.Name = c.Model.Name + user.Language = c.Model.Language + + db := cosy.UseDB(c) + err := db.Where("id = ?", user.ID).Updates(user).Error + if err != nil { + cosy.ErrHandler(c.Context, err) + return + } + + c.JSON(http.StatusOK, user) + }) +} + +func UpdateCurrentUserPassword(c *gin.Context) { + var json struct { + OldPassword string `json:"old_password" binding:"required"` + NewPassword string `json:"new_password" binding:"required"` + } + + if !cosy.BindAndValid(c, &json) { + return + } + + user := api.CurrentUser(c) + if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(json.OldPassword)); err != nil { + cosy.ErrHandler(c, err) + return + } + + user.Password = json.NewPassword + + pwdBytes, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost) + if err != nil { + cosy.ErrHandler(c, err) + return + } + + db := cosy.UseDB(c) + err = db.Where("id = ?", user.ID).Updates(&model.User{ + Password: string(pwdBytes), + }).Error + if err != nil { + cosy.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "message": "ok", + }) +} + +func UpdateCurrentUserLanguage(c *gin.Context) { + var json struct { + Language string `json:"language" binding:"required"` + } + + if !cosy.BindAndValid(c, &json) { + return + } + + user := api.CurrentUser(c) + user.Language = json.Language + + db := cosy.UseDB(c) + err := db.Where("id = ?", user.ID).Updates(&model.User{ + Language: json.Language, + }).Error + if err != nil { + cosy.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "language": json.Language, + }) +} diff --git a/api/user/passkey.go b/api/user/passkey.go index e1991a858..7fd07ac40 100644 --- a/api/user/passkey.go +++ b/api/user/passkey.go @@ -157,8 +157,8 @@ func FinishPasskeyLogin(c *gin.Context) { c.JSON(http.StatusOK, LoginResponse{ Code: LoginSuccess, Message: "ok", - Token: token, - SecureSessionID: secureSessionID, + AccessTokenPayload: token, + SecureSessionID: secureSessionID, }) } diff --git a/api/user/router.go b/api/user/router.go index 38dce1a91..5f506f212 100644 --- a/api/user/router.go +++ b/api/user/router.go @@ -42,4 +42,9 @@ func InitUserRouter(r *gin.RouterGroup) { o.GET("/recovery_codes", ViewRecoveryCodes) o.GET("/recovery_codes_generate", GenerateRecoveryCodes) } + + r.GET("/user", GetCurrentUser) + r.POST("/user", middleware.RequireSecureSession(), UpdateCurrentUser) + r.POST("/user/password", middleware.RequireSecureSession(), UpdateCurrentUserPassword) + r.POST("/user/language", UpdateCurrentUserLanguage) } diff --git a/app.example.ini b/app.example.ini index 40e9b3dc2..4399c2ee2 100644 --- a/app.example.ini +++ b/app.example.ini @@ -69,6 +69,9 @@ BaseUrl = Token = Proxy = Model = gpt-4o +APIType = +EnableCodeCompletion = false +CodeCompletionModel = gpt-4o-mini [terminal] StartCmd = bash diff --git a/app/.env b/app/.env index 18122654e..d9f8542d5 100644 --- a/app/.env +++ b/app/.env @@ -1 +1 @@ -VITE_PROXY_TARGET=http://127.0.0.1:9000 +VITE_PROXY_TARGET=http://127.0.0.1:9001 diff --git a/app/.eslint-auto-import.mjs b/app/.eslint-auto-import.mjs index d09af3145..d8638c47e 100644 --- a/app/.eslint-auto-import.mjs +++ b/app/.eslint-auto-import.mjs @@ -17,6 +17,9 @@ export default { "MaybeRefOrGetter": true, "PropType": true, "Ref": true, + "Slot": true, + "Slots": true, + "T": true, "VNode": true, "WritableComputedRef": true, "acceptHMRUpdate": true, diff --git a/app/auto-imports.d.ts b/app/auto-imports.d.ts index 736276d8e..a4acfbe30 100644 --- a/app/auto-imports.d.ts +++ b/app/auto-imports.d.ts @@ -11,6 +11,7 @@ declare global { const $npgettext: typeof import('@/gettext')['$npgettext'] const $pgettext: typeof import('@/gettext')['$pgettext'] const EffectScope: typeof import('vue')['EffectScope'] + const T: typeof import('@/language')['T'] const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] const computed: typeof import('vue')['computed'] const createApp: typeof import('vue')['createApp'] @@ -87,7 +88,7 @@ declare global { // for type re-export declare global { // @ts-ignore - export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' + export type { Component, Slot, Slots, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue' import('vue') } @@ -101,6 +102,7 @@ declare module 'vue' { readonly $npgettext: UnwrapRef readonly $pgettext: UnwrapRef readonly EffectScope: UnwrapRef + readonly T: UnwrapRef readonly acceptHMRUpdate: UnwrapRef readonly computed: UnwrapRef readonly createApp: UnwrapRef diff --git a/app/components.d.ts b/app/components.d.ts index 0f8694f5e..cabbd1cf7 100644 --- a/app/components.d.ts +++ b/app/components.d.ts @@ -23,8 +23,6 @@ declare module 'vue' { ACollapsePanel: typeof import('ant-design-vue/es')['CollapsePanel'] AComment: typeof import('ant-design-vue/es')['Comment'] AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider'] - ADescriptions: typeof import('ant-design-vue/es')['Descriptions'] - ADescriptionsItem: typeof import('ant-design-vue/es')['DescriptionsItem'] ADivider: typeof import('ant-design-vue/es')['Divider'] ADrawer: typeof import('ant-design-vue/es')['Drawer'] ADropdown: typeof import('ant-design-vue/es')['Dropdown'] @@ -46,13 +44,10 @@ declare module 'vue' { AMenu: typeof import('ant-design-vue/es')['Menu'] AMenuItem: typeof import('ant-design-vue/es')['MenuItem'] AModal: typeof import('ant-design-vue/es')['Modal'] - APagination: typeof import('ant-design-vue/es')['Pagination'] APopconfirm: typeof import('ant-design-vue/es')['Popconfirm'] APopover: typeof import('ant-design-vue/es')['Popover'] AProgress: typeof import('ant-design-vue/es')['Progress'] AQrcode: typeof import('ant-design-vue/es')['QRCode'] - ARadioButton: typeof import('ant-design-vue/es')['RadioButton'] - ARadioGroup: typeof import('ant-design-vue/es')['RadioGroup'] AResult: typeof import('ant-design-vue/es')['Result'] ARow: typeof import('ant-design-vue/es')['Row'] ASelect: typeof import('ant-design-vue/es')['Select'] @@ -71,38 +66,51 @@ declare module 'vue' { ATextarea: typeof import('ant-design-vue/es')['Textarea'] ATooltip: typeof import('ant-design-vue/es')['Tooltip'] AUploadDragger: typeof import('ant-design-vue/es')['UploadDragger'] + AutoCertFormAutoCertForm: typeof import('./src/components/AutoCertForm/AutoCertForm.vue')['default'] + AutoCertFormDNSChallenge: typeof import('./src/components/AutoCertForm/DNSChallenge.vue')['default'] + BaseEditorBaseEditor: typeof import('./src/components/BaseEditor/BaseEditor.vue')['default'] BreadcrumbBreadcrumb: typeof import('./src/components/Breadcrumb/Breadcrumb.vue')['default'] + CertInfoCertInfo: typeof import('./src/components/CertInfo/CertInfo.vue')['default'] ChartAreaChart: typeof import('./src/components/Chart/AreaChart.vue')['default'] ChartRadialBarChart: typeof import('./src/components/Chart/RadialBarChart.vue')['default'] ChartUsageProgressLine: typeof import('./src/components/Chart/UsageProgressLine.vue')['default'] ChatGPTChatGPT: typeof import('./src/components/ChatGPT/ChatGPT.vue')['default'] + ChatGPTChatMessage: typeof import('./src/components/ChatGPT/ChatMessage.vue')['default'] + ChatGPTChatMessageInput: typeof import('./src/components/ChatGPT/ChatMessageInput.vue')['default'] + ChatGPTChatMessageList: typeof import('./src/components/ChatGPT/ChatMessageList.vue')['default'] CodeEditorCodeEditor: typeof import('./src/components/CodeEditor/CodeEditor.vue')['default'] + ConfigHistoryConfigHistory: typeof import('./src/components/ConfigHistory/ConfigHistory.vue')['default'] + ConfigHistoryDiffViewer: typeof import('./src/components/ConfigHistory/DiffViewer.vue')['default'] + EnvGroupTabsEnvGroupTabs: typeof import('./src/components/EnvGroupTabs/EnvGroupTabs.vue')['default'] EnvIndicatorEnvIndicator: typeof import('./src/components/EnvIndicator/EnvIndicator.vue')['default'] FooterToolbarFooterToolBar: typeof import('./src/components/FooterToolbar/FooterToolBar.vue')['default'] ICPICP: typeof import('./src/components/ICP/ICP.vue')['default'] LogoLogo: typeof import('./src/components/Logo/Logo.vue')['default'] NginxControlNginxControl: typeof import('./src/components/NginxControl/NginxControl.vue')['default'] + NgxConfigEditorDirectiveDirectiveAdd: typeof import('./src/components/NgxConfigEditor/directive/DirectiveAdd.vue')['default'] + NgxConfigEditorDirectiveDirectiveDocuments: typeof import('./src/components/NgxConfigEditor/directive/DirectiveDocuments.vue')['default'] + NgxConfigEditorDirectiveDirectiveEditor: typeof import('./src/components/NgxConfigEditor/directive/DirectiveEditor.vue')['default'] + NgxConfigEditorDirectiveDirectiveEditorItem: typeof import('./src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue')['default'] + NgxConfigEditorLocationEditor: typeof import('./src/components/NgxConfigEditor/LocationEditor.vue')['default'] + NgxConfigEditorLogEntry: typeof import('./src/components/NgxConfigEditor/LogEntry.vue')['default'] + NgxConfigEditorNginxStatusAlert: typeof import('./src/components/NgxConfigEditor/NginxStatusAlert.vue')['default'] + NgxConfigEditorNgxConfigEditor: typeof import('./src/components/NgxConfigEditor/NgxConfigEditor.vue')['default'] + NgxConfigEditorNgxServer: typeof import('./src/components/NgxConfigEditor/NgxServer.vue')['default'] + NgxConfigEditorNgxUpstream: typeof import('./src/components/NgxConfigEditor/NgxUpstream.vue')['default'] NodeSelectorNodeSelector: typeof import('./src/components/NodeSelector/NodeSelector.vue')['default'] NotificationNotification: typeof import('./src/components/Notification/Notification.vue')['default'] OTPInputOTPInput: typeof import('./src/components/OTPInput/OTPInput.vue')['default'] PageHeaderPageHeader: typeof import('./src/components/PageHeader/PageHeader.vue')['default'] + PortScannerPortScannerCompact: typeof import('./src/components/PortScanner/PortScannerCompact.vue')['default'] + ProcessingStatusProcessingStatus: typeof import('./src/components/ProcessingStatus/ProcessingStatus.vue')['default'] + ProxyTargetsProxyTargets: typeof import('./src/components/ProxyTargets/ProxyTargets.vue')['default'] ReactiveFromNowReactiveFromNow: typeof import('./src/components/ReactiveFromNow/ReactiveFromNow.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + SelfCheckSelfCheck: typeof import('./src/components/SelfCheck/SelfCheck.vue')['default'] + SelfCheckSelfCheckHeaderBanner: typeof import('./src/components/SelfCheck/SelfCheckHeaderBanner.vue')['default'] SensitiveStringSensitiveString: typeof import('./src/components/SensitiveString/SensitiveString.vue')['default'] SetLanguageSetLanguage: typeof import('./src/components/SetLanguage/SetLanguage.vue')['default'] - StdDesignStdDataDisplayStdBatchEdit: typeof import('./src/components/StdDesign/StdDataDisplay/StdBatchEdit.vue')['default'] - StdDesignStdDataDisplayStdBulkActions: typeof import('./src/components/StdDesign/StdDataDisplay/StdBulkActions.vue')['default'] - StdDesignStdDataDisplayStdCurd: typeof import('./src/components/StdDesign/StdDataDisplay/StdCurd.vue')['default'] - StdDesignStdDataDisplayStdCurdDetail: typeof import('./src/components/StdDesign/StdDataDisplay/StdCurdDetail.vue')['default'] - StdDesignStdDataDisplayStdPagination: typeof import('./src/components/StdDesign/StdDataDisplay/StdPagination.vue')['default'] - StdDesignStdDataDisplayStdTable: typeof import('./src/components/StdDesign/StdDataDisplay/StdTable.vue')['default'] - StdDesignStdDataEntryComponentsStdPassword: typeof import('./src/components/StdDesign/StdDataEntry/components/StdPassword.vue')['default'] - StdDesignStdDataEntryComponentsStdSelect: typeof import('./src/components/StdDesign/StdDataEntry/components/StdSelect.vue')['default'] - StdDesignStdDataEntryComponentsStdSelector: typeof import('./src/components/StdDesign/StdDataEntry/components/StdSelector.vue')['default'] - StdDesignStdDataEntryStdDataEntry: typeof import('./src/components/StdDesign/StdDataEntry/StdDataEntry.vue')['default'] - StdDesignStdDataEntryStdFormItem: typeof import('./src/components/StdDesign/StdDataEntry/StdFormItem.vue')['default'] - StdDesignStdDetailStdDetail: typeof import('./src/components/StdDesign/StdDetail/StdDetail.vue')['default'] SwitchAppearanceIconsVPIconMoon: typeof import('./src/components/SwitchAppearance/icons/VPIconMoon.vue')['default'] SwitchAppearanceIconsVPIconSun: typeof import('./src/components/SwitchAppearance/icons/VPIconSun.vue')['default'] SwitchAppearanceSwitchAppearance: typeof import('./src/components/SwitchAppearance/SwitchAppearance.vue')['default'] diff --git a/app/env.d.ts b/app/env.d.ts index 602682f94..478bba325 100644 --- a/app/env.d.ts +++ b/app/env.d.ts @@ -1,3 +1,10 @@ +/// + +// Extend Window interface +interface Window { + inWorkspace?: boolean +} + declare module '*.svg' { import type React from 'react' diff --git a/app/eslint.config.mjs b/app/eslint.config.mjs index c6ffbe03b..6ab7a1a94 100644 --- a/app/eslint.config.mjs +++ b/app/eslint.config.mjs @@ -51,6 +51,8 @@ export default createConfig( 'sonarjs/no-nested-template-literals': 'off', 'sonarjs/pseudo-random': 'warn', 'sonarjs/no-nested-functions': 'off', + + 'eslint-comments/no-unlimited-disable': 'off', }, }, ) diff --git a/app/i18n.json b/app/i18n.json index 9e1963d2d..9e9d49ed1 100644 --- a/app/i18n.json +++ b/app/i18n.json @@ -9,5 +9,8 @@ "vi_VN": "Vi", "ko_KR": "한글", "tr_TR": "Tr", - "ar": "عَرَبِيّ" + "ar": "عَرَبِيّ", + "uk_UA": "Uk", + "ja_JP": "日", + "pt_PT": "Pt" } diff --git a/app/index.html b/app/index.html index 3d216c664..f0d9f599d 100644 --- a/app/index.html +++ b/app/index.html @@ -14,7 +14,7 @@ color: #fff; } #app { - height: 100%; + height: 100vh; } Codestin Search App diff --git a/app/package.json b/app/package.json index 51a6500f5..dcd7f76f3 100644 --- a/app/package.json +++ b/app/package.json @@ -1,8 +1,8 @@ { "name": "nginx-ui-app-next", "type": "module", - "version": "2.0.0-rc.5", - "packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6", + "version": "2.1.10", + "packageManager": "pnpm@10.12.4+sha512.5ea8b0deed94ed68691c9bad4c955492705c5eeb8a87ef86bc62c74a26b037b08ff9570f108b2e4dbd1dd1a9186fea925e527f141c648e85af45631074680184", "scripts": { "dev": "vite --host", "typecheck": "vue-tsc --noEmit", @@ -10,75 +10,80 @@ "lint:fix": "eslint --fix .", "build": "vite build", "preview": "vite preview", - "gettext:extract": "vue-gettext-extract" + "gettext:extract": "generate-curd-translations --output src/language/curd.ts && vue-gettext-extract" }, "dependencies": { "@0xjacky/vue-github-button": "^3.1.1", "@ant-design/icons-vue": "^7.0.1", "@formkit/auto-animate": "^0.8.2", "@simplewebauthn/browser": "^13.1.0", - "@vue/reactivity": "^3.5.13", - "@vue/shared": "^3.5.13", - "@vueuse/components": "^13.0.0", - "@vueuse/core": "^13.0.0", - "@vueuse/integrations": "^13.0.0", + "@uozi-admin/curd": "^4.3.12", + "@uozi-admin/request": "^2.8.1", + "@vue/reactivity": "^3.5.17", + "@vue/shared": "^3.5.17", + "@vueuse/components": "^13.5.0", + "@vueuse/core": "^13.5.0", + "@vueuse/integrations": "^13.5.0", "@xterm/addon-attach": "^0.11.0", "@xterm/addon-fit": "^0.10.0", "@xterm/xterm": "^5.5.0", "ant-design-vue": "^4.2.6", - "apexcharts": "^4.5.0", - "axios": "^1.8.4", + "apexcharts": "^4.7.0", + "axios": "^1.10.0", "dayjs": "^1.11.13", "highlight.js": "^11.11.1", "jsencrypt": "^3.3.2", "lodash": "^4.17.21", - "marked": "^15.0.7", - "marked-highlight": "^2.2.1", + "marked": "^16.0.0", + "marked-highlight": "^2.2.2", "nprogress": "^0.2.0", - "pinia": "^3.0.1", - "pinia-plugin-persistedstate": "^4.2.0", + "pinia": "^3.0.3", + "pinia-plugin-persistedstate": "^4.4.1", "reconnecting-websocket": "^4.4.0", "sortablejs": "^1.15.6", + "splitpanes": "^4.0.4", "sse.js": "^2.6.0", "universal-cookie": "^8.0.1", - "unocss": "^66.0.0", + "unocss": "^66.3.2", + "uuid": "^11.1.0", "vite-plugin-build-id": "0.5.0", - "vue": "^3.5.13", - "vue-dompurify-html": "^5.2.0", - "vue-router": "^4.5.0", + "vue": "^3.5.17", + "vue-dompurify-html": "^5.3.0", + "vue-router": "^4.5.1", "vue3-ace-editor": "2.2.4", "vue3-apexcharts": "1.5.3", "vue3-gettext": "3.0.0-beta.6", - "vue3-otp-input": "^0.5.21", + "vue3-otp-input": "^0.5.40", "vuedraggable": "^4.1.0" }, "devDependencies": { - "@antfu/eslint-config": "^4.11.0", + "@antfu/eslint-config": "^4.16.2", "@iconify-json/fa": "1.2.1", - "@iconify-json/tabler": "^1.2.17", + "@iconify-json/tabler": "^1.2.19", "@iconify/tools": "^4.1.2", "@iconify/types": "^2.0.0", "@iconify/utils": "^2.3.0", - "@iconify/vue": "^4.3.0", - "@types/lodash": "^4.17.16", + "@iconify/vue": "^5.0.0", + "@types/lodash": "^4.17.20", "@types/nprogress": "^0.2.3", "@types/sortablejs": "^1.15.8", - "@vitejs/plugin-vue": "^5.2.3", - "@vitejs/plugin-vue-jsx": "^4.1.2", - "@vue/compiler-sfc": "^3.5.13", + "@vitejs/plugin-vue": "^6.0.0", + "@vitejs/plugin-vue-jsx": "^5.0.1", + "@vue/compiler-sfc": "^3.5.17", "@vue/tsconfig": "^0.7.0", - "ace-builds": "^1.39.1", + "ace-builds": "^1.43.1", "autoprefixer": "^10.4.21", - "eslint": "9.23.0", - "eslint-plugin-sonarjs": "^3.0.2", - "less": "^4.2.2", - "postcss": "^8.5.3", - "typescript": "5.8.2", - "unplugin-auto-import": "^19.1.2", - "unplugin-vue-components": "^28.4.1", + "eslint": "^9.30.1", + "eslint-plugin-sonarjs": "^3.0.4", + "less": "^4.3.0", + "postcss": "^8.5.6", + "typescript": "5.8.3", + "unplugin-auto-import": "^19.3.0", + "unplugin-vue-components": "^28.8.0", "unplugin-vue-define-options": "^1.5.5", - "vite": "^6.2.3", + "vite": "npm:rolldown-vite@^7.0.4", + "vite-plugin-inspect": "^11.3.0", "vite-svg-loader": "^5.1.0", - "vue-tsc": "^2.2.8" + "vue-tsc": "^3.0.1" } } diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index 330fe5270..60fbc020f 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -13,28 +13,34 @@ importers: version: 3.1.1 '@ant-design/icons-vue': specifier: ^7.0.1 - version: 7.0.1(vue@3.5.13(typescript@5.8.2)) + version: 7.0.1(vue@3.5.17(typescript@5.8.3)) '@formkit/auto-animate': specifier: ^0.8.2 version: 0.8.2 '@simplewebauthn/browser': specifier: ^13.1.0 version: 13.1.0 + '@uozi-admin/curd': + specifier: ^4.3.12 + version: 4.3.12(@ant-design/icons-vue@7.0.1(vue@3.5.17(typescript@5.8.3)))(ant-design-vue@4.2.6(vue@3.5.17(typescript@5.8.3)))(dayjs@1.11.13)(lodash-es@4.17.21)(vue-router@4.5.1(vue@3.5.17(typescript@5.8.3)))(vue@3.5.17(typescript@5.8.3)) + '@uozi-admin/request': + specifier: ^2.8.1 + version: 2.8.1(lodash-es@4.17.21) '@vue/reactivity': - specifier: ^3.5.13 - version: 3.5.13 + specifier: ^3.5.17 + version: 3.5.17 '@vue/shared': - specifier: ^3.5.13 - version: 3.5.13 + specifier: ^3.5.17 + version: 3.5.17 '@vueuse/components': - specifier: ^13.0.0 - version: 13.0.0(vue@3.5.13(typescript@5.8.2)) + specifier: ^13.5.0 + version: 13.5.0(vue@3.5.17(typescript@5.8.3)) '@vueuse/core': - specifier: ^13.0.0 - version: 13.0.0(vue@3.5.13(typescript@5.8.2)) + specifier: ^13.5.0 + version: 13.5.0(vue@3.5.17(typescript@5.8.3)) '@vueuse/integrations': - specifier: ^13.0.0 - version: 13.0.0(async-validator@4.2.5)(axios@1.8.4)(nprogress@0.2.0)(sortablejs@1.15.6)(universal-cookie@8.0.1)(vue@3.5.13(typescript@5.8.2)) + specifier: ^13.5.0 + version: 13.5.0(async-validator@4.2.5)(axios@1.10.0)(nprogress@0.2.0)(sortablejs@1.15.6)(universal-cookie@8.0.1)(vue@3.5.17(typescript@5.8.3)) '@xterm/addon-attach': specifier: ^0.11.0 version: 0.11.0(@xterm/xterm@5.5.0) @@ -46,13 +52,13 @@ importers: version: 5.5.0 ant-design-vue: specifier: ^4.2.6 - version: 4.2.6(vue@3.5.13(typescript@5.8.2)) + version: 4.2.6(vue@3.5.17(typescript@5.8.3)) apexcharts: - specifier: ^4.5.0 - version: 4.5.0 + specifier: ^4.7.0 + version: 4.7.0 axios: - specifier: ^1.8.4 - version: 1.8.4 + specifier: ^1.10.0 + version: 1.10.0 dayjs: specifier: ^1.11.13 version: 1.11.13 @@ -66,26 +72,29 @@ importers: specifier: ^4.17.21 version: 4.17.21 marked: - specifier: ^15.0.7 - version: 15.0.7 + specifier: ^16.0.0 + version: 16.0.0 marked-highlight: - specifier: ^2.2.1 - version: 2.2.1(marked@15.0.7) + specifier: ^2.2.2 + version: 2.2.2(marked@16.0.0) nprogress: specifier: ^0.2.0 version: 0.2.0 pinia: - specifier: ^3.0.1 - version: 3.0.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)) + specifier: ^3.0.3 + version: 3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)) pinia-plugin-persistedstate: - specifier: ^4.2.0 - version: 4.2.0(pinia@3.0.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))(rollup@4.34.6) + specifier: ^4.4.1 + version: 4.4.1(@nuxt/kit@3.17.5)(pinia@3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3))) reconnecting-websocket: specifier: ^4.4.0 version: 4.4.0 sortablejs: specifier: ^1.15.6 version: 1.15.6 + splitpanes: + specifier: ^4.0.4 + version: 4.0.4(vue@3.5.17(typescript@5.8.3)) sse.js: specifier: ^2.6.0 version: 2.6.0 @@ -93,45 +102,48 @@ importers: specifier: ^8.0.1 version: 8.0.1 unocss: - specifier: ^66.0.0 - version: 66.0.0(postcss@8.5.3)(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + specifier: ^66.3.2 + version: 66.3.2(postcss@8.5.6)(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) + uuid: + specifier: ^11.1.0 + version: 11.1.0 vite-plugin-build-id: specifier: 0.5.0 version: 0.5.0 vue: - specifier: ^3.5.13 - version: 3.5.13(typescript@5.8.2) + specifier: ^3.5.17 + version: 3.5.17(typescript@5.8.3) vue-dompurify-html: - specifier: ^5.2.0 - version: 5.2.0(vue@3.5.13(typescript@5.8.2)) + specifier: ^5.3.0 + version: 5.3.0(vue@3.5.17(typescript@5.8.3)) vue-router: - specifier: ^4.5.0 - version: 4.5.0(vue@3.5.13(typescript@5.8.2)) + specifier: ^4.5.1 + version: 4.5.1(vue@3.5.17(typescript@5.8.3)) vue3-ace-editor: specifier: 2.2.4 - version: 2.2.4(ace-builds@1.39.1)(vue@3.5.13(typescript@5.8.2)) + version: 2.2.4(ace-builds@1.43.1)(vue@3.5.17(typescript@5.8.3)) vue3-apexcharts: specifier: 1.5.3 - version: 1.5.3(apexcharts@4.5.0)(vue@3.5.13(typescript@5.8.2)) + version: 1.5.3(apexcharts@4.7.0)(vue@3.5.17(typescript@5.8.3)) vue3-gettext: specifier: 3.0.0-beta.6 - version: 3.0.0-beta.6(@vue/compiler-sfc@3.5.13)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)) + version: 3.0.0-beta.6(@vue/compiler-sfc@3.5.17)(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)) vue3-otp-input: - specifier: ^0.5.21 - version: 0.5.21(vue@3.5.13(typescript@5.8.2)) + specifier: ^0.5.40 + version: 0.5.40(vue@3.5.17(typescript@5.8.3)) vuedraggable: specifier: ^4.1.0 - version: 4.1.0(vue@3.5.13(typescript@5.8.2)) + version: 4.1.0(vue@3.5.17(typescript@5.8.3)) devDependencies: '@antfu/eslint-config': - specifier: ^4.11.0 - version: 4.11.0(@typescript-eslint/utils@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + specifier: ^4.16.2 + version: 4.16.2(@vue/compiler-sfc@3.5.17)(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) '@iconify-json/fa': specifier: 1.2.1 version: 1.2.1 '@iconify-json/tabler': - specifier: ^1.2.17 - version: 1.2.17 + specifier: ^1.2.19 + version: 1.2.19 '@iconify/tools': specifier: ^4.1.2 version: 4.1.2 @@ -142,11 +154,11 @@ importers: specifier: ^2.3.0 version: 2.3.0 '@iconify/vue': - specifier: ^4.3.0 - version: 4.3.0(vue@3.5.13(typescript@5.8.2)) + specifier: ^5.0.0 + version: 5.0.0(vue@3.5.17(typescript@5.8.3)) '@types/lodash': - specifier: ^4.17.16 - version: 4.17.16 + specifier: ^4.17.20 + version: 4.17.20 '@types/nprogress': specifier: ^0.2.3 version: 0.2.3 @@ -154,56 +166,59 @@ importers: specifier: ^1.15.8 version: 1.15.8 '@vitejs/plugin-vue': - specifier: ^5.2.3 - version: 5.2.3(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + specifier: ^6.0.0 + version: 6.0.0(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) '@vitejs/plugin-vue-jsx': - specifier: ^4.1.2 - version: 4.1.2(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + specifier: ^5.0.1 + version: 5.0.1(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) '@vue/compiler-sfc': - specifier: ^3.5.13 - version: 3.5.13 + specifier: ^3.5.17 + version: 3.5.17 '@vue/tsconfig': specifier: ^0.7.0 - version: 0.7.0(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)) + version: 0.7.0(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)) ace-builds: - specifier: ^1.39.1 - version: 1.39.1 + specifier: ^1.43.1 + version: 1.43.1 autoprefixer: specifier: ^10.4.21 - version: 10.4.21(postcss@8.5.3) + version: 10.4.21(postcss@8.5.6) eslint: - specifier: 9.23.0 - version: 9.23.0(jiti@2.4.2) + specifier: ^9.30.1 + version: 9.30.1(jiti@2.4.2) eslint-plugin-sonarjs: - specifier: ^3.0.2 - version: 3.0.2(eslint@9.23.0(jiti@2.4.2)) + specifier: ^3.0.4 + version: 3.0.4(eslint@9.30.1(jiti@2.4.2)) less: - specifier: ^4.2.2 - version: 4.2.2 + specifier: ^4.3.0 + version: 4.3.0 postcss: - specifier: ^8.5.3 - version: 8.5.3 + specifier: ^8.5.6 + version: 8.5.6 typescript: - specifier: 5.8.2 - version: 5.8.2 + specifier: 5.8.3 + version: 5.8.3 unplugin-auto-import: - specifier: ^19.1.2 - version: 19.1.2(@nuxt/kit@3.14.1592(rollup@4.34.6))(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2))) + specifier: ^19.3.0 + version: 19.3.0(@nuxt/kit@3.17.5)(@vueuse/core@13.5.0(vue@3.5.17(typescript@5.8.3))) unplugin-vue-components: - specifier: ^28.4.1 - version: 28.4.1(@babel/parser@7.26.10)(@nuxt/kit@3.14.1592(rollup@4.34.6))(vue@3.5.13(typescript@5.8.2)) + specifier: ^28.8.0 + version: 28.8.0(@babel/parser@7.28.0)(@nuxt/kit@3.17.5)(vue@3.5.17(typescript@5.8.3)) unplugin-vue-define-options: specifier: ^1.5.5 - version: 1.5.5(vue@3.5.13(typescript@5.8.2)) + version: 1.5.5(vue@3.5.17(typescript@5.8.3)) vite: - specifier: ^6.2.3 - version: 6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0) + specifier: npm:rolldown-vite@^7.0.4 + version: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) + vite-plugin-inspect: + specifier: ^11.3.0 + version: 11.3.0(@nuxt/kit@3.17.5)(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0)) vite-svg-loader: specifier: ^5.1.0 - version: 5.1.0(vue@3.5.13(typescript@5.8.2)) + version: 5.1.0(vue@3.5.17(typescript@5.8.3)) vue-tsc: - specifier: ^2.2.8 - version: 2.2.8(typescript@5.8.2) + specifier: ^3.0.1 + version: 3.0.1(typescript@5.8.3) packages: @@ -225,11 +240,11 @@ packages: peerDependencies: vue: '>=3.0.3' - '@antfu/eslint-config@4.11.0': - resolution: {integrity: sha512-KMLIrZflEFsOEF/N0Xl8iVaheLTdgT3gAwXVzdG5Ng8ieNhBsRsaThnqI7of10kh6psSBLJ6SkNK+ZF98fQIXQ==} + '@antfu/eslint-config@4.16.2': + resolution: {integrity: sha512-5KHZR+7ne+HZnOJUKeTTdHKYA/yOygPssaJ7TZOMoBqjSMtVAa7FO5Wvu2dEtkibM6v3emYyKnQnia1S8NHQeA==} hasBin: true peerDependencies: - '@eslint-react/eslint-plugin': ^1.19.0 + '@eslint-react/eslint-plugin': ^1.38.4 '@prettier/plugin-xml': ^3.4.1 '@unocss/eslint-plugin': '>=0.50.0' astro-eslint-parser: ^1.0.2 @@ -274,201 +289,151 @@ packages: svelte-eslint-parser: optional: true - '@antfu/install-pkg@1.0.0': - resolution: {integrity: sha512-xvX6P/lo1B3ej0OsaErAjqgFYzYVcJpamjLAFLYh9vRJngBrMoUG7aVnrGTeqM7yxbyTD5p3F2+0/QUEh8Vzhw==} - - '@antfu/utils@8.1.0': - resolution: {integrity: sha512-XPR7Jfwp0FFl/dFYPX8ZjpmU4/1mIXTjnZ1ba48BLMyKOV62/tiRjdsFcPs2hsYcSud4tzk7w3a3LjX8Fu3huA==} - - '@babel/code-frame@7.26.2': - resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.26.3': - resolution: {integrity: sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==} - engines: {node: '>=6.9.0'} - - '@babel/compat-data@7.26.8': - resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} - engines: {node: '>=6.9.0'} + '@antfu/install-pkg@1.1.0': + resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} - '@babel/core@7.26.0': - resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} - engines: {node: '>=6.9.0'} + '@antfu/utils@8.1.1': + resolution: {integrity: sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==} - '@babel/core@7.26.10': - resolution: {integrity: sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==} + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.10': - resolution: {integrity: sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==} + '@babel/compat-data@7.28.0': + resolution: {integrity: sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.3': - resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} + '@babel/core@7.28.0': + resolution: {integrity: sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.25.9': - resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + '@babel/generator@7.28.0': + resolution: {integrity: sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.25.9': - resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} + '@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.26.5': - resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} engines: {node: '>=6.9.0'} - '@babel/helper-create-class-features-plugin@7.25.9': - resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==} + '@babel/helper-create-class-features-plugin@7.27.1': + resolution: {integrity: sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-member-expression-to-functions@7.25.9': - resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.25.9': - resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + '@babel/helper-member-expression-to-functions@7.27.1': + resolution: {integrity: sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==} engines: {node: '>=6.9.0'} - '@babel/helper-module-transforms@7.26.0': - resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - '@babel/helper-optimise-call-expression@7.25.9': - resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} + '@babel/helper-module-transforms@7.27.3': + resolution: {integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==} engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - '@babel/helper-plugin-utils@7.25.9': - resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.26.5': - resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} engines: {node: '>=6.9.0'} - '@babel/helper-replace-supers@7.25.9': - resolution: {integrity: sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==} + '@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.25.9': - resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} - engines: {node: '>=6.9.0'} - - '@babel/helper-string-parser@7.25.9': - resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.25.9': - resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-option@7.25.9': - resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.0': - resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} engines: {node: '>=6.9.0'} - '@babel/helpers@7.26.10': - resolution: {integrity: sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==} + '@babel/helpers@7.27.6': + resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.10': - resolution: {integrity: sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@7.26.3': - resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} - engines: {node: '>=6.0.0'} - hasBin: true - - '@babel/parser@7.26.5': - resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==} + '@babel/parser@7.28.0': + resolution: {integrity: sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/plugin-syntax-jsx@7.25.9': - resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-syntax-typescript@7.25.9': - resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.26.8': - resolution: {integrity: sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw==} + '@babel/plugin-transform-typescript@7.28.0': + resolution: {integrity: sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/runtime@7.26.0': - resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} - engines: {node: '>=6.9.0'} - - '@babel/standalone@7.26.4': - resolution: {integrity: sha512-SF+g7S2mhTT1b7CHyfNjDkPU1corxg4LPYsyP0x5KuCl+EbtBQHRLqr9N3q7e7+x7NQ5LYxQf8mJ2PmzebLr0A==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.25.9': - resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} - engines: {node: '>=6.9.0'} - - '@babel/template@7.26.9': - resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.26.10': - resolution: {integrity: sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==} - engines: {node: '>=6.9.0'} - - '@babel/traverse@7.26.4': - resolution: {integrity: sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==} + '@babel/runtime@7.27.6': + resolution: {integrity: sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.10': - resolution: {integrity: sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==} + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.3': - resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} + '@babel/traverse@7.28.0': + resolution: {integrity: sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.5': - resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==} + '@babel/types@7.28.0': + resolution: {integrity: sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==} engines: {node: '>=6.9.0'} - '@clack/core@0.4.1': - resolution: {integrity: sha512-Pxhij4UXg8KSr7rPek6Zowm+5M22rbd2g1nfojHJkxp5YkFqiZ2+YLEM/XGVIzvGOcM0nqjIFxrpDwWRZYWYjA==} + '@clack/core@0.5.0': + resolution: {integrity: sha512-p3y0FIOwaYRUPRcMO7+dlmLh8PSRcrjuTndsiA0WAFbWES0mLZlrjVoBRZ9DzkPFJZG6KGkJmoEAY0ZcVWTkow==} - '@clack/prompts@0.10.0': - resolution: {integrity: sha512-H3rCl6CwW1NdQt9rE3n373t7o5cthPv7yUoxF2ytZvyvlJv89C5RYMJu83Hed8ODgys5vpBU0GKxIRG83jd8NQ==} + '@clack/prompts@0.11.0': + resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==} '@ctrl/tinycolor@3.6.1': resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} engines: {node: '>=10'} - '@emnapi/core@1.3.1': - resolution: {integrity: sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==} + '@emnapi/core@1.4.3': + resolution: {integrity: sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==} - '@emnapi/runtime@1.3.1': - resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==} + '@emnapi/runtime@1.4.3': + resolution: {integrity: sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==} - '@emnapi/wasi-threads@1.0.1': - resolution: {integrity: sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==} + '@emnapi/wasi-threads@1.0.2': + resolution: {integrity: sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==} '@emotion/hash@0.9.2': resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} @@ -476,22 +441,22 @@ packages: '@emotion/unitless@0.8.1': resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} - '@es-joy/jsdoccomment@0.49.0': - resolution: {integrity: sha512-xjZTSFgECpb9Ohuk5yMX5RhUEbfeQcuOp8IF60e+wyzWEF0M5xeSgqsfLtvPEX8BIyOX9saZqzuGPmZ8oWc+5Q==} - engines: {node: '>=16'} - - '@es-joy/jsdoccomment@0.50.0': - resolution: {integrity: sha512-+zZymuVLH6zVwXPtCAtC+bDymxmEwEqDftdAK+f407IF1bnX49anIxvBhCA1AqUIfD6egj1jM1vUnSuijjNyYg==} + '@es-joy/jsdoccomment@0.50.2': + resolution: {integrity: sha512-YAdE/IJSpwbOTiaURNCKECdAwqrJuFiZhylmesBcIRawtYKnBR2wxPhoIewMg+Yu+QuYvHfJNReWpoxGBKOChA==} engines: {node: '>=18'} + '@es-joy/jsdoccomment@0.52.0': + resolution: {integrity: sha512-BXuN7BII+8AyNtn57euU2Yxo9yA/KUDNzrpXyi3pfqKmBhhysR6ZWOebFh3vyPoqA3/j1SOvGgucElMGwlXing==} + engines: {node: '>=20.11.0'} + '@esbuild/aix-ppc64@0.23.1': resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/aix-ppc64@0.25.0': - resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] @@ -502,8 +467,8 @@ packages: cpu: [arm64] os: [android] - '@esbuild/android-arm64@0.25.0': - resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} engines: {node: '>=18'} cpu: [arm64] os: [android] @@ -514,8 +479,8 @@ packages: cpu: [arm] os: [android] - '@esbuild/android-arm@0.25.0': - resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} engines: {node: '>=18'} cpu: [arm] os: [android] @@ -526,8 +491,8 @@ packages: cpu: [x64] os: [android] - '@esbuild/android-x64@0.25.0': - resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} engines: {node: '>=18'} cpu: [x64] os: [android] @@ -538,8 +503,8 @@ packages: cpu: [arm64] os: [darwin] - '@esbuild/darwin-arm64@0.25.0': - resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] @@ -550,8 +515,8 @@ packages: cpu: [x64] os: [darwin] - '@esbuild/darwin-x64@0.25.0': - resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] @@ -562,8 +527,8 @@ packages: cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-arm64@0.25.0': - resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] @@ -574,8 +539,8 @@ packages: cpu: [x64] os: [freebsd] - '@esbuild/freebsd-x64@0.25.0': - resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] @@ -586,8 +551,8 @@ packages: cpu: [arm64] os: [linux] - '@esbuild/linux-arm64@0.25.0': - resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] @@ -598,8 +563,8 @@ packages: cpu: [arm] os: [linux] - '@esbuild/linux-arm@0.25.0': - resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} engines: {node: '>=18'} cpu: [arm] os: [linux] @@ -610,8 +575,8 @@ packages: cpu: [ia32] os: [linux] - '@esbuild/linux-ia32@0.25.0': - resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} engines: {node: '>=18'} cpu: [ia32] os: [linux] @@ -622,8 +587,8 @@ packages: cpu: [loong64] os: [linux] - '@esbuild/linux-loong64@0.25.0': - resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] @@ -634,8 +599,8 @@ packages: cpu: [mips64el] os: [linux] - '@esbuild/linux-mips64el@0.25.0': - resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] @@ -646,8 +611,8 @@ packages: cpu: [ppc64] os: [linux] - '@esbuild/linux-ppc64@0.25.0': - resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] @@ -658,8 +623,8 @@ packages: cpu: [riscv64] os: [linux] - '@esbuild/linux-riscv64@0.25.0': - resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] @@ -670,8 +635,8 @@ packages: cpu: [s390x] os: [linux] - '@esbuild/linux-s390x@0.25.0': - resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} engines: {node: '>=18'} cpu: [s390x] os: [linux] @@ -682,14 +647,14 @@ packages: cpu: [x64] os: [linux] - '@esbuild/linux-x64@0.25.0': - resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.25.0': - resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] @@ -700,8 +665,8 @@ packages: cpu: [x64] os: [netbsd] - '@esbuild/netbsd-x64@0.25.0': - resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] @@ -712,8 +677,8 @@ packages: cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-arm64@0.25.0': - resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] @@ -724,8 +689,8 @@ packages: cpu: [x64] os: [openbsd] - '@esbuild/openbsd-x64@0.25.0': - resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] @@ -736,8 +701,8 @@ packages: cpu: [x64] os: [sunos] - '@esbuild/sunos-x64@0.25.0': - resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} engines: {node: '>=18'} cpu: [x64] os: [sunos] @@ -748,8 +713,8 @@ packages: cpu: [arm64] os: [win32] - '@esbuild/win32-arm64@0.25.0': - resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] @@ -760,8 +725,8 @@ packages: cpu: [ia32] os: [win32] - '@esbuild/win32-ia32@0.25.0': - resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} engines: {node: '>=18'} cpu: [ia32] os: [win32] @@ -772,20 +737,20 @@ packages: cpu: [x64] os: [win32] - '@esbuild/win32-x64@0.25.0': - resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} engines: {node: '>=18'} cpu: [x64] os: [win32] - '@eslint-community/eslint-plugin-eslint-comments@4.4.1': - resolution: {integrity: sha512-lb/Z/MzbTf7CaVYM9WCFNQZ4L1yi3ev2fsFPF99h31ljhSEyUoyEsKsNWiU+qD1glbYTDJdqgyaLKtyTkkqtuQ==} + '@eslint-community/eslint-plugin-eslint-comments@4.5.0': + resolution: {integrity: sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 - '@eslint-community/eslint-utils@4.4.1': - resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + '@eslint-community/eslint-utils@4.7.0': + resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -794,49 +759,57 @@ packages: resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - '@eslint/compat@1.2.6': - resolution: {integrity: sha512-k7HNCqApoDHM6XzT30zGoETj+D+uUcZUb+IVAJmar3u6bvHf7hhHJcWx09QHj4/a2qrKZMWU0E16tvkiAdv06Q==} + '@eslint/compat@1.3.1': + resolution: {integrity: sha512-k8MHony59I5EPic6EQTCNOuPoVBnoYXkP+20xvwFjN7t0qI3ImyvyBgg+hIVPwC8JaxVjjUZld+cLfBLFDLucg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^9.10.0 + eslint: ^8.40 || 9 peerDependenciesMeta: eslint: optional: true - '@eslint/config-array@0.19.2': - resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + '@eslint/config-array@0.21.0': + resolution: {integrity: sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.3.0': + resolution: {integrity: sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/config-helpers@0.2.0': - resolution: {integrity: sha512-yJLLmLexii32mGrhW29qvU3QBVTu0GUmEf/J4XsBtVhp4JkIUFN/BjWqTF63yRvGApIDpZm5fa97LtYtINmfeQ==} + '@eslint/core@0.13.0': + resolution: {integrity: sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.10.0': - resolution: {integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==} + '@eslint/core@0.14.0': + resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.12.0': - resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + '@eslint/core@0.15.1': + resolution: {integrity: sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/eslintrc@3.3.1': resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.23.0': - resolution: {integrity: sha512-35MJ8vCPU0ZMxo7zfev2pypqTwWTofFZO6m4KAtdoFhRpLJUpHTZZ+KB3C7Hb1d7bULYwO4lJXGCi5Se+8OMbw==} + '@eslint/js@9.30.1': + resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/markdown@6.3.0': - resolution: {integrity: sha512-8rj7wmuP5hwXZ0HWoad+WL9nftpN373bCCQz9QL6sA+clZiz7et8Pk0yDAKeo//xLlPONKQ6wCpjkOHCLkbYUw==} + '@eslint/markdown@6.6.0': + resolution: {integrity: sha512-IsWPy2jU3gaQDlioDC4sT4I4kG1hX1OMWs/q2sWwJrPoMASHW/Z4SDw+6Aql6EsHejGbagYuJbFq9Zvx+Y1b1Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.7': - resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + '@eslint/plugin-kit@0.2.8': + resolution: {integrity: sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.3.3': + resolution: {integrity: sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@formkit/auto-animate@0.8.2': @@ -858,15 +831,15 @@ packages: resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.2': - resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} '@iconify-json/fa@1.2.1': resolution: {integrity: sha512-aY2+tQNWq5ch+ShtAz3KKbNrFfwf4BPrXvyN7S4/lcf6Wms+kIxsd7C7KortzHZhoBnbhVN+qo+YUWLW7rLs9Q==} - '@iconify-json/tabler@1.2.17': - resolution: {integrity: sha512-Jfk20IC/n7UOQQSXM600BUhAwEfg8KU1dNUF+kg4eRhbET5w1Ktyax7CDx8Z8y0H6+J/8//AXpJOEgG8YoP8rw==} + '@iconify-json/tabler@1.2.19': + resolution: {integrity: sha512-JDeQTQxHD8KE12pAbPVHX1WFVOPq8D0XfRb/LwYHwGwYE0HP9OIjJ//TKxS1Gt++RirYu6Xsx+Jm5LA5KbykoA==} '@iconify/tools@4.1.2': resolution: {integrity: sha512-q6NzLQYEN9zkDfcyBqD3vItHcZw97w/s++3H3TBxUORr57EfHxj6tOW6fyufDjMq+Vl56WXWaPx1csBPYlI5CA==} @@ -877,35 +850,50 @@ packages: '@iconify/utils@2.3.0': resolution: {integrity: sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==} - '@iconify/vue@4.3.0': - resolution: {integrity: sha512-Xq0h6zMrHBbrW8jXJ9fISi+x8oDQllg5hTDkDuxnWiskJ63rpJu9CvJshj8VniHVTbsxCg9fVoPAaNp3RQI5OQ==} + '@iconify/vue@5.0.0': + resolution: {integrity: sha512-C+KuEWIF5nSBrobFJhT//JS87OZ++QDORB6f2q2Wm6fl2mueSTpFBeBsveK0KW9hWiZ4mNiPjsh6Zs4jjdROSg==} peerDependencies: vue: '>=3' + '@intlify/core-base@11.1.7': + resolution: {integrity: sha512-gYiGnQeJVp3kNBeXQ73m1uFOak0ry4av8pn+IkEWigyyPWEMGzB+xFeQdmGMFn49V+oox6294oGVff8bYOhtOw==} + engines: {node: '>= 16'} + + '@intlify/message-compiler@11.1.7': + resolution: {integrity: sha512-0ezkep1AT30NyuKj8QbRlmvMORCCRlOIIu9v8RNU8SwDjjTiFCZzczCORMns2mCH4HZ1nXgrfkKzYUbfjNRmng==} + engines: {node: '>= 16'} + + '@intlify/shared@11.1.7': + resolution: {integrity: sha512-4yZeMt2Aa/7n5Ehy4KalUlvt3iRLcg1tq9IBVfOgkyWFArN4oygn6WxgGIFibP3svpaH8DarbNaottq+p0gUZQ==} + engines: {node: '>= 16'} + + '@isaacs/balanced-match@4.0.1': + resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} + engines: {node: 20 || >=22} + + '@isaacs/brace-expansion@5.0.0': + resolution: {integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==} + engines: {node: 20 || >=22} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@jridgewell/gen-mapping@0.3.8': - resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} - engines: {node: '>=6.0.0'} + '@jridgewell/gen-mapping@0.3.12': + resolution: {integrity: sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==} '@jridgewell/resolve-uri@3.1.2': resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - '@jridgewell/set-array@1.2.1': - resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} - engines: {node: '>=6.0.0'} - - '@jridgewell/sourcemap-codec@1.5.0': - resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.4': + resolution: {integrity: sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==} - '@jridgewell/trace-mapping@0.3.25': - resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@jridgewell/trace-mapping@0.3.29': + resolution: {integrity: sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==} - '@napi-rs/wasm-runtime@0.2.7': - resolution: {integrity: sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==} + '@napi-rs/wasm-runtime@0.2.11': + resolution: {integrity: sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -919,152 +907,117 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@nuxt/kit@3.14.1592': - resolution: {integrity: sha512-r9r8bISBBisvfcNgNL3dSIQHSBe0v5YkX5zwNblIC2T0CIEgxEVoM5rq9O5wqgb5OEydsHTtT2hL57vdv6VT2w==} - engines: {node: ^14.18.0 || >=16.10.0} + '@nuxt/kit@3.17.5': + resolution: {integrity: sha512-NdCepmA+S/SzgcaL3oYUeSlXGYO6BXGr9K/m1D0t0O9rApF8CSq/QQ+ja5KYaYMO1kZAEWH4s2XVcE3uPrrAVg==} + engines: {node: '>=18.12.0'} - '@nuxt/schema@3.14.1592': - resolution: {integrity: sha512-A1d/08ueX8stTXNkvGqnr1eEXZgvKn+vj6s7jXhZNWApUSqMgItU4VK28vrrdpKbjIPwq2SwhnGOHUYvN9HwCQ==} - engines: {node: ^14.18.0 || >=16.10.0} + '@oxc-project/runtime@0.75.0': + resolution: {integrity: sha512-gzRmVI/vorsPmbDXt7GD4Uh2lD3rCOku/1xWPB4Yx48k0EP4TZmzQudWapjN4+7Vv+rgXr0RqCHQadeaMvdBuw==} + engines: {node: '>=6.9.0'} + + '@oxc-project/types@0.75.0': + resolution: {integrity: sha512-QMW+06WOXs7+F301Y3X0VpmWhwuQVc/X/RP2zF9OIwvSMmsif3xURS2wxbakFIABYsytgBcHpUcFepVS0Qnd3A==} '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pkgr/core@0.1.1': - resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + '@pkgr/core@0.2.7': + resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@polka/url@1.0.0-next.28': - resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} - - '@rollup/pluginutils@5.1.4': - resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - - '@rollup/rollup-android-arm-eabi@4.34.6': - resolution: {integrity: sha512-+GcCXtOQoWuC7hhX1P00LqjjIiS/iOouHXhMdiDSnq/1DGTox4SpUvO52Xm+div6+106r+TcvOeo/cxvyEyTgg==} - cpu: [arm] - os: [android] + '@polka/url@1.0.0-next.29': + resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@rollup/rollup-android-arm64@4.34.6': - resolution: {integrity: sha512-E8+2qCIjciYUnCa1AiVF1BkRgqIGW9KzJeesQqVfyRITGQN+dFuoivO0hnro1DjT74wXLRZ7QF8MIbz+luGaJA==} - cpu: [arm64] - os: [android] + '@quansync/fs@0.1.3': + resolution: {integrity: sha512-G0OnZbMWEs5LhDyqy2UL17vGhSVHkQIfVojMtEWVenvj0V5S84VBgy86kJIuNsGDp2p7sTKlpSIpBUWdC35OKg==} + engines: {node: '>=20.0.0'} - '@rollup/rollup-darwin-arm64@4.34.6': - resolution: {integrity: sha512-z9Ib+OzqN3DZEjX7PDQMHEhtF+t6Mi2z/ueChQPLS/qUMKY7Ybn5A2ggFoKRNRh1q1T03YTQfBTQCJZiepESAg==} + '@rolldown/binding-darwin-arm64@1.0.0-beta.23': + resolution: {integrity: sha512-rppgXFU4+dNDPQvPsfovUuYfDgMoATDomKGjIRR5bIU98BYkQF1fm+87trApilfWSosLQP9JsXOoUJO/EMrspQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.34.6': - resolution: {integrity: sha512-PShKVY4u0FDAR7jskyFIYVyHEPCPnIQY8s5OcXkdU8mz3Y7eXDJPdyM/ZWjkYdR2m0izD9HHWA8sGcXn+Qrsyg==} + '@rolldown/binding-darwin-x64@1.0.0-beta.23': + resolution: {integrity: sha512-aFo1v7GKysuwSAfsyNcBb9mj3M+wxMCu3N+DcTD5eAaz3mFex6l+2b/vLGaTWNrCMoWhRxV8rTaI1eFoMVdSuQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.34.6': - resolution: {integrity: sha512-YSwyOqlDAdKqs0iKuqvRHLN4SrD2TiswfoLfvYXseKbL47ht1grQpq46MSiQAx6rQEN8o8URtpXARCpqabqxGQ==} - cpu: [arm64] - os: [freebsd] - - '@rollup/rollup-freebsd-x64@4.34.6': - resolution: {integrity: sha512-HEP4CgPAY1RxXwwL5sPFv6BBM3tVeLnshF03HMhJYCNc6kvSqBgTMmsEjb72RkZBAWIqiPUyF1JpEBv5XT9wKQ==} + '@rolldown/binding-freebsd-x64@1.0.0-beta.23': + resolution: {integrity: sha512-/NzbXIFIR5KR+fZ351K1qONekakXpiPhUX55ydP6ok8iKdG7bTbgs6dlMg7Ow0E2DKlQoTbZbPTUY3kTzmNrsQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.34.6': - resolution: {integrity: sha512-88fSzjC5xeH9S2Vg3rPgXJULkHcLYMkh8faix8DX4h4TIAL65ekwuQMA/g2CXq8W+NJC43V6fUpYZNjaX3+IIg==} - cpu: [arm] - os: [linux] - - '@rollup/rollup-linux-arm-musleabihf@4.34.6': - resolution: {integrity: sha512-wM4ztnutBqYFyvNeR7Av+reWI/enK9tDOTKNF+6Kk2Q96k9bwhDDOlnCUNRPvromlVXo04riSliMBs/Z7RteEg==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.23': + resolution: {integrity: sha512-vPnCHxjyR4ZVj9x6sLJMCAdBY99RPe6Mnwxb5BSaE6ccHzvy015xtsIEG7H9E9pVj3yfI/om77jrP+YA5IqL3w==} cpu: [arm] os: [linux] - '@rollup/rollup-linux-arm64-gnu@4.34.6': - resolution: {integrity: sha512-9RyprECbRa9zEjXLtvvshhw4CMrRa3K+0wcp3KME0zmBe1ILmvcVHnypZ/aIDXpRyfhSYSuN4EPdCCj5Du8FIA==} + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.23': + resolution: {integrity: sha512-PFBBnj9JqLOL8gjZtoVGfOXe0PSpnPUXE+JuMcWz568K/p4Zzk7lDDHl7guD95wVtV89TmfaRwK2PWd9vKxHtg==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-arm64-musl@4.34.6': - resolution: {integrity: sha512-qTmklhCTyaJSB05S+iSovfo++EwnIEZxHkzv5dep4qoszUMX5Ca4WM4zAVUMbfdviLgCSQOu5oU8YoGk1s6M9Q==} + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.23': + resolution: {integrity: sha512-KyQRLofVP78yUCXT90YmEzxK6I9VCBeOTSyOrs40Qx0Q0XwaGVwxo7sKj2SmnqxribdcouBA3CfNZC4ZNcyEnQ==} cpu: [arm64] os: [linux] - '@rollup/rollup-linux-loongarch64-gnu@4.34.6': - resolution: {integrity: sha512-4Qmkaps9yqmpjY5pvpkfOerYgKNUGzQpFxV6rnS7c/JfYbDSU0y6WpbbredB5cCpLFGJEqYX40WUmxMkwhWCjw==} - cpu: [loong64] - os: [linux] - - '@rollup/rollup-linux-powerpc64le-gnu@4.34.6': - resolution: {integrity: sha512-Zsrtux3PuaxuBTX/zHdLaFmcofWGzaWW1scwLU3ZbW/X+hSsFbz9wDIp6XvnT7pzYRl9MezWqEqKy7ssmDEnuQ==} - cpu: [ppc64] - os: [linux] - - '@rollup/rollup-linux-riscv64-gnu@4.34.6': - resolution: {integrity: sha512-aK+Zp+CRM55iPrlyKiU3/zyhgzWBxLVrw2mwiQSYJRobCURb781+XstzvA8Gkjg/hbdQFuDw44aUOxVQFycrAg==} - cpu: [riscv64] - os: [linux] - - '@rollup/rollup-linux-s390x-gnu@4.34.6': - resolution: {integrity: sha512-WoKLVrY9ogmaYPXwTH326+ErlCIgMmsoRSx6bO+l68YgJnlOXhygDYSZe/qbUJCSiCiZAQ+tKm88NcWuUXqOzw==} - cpu: [s390x] - os: [linux] - - '@rollup/rollup-linux-x64-gnu@4.34.6': - resolution: {integrity: sha512-Sht4aFvmA4ToHd2vFzwMFaQCiYm2lDFho5rPcvPBT5pCdC+GwHG6CMch4GQfmWTQ1SwRKS0dhDYb54khSrjDWw==} + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.23': + resolution: {integrity: sha512-EubfEsJyjQbKK9j3Ez1hhbIOsttABb07Z7PhMRcVYW0wrVr8SfKLew9pULIMfcSNnoz8QqzoI4lOSmezJ9bYWw==} cpu: [x64] os: [linux] - '@rollup/rollup-linux-x64-musl@4.34.6': - resolution: {integrity: sha512-zmmpOQh8vXc2QITsnCiODCDGXFC8LMi64+/oPpPx5qz3pqv0s6x46ps4xoycfUiVZps5PFn1gksZzo4RGTKT+A==} + '@rolldown/binding-linux-x64-musl@1.0.0-beta.23': + resolution: {integrity: sha512-MUAthvl3I/+hySltZuj5ClKiq8fAMqExeBnxadLFShwWCbdHKFd+aRjBxxzarPcnqbDlTaOCUaAaYmQTOTOHSg==} cpu: [x64] os: [linux] - '@rollup/rollup-win32-arm64-msvc@4.34.6': - resolution: {integrity: sha512-3/q1qUsO/tLqGBaD4uXsB6coVGB3usxw3qyeVb59aArCgedSF66MPdgRStUd7vbZOsko/CgVaY5fo2vkvPLWiA==} + '@rolldown/binding-wasm32-wasi@1.0.0-beta.23': + resolution: {integrity: sha512-YI7QMQU01QFVNTEaQt3ysrq+wGBwLdFVFEGO64CoZ3gTsr/HulU8gvgR+67coQOlQC9iO/Hm1bvkBtceLxKrnA==} + engines: {node: '>=14.21.3'} + cpu: [wasm32] + + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.23': + resolution: {integrity: sha512-JdHx6Hli53etB/QsZL1tjpf4qa87kNcwPdx4iVicP/kL7po6k5bHoS5/l/nRRccwPh7BlPlB2uoEuTwJygJosQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.34.6': - resolution: {integrity: sha512-oLHxuyywc6efdKVTxvc0135zPrRdtYVjtVD5GUm55I3ODxhU/PwkQFD97z16Xzxa1Fz0AEe4W/2hzRtd+IfpOA==} + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.23': + resolution: {integrity: sha512-rMZ0QBmcDND97+5unXxquKvSudV8tz6S7tBY3gOYlqMFEDIRX0BAgxaqQBQbq34ZxB9bXwGdjuau3LZHGreB6g==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.34.6': - resolution: {integrity: sha512-0PVwmgzZ8+TZ9oGBmdZoQVXflbvuwzN/HRclujpl4N/q3i+y0lqLw8n1bXA8ru3sApDjlmONaNAuYr38y1Kr9w==} + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.23': + resolution: {integrity: sha512-0PqE7vGIpA+XT+qxAYJQKTrB5zz8vJiuCOInfY/ks/QOs6ZZ9Os8bdNkcpCy4rYo+GMZn0Q8CwyPu4uexWB1aA==} cpu: [x64] os: [win32] + '@rolldown/pluginutils@1.0.0-beta.19': + resolution: {integrity: sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==} + + '@rolldown/pluginutils@1.0.0-beta.23': + resolution: {integrity: sha512-lLCP4LUecUGBLq8EfkbY2esGYyvZj5ee+WZG12+mVnQH48b46SVbwp+0vJkD+6Pnsc+u9SWarBV9sQ5mVwmb5g==} + '@simonwep/pickr@1.8.2': resolution: {integrity: sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==} '@simplewebauthn/browser@13.1.0': resolution: {integrity: sha512-WuHZ/PYvyPJ9nxSzgHtOEjogBhwJfC8xzYkPC+rR/+8chl/ft4ngjiK8kSU5HtRJfczupyOh33b25TjYbvwAcg==} - '@sindresorhus/merge-streams@2.3.0': - resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} - engines: {node: '>=18'} - - '@stylistic/eslint-plugin@4.2.0': - resolution: {integrity: sha512-8hXezgz7jexGHdo5WN6JBEIPHCSFyyU4vgbxevu4YLVS5vl+sxqAAGyXSzfNDyR6xMNSH5H1x67nsXcYMOHtZA==} + '@stylistic/eslint-plugin@5.1.0': + resolution: {integrity: sha512-TJRJul4u/lmry5N/kyCU+7RWWOk0wyXN+BncRlDYBqpLFnzXkd7QGVfN7KewarFIXv0IX0jSF/Ksu7aHWEDeuw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=9.0.0' - '@svgdotjs/svg.draggable.js@3.0.4': - resolution: {integrity: sha512-vWi/Col5Szo74HJVBgMHz23kLVljt3jvngmh0DzST45iO2ubIZ487uUAHIxSZH2tVRyiaaTL+Phaasgp4gUD2g==} + '@svgdotjs/svg.draggable.js@3.0.6': + resolution: {integrity: sha512-7iJFm9lL3C40HQcqzEfezK2l+dW2CpoVY3b77KQGqc8GXWa6LhhmX5Ckv7alQfUXBuZbjpICZ+Dvq1czlGx7gA==} peerDependencies: '@svgdotjs/svg.js': ^3.2.4 - '@svgdotjs/svg.filter.js@3.0.8': - resolution: {integrity: sha512-YshF2YDaeRA2StyzAs5nUPrev7npQ38oWD0eTRwnsciSL2KrRPMoUw8BzjIXItb3+dccKGTX3IQOd2NFzmHkog==} + '@svgdotjs/svg.filter.js@3.0.9': + resolution: {integrity: sha512-/69XMRCDoam2HgC4ldHIaDgeQf1ViHIsa0Ld4uWgiXtZ+E24DWHe/9Ib6kbNiZ7WRIdlVokUDR1Fg0kjIpkfbw==} engines: {node: '>= 0.8.0'} '@svgdotjs/svg.js@3.2.4': @@ -1077,8 +1030,8 @@ packages: '@svgdotjs/svg.js': ^3.2.4 '@svgdotjs/svg.select.js': ^4.0.1 - '@svgdotjs/svg.select.js@4.0.2': - resolution: {integrity: sha512-5gWdrvoQX3keo03SCmgaBbD+kFftq0F/f2bzCbNnpkkvW6tk4rl4MakORzFuNjvXPWwB4az9GwuvVxQVnjaK2g==} + '@svgdotjs/svg.select.js@4.0.3': + resolution: {integrity: sha512-qkMgso1sd2hXKd1FZ1weO7ANq12sNmQJeGDjs46QwDVsxSRcHmvWKL2NDF7Yimpwf3sl5esOLkPqtV2bQ3v/Jg==} engines: {node: '>= 14.18'} peerDependencies: '@svgdotjs/svg.js': ^3.2.4 @@ -1093,14 +1046,8 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} - '@types/doctrine@0.0.9': - resolution: {integrity: sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==} - - '@types/eslint@9.6.1': - resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} - - '@types/estree@1.0.6': - resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} '@types/glob@7.2.0': resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} @@ -1108,23 +1055,21 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} - '@types/lodash@4.17.16': - resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} - '@types/minimatch@5.1.2': - resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + '@types/minimatch@6.0.0': + resolution: {integrity: sha512-zmPitbQ8+6zNutpwgcQuLcsEpn/Cj54Kbn7L5pX0Os5kdWplB7xPgEh/g+SWOB/qmows2gpuCaPyduq8ZZRnxA==} + deprecated: This is a stub types definition. minimatch provides its own type definitions, so you do not need this installed. - '@types/ms@0.7.34': - resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@22.10.2': - resolution: {integrity: sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==} - - '@types/normalize-package-data@2.4.4': - resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/node@24.0.10': + resolution: {integrity: sha512-ENHwaH+JIRTDIEEbDK6QSQntAYGtbvdDXnMXnZaZ6k13Du1dPMmprkEHIL7ok2Wl2aZevetwTAb5S+7yIF+enA==} '@types/nprogress@0.2.3': resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} @@ -1150,234 +1095,184 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.27.0': - resolution: {integrity: sha512-4henw4zkePi5p252c8ncBLzLce52SEUz2Ebj8faDnuUXz2UuHEONYcJ+G0oaCF+bYCWVZtrGzq3FD7YXetmnSA==} + '@typescript-eslint/eslint-plugin@8.35.1': + resolution: {integrity: sha512-9XNTlo7P7RJxbVeICaIIIEipqxLKguyh+3UbXuT2XQuFp6d8VOeDEGuz5IiX0dgZo8CiI6aOFLg4e8cF71SFVg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + '@typescript-eslint/parser': ^8.35.1 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/parser@8.27.0': - resolution: {integrity: sha512-XGwIabPallYipmcOk45DpsBSgLC64A0yvdAkrwEzwZ2viqGqRUJ8eEYoPz0CWnutgAFbNMPdsGGvzjSmcWVlEA==} + '@typescript-eslint/parser@8.35.1': + resolution: {integrity: sha512-3MyiDfrfLeK06bi/g9DqJxP5pV74LNv4rFTyvGDmT3x2p1yp1lOd+qYZfiRPIOf/oON+WRZR5wxxuF85qOar+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/scope-manager@8.26.1': - resolution: {integrity: sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/scope-manager@8.27.0': - resolution: {integrity: sha512-8oI9GwPMQmBryaaxG1tOZdxXVeMDte6NyJA4i7/TWa4fBwgnAXYlIQP+uYOeqAaLJ2JRxlG9CAyL+C+YE9Xknw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/type-utils@8.27.0': - resolution: {integrity: sha512-wVArTVcz1oJOIEJxui/nRhV0TXzD/zMSOYi/ggCfNq78EIszddXcJb7r4RCp/oBrjt8n9A0BSxRMKxHftpDxDA==} + '@typescript-eslint/project-service@8.35.1': + resolution: {integrity: sha512-VYxn/5LOpVxADAuP3NrnxxHYfzVtQzLKeldIhDhzC8UHaiQvYlXvKuVho1qLduFbJjjy5U5bkGwa3rUGUb1Q6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/types@8.26.1': - resolution: {integrity: sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==} + '@typescript-eslint/scope-manager@8.35.1': + resolution: {integrity: sha512-s/Bpd4i7ht2934nG+UoSPlYXd08KYz3bmjLEb7Ye1UVob0d1ENiT3lY8bsCmik4RqfSbPw9xJJHbugpPpP5JUg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.27.0': - resolution: {integrity: sha512-/6cp9yL72yUHAYq9g6DsAU+vVfvQmd1a8KyA81uvfDE21O2DwQ/qxlM4AR8TSdAu+kJLBDrEHKC5/W2/nxsY0A==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/typescript-estree@8.26.1': - resolution: {integrity: sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==} + '@typescript-eslint/tsconfig-utils@8.35.1': + resolution: {integrity: sha512-K5/U9VmT9dTHoNowWZpz+/TObS3xqC5h0xAIjXPw+MNcKV9qg6eSatEnmeAwkjHijhACH0/N7bkhKvbt1+DXWQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/typescript-estree@8.27.0': - resolution: {integrity: sha512-BnKq8cqPVoMw71O38a1tEb6iebEgGA80icSxW7g+kndx0o6ot6696HjG7NdgfuAVmVEtwXUr3L8R9ZuVjoQL6A==} + '@typescript-eslint/type-utils@8.35.1': + resolution: {integrity: sha512-HOrUBlfVRz5W2LIKpXzZoy6VTZzMu2n8q9C2V/cFngIC5U1nStJgv0tMV4sZPzdf4wQm9/ToWUFPMN9Vq9VJQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: + eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.26.1': - resolution: {integrity: sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==} + '@typescript-eslint/types@8.35.1': + resolution: {integrity: sha512-q/O04vVnKHfrrhNAscndAn1tuQhIkwqnaW+eu5waD5IPts2eX1dgJxgqcPx5BX109/qAz7IG6VrEPTOYKCNfRQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.35.1': + resolution: {integrity: sha512-Vvpuvj4tBxIka7cPs6Y1uvM7gJgdF5Uu9F+mBJBPY4MhvjrjWGK4H0lVgLJd/8PWZ23FTqsaJaLEkBCFUk8Y9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/utils@8.27.0': - resolution: {integrity: sha512-njkodcwH1yvmo31YWgRHNb/x1Xhhq4/m81PhtvmRngD8iHPehxffz1SNCO+kwaePhATC+kOa/ggmvPoPza5i0Q==} + '@typescript-eslint/utils@8.35.1': + resolution: {integrity: sha512-lhnwatFmOFcazAsUm3ZnZFpXSxiwoa1Lj50HphnDe1Et01NF4+hrdXONSUHIcbVu2eFb1bAf+5yjXkGVkXBKAQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.9.0' - '@typescript-eslint/visitor-keys@8.26.1': - resolution: {integrity: sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/visitor-keys@8.27.0': - resolution: {integrity: sha512-WsXQwMkILJvffP6z4U3FYJPlbf/j07HIxmDjZpbNvBJkMfvwXj5ACRkkHwBDvLBbDbtX5TdU64/rcvKJ/vuInQ==} + '@typescript-eslint/visitor-keys@8.35.1': + resolution: {integrity: sha512-VRwixir4zBWCSTP/ljEo091lbpypz57PoeAQ9imjG+vbeof9LplljsL1mos4ccG6H9IjfrVGM359RozUnuFhpw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@unocss/astro@66.0.0': - resolution: {integrity: sha512-GBhXT6JPqXjDXoJZTXhySk83NgOt0UigChqrUUdG4x7Z+DVYkDBION8vZUJjw0OdIaxNQ4euGWu4GDsMF6gQQg==} + '@unocss/astro@66.3.2': + resolution: {integrity: sha512-O3cmQyAQsSqRSI3CkDpm3to4CrkYPyxrO7XHO0QpfTl2XcFoYsVNTAHnIKdxPG9gjZcB7x03gpRMZKjQHreihA==} peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 peerDependenciesMeta: vite: optional: true - '@unocss/cli@66.0.0': - resolution: {integrity: sha512-KVQiskoOjVkLVpNaG6WpLa4grPplrZROYZJVIUYSTqZyZRFNSvjttHcsCwpoWUEUdEombPtVZl8FrXePjY5IiQ==} + '@unocss/cli@66.3.2': + resolution: {integrity: sha512-nwHZz7FN1/VAK3jIWiDShscs6ru7ovXzzg5IxRJFPM5ZjEq/93ToBP7eSnhlJ6opEINLat/Qq0w/w+YNRLOpEg==} engines: {node: '>=14'} hasBin: true - '@unocss/config@66.0.0': - resolution: {integrity: sha512-nFRGop/guBa4jLkrgXjaRDm5JPz4x3YpP10m5IQkHpHwlnHUVn1L9smyPl04ohYWhYn9ZcAHgR28Ih2jwta8hw==} + '@unocss/config@66.3.2': + resolution: {integrity: sha512-G/kkFPhYjzCWa19jLhOhJ/yLL3JDt/kWJCmc5Z532/oNT1kzh9YJjAbprflVsAUEsIXyqm6WAmd26JD+KQKTWQ==} engines: {node: '>=14'} - '@unocss/core@66.0.0': - resolution: {integrity: sha512-PdVbSMHNDDkr++9nkqzsZRAkaU84gxMTEgYbqI7dt2p1DXp/5tomVtmMsr2/whXGYKRiUc0xZ3p4Pzraz8TcXA==} + '@unocss/core@66.3.2': + resolution: {integrity: sha512-C8UbTenNb/pHo68Ob+G1DTKJkQOeWT8IXTzDV7Vq6hPa9R7eE1l2l20pDKGs6gXYEBYPpY9EV4f5E0vUKDf8sw==} - '@unocss/extractor-arbitrary-variants@66.0.0': - resolution: {integrity: sha512-vlkOIOuwBfaFBJcN6o7+obXjigjOlzVFN/jT6pG1WXbQDTRZ021jeF3i9INdb9D/0cQHSeDvNgi1TJ5oUxfiow==} + '@unocss/extractor-arbitrary-variants@66.3.2': + resolution: {integrity: sha512-D3R4GR6yGy/XlVz1lQldFZqvxdsmIhRCHLCXV3Oeg9nR93BgE9gBiPs17qK8Wuw+i5xXVstGQXftmsoSPSA23Q==} - '@unocss/inspector@66.0.0': - resolution: {integrity: sha512-mkIxieVm0kMOKw+E4ABpIerihYMdjgq9A92RD5h2+W/ebpxTEw5lTTK1xcMLiAlmOrVYMQKjpgPeu3vQmDyGZQ==} + '@unocss/inspector@66.3.2': + resolution: {integrity: sha512-zlMMZovXZ4wSigB+M7egn84OmH+2q5jHYvrsmpLI3DgCXqjKbX5UYI0QN1XZ4lW/i9mL2Za6CZqKYK/6auxP/g==} - '@unocss/postcss@66.0.0': - resolution: {integrity: sha512-6bi+ujzh8I1PJwtmHX71LH8z/H9+vPxeYD4XgFihyU1k4Y6MVhjr7giGjLX4yP27IP+NsVyotD22V7by/dBVEA==} + '@unocss/postcss@66.3.2': + resolution: {integrity: sha512-gbSlHhSezn4q2inEc5lPvz4upsAiewHyWS3k1o5ZH2Y7w/0jJxfIPYsjs8q5eFB3rkicdWWoGwd8HzuSXOrB/w==} engines: {node: '>=14'} peerDependencies: postcss: ^8.4.21 - '@unocss/preset-attributify@66.0.0': - resolution: {integrity: sha512-eYsOgmcDoiIgGAepIwRX+DKGYxc/wm0r4JnDuZdz29AB+A6oY/FGHS1BVt4rq9ny4B5PofP4p6Rty+vwD9rigw==} + '@unocss/preset-attributify@66.3.2': + resolution: {integrity: sha512-ODKaW4x2ZfaHsOgNsSNUbdM0Ifk89K3FZQgleOvlNJx60iHeCE+X1u24FpyFKQ81DgK2Kcwuv/HOg7rrA0n16w==} - '@unocss/preset-icons@66.0.0': - resolution: {integrity: sha512-6ObwTvEGuPBbKWRoMMiDioHtwwQTFI5oojFLJ32Y8tW6TdXvBLkO88d7qpgQxEjgVt4nJrqF1WEfR4niRgBm0Q==} + '@unocss/preset-icons@66.3.2': + resolution: {integrity: sha512-E72sTaLjmIPExM0d32MMvjp040BP9xJ/xbpL/J4LqTMebo6PYE+is2+SmLkENrN7P3lSeDY3RI7iHyWLCoI/qw==} - '@unocss/preset-mini@66.0.0': - resolution: {integrity: sha512-d62eACnuKtR0dwCFOQXgvw5VLh5YSyK56xCzpHkh0j0GstgfDLfKTys0T/XVAAvdSvAy/8A8vhSNJ4PlIc9V2A==} + '@unocss/preset-mini@66.3.2': + resolution: {integrity: sha512-9jaJ3Kk7qTUHY84PIUU53yl1BaFYnoFYu22TGLqd9bV6/OihsZ454sTRmpkjXFWGPWENEv6vfs1BQANliMZGIA==} - '@unocss/preset-tagify@66.0.0': - resolution: {integrity: sha512-GGYGyWxaevh0jN0NoATVO1Qe7DFXM3ykLxchlXmG6/zy963pZxItg/njrKnxE9la4seCdxpFH7wQBa68imwwdA==} + '@unocss/preset-tagify@66.3.2': + resolution: {integrity: sha512-6nGSu6EE0s3HI0Ni+AZDGFhcKrz5Q0Ic+t6fS2+x1ZFgGQfHs5UVvSzr8W2pfLFJ5WUWZ0PLdIrRj8aw1X8x3A==} - '@unocss/preset-typography@66.0.0': - resolution: {integrity: sha512-apjckP5nPU5mtaHTCzz5u/dK9KJWwJ2kOFCVk0+a/KhUWmnqnzmjRYZlEuWxxr5QxTdCW+9cIoRDSA0lYZS5tg==} + '@unocss/preset-typography@66.3.2': + resolution: {integrity: sha512-h6prtgy6lyl7QXsVRJXVF7B7HR+E0v6qCjBN2AsT1zjHPAwqiUJibmHryRNZllh/lxLIR2D7atK1Ftnrx4BSeg==} - '@unocss/preset-uno@66.0.0': - resolution: {integrity: sha512-qgoZ/hzTI32bQvcyjcwvv1X/dbPlmQNehzgjUaL7QFT0q0/CN/SRpysfzoQ8DLl2se9T+YCOS9POx3KrpIiYSQ==} + '@unocss/preset-uno@66.3.2': + resolution: {integrity: sha512-PisryQfY2VwaA3Pj2OTZX4bb1wbqpQdZ4CmQjGkU040SK+qWObEAUMF2NdMwt2agFimDR9bJVZSVIUDMzlZa0A==} - '@unocss/preset-web-fonts@66.0.0': - resolution: {integrity: sha512-9MzfDc6AJILN4Kq7Z91FfFbizBOYgw3lJd2UwqIs3PDYWG5iH5Zv5zhx6jelZVqEW5uWcIARYEEg2m4stZO1ZA==} + '@unocss/preset-web-fonts@66.3.2': + resolution: {integrity: sha512-Mn0DP21qeZlUsucdw1gDsuPU+h8NBbsmDoYsy5Aq5SBHNdBCcWqv8+O3H1KrzVEcPnYsGULwlwe5oNWbgHdBgQ==} - '@unocss/preset-wind3@66.0.0': - resolution: {integrity: sha512-WAGRmpi1sb2skvYn9DBQUvhfqrJ+VmQmn5ZGsT2ewvsk7HFCvVLAMzZeKrrTQepeNBRhg6HzFDDi8yg6yB5c9g==} + '@unocss/preset-wind3@66.3.2': + resolution: {integrity: sha512-OrZdbiEGIzo4Cg/65SHCnZLRXlPe6DnlVRsQJqyPJK7gGWuLZYK1ysp06vmgrVsFdIbaGs65olml1mHygsAklw==} - '@unocss/preset-wind@66.0.0': - resolution: {integrity: sha512-FtvGpHnGC7FiyKJavPnn5y9lsaoWRhXlujCqlT5Bw63kKhMNr0ogKySBpenUhJOhWhVM0OQXn2nZ3GZRxW2qpw==} + '@unocss/preset-wind4@66.3.2': + resolution: {integrity: sha512-/MNCHUAe+Guwz3oO8X8o2N6YTSKsA7feiLD0WKusFoCgWLZwVLX0ZrX3n2U4z1EhGrcjlGOj0WSOQMf/W2vHcQ==} - '@unocss/reset@66.0.0': - resolution: {integrity: sha512-YLFz/5yT7mFJC8JSmIUA5+bS3CBCJbtztOw+8rWzjQr/BEVSGuihWUUpI2Df6VVxXIXxKanZR6mIl59yvf+GEA==} + '@unocss/preset-wind@66.3.2': + resolution: {integrity: sha512-+CFabjgL6IswEIayeFsogr9I+kPtHQNYsQutzZSdzcYw+0HPM0SdwzVYhDQFIqf554dEyK/EGXcJTKWv32Lm3A==} - '@unocss/rule-utils@66.0.0': - resolution: {integrity: sha512-UJ51YHbwxYTGyj35ugsPlOT4gaa7tCbXdywZ3m5Nn0JgywwIqGmBFyiN9ZjHBHfJuDxmmPd6lxojoBscih/WMQ==} + '@unocss/reset@66.3.2': + resolution: {integrity: sha512-3Q6ND9ifUGXgY0+bkFNjYXhftIKCQYIsaeHKjfTjhuZukB8SSmnl7Vo9hn0rDeFGF+3mAo6PVv3/uJbJGQ2+IA==} + + '@unocss/rule-utils@66.3.2': + resolution: {integrity: sha512-zdKhZdRsU0iB+6ba1xX5YOJVI2UqwrvffAalONRSal2VUYpZxCFCvJhyt5bbneIOBQ6pQMVgi7UVEqQ6Y7A5kQ==} engines: {node: '>=14'} - '@unocss/transformer-attributify-jsx@66.0.0': - resolution: {integrity: sha512-jS7szFXXC6RjTv9wo0NACskf618w981bkbyQ5izRO7Ha47sNpHhHDpaltnG7SR9qV4cCtGalOw4onVMHsRKwRg==} + '@unocss/transformer-attributify-jsx@66.3.2': + resolution: {integrity: sha512-v8i1hYbYw7DhrT0WeHPhbnpSyQMltdMT3OsF2Zkq5+MEkYoSok+xykArzGl8Lxz6BsbFK3yAFWMRVpvlCB6apQ==} - '@unocss/transformer-compile-class@66.0.0': - resolution: {integrity: sha512-ytUIE0nAcHRMACuTXkHp8auZ483DXrOZw99jk3FJ+aFjpD/pVSFmX14AWJ7bqPFObxb4SLFs6KhQma30ESC22A==} + '@unocss/transformer-compile-class@66.3.2': + resolution: {integrity: sha512-2GBmUByGi1nACPEh0cLsd+95rqt29RwZSW4d9kzZfeyJqEPyD0oH9ufvHUXwtiIsaQpDCDgdNSLaNQ1xNMpe8A==} - '@unocss/transformer-directives@66.0.0': - resolution: {integrity: sha512-utcg7m2Foi7uHrU5WHadNuJ0a3qWG8tZNkQMi+m0DQpX6KWfuDtDn0zDZ1X+z5lmiB3WGSJERRrsvZbj1q50Mw==} + '@unocss/transformer-directives@66.3.2': + resolution: {integrity: sha512-ihyznSsftQ3S4BnqI4kNoB6+JRDk773xjZjRHSWrOPQ/bBkKqVjkijxIg5fJWgkIzk1lKcrYn/s6amD9/Pt3pw==} - '@unocss/transformer-variant-group@66.0.0': - resolution: {integrity: sha512-1BLjNWtAnR1JAcQGw0TS+nGrVoB9aznzvVZRoTx23dtRr3btvgKPHb8LrD48eD/p8Dtw9j3WfuxMDKXKegKDLg==} + '@unocss/transformer-variant-group@66.3.2': + resolution: {integrity: sha512-LW9Nim8DjzdYYao6IS17On2vW3u/QjSylvMdAqi6XlJ2lHEulN1YatSX74pGOyyQ7jh8WSXE0xqsw3uxkY48tA==} - '@unocss/vite@66.0.0': - resolution: {integrity: sha512-IVcPX8xL+2edyXKt4tp9yu5A6gcbPVCsspfcL0XgziCr01kS+4qSoZ90F3IUs3hXc/AyO5eCpRtGFMPLpOjXQg==} + '@unocss/vite@66.3.2': + resolution: {integrity: sha512-m1et66BVSbaLcoHJy6dt0esEnLZnBDO0pdXIXJH+oqCmjjDdKquPXdCa1lei90sjeS+VnO59c5b/Nz5EwZPRYQ==} peerDependencies: - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 - - '@unrs/rspack-resolver-binding-darwin-arm64@1.2.2': - resolution: {integrity: sha512-i7z0B+C0P8Q63O/5PXJAzeFtA1ttY3OR2VSJgGv18S+PFNwD98xHgAgPOT1H5HIV6jlQP8Avzbp09qxJUdpPNw==} - cpu: [arm64] - os: [darwin] - - '@unrs/rspack-resolver-binding-darwin-x64@1.2.2': - resolution: {integrity: sha512-YEdFzPjIbDUCfmehC6eS+AdJYtFWY35YYgWUnqqTM2oe/N58GhNy5yRllxYhxwJ9GcfHoNc6Ubze1yjkNv+9Qg==} - cpu: [x64] - os: [darwin] - - '@unrs/rspack-resolver-binding-freebsd-x64@1.2.2': - resolution: {integrity: sha512-TU4ntNXDgPN2giQyyzSnGWf/dVCem5lvwxg0XYvsvz35h5H19WrhTmHgbrULMuypCB3aHe1enYUC9rPLDw45mA==} - cpu: [x64] - os: [freebsd] - - '@unrs/rspack-resolver-binding-linux-arm-gnueabihf@1.2.2': - resolution: {integrity: sha512-ik3w4/rU6RujBvNWiDnKdXi1smBhqxEDhccNi/j2rHaMjm0Fk49KkJ6XKsoUnD2kZ5xaMJf9JjailW/okfUPIw==} - cpu: [arm] - os: [linux] - - '@unrs/rspack-resolver-binding-linux-arm64-gnu@1.2.2': - resolution: {integrity: sha512-fp4Azi8kHz6TX8SFmKfyScZrMLfp++uRm2srpqRjsRZIIBzH74NtSkdEUHImR4G7f7XJ+sVZjCc6KDDK04YEpQ==} - cpu: [arm64] - os: [linux] - - '@unrs/rspack-resolver-binding-linux-arm64-musl@1.2.2': - resolution: {integrity: sha512-gMiG3DCFioJxdGBzhlL86KcFgt9HGz0iDhw0YVYPsShItpN5pqIkNrI+L/Q/0gfDiGrfcE0X3VANSYIPmqEAlQ==} - cpu: [arm64] - os: [linux] - - '@unrs/rspack-resolver-binding-linux-x64-gnu@1.2.2': - resolution: {integrity: sha512-n/4n2CxaUF9tcaJxEaZm+lqvaw2gflfWQ1R9I7WQgYkKEKbRKbpG/R3hopYdUmLSRI4xaW1Cy0Bz40eS2Yi4Sw==} - cpu: [x64] - os: [linux] - - '@unrs/rspack-resolver-binding-linux-x64-musl@1.2.2': - resolution: {integrity: sha512-cHyhAr6rlYYbon1L2Ag449YCj3p6XMfcYTP0AQX+KkQo025d1y/VFtPWvjMhuEsE2lLvtHm7GdJozj6BOMtzVg==} - cpu: [x64] - os: [linux] - - '@unrs/rspack-resolver-binding-wasm32-wasi@1.2.2': - resolution: {integrity: sha512-eogDKuICghDLGc32FtP+WniG38IB1RcGOGz0G3z8406dUdjJvxfHGuGs/dSlM9YEp/v0lEqhJ4mBu6X2nL9pog==} - engines: {node: '>=14.0.0'} - cpu: [wasm32] + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 - '@unrs/rspack-resolver-binding-win32-arm64-msvc@1.2.2': - resolution: {integrity: sha512-7sWRJumhpXSi2lccX8aQpfFXHsSVASdWndLv8AmD8nDRA/5PBi8IplQVZNx2mYRx6+Bp91Z00kuVqpXO9NfCTg==} - cpu: [arm64] - os: [win32] - - '@unrs/rspack-resolver-binding-win32-x64-msvc@1.2.2': - resolution: {integrity: sha512-hewo/UMGP1a7O6FG/ThcPzSJdm/WwrYDNkdGgWl6M18H6K6MSitklomWpT9MUtT5KGj++QJb06va/14QBC4pvw==} - cpu: [x64] - os: [win32] + '@uozi-admin/curd@4.3.12': + resolution: {integrity: sha512-UoBGCvbim8ETuHrW0vaXAx7rL/4Y7C8DWQ62aoInohL4KWh8Se34uAKOWtpzh2cs9cBctCVfoSiHDEqAnUC95A==} + hasBin: true + peerDependencies: + '@ant-design/icons-vue': '>=7.0.1' + ant-design-vue: '>=4.2.6' + dayjs: '>=1.11.13' + lodash-es: '>=4.17.21' + vue: '>=3.5.16' + vue-router: '>=4.5.1' + + '@uozi-admin/request@2.8.1': + resolution: {integrity: sha512-zyXQkK/VxmtzObMtIlccEX657EQKVPVxIuUbElZ4DGBzdEU+c6aoy7wcF3FUgB2S9h1IvrpN4xxvQZwpOSLKWw==} + peerDependencies: + lodash-es: '>=4.17.21' - '@vitejs/plugin-vue-jsx@4.1.2': - resolution: {integrity: sha512-4Rk0GdE0QCdsIkuMmWeg11gmM4x8UmTnZR/LWPm7QJ7+BsK4tq08udrN0isrrWqz5heFy9HLV/7bOLgFS8hUjA==} - engines: {node: ^18.0.0 || >=20.0.0} + '@vitejs/plugin-vue-jsx@5.0.1': + resolution: {integrity: sha512-X7qmQMXbdDh+sfHUttXokPD0cjPkMFoae7SgbkF9vi3idGUKmxLcnU2Ug49FHwiKXebfzQRIm5yK3sfCJzNBbg==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^5.0.0 || ^6.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.0.0 - '@vitejs/plugin-vue@5.2.3': - resolution: {integrity: sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==} - engines: {node: ^18.0.0 || >=20.0.0} + '@vitejs/plugin-vue@6.0.0': + resolution: {integrity: sha512-iAliE72WsdhjzTOp2DtvKThq1VBC4REhwRcaA+zPAAph6I+OQhUXv+Xu2KS7ElxYtb7Zc/3R30Hwv1DxEo7NXQ==} + engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: - vite: ^5.0.0 || ^6.0.0 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 vue: ^3.2.25 - '@vitest/eslint-plugin@1.1.38': - resolution: {integrity: sha512-KcOTZyVz8RiM5HyriiDVrP1CyBGuhRxle+lBsmSs6NTJEO/8dKVAq+f5vQzHj1/Kc7bYXSDO6yBe62Zx0t5iaw==} + '@vitest/eslint-plugin@1.3.4': + resolution: {integrity: sha512-EOg8d0jn3BAiKnR55WkFxmxfWA3nmzrbIIuOXyTe6A72duryNgyU+bdBEauA97Aab3ho9kLmAwgPX63Ckj4QEg==} peerDependencies: - '@typescript-eslint/utils': ^8.24.0 eslint: '>= 8.57.0' typescript: '>= 5.0.0' vitest: '*' @@ -1387,14 +1282,14 @@ packages: vitest: optional: true - '@volar/language-core@2.4.11': - resolution: {integrity: sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==} + '@volar/language-core@2.4.17': + resolution: {integrity: sha512-chmRZMbKmcGpKMoO7Reb70uiLrzo0KWC2CkFttKUuKvrE+VYgi+fL9vWMJ07Fv5ulX0V1TAyyacN9q3nc5/ecA==} - '@volar/source-map@2.4.11': - resolution: {integrity: sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==} + '@volar/source-map@2.4.17': + resolution: {integrity: sha512-QDybtQyO3Ms/NjFqNHTC5tbDN2oK5VH7ZaKrcubtfHBDj63n2pizHC3wlMQ+iT55kQXZUUAbmBX5L1C8CHFeBw==} - '@volar/typescript@2.4.11': - resolution: {integrity: sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==} + '@volar/typescript@2.4.17': + resolution: {integrity: sha512-3paEFNh4P5DkgNUB2YkTRrfUekN4brAXxd3Ow1syMqdIPtCZHbUy4AW99S5RO/7mzyTWPMdDSo3mqTpB/LPObQ==} '@vue-macros/common@1.16.1': resolution: {integrity: sha512-Pn/AWMTjoMYuquepLZP813BIcq8DTZiNCoaceuNlvaYuOTd8DqBZWc5u0uOMQZMInwME1mdSmmBAcTluiV9Jtg==} @@ -1405,33 +1300,33 @@ packages: vue: optional: true - '@vue/babel-helper-vue-transform-on@1.2.5': - resolution: {integrity: sha512-lOz4t39ZdmU4DJAa2hwPYmKc8EsuGa2U0L9KaZaOJUt0UwQNjNA3AZTq6uEivhOKhhG1Wvy96SvYBoFmCg3uuw==} + '@vue/babel-helper-vue-transform-on@1.4.0': + resolution: {integrity: sha512-mCokbouEQ/ocRce/FpKCRItGo+013tHg7tixg3DUNS+6bmIchPt66012kBMm476vyEIJPafrvOf4E5OYj3shSw==} - '@vue/babel-plugin-jsx@1.2.5': - resolution: {integrity: sha512-zTrNmOd4939H9KsRIGmmzn3q2zvv1mjxkYZHgqHZgDrXz5B1Q3WyGEjO2f+JrmKghvl1JIRcvo63LgM1kH5zFg==} + '@vue/babel-plugin-jsx@1.4.0': + resolution: {integrity: sha512-9zAHmwgMWlaN6qRKdrg1uKsBKHvnUU+Py+MOCTuYZBoZsopa90Di10QRjB+YPnVss0BZbG/H5XFwJY1fTxJWhA==} peerDependencies: '@babel/core': ^7.0.0-0 peerDependenciesMeta: '@babel/core': optional: true - '@vue/babel-plugin-resolve-type@1.2.5': - resolution: {integrity: sha512-U/ibkQrf5sx0XXRnUZD1mo5F7PkpKyTbfXM3a3rC4YnUz6crHEz9Jg09jzzL6QYlXNto/9CePdOg/c87O4Nlfg==} + '@vue/babel-plugin-resolve-type@1.4.0': + resolution: {integrity: sha512-4xqDRRbQQEWHQyjlYSgZsWj44KfiF6D+ktCuXyZ8EnVDYV3pztmXJDf1HveAjUAXxAnR8daCQT51RneWWxtTyQ==} peerDependencies: '@babel/core': ^7.0.0-0 - '@vue/compiler-core@3.5.13': - resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + '@vue/compiler-core@3.5.17': + resolution: {integrity: sha512-Xe+AittLbAyV0pabcN7cP7/BenRBNcteM4aSDCtRvGw0d9OL+HG1u/XHLY/kt1q4fyMeZYXyIYrsHuPSiDPosA==} - '@vue/compiler-dom@3.5.13': - resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + '@vue/compiler-dom@3.5.17': + resolution: {integrity: sha512-+2UgfLKoaNLhgfhV5Ihnk6wB4ljyW1/7wUIog2puUqajiC29Lp5R/IKDdkebh9jTbTogTbsgB+OY9cEWzG95JQ==} - '@vue/compiler-sfc@3.5.13': - resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + '@vue/compiler-sfc@3.5.17': + resolution: {integrity: sha512-rQQxbRJMgTqwRugtjw0cnyQv9cP4/4BxWfTdRBkqsTfLOHWykLzbOc3C4GGzAmdMDxhzU/1Ija5bTjMVrddqww==} - '@vue/compiler-ssr@3.5.13': - resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + '@vue/compiler-ssr@3.5.17': + resolution: {integrity: sha512-hkDbA0Q20ZzGgpj5uZjb9rBzQtIHLS78mMilwrlpWk2Ep37DYntUz0PonQ6kr113vfOEdM+zTBuJDaceNIW0tQ==} '@vue/compiler-vue2@2.7.16': resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} @@ -1439,39 +1334,39 @@ packages: '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} - '@vue/devtools-api@7.7.2': - resolution: {integrity: sha512-1syn558KhyN+chO5SjlZIwJ8bV/bQ1nOVTG66t2RbG66ZGekyiYNmRO7X9BJCXQqPsFHlnksqvPhce2qpzxFnA==} + '@vue/devtools-api@7.7.7': + resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==} - '@vue/devtools-kit@7.7.2': - resolution: {integrity: sha512-CY0I1JH3Z8PECbn6k3TqM1Bk9ASWxeMtTCvZr7vb+CHi+X/QwQm5F1/fPagraamKMAHVfuuCbdcnNg1A4CYVWQ==} + '@vue/devtools-kit@7.7.7': + resolution: {integrity: sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==} - '@vue/devtools-shared@7.7.2': - resolution: {integrity: sha512-uBFxnp8gwW2vD6FrJB8JZLUzVb6PNRG0B0jBnHsOH8uKyva2qINY8PTF5Te4QlTbMDqU5K6qtJDr6cNsKWhbOA==} + '@vue/devtools-shared@7.7.7': + resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==} - '@vue/language-core@2.2.8': - resolution: {integrity: sha512-rrzB0wPGBvcwaSNRriVWdNAbHQWSf0NlGqgKHK5mEkXpefjUlVRP62u03KvwZpvKVjRnBIQ/Lwre+Mx9N6juUQ==} + '@vue/language-core@3.0.1': + resolution: {integrity: sha512-sq+/Mc1IqIexWEQ+Q2XPiDb5SxSvY5JPqHnMOl/PlF5BekslzduX8dglSkpC17VeiAQB6dpS+4aiwNLJRduCNw==} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true - '@vue/reactivity@3.5.13': - resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + '@vue/reactivity@3.5.17': + resolution: {integrity: sha512-l/rmw2STIscWi7SNJp708FK4Kofs97zc/5aEPQh4bOsReD/8ICuBcEmS7KGwDj5ODQLYWVN2lNibKJL1z5b+Lw==} - '@vue/runtime-core@3.5.13': - resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + '@vue/runtime-core@3.5.17': + resolution: {integrity: sha512-QQLXa20dHg1R0ri4bjKeGFKEkJA7MMBxrKo2G+gJikmumRS7PTD4BOU9FKrDQWMKowz7frJJGqBffYMgQYS96Q==} - '@vue/runtime-dom@3.5.13': - resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + '@vue/runtime-dom@3.5.17': + resolution: {integrity: sha512-8El0M60TcwZ1QMz4/os2MdlQECgGoVHPuLnQBU3m9h3gdNRW9xRmI8iLS4t/22OQlOE6aJvNNlBiCzPHur4H9g==} - '@vue/server-renderer@3.5.13': - resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + '@vue/server-renderer@3.5.17': + resolution: {integrity: sha512-BOHhm8HalujY6lmC3DbqF6uXN/K00uWiEeF22LfEsm9Q93XeJ/plHTepGwf6tqFcF7GA5oGSSAAUock3VvzaCA==} peerDependencies: - vue: 3.5.13 + vue: 3.5.17 - '@vue/shared@3.5.13': - resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + '@vue/shared@3.5.17': + resolution: {integrity: sha512-CabR+UN630VnsJO/jHWYBC1YVXyMq94KKp6iF5MQgZJs5I8cmjw6oVMO1oDbtBkENSHSSn/UadWlW/OAgdmKrg==} '@vue/tsconfig@0.7.0': resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==} @@ -1484,18 +1379,18 @@ packages: vue: optional: true - '@vueuse/components@13.0.0': - resolution: {integrity: sha512-rcGp3c5Yu4SVLGUhBXT0q227nduFx1HTKzJBQkPLpIhwG1SB8RZ5bbri9sbusGaFZB5CYc6jza5+gfSJ7YidIg==} + '@vueuse/components@13.5.0': + resolution: {integrity: sha512-bU/FJNQMCxzDFp67YuxFQSV9CptHxZIgtExjFgJU8AE/gRRJMzGfPjNm+HvaVnMRl8IFFv4E+6JQV0kDu4zIpw==} peerDependencies: vue: ^3.5.0 - '@vueuse/core@13.0.0': - resolution: {integrity: sha512-rkgb4a8/0b234lMGCT29WkCjPfsX0oxrIRR7FDndRoW3FsaC9NBzefXg/9TLhAgwM11f49XnutshM4LzJBrQ5g==} + '@vueuse/core@13.5.0': + resolution: {integrity: sha512-wV7z0eUpifKmvmN78UBZX8T7lMW53Nrk6JP5+6hbzrB9+cJ3jr//hUlhl9TZO/03bUkMK6gGkQpqOPWoabr72g==} peerDependencies: vue: ^3.5.0 - '@vueuse/integrations@13.0.0': - resolution: {integrity: sha512-PXARslYRWf4u0xjdW6N5eC5kVQj2z/dxfZ7ildI1okLm2AwmhL+wiWzaNMSJMxTKX4ew7kNe70yJg1QjnWmE5w==} + '@vueuse/integrations@13.5.0': + resolution: {integrity: sha512-7RACJySnlpl0MkSzxbtadioNGSX4TL5/Wl2cUy4nDq/XkeHwPYvVM880HJUSiap/FXhVEup9VKTM9y/n5UspAw==} peerDependencies: async-validator: ^4 axios: ^1 @@ -1508,7 +1403,7 @@ packages: nprogress: ^0.2 qrcode: ^1.5 sortablejs: ^1 - universal-cookie: ^7 + universal-cookie: ^7 || ^8 vue: ^3.5.0 peerDependenciesMeta: async-validator: @@ -1536,11 +1431,11 @@ packages: universal-cookie: optional: true - '@vueuse/metadata@13.0.0': - resolution: {integrity: sha512-TRNksqmvtvqsuHf7bbgH9OSXEV2b6+M3BSN4LR5oxWKykOFT9gV78+C2/0++Pq9KCp9KQ1OQDPvGlWNQpOb2Mw==} + '@vueuse/metadata@13.5.0': + resolution: {integrity: sha512-euhItU3b0SqXxSy8u1XHxUCdQ8M++bsRs+TYhOLDU/OykS7KvJnyIFfep0XM5WjIFry9uAPlVSjmVHiqeshmkw==} - '@vueuse/shared@13.0.0': - resolution: {integrity: sha512-9MiHhAPw+sqCF/RLo8V6HsjRqEdNEWVpDLm2WBRW2G/kSQjb8X901sozXpSCaeLG0f7TEfMrT4XNaA5m1ez7Dg==} + '@vueuse/shared@13.5.0': + resolution: {integrity: sha512-K7GrQIxJ/ANtucxIXbQlUHdB0TPA8c+q5i+zbrjxuhJCnJ9GtBg75sBSnvmLSxHKPg2Yo8w62PWksl9kwH0Q8g==} peerDependencies: vue: ^3.5.0 @@ -1560,29 +1455,24 @@ packages: '@yr/monotone-cubic-spline@1.0.3': resolution: {integrity: sha512-FQXkOta0XBSUPHndIKON2Y9JeQz5ZeMqLYZVVK93FliNBFm7LNMIZmY6FrMEB9XPcDbE2bekMbZD6kzDkxwYjA==} - ace-builds@1.39.1: - resolution: {integrity: sha512-HcJbBzx8qY66t9gZo/sQu7pi0wO/CFLdYn1LxQO1WQTfIkMfyc7LRnBpsp/oNCSSU/LL83jXHN1fqyOTuIhUjg==} + ace-builds@1.43.1: + resolution: {integrity: sha512-n9/n+zBhbbkEJjU0FJ4wWAZBDl5G8WYzg4+uIjSER/U3wSSSSVo52W4sco4Jryg11JAJvorExxMr3GDINqtjdA==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.14.0: - resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} - engines: {node: '>=0.4.0'} - hasBin: true - - acorn@8.14.1: - resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} engines: {node: '>=0.4.0'} hasBin: true ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - alien-signals@1.0.3: - resolution: {integrity: sha512-zQOh3wAYK5ujENxvBBR3CFGF/b6afaSzZ/c9yNhJ1ENrGHETvpUuKQsa93Qrclp0+PzTF93MaZ7scVp1uUozhA==} + alien-signals@2.0.5: + resolution: {integrity: sha512-PdJB6+06nUNAClInE3Dweq7/2xVAYM64vvvS1IHVHSJmgeOtEdrAGyp7Z2oJtYm0B342/Exd2NT0uMJaThcjLQ==} ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} @@ -1600,8 +1490,8 @@ packages: resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} engines: {node: '>=12'} - ansis@3.17.0: - resolution: {integrity: sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==} + ansis@4.1.0: + resolution: {integrity: sha512-BGcItUBWSMRgOCe+SVZJ+S7yTRG0eGt9cXAHev72yuGcY23hnLA7Bky5L/xLyPINoSN95geovfBkqoTlNZYa7w==} engines: {node: '>=14'} ant-design-vue@4.2.6: @@ -1614,8 +1504,8 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - apexcharts@4.5.0: - resolution: {integrity: sha512-E7ZkrVqPNBUWy/Rmg8DEIqHNBmElzICE/oxOX5Ekvs2ICQUOK/VkEkMH09JGJu+O/EA0NL31hxlmF+wrwrSLaQ==} + apexcharts@4.7.0: + resolution: {integrity: sha512-iZSrrBGvVlL+nt2B1NpqfDuBZ9jX61X9I2+XV0hlYXHtTwhwLTHDKGXjNXAgFBDLuvSYCB/rq2nPWVPRv2DrGA==} are-docs-informative@0.0.2: resolution: {integrity: sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==} @@ -1628,37 +1518,37 @@ packages: resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} engines: {node: '>=6'} - array-buffer-byte-length@1.0.1: - resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} engines: {node: '>= 0.4'} - array-includes@3.1.8: - resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} engines: {node: '>= 0.4'} array-tree-filter@2.1.0: resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==} - array.prototype.flat@1.3.2: - resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} engines: {node: '>= 0.4'} - arraybuffer.prototype.slice@1.0.3: - resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} engines: {node: '>= 0.4'} - ast-kit@1.3.2: - resolution: {integrity: sha512-gdvX700WVC6sHCJQ7bJGfDvtuKAh6Sa6weIZROxfzUZKP7BjvB8y0SMlM/o4omSQ3L60PQSJROBJsb0vEViVnA==} - engines: {node: '>=16.14.0'} - - ast-kit@1.4.0: - resolution: {integrity: sha512-BlGeOw73FDsX7z0eZE/wuuafxYoek2yzNJ6l6A1nsb4+z/p87TOPbHaWuN53kFKNuUXiCQa2M+xLF71IqQmRSw==} + ast-kit@1.4.3: + resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==} engines: {node: '>=16.14.0'} ast-walker-scope@0.6.2: resolution: {integrity: sha512-1UWOyC50xI3QZkRuDj6PqDtpm1oHWtYs+NQGwqL/2R11eN3Q81PHAHPM0SWW3BNQm53UDwS//Jv8L4CCVLM1bQ==} engines: {node: '>=16.14.0'} + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + async-lock@1.4.1: resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} @@ -1679,8 +1569,8 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} - axios@1.8.4: - resolution: {integrity: sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==} + axios@1.10.0: + resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==} balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1689,24 +1579,24 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - birpc@0.2.19: - resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==} + birpc@2.4.0: + resolution: {integrity: sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==} boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - brace-expansion@1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} - brace-expansion@2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + brace-expansion@2.0.2: + resolution: {integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + browserslist@4.25.1: + resolution: {integrity: sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -1717,16 +1607,20 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} - builtin-modules@4.0.0: - resolution: {integrity: sha512-p1n8zyCkt1BVrKNFymOHjcDSAl7oq/gUvfgULv2EblgpPVQlQr9yHnWjg9IJ2MhfwPqiYqMMrr01OY7yQoK2yA==} + builtin-modules@5.0.0: + resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} engines: {node: '>=18.20'} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - c12@2.0.1: - resolution: {integrity: sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==} + c12@3.0.4: + resolution: {integrity: sha512-t5FaZTYbbCtvxuZq9xxIruYydrAGsJ+8UdP0pZzMiK2xl/gNiSOy0OxhLzHUEEb0m1QXYqfzfvyIFEmz/g9lqg==} peerDependencies: magicast: ^0.3.5 peerDependenciesMeta: @@ -1737,24 +1631,24 @@ packages: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} - call-bind-apply-helpers@1.0.1: - resolution: {integrity: sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==} + call-bind-apply-helpers@1.0.2: + 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.2: - resolution: {integrity: sha512-0lk0PHFe/uz0vl527fG9CgdE9WdafjDbCXvBbs+LUv000TVt2Jjhqbs4Jwm8gz070w8xXyEAxrPOMullsxXeGg==} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001704: - resolution: {integrity: sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==} + caniuse-lite@1.0.30001726: + resolution: {integrity: sha512-VQAUIUzBiZ/UnlM28fSp2CRF3ivUn1BWEvxMcVTNwpw91Py1pGbPIyIKtd+tzct9C3ouceCVdGAXxZOpZAsgdw==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1777,16 +1671,16 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} - chokidar@4.0.1: - resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} - ci-info@4.1.0: - resolution: {integrity: sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==} + ci-info@4.2.0: + resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==} engines: {node: '>=8'} citty@0.1.6: @@ -1825,27 +1719,23 @@ packages: resolution: {integrity: sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==} engines: {node: '>= 12.0.0'} - compatx@0.1.8: - resolution: {integrity: sha512-jcbsEAR81Bt5s1qOFymBufmCbXCXbk0Ql+K5ouj6gCyx2yHlu6AgmGIi9HxfKixpUDO5bCFJUHQ5uM6ecbTebw==} - compute-scroll-into-view@1.0.20: resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==} + compute-scroll-into-view@3.1.1: + resolution: {integrity: sha512-VRhuHOLoKYOy4UbilLbUzbYg93XLjv2PncJC50EuTWPA3gaja1UjBsUP/D/9/juV3vQFr6XBEzn9KCAHdUvOHw==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} confbox@0.1.8: resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} - confbox@0.2.1: - resolution: {integrity: sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==} - - consola@3.2.3: - resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} - engines: {node: ^14.18.0 || >=16.10.0} + confbox@0.2.2: + resolution: {integrity: sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==} - consola@3.4.0: - resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} engines: {node: ^14.18.0 || >=16.10.0} convert-source-map@2.0.0: @@ -1862,11 +1752,11 @@ packages: resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} engines: {node: '>=12.13'} - core-js-compat@3.40.0: - resolution: {integrity: sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==} + core-js-compat@3.43.0: + resolution: {integrity: sha512-2GML2ZsCc5LR7hZYz4AXmjQw8zuy2T//2QntwdnpuYI7jteT6GVYJL7F6C2C57R7gSYrcqVW3lAALefdbhBLDA==} - core-js@3.39.0: - resolution: {integrity: sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g==} + core-js@3.43.0: + resolution: {integrity: sha512-N6wEbTTZSYOY2rYAn85CuvWWkCK6QweMn7/4Nr3w+gDBeBhk/x4EJeY6FPo4QzDoJZxVTv8U7CMvgWk6pOHHqA==} cosmiconfig@9.0.0: resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} @@ -1886,8 +1776,8 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - css-select@5.1.0: - resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} css-selector-parser@1.4.1: resolution: {integrity: sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==} @@ -1904,8 +1794,8 @@ packages: resolution: {integrity: sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} - css-what@6.1.0: - resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} engines: {node: '>= 6'} cssesc@3.0.0: @@ -1920,16 +1810,16 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - data-view-buffer@1.0.1: - resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} engines: {node: '>= 0.4'} - data-view-byte-length@1.0.1: - resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + 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.0: - resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} dayjs@1.11.13: @@ -1938,16 +1828,8 @@ packages: de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} - debug@3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + debug@4.4.1: + resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -1955,8 +1837,8 @@ packages: supports-color: optional: true - decode-named-character-reference@1.0.2: - resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + decode-named-character-reference@1.2.0: + resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} decompress-response@6.0.0: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} @@ -1968,10 +1850,22 @@ packages: deep-pick-omit@1.2.1: resolution: {integrity: sha512-2J6Kc/m3irCeqVG42T+SaUMesaK7oGWaedGnQQK/+O0gYc+2SP5bKh/KKTE7d7SJ+GCA9UUE1GRzh6oDe0EnGw==} + default-browser-id@5.0.0: + resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + engines: {node: '>=18'} + + default-browser@5.2.1: + resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + engines: {node: '>=18'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -1987,8 +1881,12 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - destr@2.0.3: - resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-libc@2.0.4: + resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + engines: {node: '>=8'} devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -1996,10 +1894,6 @@ packages: diff3@0.0.3: resolution: {integrity: sha512-iSq8ngPOt0K53A6eVr4d5Kn6GNrM2nQZtC740pzIriHtn4pOQ2lyzEXQMBeVcWERN0ye7fhBsk9PbLLQOnUx/g==} - doctrine@3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dom-align@1.12.4: resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==} @@ -2016,18 +1910,18 @@ packages: resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} engines: {node: '>= 4'} - dompurify@3.2.3: - resolution: {integrity: sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA==} + dompurify@3.2.6: + resolution: {integrity: sha512-/2GogDQlohXPZe6D6NOgQvXLPSYBqIWMnZ8zzOhn09REE4eyAzb+Hed3jhoM9OkuaJ8P6ZGTTVWQKAi8ieIzfQ==} - domutils@3.1.0: - resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} - dotenv@16.4.7: - resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} - dunder-proto@1.0.0: - resolution: {integrity: sha512-9+Sj30DIu+4KvHqMfLUGLFYL2PkURSYMVXJyXe92nFRvlYq5hBjLEhblKB+vkd/WVlUYMWigiY07T91Fkk0+4A==} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} duplexer@0.1.2: @@ -2036,8 +1930,8 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} - electron-to-chromium@1.5.73: - resolution: {integrity: sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==} + electron-to-chromium@1.5.178: + resolution: {integrity: sha512-wObbz/ar3Bc6e4X5vf0iO8xTN8YAjN/tgiAOJLr7yjYFtP9wAjq8Mb5h0yn6kResir+VYx2DXBj9NNobs0ETSA==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -2045,20 +1939,24 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - encoding-sniffer@0.2.0: - resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} + encoding-sniffer@0.2.1: + resolution: {integrity: sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==} - end-of-stream@1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.17.1: - resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + enhanced-resolve@5.18.2: + resolution: {integrity: sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==} engines: {node: '>=10.13.0'} entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + entities@6.0.1: + resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} + engines: {node: '>=0.12'} + env-paths@2.2.1: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} @@ -2070,8 +1968,14 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - es-abstract@1.23.5: - resolution: {integrity: sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==} + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + errx@0.1.0: + resolution: {integrity: sha512-fZmsRiDNv07K6s2KkKFTiD2aIvECa7++PKyD5NC32tpRw46qZA3sOz+aM+/V9V0GDHxVTKLziveV4JhzBHDp9Q==} + + es-abstract@1.24.0: + resolution: {integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==} engines: {node: '>= 0.4'} es-define-property@1.0.1: @@ -2082,19 +1986,17 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-module-lexer@1.5.4: - resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} - - es-object-atoms@1.0.0: - resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} engines: {node: '>= 0.4'} - es-set-tostringtag@2.0.3: - resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} engines: {node: '>= 0.4'} - es-shim-unscopables@1.0.2: - resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} es-to-primitive@1.3.0: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} @@ -2105,8 +2007,8 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.25.0: - resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} engines: {node: '>=18'} hasBin: true @@ -2132,8 +2034,8 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-compat-utils@0.6.4: - resolution: {integrity: sha512-/u+GQt8NMfXO8w17QendT4gvO5acfxQsAKirAt0LVxDnr2N8YLCVbregaNc/Yhp7NM128DwCaRvr8PLDfeNkQw==} + eslint-compat-utils@0.6.5: + resolution: {integrity: sha512-vAUHYzue4YAa2hNACjB8HvUQj5yehAZgiClyFVVom9cP8z5NSFq3PwB/TtJslN2zAMgRX6FCFCjYBbQh71g5RQ==} engines: {node: '>=12'} peerDependencies: eslint: '>=6.0.0' @@ -2143,11 +2045,8 @@ packages: peerDependencies: eslint: ^9.5.0 - eslint-flat-config-utils@2.0.1: - resolution: {integrity: sha512-brf0eAgQ6JlKj3bKfOTuuI7VcCZvi8ZCD1MMTVoEvS/d38j8cByZViLFALH/36+eqB17ukmfmKq3bWzGvizejA==} - - eslint-import-resolver-node@0.3.9: - resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + eslint-flat-config-utils@2.1.0: + resolution: {integrity: sha512-6fjOJ9tS0k28ketkUcQ+kKptB4dBZY2VijMZ9rGn8Cwnn1SH0cZBoPXT8AHBFHxmHcLFQK9zbELDinZ2Mr1rng==} eslint-json-compat-utils@0.2.1: resolution: {integrity: sha512-YzEodbDyW8DX8bImKhAcCeu/L31Dd/70Bidx2Qex9OFUtgzXLqtfWL4Hr5fM/aCCB8QUZLuJur0S9k6UfgFkfg==} @@ -2170,8 +2069,8 @@ packages: peerDependencies: eslint: '*' - eslint-plugin-command@3.2.0: - resolution: {integrity: sha512-PSDOB9k7Wd57pp4HD/l3C1D93pKX8/wQo0kWDI4q6/UpgrfMTyNsavklipgiZqbXl1+VBABY1buCcQE5LDpg5g==} + eslint-plugin-command@3.3.1: + resolution: {integrity: sha512-fBVTXQ2y48TVLT0+4A6PFINp7GcdIailHAXbvPBixE7x+YpYnNQhFZxTdvnb+aWk+COgNebQKen/7m4dmgyWAw==} peerDependencies: eslint: '*' @@ -2181,26 +2080,30 @@ packages: peerDependencies: eslint: '>=8' - eslint-plugin-import-x@4.9.1: - resolution: {integrity: sha512-YJ9W12tfDBBYVUUI5FVls6ZrzbVmfrHcQkjeHrG6I7QxWAlIbueRD+G4zPTg1FwlBouunTYm9dhJMVJZdj9wwQ==} + eslint-plugin-import-lite@0.3.0: + resolution: {integrity: sha512-dkNBAL6jcoCsXZsQ/Tt2yXmMDoNt5NaBh/U7yvccjiK8cai6Ay+MK77bMykmqQA2bTF6lngaLCDij6MTO3KkvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 + eslint: '>=9.0.0' + typescript: '>=4.5' + peerDependenciesMeta: + typescript: + optional: true - eslint-plugin-jsdoc@50.6.8: - resolution: {integrity: sha512-PPZVqhoXaalMQwDGzcQrJtPSPIPOYsSMtvkjYAdsIazOW20yhYtVX4+jLL+XznD4zYTXyZbPWPRKkNev4D4lyw==} - engines: {node: '>=18'} + eslint-plugin-jsdoc@51.3.2: + resolution: {integrity: sha512-sBmS2MoxbUuKE1wMn/jeHitlCwdk3jAkkpdo3TNA5qGADjiow9D5z/zJ3XScScDsNI2fzZJsmCyf5rc12oRbUA==} + engines: {node: '>=20.11.0'} peerDependencies: eslint: ^7.0.0 || ^8.0.0 || ^9.0.0 - eslint-plugin-jsonc@2.19.1: - resolution: {integrity: sha512-MmlAOaZK1+Lg7YoCZPGRjb88ZjT+ct/KTsvcsbZdBm+w8WMzGx+XEmexk0m40P1WV9G2rFV7X3klyRGRpFXEjA==} + eslint-plugin-jsonc@2.20.1: + resolution: {integrity: sha512-gUzIwQHXx7ZPypUoadcyRi4WbHW2TPixDr0kqQ4miuJBU0emJmyGTlnaT3Og9X2a8R1CDayN9BFSq5weGWbTng==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' - eslint-plugin-n@17.16.2: - resolution: {integrity: sha512-iQM5Oj+9o0KaeLoObJC/uxNGpktZCkYiTTBo8PkRWq3HwNcRxwpvSDFjBhQ5+HLJzBTy+CLDC5+bw0Z5GyhlOQ==} + eslint-plugin-n@17.20.0: + resolution: {integrity: sha512-IRSoatgB/NQJZG5EeTbv/iAx1byOGdbbyhQrNvWdCfTnmPxUT0ao9/eGOeG7ljD8wJBsxwE8f6tES5Db0FRKEw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=8.23.0' @@ -2209,8 +2112,8 @@ packages: resolution: {integrity: sha512-brcKcxGnISN2CcVhXJ/kEQlNa0MEfGRtwKtWA16SkqXHKitaKIMrfemJKLKX1YqDU5C/5JY3PvZXd5jEW04e0Q==} engines: {node: '>=5.0.0'} - eslint-plugin-perfectionist@4.10.1: - resolution: {integrity: sha512-GXwFfL47RfBLZRGQdrvGZw9Ali2T2GPW8p4Gyj2fyWQ9396R/HgJMf0m9kn7D6WXRwrINfTDGLS+QYIeok9qEg==} + eslint-plugin-perfectionist@4.15.0: + resolution: {integrity: sha512-pC7PgoXyDnEXe14xvRUhBII8A3zRgggKqJFx2a82fjrItDs1BSI7zdZnQtM2yQvcyod6/ujmzb7ejKPx8lZTnw==} engines: {node: ^18.0.0 || >=20.0.0} peerDependencies: eslint: '>=8.45.0' @@ -2220,14 +2123,14 @@ packages: peerDependencies: eslint: ^9.0.0 - eslint-plugin-regexp@2.7.0: - resolution: {integrity: sha512-U8oZI77SBtH8U3ulZ05iu0qEzIizyEDXd+BWHvyVxTOjGwcDcvy/kEpgFG4DYca2ByRLiVPFZ2GeH7j1pdvZTA==} + eslint-plugin-regexp@2.9.0: + resolution: {integrity: sha512-9WqJMnOq8VlE/cK+YAo9C9YHhkOtcEtEk9d12a+H7OSZFwlpI6stiHmYPGa2VE0QhTzodJyhlyprUaXDZLgHBw==} engines: {node: ^18 || >=20} peerDependencies: eslint: '>=8.44.0' - eslint-plugin-sonarjs@3.0.2: - resolution: {integrity: sha512-LxjbfwI7ypENeTmGyKmDyNux3COSkMi7H/6Cal5StSLQ6edf0naP45SZR43OclaNR7WfhVTZdhOn63q3/Y6puQ==} + eslint-plugin-sonarjs@3.0.4: + resolution: {integrity: sha512-ftQcP811kRJNXapqpQXHErEoVOdTPfYPPYd7n3AExIPwv4qWKKHf4slFvXmodiOnfgy1Tl3waPZZLD7lcvJOtw==} peerDependencies: eslint: ^8.0.0 || ^9.0.0 @@ -2237,11 +2140,11 @@ packages: peerDependencies: eslint: '>=6.0.0' - eslint-plugin-unicorn@57.0.0: - resolution: {integrity: sha512-zUYYa6zfNdTeG9BISWDlcLmz16c+2Ck2o5ZDHh0UzXJz3DEP7xjmlVDTzbyV0W+XksgZ0q37WEWzN2D2Ze+g9Q==} - engines: {node: '>=18.18'} + eslint-plugin-unicorn@59.0.1: + resolution: {integrity: sha512-EtNXYuWPUmkgSU2E7Ttn57LbRREQesIP1BiLn7OZLKodopKfDXfBUkC/0j6mpw2JExwf43Uf3qLSvrSvppgy8Q==} + engines: {node: ^18.20.0 || ^20.10.0 || >=21.0.0} peerDependencies: - eslint: '>=9.20.0' + eslint: '>=9.22.0' eslint-plugin-unused-imports@4.1.4: resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==} @@ -2252,15 +2155,19 @@ packages: '@typescript-eslint/eslint-plugin': optional: true - eslint-plugin-vue@10.0.0: - resolution: {integrity: sha512-XKckedtajqwmaX6u1VnECmZ6xJt+YvlmMzBPZd+/sI3ub2lpYZyFnsyWo7c3nMOQKJQudeyk1lw/JxdgeKT64w==} + eslint-plugin-vue@10.3.0: + resolution: {integrity: sha512-A0u9snqjCfYaPnqqOaH6MBLVWDUIN4trXn8J3x67uDcXvR7X6Ut8p16N+nYhMCQ9Y7edg2BIRGzfyZsY0IdqoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: + '@typescript-eslint/parser': ^7.0.0 || ^8.0.0 eslint: ^8.57.0 || ^9.0.0 vue-eslint-parser: ^10.0.0 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true - eslint-plugin-yml@1.17.0: - resolution: {integrity: sha512-Q3LXFRnNpGYAK/PM0BY1Xs0IY1xTLfM0kC986nNQkx1l8tOGz+YS50N6wXkAJkrBpeUN9OxEMB7QJ+9MTDAqIQ==} + eslint-plugin-yml@1.18.0: + resolution: {integrity: sha512-9NtbhHRN2NJa/s3uHchO3qVVZw0vyOIvWlXWGaKCr/6l3Go62wsvJK5byiI6ZoYztDsow4GnS69BZD3GnqH3hA==} engines: {node: ^14.17.0 || >=16.0.0} peerDependencies: eslint: '>=6.0.0' @@ -2271,20 +2178,20 @@ packages: '@vue/compiler-sfc': ^3.3.0 eslint: '>=9.0.0' - eslint-scope@8.3.0: - resolution: {integrity: sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==} + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - eslint-visitor-keys@4.2.0: - resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.23.0: - resolution: {integrity: sha512-jV7AbNoFPAY1EkFYpLq5bslU9NLNO8xnEeQXwErNibVryjk67wHVmddTBilc5srIttJDBrB0eMHKZBFbSIABCw==} + eslint@9.30.1: + resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -2293,8 +2200,8 @@ packages: jiti: optional: true - espree@10.3.0: - resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} espree@9.6.1: @@ -2323,12 +2230,8 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} - execa@8.0.1: - resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} - engines: {node: '>=16.17'} - - exsolve@1.0.4: - resolution: {integrity: sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==} + exsolve@1.0.7: + resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==} extract-zip@2.0.1: resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} @@ -2348,14 +2251,17 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - fastq@1.17.1: - resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} fd-slicer@1.1.0: resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.4.3: - resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + fdir@6.4.6: + resolution: {integrity: sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==} peerDependencies: picomatch: ^3 || ^4 peerDependenciesMeta: @@ -2386,8 +2292,8 @@ packages: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} engines: {node: '>=16'} - flatted@3.3.2: - resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==} + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} follow-redirects@1.15.9: resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} @@ -2398,17 +2304,22 @@ packages: debug: optional: true - for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} - foreground-child@3.3.0: - resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} - form-data@4.0.1: - resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + form-data@4.0.3: + resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==} engines: {node: '>= 6'} + format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} @@ -2427,8 +2338,8 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - function.prototype.name@1.1.6: - resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} functional-red-black-tree@1.0.1: @@ -2441,39 +2352,39 @@ packages: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} - get-intrinsic@1.2.6: - resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} - get-stream@8.0.1: - resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} - engines: {node: '>=16'} - - get-symbol-description@1.0.2: - resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@4.10.0: - resolution: {integrity: sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==} - - get-tsconfig@4.8.1: - resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} gettext-extractor@3.8.0: resolution: {integrity: sha512-i/3mDQufQoJd2/EKm/B+VlaYrt3yGjVfLZu8DQpESKH29klNiW6z2S89FVCIEB85bDNgtGCeM/3A/yR1njr/Lw==} engines: {node: '>=6'} - giget@1.2.3: - resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==} + giget@2.0.0: + resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==} hasBin: true github-buttons@2.29.1: resolution: {integrity: sha512-TV3YgAKda5hPz75n7QXmGCsSzgVya1vvmBieebg3EB5ScmashTZ0FldViG1aU2d4V5rcAGrtQ7k5uAaCo0A4PA==} + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2490,34 +2401,22 @@ packages: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} deprecated: Glob versions prior to v9 are no longer supported - globals@11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - globals@14.0.0: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@15.14.0: - resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} - engines: {node: '>=18'} - globals@15.15.0: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} - globals@16.0.0: - resolution: {integrity: sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==} + globals@16.3.0: + resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} engines: {node: '>=18'} globalthis@1.0.4: resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} engines: {node: '>= 0.4'} - globby@14.0.2: - resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==} - engines: {node: '>=18'} - gopd@1.2.0: resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} engines: {node: '>= 0.4'} @@ -2532,8 +2431,9 @@ packages: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} - has-bigints@1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + 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==} @@ -2554,9 +2454,6 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hash-sum@2.0.0: - resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} - hasown@2.0.2: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} @@ -2572,21 +2469,9 @@ packages: hookable@5.5.3: resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==} - hosted-git-info@7.0.2: - resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==} - engines: {node: ^16.14.0 || >=18.0.0} - - html-tags@3.3.1: - resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} - engines: {node: '>=8'} - htmlparser2@9.1.0: resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} - human-signals@5.0.0: - resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} - engines: {node: '>=16.17.0'} - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2595,8 +2480,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@6.0.2: - resolution: {integrity: sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==} + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} engines: {node: '>= 4'} image-size@0.5.5: @@ -2604,8 +2489,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - import-fresh@3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} imurmurhash@0.1.4: @@ -2616,10 +2501,6 @@ packages: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} - index-to-position@0.1.2: - resolution: {integrity: sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==} - engines: {node: '>=18'} - inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. @@ -2631,15 +2512,15 @@ packages: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} - is-array-buffer@3.0.4: - resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - is-async-function@2.0.0: - resolution: {integrity: sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==} + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} engines: {node: '>= 0.4'} is-bigint@1.1.0: @@ -2650,22 +2531,18 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} - is-boolean-object@1.2.1: - resolution: {integrity: sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==} + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} engines: {node: '>= 0.4'} - is-builtin-module@4.0.0: - resolution: {integrity: sha512-rWP3AMAalQSesXO8gleROyL2iKU73SX5Er66losQn9rWOWL4Gef0a/xOEOVqjWGMuR2vHG3FJ8UUmT700O8oFg==} + is-builtin-module@5.0.0: + resolution: {integrity: sha512-f4RqJKBUe5rQkJ2eJEJBXSticB3hGbN9j0yxxMQFqIW89Jp9WYFtzfTcRlstDKVUTRzSOTLKRfO9vIztenwtxA==} engines: {node: '>=18.20'} is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.16.0: - resolution: {integrity: sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==} - engines: {node: '>= 0.4'} - is-data-view@1.0.2: resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} engines: {node: '>= 0.4'} @@ -2674,26 +2551,36 @@ packages: resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} engines: {node: '>= 0.4'} + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - is-finalizationregistry@1.1.0: - resolution: {integrity: sha512-qfMdqbAQEwBw78ZyReKnlA8ezmPdb9BemzIIip/JkjaZUhitfXDkkr+3QTboW0JrSXT1QWyYShpvnNHGZ4c4yA==} + 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.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} engines: {node: '>= 0.4'} is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-map@2.0.3: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} @@ -2702,8 +2589,8 @@ packages: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} - is-number-object@1.1.0: - resolution: {integrity: sha512-KVSZV0Dunv9DTPkhXwcZ3Q+tUc9TsaE1ZwX5J2WMvsSGS6Md8TFPun5uwh0yRdrNerI6vf/tbJxqSx4c1ZI1Lw==} + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} engines: {node: '>= 0.4'} is-number@7.0.0: @@ -2722,36 +2609,32 @@ packages: resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} engines: {node: '>= 0.4'} - is-shared-array-buffer@1.0.3: - resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} engines: {node: '>= 0.4'} - is-stream@3.0.0: - resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - - is-string@1.1.0: - resolution: {integrity: sha512-PlfzajuF9vSo5wErv3MJAKD/nqf9ngAs1NFQYm16nUYFO2IzxJ2hcm+IOCg+EEopdykNNUhVq5cz35cAUxU8+g==} + 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.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} - is-weakref@1.1.0: - resolution: {integrity: sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==} + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} engines: {node: '>= 0.4'} - is-weakset@2.0.3: - resolution: {integrity: sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==} + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} engines: {node: '>= 0.4'} is-what@3.14.1: @@ -2761,24 +2644,24 @@ packages: resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} engines: {node: '>=12.13'} + is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - isomorphic-git@1.27.2: - resolution: {integrity: sha512-nCiz+ieOkWb5kDJSSckDTiMjTcgkxqH2xuiQmw1Y6O/spwx4d6TKYSfGCd4f71HGvUYcRSUGqJEI+3uN6UQlOw==} - engines: {node: '>=12'} + isomorphic-git@1.32.1: + resolution: {integrity: sha512-NZCS7qpLkCZ1M/IrujYBD31sM6pd/fMVArK4fz4I7h6m0rUW2AsYU7S7zXeABuHL6HIfW6l53b4UQ/K441CQjg==} + engines: {node: '>=14.17'} hasBin: true jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jiti@2.4.1: - resolution: {integrity: sha512-yPBThwecp1wS9DmoA4x4KR2h3QoslacnDR8ypuFM962kI4/456Iy1oHx2RAgh4jfZNdn0bctsdadceiBUgpU1g==} - hasBin: true - jiti@2.4.2: resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} hasBin: true @@ -2842,38 +2725,98 @@ packages: resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} engines: {node: '>= 8'} - knitwork@1.1.0: - resolution: {integrity: sha512-oHnmiBUVHz1V+URE77PNot2lv3QiYU2zQf1JjOVkMt3YDKGbu8NAFr+c4mcNOhdsGrB/VpVbRwPwhiXrPhxQbw==} + knitwork@1.2.0: + resolution: {integrity: sha512-xYSH7AvuQ6nXkq42x0v5S8/Iry+cfulBz/DJQzhIyESdLD7425jXsPy4vn5cCXU+HhRN2kVw51Vd1K6/By4BQg==} kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} - less@4.2.2: - resolution: {integrity: sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==} - engines: {node: '>=6'} + less@4.3.0: + resolution: {integrity: sha512-X9RyH9fvemArzfdP8Pi3irr7lor2Ok4rOttDXBhlwDg+wKQsXOXgHWduAJE1EsF7JJx0w0bcO6BC6tCKKYnXKA==} + engines: {node: '>=14'} hasBin: true levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} - lines-and-columns@1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + lightningcss-darwin-arm64@1.30.1: + resolution: {integrity: sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] - local-pkg@0.5.1: - resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} - engines: {node: '>=14'} + lightningcss-darwin-x64@1.30.1: + resolution: {integrity: sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] - local-pkg@1.0.0: - resolution: {integrity: sha512-bbgPw/wmroJsil/GgL4qjDzs5YLTBMQ99weRsok1XCDccQeehbHA/I1oRvk2NPtr7KGZgT/Y5tPRnAtMqeG2Kg==} - engines: {node: '>=14'} + lightningcss-freebsd-x64@1.30.1: + resolution: {integrity: sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] - local-pkg@1.1.1: - resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} - engines: {node: '>=14'} + lightningcss-linux-arm-gnueabihf@1.30.1: + resolution: {integrity: sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] - locate-path@6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + lightningcss-linux-arm64-gnu@1.30.1: + resolution: {integrity: sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.30.1: + resolution: {integrity: sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.30.1: + resolution: {integrity: sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.30.1: + resolution: {integrity: sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.30.1: + resolution: {integrity: sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.30.1: + resolution: {integrity: sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.30.1: + resolution: {integrity: sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==} + engines: {node: '>= 12.0.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + local-pkg@1.1.1: + resolution: {integrity: sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==} + engines: {node: '>=14'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} lodash-es@4.17.21: @@ -2901,13 +2844,10 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - magic-string-ast@0.7.0: - resolution: {integrity: sha512-686fgAHaJY7wLTFEq7nnKqeQrhqmXB19d1HnqT35Ci7BN6hbAYLZUezTQ062uUHM7ggZEQlqJ94Ftls+KDXU8Q==} + magic-string-ast@0.7.1: + resolution: {integrity: sha512-ub9iytsEbT7Yw/Pd29mSo/cNQpaEu67zR1VVcXDiYjSFwzeBxNdTd0FMnSslLQXiRj8uGPzwsaoefrMD5XAmdw==} engines: {node: '>=16.14.0'} - magic-string@0.30.15: - resolution: {integrity: sha512-zXeaYRgZ6ldS1RJJUrMrYgNJ4fdwnyI6tVqoiIhyCyv5IVTK9BU8Ic2l253GGETQHxI4HNUwhJ3fjDhKqEoaAw==} - magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -2918,31 +2858,34 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - marked-highlight@2.2.1: - resolution: {integrity: sha512-SiCIeEiQbs9TxGwle9/OwbOejHCZsohQRaNTY2u8euEXYt2rYUFoiImUirThU3Gd/o6Q1gHGtH9qloHlbJpNIA==} + marked-highlight@2.2.2: + resolution: {integrity: sha512-KlHOP31DatbtPPXPaI8nx1KTrG3EW0Z5zewCwpUj65swbtKOTStteK3sNAjBqV75Pgo3fNEVNHeptg18mDuWgw==} peerDependencies: - marked: '>=4 <16' + marked: '>=4 <17' - marked@15.0.7: - resolution: {integrity: sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==} - engines: {node: '>= 18'} + marked@16.0.0: + resolution: {integrity: sha512-MUKMXDjsD/eptB7GPzxo4xcnLS6oo7/RHimUMHEDRhUooPwmN9BEpMl7AEOJv3bmso169wHI2wUF9VQgL7zfmA==} + engines: {node: '>= 20'} hasBin: true - math-intrinsics@1.0.0: - resolution: {integrity: sha512-4MqMiKP90ybymYvsut0CH2g4XWbfLtmlCkXmtmdcDCxNB+mQcu1w/1+L/VD7vi/PSv7X2JYV7SCcR+jiPXnQtA==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} - mdast-util-find-and-replace@3.0.1: - resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==} + mdast-util-find-and-replace@3.0.2: + resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} mdast-util-from-markdown@2.0.2: resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==} + mdast-util-frontmatter@2.0.1: + resolution: {integrity: sha512-LRqI9+wdgC25P0URIJY9vwocIzCcksduHQ9OF2joxQoyTNVduwLAFUzjoopuRJbJAReaKrNQKAZKL3uCMugWJA==} + mdast-util-gfm-autolink-literal@2.0.1: resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==} - mdast-util-gfm-footnote@2.0.0: - resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==} + mdast-util-gfm-footnote@2.1.0: + resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==} mdast-util-gfm-strikethrough@2.0.0: resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==} @@ -2953,8 +2896,8 @@ packages: mdast-util-gfm-task-list-item@2.0.0: resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==} - mdast-util-gfm@3.0.0: - resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==} + mdast-util-gfm@3.1.0: + resolution: {integrity: sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==} mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} @@ -2974,15 +2917,15 @@ packages: mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} - merge-stream@2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} - micromark-core-commonmark@2.0.2: - resolution: {integrity: sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==} + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-frontmatter@2.0.0: + resolution: {integrity: sha512-C4AkuM3dA58cgZha7zVnuVxBhDsbttIMiytjgsM2XbHAB2faRVaHRle40558FBN+DJcrLNCoqG5mlrpdU4cRtg==} micromark-extension-gfm-autolink-literal@2.1.0: resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} @@ -2993,8 +2936,8 @@ packages: micromark-extension-gfm-strikethrough@2.1.0: resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==} - micromark-extension-gfm-table@2.1.0: - resolution: {integrity: sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==} + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} micromark-extension-gfm-tagfilter@2.0.0: resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==} @@ -3053,17 +2996,17 @@ packages: micromark-util-sanitize-uri@2.0.1: resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - micromark-util-subtokenize@2.0.3: - resolution: {integrity: sha512-VXJJuNxYWSoYL6AJ6OQECCFGhIU2GGHMw8tahogePBrjkG8aCCas3ibkp7RnVOSTClg2is05/R7maAhF1XyQMg==} + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} micromark-util-symbol@2.0.1: resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} - micromark-util-types@2.0.1: - resolution: {integrity: sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==} + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} - micromark@4.0.1: - resolution: {integrity: sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==} + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} @@ -3082,10 +3025,6 @@ packages: engines: {node: '>=4'} hasBin: true - mimic-fn@4.0.0: - resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} - engines: {node: '>=12'} - mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -3094,8 +3033,8 @@ packages: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} - minimatch@10.0.1: - resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==} + minimatch@10.0.3: + resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==} engines: {node: 20 || >=22} minimatch@3.1.2: @@ -3142,12 +3081,8 @@ packages: mlly@1.7.4: resolution: {integrity: sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==} - mri@1.2.0: - resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} - engines: {node: '>=4'} - - mrmime@2.0.0: - resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} engines: {node: '>=10'} ms@2.1.3: @@ -3156,8 +3091,8 @@ packages: muggle-string@0.4.1: resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} - nanoid@3.3.8: - resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -3176,20 +3111,16 @@ packages: engines: {node: '>= 4.4.x'} hasBin: true - node-fetch-native@1.6.4: - resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + node-fetch-native@1.6.6: + resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} - node-object-hash@3.0.0: - resolution: {integrity: sha512-jLF6tlyletktvSAawuPmH1SReP0YfZQ+tBrDiTCK+Ai7eXPMS9odi5xW/iKC7ZhrWJJ0Z5xYcW/x+1fVMn1Qvw==} + node-object-hash@3.1.1: + resolution: {integrity: sha512-A32kRGjXtwQ+uSa3GrXiCl8HVFY0Jy6IiKFO7UjagAKSaOOrruxB2Qf/w7TP5QtNfB3uOiHTu3cjhp8k/C0PCg==} engines: {node: '>=16', pnpm: '>=8'} node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - normalize-package-data@6.0.2: - resolution: {integrity: sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==} - engines: {node: ^16.14.0 || >=18.0.0} - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -3198,54 +3129,54 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} - npm-run-path@5.3.0: - resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - nprogress@0.2.0: resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} - nypm@0.3.12: - resolution: {integrity: sha512-D3pzNDWIvgA+7IORhD/IuWzEk4uXv6GsgOxiid4UU3h9oq5IqV1KtPDi63n4sZJ/xcWlr88c0QM2RgN5VbOhFA==} + nypm@0.6.0: + resolution: {integrity: sha512-mn8wBFV9G9+UFHIrq+pZ2r2zL4aPau/by3kJb3cM7+5tQHMt6HGQB8FDIeKFYp8o0D2pnH6nVsO88N4AmUxIWg==} engines: {node: ^14.16.0 || >=16.10.0} hasBin: true - object-inspect@1.13.3: - resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} + 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.5: - resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} engines: {node: '>= 0.4'} - object.values@1.2.0: - resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} ofetch@1.4.1: resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} - ohash@1.1.4: - resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} + ohash@2.0.11: + resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - onetime@6.0.0: - resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} - engines: {node: '>=12'} + open@10.1.2: + resolution: {integrity: sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==} + engines: {node: '>=18'} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} @@ -3257,8 +3188,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@0.2.8: - resolution: {integrity: sha512-ts9KSdroZisdvKMWVAVCXiKqnqNfXz4+IbrBG8/BWx/TR5le+jfenvoBuIZ6UWM9nz47W7AbD9qYfAwfWMIwzA==} + package-manager-detector@1.3.0: + resolution: {integrity: sha512-ZsEbbZORsyHuO00lY1kV3/t72yp6Ysay6Pd17ZAlNGuGwmWDLCJxFpRs0IzfXfj1o4icJOkUEioexFHzyPurSQ==} pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -3271,22 +3202,20 @@ packages: resolution: {integrity: sha512-RmVuCHWsfu0QPNW+mraxh/xjQVw/lhUCUru8Zni3Ctq3AoMhpDTq0OVdKS6iesd6Kqb7viCV3isAL43dciOSog==} engines: {node: '>=14'} - parse-imports@2.2.1: - resolution: {integrity: sha512-OL/zLggRp8mFhKL0rNORUTR4yBYujK/uU+xZL+/0Rgm2QE4nLO9v8PzEweSJEbMGKmDRjJE4R3IMJlL2di4JeQ==} - engines: {node: '>= 18'} + parse-imports-exports@0.2.4: + resolution: {integrity: sha512-4s6vd6dx1AotCx/RCI2m7t7GCh5bDRUtGNvRfHSP2wbBQdMi67pPe7mtzmgwcaQ8VKK/6IB7Glfyu3qdZJPybQ==} parse-json@5.2.0: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} - parse-json@8.1.0: - resolution: {integrity: sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==} - engines: {node: '>=18'} - parse-node-version@1.0.1: resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} engines: {node: '>= 0.10'} + parse-statements@1.0.11: + resolution: {integrity: sha512-HlsyYdMBnbPQ9Jr/VgJ1YF4scnldvJpJxCVx6KgqPL4dxppsWrJHCIIxQXMJrqGnsRkNPATbeMJ8Yxu7JMsYcA==} + parse5-htmlparser2-tree-adapter@6.0.1: resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} @@ -3299,8 +3228,8 @@ packages: parse5@6.0.1: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} - parse5@7.2.1: - resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + parse5@7.3.0: + resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} path-browserify@1.0.1: resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} @@ -3317,21 +3246,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-key@4.0.0: - resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} - engines: {node: '>=12'} - - path-parse@1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-type@5.0.0: - resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==} - engines: {node: '>=12'} - pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -3359,19 +3277,22 @@ packages: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} - pinia-plugin-persistedstate@4.2.0: - resolution: {integrity: sha512-3buhA7ac+ssbOIx3VRCC8oHkoFwhDM9oHRCjo7nj+O8WUqnW+jRqh7eYT5eS/DNa3H28zp3dYf/nd/Vc8zj8eQ==} + pinia-plugin-persistedstate@4.4.1: + resolution: {integrity: sha512-lmuMPpXla2zJKjxEq34e1E9P9jxkWEhcVwwioCCE0izG45kkTOvQfCzvwhW3i38cvnaWC7T1eRdkd15Re59ldw==} peerDependencies: - '@pinia/nuxt': '>=0.9.0' - pinia: '>=2.3.0' + '@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 - pinia@3.0.1: - resolution: {integrity: sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg==} + pinia@3.0.3: + resolution: {integrity: sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==} peerDependencies: typescript: '>=4.4.4' vue: ^2.7.0 || ^3.5.11 @@ -3382,8 +3303,8 @@ packages: pkg-types@1.3.1: resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==} - pkg-types@2.1.0: - resolution: {integrity: sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==} + pkg-types@2.2.0: + resolution: {integrity: sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==} pluralize@8.0.0: resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} @@ -3398,8 +3319,8 @@ packages: pofile@1.1.4: resolution: {integrity: sha512-r6Q21sKsY1AjTVVjOuU02VYKVNQGJNQHjTIvs4dEbeuuYfxgYk/DGD2mqqq4RDaVkwdSq0VEtmQUOPe/wH8X3g==} - possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} postcss-selector-parser@6.1.2: @@ -3409,8 +3330,8 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.3: - resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} prelude-ls@1.2.1: @@ -3423,15 +3344,15 @@ packages: prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} - pump@3.0.2: - resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - quansync@0.2.8: - resolution: {integrity: sha512-4+saucphJMazjt7iOM27mbFCk+D9dd/zmgMDCzRZ8MEoBfYp7lAvoN38et/phRQF6wOPMy/OROBGgoWeSKyluA==} + quansync@0.2.10: + resolution: {integrity: sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3439,14 +3360,6 @@ packages: rc9@2.1.2: resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==} - read-package-up@11.0.0: - resolution: {integrity: sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==} - engines: {node: '>=18'} - - read-pkg@9.0.1: - resolution: {integrity: sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==} - engines: {node: '>=18'} - readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3455,9 +3368,9 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - readdirp@4.0.2: - resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} - engines: {node: '>= 14.16.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} reconnecting-websocket@4.4.0: resolution: {integrity: sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==} @@ -3466,13 +3379,10 @@ packages: resolution: {integrity: sha512-J8rn6v4DBb2nnFqkqwy6/NnTYMcgLA+sLr0iIO41qpv0n+ngb7ksag2tMRl0inb1bbO/esUwzW1vbJi7K0sI0g==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - reflect.getprototypeof@1.0.8: - resolution: {integrity: sha512-B5dj6usc5dkk8uFliwjwDHM8To5/QwdKz9JcBZ8Ic4G1f0YmeeJTtE/ZTdgRFPAfxZFiUaPhZ1Jcs4qeagItGQ==} + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} engines: {node: '>= 0.4'} - regenerator-runtime@0.14.1: - resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - regexp-ast-analysis@0.7.1: resolution: {integrity: sha512-sZuz1dYW/ZsfG17WSAG7eS85r5a0dDsvg+7BiiYR5o6lKCAtUrEwdmRmaGF6rwVj3LcmAeYkOWKEPlbPzN3Y3A==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} @@ -3481,8 +3391,8 @@ packages: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true - regexp.prototype.flags@1.5.3: - resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} regjsparser@0.12.0: @@ -3499,24 +3409,60 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} - resolve@1.22.9: - resolution: {integrity: sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==} - hasBin: true - - reusify@1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} - rollup@4.34.6: - resolution: {integrity: sha512-wc2cBWqJgkU3Iz5oztRkQbfVkbxoz5EhnCGOrnJvnLnQ7O0WhQUYyv18qQI79O8L7DdHrrlJNeCHd4VGpnaXKQ==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} + rolldown-vite@7.0.4: + resolution: {integrity: sha512-AcFt2mBWuwH3svDHcz8V5+K8Es1TuZOBDdJh6+ySkGSuNS5sEpRJqnopupeMfB8SHCAXVA6Wp75OQmTBZc+TgQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + 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 + + rolldown@1.0.0-beta.23: + resolution: {integrity: sha512-+/TR2YSZxLTtDAfG9LHlYqsHO6jtvr9qxaRD77E+PCAQi5X47bJkgiZsjDmE1jGR19NfYegWToOvSe6E+8NfwA==} hasBin: true - rspack-resolver@1.2.2: - resolution: {integrity: sha512-Fwc19jMBA3g+fxDJH2B4WxwZjE0VaaOL7OX/A4Wn5Zv7bOD/vyPZhzXfaO73Xc2GAlfi96g5fGUa378WbIGfFw==} + run-applescript@7.0.0: + resolution: {integrity: sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==} + engines: {node: '>=18'} run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -3528,6 +3474,10 @@ packages: 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'} @@ -3541,6 +3491,9 @@ packages: scroll-into-view-if-needed@2.2.31: resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==} + scroll-into-view-if-needed@3.1.0: + resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} + scslre@0.3.0: resolution: {integrity: sha512-3A6sD0WYP7+QrjbfNA2FN3FsOaGGFoekCVgTyypy53gPxhbkCIjtO6YWgdrfM+n/8sI8JeXZOIxsHjMTNxQ4nQ==} engines: {node: ^14.0.0 || >=16.0.0} @@ -3556,13 +3509,8 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} - hasBin: true - - semver@7.7.1: - resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} hasBin: true @@ -3574,8 +3522,13 @@ packages: resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} engines: {node: '>= 0.4'} - sha.js@2.4.11: - resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} hasBin: true shallow-equal@1.2.1: @@ -3615,20 +3568,13 @@ packages: simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - sirv@3.0.0: - resolution: {integrity: sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==} + sirv@3.0.1: + resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} engines: {node: '>=18'} sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} - - slashes@3.0.12: - resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} - sortablejs@1.14.0: resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==} @@ -3643,33 +3589,33 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - spdx-correct@3.2.0: - resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} - spdx-exceptions@2.5.0: resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} - spdx-expression-parse@3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-expression-parse@4.0.0: resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} - spdx-license-ids@3.0.20: - resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + spdx-license-ids@3.0.21: + resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} speakingurl@14.0.1: resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==} engines: {node: '>=0.10.0'} + splitpanes@4.0.4: + resolution: {integrity: sha512-RbysugZhjbCw5fgplvk3hOXr41stahQDtZhHVkhnnJI6H4wlGDhM2kIpbehy7v92duy9GnMa8zIhHigIV1TWtg==} + peerDependencies: + vue: ^3.2.0 + sse.js@2.6.0: resolution: {integrity: sha512-eGEqOwiPX9Cm+KsOYkcz7HIEqWUSOFeChr0sT515hDOBLvQy5yxaLSZx9JWMhwjf75CXJq+7cgG1MKNh9GQ36w==} - stable-hash@0.0.5: - resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} - std-env@3.8.0: - resolution: {integrity: sha512-Bc3YwwCB+OzldMxOXJIIvC6cPRWr/LxOp48CdQTOkPyk/t4JWWJbrilwBd7RJzKV8QW7tJkcgAmeuLLJugl5/w==} + 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==} @@ -3702,10 +3648,6 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} - strip-final-newline@3.0.0: - resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} - engines: {node: '>=12'} - strip-indent@4.0.0: resolution: {integrity: sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==} engines: {node: '>=12'} @@ -3714,14 +3656,11 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} - strip-literal@2.1.1: - resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==} - strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - stylis@4.3.4: - resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} + stylis@4.3.6: + resolution: {integrity: sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==} superjson@2.2.2: resolution: {integrity: sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==} @@ -3731,28 +3670,17 @@ 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'} - - svg-tags@1.0.0: - resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} - svgo@3.3.2: resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} engines: {node: '>=14.0.0'} hasBin: true - synckit@0.6.2: - resolution: {integrity: sha512-Vhf+bUa//YSTYKseDiiEuQmhGCoIF3CVBhunm3r/DQnYiGT4JssmnKQc44BIyOZRK2pKjXXAgbhfmbeoC9CJpA==} - engines: {node: '>=12.20'} - - synckit@0.9.2: - resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + synckit@0.11.8: + resolution: {integrity: sha512-+XZ+r1XGIJGeQk3VvXhT6xx/VpbHsRzsTkGgF6E5RX9TTXD0118l87puaEBZ566FhqblC6U0d4XnubznJDm30A==} engines: {node: ^14.18.0 || >=16.0.0} - tapable@2.2.1: - resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + tapable@2.2.2: + resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} engines: {node: '>=6'} tar@6.2.1: @@ -3766,10 +3694,17 @@ packages: tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} - tinyglobby@0.2.12: - resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + tinyexec@1.0.1: + resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==} + + tinyglobby@0.2.14: + resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==} engines: {node: '>=12.0.0'} + to-buffer@1.2.1: + resolution: {integrity: sha512-tB82LpAIWjhLYbqjx3X4zEeHN6M8CiuOEy2JY8SEQVdYRe3CCHOFaqrBW1doLDrfpWhplcW7BL+bO3/6S3pcDQ==} + engines: {node: '>= 0.4'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -3782,12 +3717,17 @@ packages: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - ts-api-utils@2.0.1: - resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + ts-api-utils@2.1.0: + resolution: {integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==} engines: {node: '>=18.12'} peerDependencies: typescript: '>=4.8.4' + ts-declaration-location@1.0.7: + resolution: {integrity: sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==} + peerDependencies: + typescript: '>=4.0.0' + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -3800,28 +3740,24 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@4.35.0: - resolution: {integrity: sha512-2/AwEFQDFEy30iOLjrvHDIH7e4HEWH+f1Yl1bI5XMqzuoCUqwYCdxachgsgv0og/JdVZUhbfjcJAoHj5L1753A==} - engines: {node: '>=16'} - - typed-array-buffer@1.0.2: - resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} - typed-array-byte-length@1.0.1: - resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.3: - resolution: {integrity: sha512-GsvTyUHTriq6o/bHcTd0vM7OQ9JEdlvluu9YISaA7+KzDzPaIzEeDFNkTfhdE3MYcNhNi0vq/LlegYgIs5yPAw==} + 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.8.2: - resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} engines: {node: '>=14.17'} hasBin: true @@ -3829,37 +3765,32 @@ packages: resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} engines: {node: '>=8'} - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} - unbox-primitive@1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - - unconfig@7.0.0: - resolution: {integrity: sha512-G5CJSoG6ZTxgzCJblEfgpdRK2tos9+UdD2WtecDUVfImzQ0hFjwpH5RVvGMhP4pRpC9ML7NrC4qBsBl0Ttj35A==} + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} - uncrypto@0.1.3: - resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + unconfig@7.3.2: + resolution: {integrity: sha512-nqG5NNL2wFVGZ0NA/aCFw0oJ2pxSf1lwg4Z5ill8wd7K4KX/rQbHlwbh+bjctXL5Ly1xtzHenHGOK0b+lG6JVg==} - unctx@2.4.0: - resolution: {integrity: sha512-VSwGlVn3teRLkFS9OH4JoZ25ky133vVPQkS6qHv/itYVrqHBa+7SO46Yh07Zve1WEi9A1X135g9DR6KMv6ZsJg==} + unctx@2.4.1: + resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} - undici-types@6.20.0: - resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} - undici@6.21.0: - resolution: {integrity: sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==} + undici@6.21.3: + resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} - unicorn-magic@0.1.0: - resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==} - engines: {node: '>=18'} - - unimport@3.14.5: - resolution: {integrity: sha512-tn890SwFFZxqaJSKQPPd+yygfKSATbM8BZWW1aCR2TJBTs1SDrmLamBueaFtYsGjHtQaRgqEbQflOjN2iW12gA==} + unimport@4.2.0: + resolution: {integrity: sha512-mYVtA0nmzrysnYnyb3ALMbByJ+Maosee2+WyE0puXl+Xm2bUwPorPaaeZt0ETfuroPOtG8jj1g/qeFZ6buFnag==} + engines: {node: '>=18.12.0'} - unimport@4.1.2: - resolution: {integrity: sha512-oVUL7PSlyVV3QRhsdcyYEMaDX8HJyS/CnUonEJTYA3//bWO+o/4gG8F7auGWWWkrrxBQBYOO8DKe+C53ktpRXw==} + unimport@5.1.0: + resolution: {integrity: sha512-wMmuG+wkzeHh2KCE6yiDlHmKelN8iE/maxkUYMbmrS6iV8+n6eP1TH3yKKlepuF4hrkepinEGmBXdfo9XZUvAw==} engines: {node: '>=18.12.0'} unist-util-is@6.0.0: @@ -3877,20 +3808,20 @@ packages: universal-cookie@8.0.1: resolution: {integrity: sha512-B6ks9FLLnP1UbPPcveOidfvB9pHjP+wekP2uRYB9YDfKVpvcjKgy1W5Zj+cEXJ9KTPnqOKGfVDQBmn8/YCQfRg==} - unocss@66.0.0: - resolution: {integrity: sha512-SHstiv1s7zGPSjzOsADzlwRhQM+6817+OqQE3Fv+N/nn2QLNx1bi3WXybFfz5tWkzBtyTZlwdPmeecsIs1yOCA==} + unocss@66.3.2: + resolution: {integrity: sha512-u5FPNsjI2Ah1wGtpmteVxWe6Bja9Oggg25IeAatJCoDd1LxtLm0iHr+I0RlSq0ZwewMWzx/Qlmrw7jU0ZMO+0Q==} engines: {node: '>=14'} peerDependencies: - '@unocss/webpack': 66.0.0 - vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 + '@unocss/webpack': 66.3.2 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 peerDependenciesMeta: '@unocss/webpack': optional: true vite: optional: true - unplugin-auto-import@19.1.2: - resolution: {integrity: sha512-EkxNIJm4ZPYtV7rRaPBKnsscgTaifIZNrJF5DkMffTxkUOJOlJuKVypA6YBSBOjzPJDTFPjfVmCQPoBuOO+YYQ==} + unplugin-auto-import@19.3.0: + resolution: {integrity: sha512-iIi0u4Gq2uGkAOGqlPJOAMI8vocvjh1clGTfSK4SOrJKrt+tirrixo/FjgBwXQNNdS7ofcr7OxzmOb/RjWxeEQ==} engines: {node: '>=14'} peerDependencies: '@nuxt/kit': ^3.2.2 @@ -3905,12 +3836,12 @@ packages: resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==} engines: {node: '>=18.12.0'} - unplugin-vue-components@28.4.1: - resolution: {integrity: sha512-niGSc0vJD9ueAnsqcfAldmtpkppZ09B6p2G1dL7X5S8KPdgbk1P+txPwaaDCe7N+eZh2VG1aAypLXkuJs3OSUg==} + unplugin-vue-components@28.8.0: + resolution: {integrity: sha512-2Q6ZongpoQzuXDK0ZsVzMoshH0MWZQ1pzVL538G7oIDKRTVzHjppBDS8aB99SADGHN3lpGU7frraCG6yWNoL5Q==} engines: {node: '>=14'} peerDependencies: '@babel/parser': ^7.15.8 - '@nuxt/kit': ^3.2.2 + '@nuxt/kit': ^3.2.2 || ^4.0.0 vue: 2 || 3 peerDependenciesMeta: '@babel/parser': @@ -3926,20 +3857,16 @@ packages: resolution: {integrity: sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==} engines: {node: '>=14.0.0'} - unplugin@2.2.0: - resolution: {integrity: sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw==} + unplugin@2.3.5: + resolution: {integrity: sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==} engines: {node: '>=18.12.0'} - unplugin@2.2.2: - resolution: {integrity: sha512-Qp+iiD+qCRnUek+nDoYvtWX7tfnYyXsrOnJ452FRTgOyKmTM7TUJ3l+PLPJOOWPTUyKISKp4isC5JJPSXUjGgw==} - engines: {node: '>=18.12.0'} - - untyped@1.5.1: - resolution: {integrity: sha512-reBOnkJBFfBZ8pCKaeHgfZLcehXtM6UTxc+vqs1JvCps0c4amLNp3fhdGBZwYp+VLyoY9n3X5KOP7lCyWBUX9A==} + untyped@2.0.0: + resolution: {integrity: sha512-nwNCjxJTjNuLCgFr42fEak5OcLuB3ecca+9ksPFNvtfYSLpjf+iJqSIaSnIile6ZPbKYxI5k2AfXqeopGudK/g==} hasBin: true - update-browserslist-db@1.1.1: - resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -3950,67 +3877,48 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - validate-npm-package-license@3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + vite-dev-rpc@1.1.0: + resolution: {integrity: sha512-pKXZlgoXGoE8sEKiKJSng4hI1sQ4wi5YT24FCrwrLt6opmkjlqPPVmiPWWJn8M8byMxRGzp1CrFuqQs4M/Z39A==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.1 || ^7.0.0-0 + + vite-hot-client@2.1.0: + resolution: {integrity: sha512-7SpgZmU7R+dDnSmvXE1mfDtnHLHQSisdySVR7lO8ceAXvM0otZeuQQ6C8LrS5d/aYyP/QZ0hI0L+dIPrm4YlFQ==} + peerDependencies: + vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0 vite-plugin-build-id@0.5.0: resolution: {integrity: sha512-dvf3PSSjzSZSCoWodOjDSDei7wRgQKTYHBKfAZAEoIDTuQtxIVFNzKPHuWETFDOE3pnOa76BUjbTOKxRjMKD9Q==} + vite-plugin-inspect@11.3.0: + resolution: {integrity: sha512-vmt7K1WVKQkuiwvsM6e5h3HDJ2pSWTnzoj+JP9Kvu3Sh2G+nFap1F1V7tqpyA4qFxM1GQ84ryffWFGQrwShERQ==} + engines: {node: '>=14'} + peerDependencies: + '@nuxt/kit': '*' + vite: ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + vite-svg-loader@5.1.0: resolution: {integrity: sha512-M/wqwtOEjgb956/+m5ZrYT/Iq6Hax0OakWbokj8+9PXOnB7b/4AxESHieEtnNEy7ZpjsjYW1/5nK8fATQMmRxw==} peerDependencies: vue: '>=3.2.13' - vite@6.2.3: - resolution: {integrity: sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} - hasBin: true - peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' - less: '*' - lightningcss: ^1.21.0 - sass: '*' - sass-embedded: '*' - stylus: '*' - sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - - vscode-uri@3.0.8: - resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + vscode-uri@3.1.0: + resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==} - vue-dompurify-html@5.2.0: - resolution: {integrity: sha512-GX+BStkKEJ8wu/+hU1EK2nu/gzXWhb4XzBu6aowpsuU/3nkvXvZ2jx4nZ9M3jtS/Vu7J7MtFXjc7x3cWQ+zbVQ==} + vue-dompurify-html@5.3.0: + resolution: {integrity: sha512-HJQGBHbfSPcb6Mu97McdKbX7TqRHZa6Ji8OCpCNyuHca5QvQZ8IiuwghFPSO8OkSQfqXPNPKFMZdCOrnGGmOSQ==} peerDependencies: - vue: ^3.0.0 + vue: ^3.4.36 - vue-eslint-parser@10.1.1: - resolution: {integrity: sha512-bh2Z/Au5slro9QJ3neFYLanZtb1jH+W2bKqGHXAoYD4vZgNG3KeotL7JpPv5xzY4UXUXJl7TrIsnzECH63kd3Q==} + vue-eslint-parser@10.2.0: + resolution: {integrity: sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -4020,13 +3928,19 @@ packages: peerDependencies: vue: ^3.4.37 - vue-router@4.5.0: - resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==} + vue-i18n@11.1.7: + resolution: {integrity: sha512-CDrU7Cmyh1AxJjerQmipV9nVa//exVBdhTcWGlbfcDCN8bKp/uAe7Le6IoN4//5emIikbsSKe9Uofmf/xXkhOA==} + engines: {node: '>= 16'} + peerDependencies: + vue: ^3.0.0 + + vue-router@4.5.1: + resolution: {integrity: sha512-ogAF3P97NPm8fJsE4by9dwSYtDwXIY1nFY9T6DyQnGHd1E2Da94w9JIolpe42LJGIl0DwOHBi8TcRPlPGwbTtw==} peerDependencies: vue: ^3.2.0 - vue-tsc@2.2.8: - resolution: {integrity: sha512-jBYKBNFADTN+L+MdesNX/TB3XuDSyaWynKMDgR+yCSln0GQ9Tfb7JS2lr46s2LiFUT1WsmfWsSvIElyxzOPqcQ==} + vue-tsc@3.0.1: + resolution: {integrity: sha512-UvMLQD0hAGL1g/NfEQelnSVB4H5gtf/gz2lJKjMMwWNOUmSNyWkejwJagAxEbSjtV5CPPJYslOtoSuqJ63mhdg==} hasBin: true peerDependencies: typescript: '>=5.0.0' @@ -4037,6 +3951,15 @@ packages: peerDependencies: vue: ^3.0.0 + vue-types@6.0.0: + resolution: {integrity: sha512-fBgCA4nrBrB8SCU/AN40tFq8HUxLGBvU2ds7a5+SEDse6dYc+TJyvy8mWiwwL8oWIC/aGS/8nTqmhwxApgU5eA==} + engines: {node: '>=14.0.0'} + peerDependencies: + vue: ^3.0.0 + peerDependenciesMeta: + vue: + optional: true + vue3-ace-editor@2.2.4: resolution: {integrity: sha512-FZkEyfpbH068BwjhMyNROxfEI8135Sc+x8ouxkMdCNkuj/Tuw83VP/gStFQqZHqljyX9/VfMTCdTqtOnJZGN8g==} peerDependencies: @@ -4057,13 +3980,13 @@ packages: '@vue/compiler-sfc': '>=3.0.0' vue: '>=3.0.0' - vue3-otp-input@0.5.21: - resolution: {integrity: sha512-dRxmGJqXlU+U5dCijNCyY7ird49+pyfeQspSTqvIp2Xs+VByIluNlTOjgHrftzSdeVZggtx+Ojb8uKiRLaob4Q==} + vue3-otp-input@0.5.40: + resolution: {integrity: sha512-3AMYHqNz9ZDa9y7ICwcEcsJG7XdZGaLAr6IRLIl3whvseFE95F5Duc9q963HcqEbu8CeMWilkmbAt/0eZOZxow==} peerDependencies: vue: ^3.0.* - vue@3.5.13: - resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + vue@3.5.17: + resolution: {integrity: sha512-LbHV3xPN9BeljML+Xctq4lbz2lVHCR6DtbpTf5XIO6gugpXUN49j2QQPcMj086r9+AkJ0FfUT8xjulKKBkkr9g==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -4089,8 +4012,8 @@ packages: resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} engines: {node: '>=18'} - which-boxed-primitive@1.1.0: - resolution: {integrity: sha512-Ei7Miu/AXe2JJ4iNF5j/UphAgRoma4trE6PtisM09bPygb3egMH3YLW/befsWb1A1AxvNSFidOFTB18XtnIIng==} + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} engines: {node: '>= 0.4'} which-builtin-type@1.2.1: @@ -4101,8 +4024,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.16: - resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==} + which-typed-array@1.1.19: + resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} which@2.0.2: @@ -4125,6 +4048,12 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz: + resolution: {tarball: https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz} + version: 0.20.3 + engines: {node: '>=0.8'} + hasBin: true + xml-name-validator@4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} @@ -4139,9 +4068,9 @@ packages: resolution: {integrity: sha512-E/+VitOorXSLiAqtTd7Yqax0/pAS3xaYMP+AUUJGOK1OZG3rhcj9fcJOM5HJ2VrP1FrStVCWr1muTfQCdj4tAA==} engines: {node: ^14.17.0 || >=16.0.0} - yaml@2.7.0: - resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} - engines: {node: '>= 14'} + yaml@2.8.0: + resolution: {integrity: sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==} + engines: {node: '>= 14.6'} hasBin: true yauzl@2.10.0: @@ -4162,8 +4091,8 @@ snapshots: '@ampproject/remapping@2.3.0': dependencies: - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 '@ant-design/colors@6.0.0': dependencies: @@ -4171,352 +4100,259 @@ snapshots: '@ant-design/icons-svg@4.4.2': {} - '@ant-design/icons-vue@7.0.1(vue@3.5.13(typescript@5.8.2))': + '@ant-design/icons-vue@7.0.1(vue@3.5.17(typescript@5.8.3))': dependencies: '@ant-design/colors': 6.0.0 '@ant-design/icons-svg': 4.4.2 - vue: 3.5.13(typescript@5.8.2) - - '@antfu/eslint-config@4.11.0(@typescript-eslint/utils@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': - dependencies: - '@antfu/install-pkg': 1.0.0 - '@clack/prompts': 0.10.0 - '@eslint-community/eslint-plugin-eslint-comments': 4.4.1(eslint@9.23.0(jiti@2.4.2)) - '@eslint/markdown': 6.3.0 - '@stylistic/eslint-plugin': 4.2.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/eslint-plugin': 8.27.0(@typescript-eslint/parser@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/parser': 8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - '@vitest/eslint-plugin': 1.1.38(@typescript-eslint/utils@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - ansis: 3.17.0 + vue: 3.5.17(typescript@5.8.3) + + '@antfu/eslint-config@4.16.2(@vue/compiler-sfc@3.5.17)(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': + dependencies: + '@antfu/install-pkg': 1.1.0 + '@clack/prompts': 0.11.0 + '@eslint-community/eslint-plugin-eslint-comments': 4.5.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint/markdown': 6.6.0 + '@stylistic/eslint-plugin': 5.1.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@vitest/eslint-plugin': 1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + ansis: 4.1.0 cac: 6.7.14 - eslint: 9.23.0(jiti@2.4.2) - eslint-config-flat-gitignore: 2.1.0(eslint@9.23.0(jiti@2.4.2)) - eslint-flat-config-utils: 2.0.1 - eslint-merge-processors: 2.0.0(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-antfu: 3.1.1(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-command: 3.2.0(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-import-x: 4.9.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - eslint-plugin-jsdoc: 50.6.8(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-jsonc: 2.19.1(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-n: 17.16.2(eslint@9.23.0(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) + eslint-config-flat-gitignore: 2.1.0(eslint@9.30.1(jiti@2.4.2)) + eslint-flat-config-utils: 2.1.0 + eslint-merge-processors: 2.0.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-antfu: 3.1.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-command: 3.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-import-lite: 0.3.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-jsdoc: 51.3.2(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-jsonc: 2.20.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-n: 17.20.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) eslint-plugin-no-only-tests: 3.3.0 - eslint-plugin-perfectionist: 4.10.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - eslint-plugin-pnpm: 0.3.1(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-regexp: 2.7.0(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-toml: 0.12.0(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-unicorn: 57.0.0(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.27.0(@typescript-eslint/parser@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2)) - eslint-plugin-vue: 10.0.0(eslint@9.23.0(jiti@2.4.2))(vue-eslint-parser@10.1.1(eslint@9.23.0(jiti@2.4.2))) - eslint-plugin-yml: 1.17.0(eslint@9.23.0(jiti@2.4.2)) - eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2)) - globals: 16.0.0 + eslint-plugin-perfectionist: 4.15.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint-plugin-pnpm: 0.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-regexp: 2.9.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-toml: 0.12.0(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unicorn: 59.0.1(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-unused-imports: 4.1.4(@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2)) + eslint-plugin-vue: 10.3.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2))) + eslint-plugin-yml: 1.18.0(eslint@9.30.1(jiti@2.4.2)) + eslint-processor-vue-blocks: 2.0.0(@vue/compiler-sfc@3.5.17)(eslint@9.30.1(jiti@2.4.2)) + globals: 16.3.0 jsonc-eslint-parser: 2.4.0 local-pkg: 1.1.1 parse-gitignore: 2.0.0 toml-eslint-parser: 0.10.0 - vue-eslint-parser: 10.1.1(eslint@9.23.0(jiti@2.4.2)) + vue-eslint-parser: 10.2.0(eslint@9.30.1(jiti@2.4.2)) yaml-eslint-parser: 1.3.0 transitivePeerDependencies: - '@eslint/json' - - '@typescript-eslint/utils' - '@vue/compiler-sfc' - supports-color - typescript - vitest - '@antfu/install-pkg@1.0.0': + '@antfu/install-pkg@1.1.0': dependencies: - package-manager-detector: 0.2.8 - tinyexec: 0.3.2 + package-manager-detector: 1.3.0 + tinyexec: 1.0.1 - '@antfu/utils@8.1.0': {} + '@antfu/utils@8.1.1': {} - '@babel/code-frame@7.26.2': + '@babel/code-frame@7.27.1': dependencies: - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-validator-identifier': 7.27.1 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.3': {} - - '@babel/compat-data@7.26.8': {} - - '@babel/core@7.26.0': - dependencies: - '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.3 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helpers': 7.26.0 - '@babel/parser': 7.26.5 - '@babel/template': 7.25.9 - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.5 - convert-source-map: 2.0.0 - debug: 4.4.0 - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color + '@babel/compat-data@7.28.0': {} - '@babel/core@7.26.10': + '@babel/core@7.28.0': dependencies: '@ampproject/remapping': 2.3.0 - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/helper-compilation-targets': 7.26.5 - '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.10) - '@babel/helpers': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/template': 7.26.9 - '@babel/traverse': 7.26.10 - '@babel/types': 7.26.10 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.3(@babel/core@7.28.0) + '@babel/helpers': 7.27.6 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 convert-source-map: 2.0.0 - debug: 4.4.0 + debug: 4.4.1 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/generator@7.26.10': + '@babel/generator@7.28.0': dependencies: - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 + '@jridgewell/gen-mapping': 0.3.12 + '@jridgewell/trace-mapping': 0.3.29 jsesc: 3.1.0 - '@babel/generator@7.26.3': + '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/parser': 7.26.5 - '@babel/types': 7.26.5 - '@jridgewell/gen-mapping': 0.3.8 - '@jridgewell/trace-mapping': 0.3.25 - jsesc: 3.1.0 - - '@babel/helper-annotate-as-pure@7.25.9': - dependencies: - '@babel/types': 7.26.5 - - '@babel/helper-compilation-targets@7.25.9': - dependencies: - '@babel/compat-data': 7.26.3 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.4 - lru-cache: 5.1.1 - semver: 6.3.1 + '@babel/types': 7.28.0 - '@babel/helper-compilation-targets@7.26.5': + '@babel/helper-compilation-targets@7.27.2': dependencies: - '@babel/compat-data': 7.26.8 - '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.4 + '@babel/compat-data': 7.28.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.25.1 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.26.10)': + '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.10) - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/core': 7.28.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.28.0 semver: 6.3.1 transitivePeerDependencies: - supports-color - '@babel/helper-member-expression-to-functions@7.25.9': - dependencies: - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.5 - transitivePeerDependencies: - - supports-color + '@babel/helper-globals@7.28.0': {} - '@babel/helper-module-imports@7.25.9': + '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.5 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': + '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/core': 7.26.0 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.26.10 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': + '@babel/helper-module-transforms@7.27.3(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.26.10 + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-optimise-call-expression@7.25.9': + '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.26.5 - - '@babel/helper-plugin-utils@7.25.9': {} + '@babel/types': 7.28.0 - '@babel/helper-plugin-utils@7.26.5': {} + '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-replace-supers@7.25.9(@babel/core@7.26.10)': + '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/core': 7.26.10 - '@babel/helper-member-expression-to-functions': 7.25.9 - '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/core': 7.28.0 + '@babel/helper-member-expression-to-functions': 7.27.1 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.5 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 transitivePeerDependencies: - supports-color - '@babel/helper-string-parser@7.25.9': {} + '@babel/helper-string-parser@7.27.1': {} - '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-identifier@7.27.1': {} - '@babel/helper-validator-option@7.25.9': {} + '@babel/helper-validator-option@7.27.1': {} - '@babel/helpers@7.26.0': + '@babel/helpers@7.27.6': dependencies: - '@babel/template': 7.25.9 - '@babel/types': 7.26.5 + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 - '@babel/helpers@7.26.10': + '@babel/parser@7.28.0': dependencies: - '@babel/template': 7.26.9 - '@babel/types': 7.26.10 + '@babel/types': 7.28.0 - '@babel/parser@7.26.10': + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/types': 7.26.10 + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/parser@7.26.3': + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.28.0)': dependencies: - '@babel/types': 7.26.3 + '@babel/core': 7.28.0 + '@babel/helper-plugin-utils': 7.27.1 - '@babel/parser@7.26.5': + '@babel/plugin-transform-typescript@7.28.0(@babel/core@7.28.0)': dependencies: - '@babel/types': 7.26.5 - - '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.25.9 - - '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.26.5 - - '@babel/plugin-transform-typescript@7.26.8(@babel/core@7.26.10)': - dependencies: - '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.10) - '@babel/helper-plugin-utils': 7.26.5 - '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.10) + '@babel/core': 7.28.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.0) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.0) transitivePeerDependencies: - supports-color - '@babel/runtime@7.26.0': - dependencies: - regenerator-runtime: 0.14.1 - - '@babel/standalone@7.26.4': {} - - '@babel/template@7.25.9': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.5 - '@babel/types': 7.26.5 - - '@babel/template@7.26.9': - dependencies: - '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.10 - '@babel/types': 7.26.10 + '@babel/runtime@7.27.6': {} - '@babel/traverse@7.26.10': + '@babel/template@7.27.2': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.10 - '@babel/parser': 7.26.10 - '@babel/template': 7.26.9 - '@babel/types': 7.26.10 - debug: 4.4.0 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.28.0 + '@babel/types': 7.28.0 - '@babel/traverse@7.26.4': + '@babel/traverse@7.28.0': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.3 - '@babel/parser': 7.26.5 - '@babel/template': 7.25.9 - '@babel/types': 7.26.5 - debug: 4.4.0 - globals: 11.12.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.28.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.0 + '@babel/template': 7.27.2 + '@babel/types': 7.28.0 + debug: 4.4.1 transitivePeerDependencies: - supports-color - '@babel/types@7.26.10': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - - '@babel/types@7.26.3': + '@babel/types@7.28.0': dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 - '@babel/types@7.26.5': - dependencies: - '@babel/helper-string-parser': 7.25.9 - '@babel/helper-validator-identifier': 7.25.9 - - '@clack/core@0.4.1': + '@clack/core@0.5.0': dependencies: picocolors: 1.1.1 sisteransi: 1.0.5 - '@clack/prompts@0.10.0': + '@clack/prompts@0.11.0': dependencies: - '@clack/core': 0.4.1 + '@clack/core': 0.5.0 picocolors: 1.1.1 sisteransi: 1.0.5 '@ctrl/tinycolor@3.6.1': {} - '@emnapi/core@1.3.1': + '@emnapi/core@1.4.3': dependencies: - '@emnapi/wasi-threads': 1.0.1 + '@emnapi/wasi-threads': 1.0.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.3.1': + '@emnapi/runtime@1.4.3': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.0.1': + '@emnapi/wasi-threads@1.0.2': dependencies: tslib: 2.8.1 optional: true @@ -4525,17 +4361,18 @@ snapshots: '@emotion/unitless@0.8.1': {} - '@es-joy/jsdoccomment@0.49.0': + '@es-joy/jsdoccomment@0.50.2': dependencies: + '@types/estree': 1.0.8 + '@typescript-eslint/types': 8.35.1 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 - '@es-joy/jsdoccomment@0.50.0': + '@es-joy/jsdoccomment@0.52.0': dependencies: - '@types/eslint': 9.6.1 - '@types/estree': 1.0.6 - '@typescript-eslint/types': 8.26.1 + '@types/estree': 1.0.8 + '@typescript-eslint/types': 8.35.1 comment-parser: 1.4.1 esquery: 1.6.0 jsdoc-type-pratt-parser: 4.1.0 @@ -4543,216 +4380,228 @@ snapshots: '@esbuild/aix-ppc64@0.23.1': optional: true - '@esbuild/aix-ppc64@0.25.0': + '@esbuild/aix-ppc64@0.25.5': optional: true '@esbuild/android-arm64@0.23.1': optional: true - '@esbuild/android-arm64@0.25.0': + '@esbuild/android-arm64@0.25.5': optional: true '@esbuild/android-arm@0.23.1': optional: true - '@esbuild/android-arm@0.25.0': + '@esbuild/android-arm@0.25.5': optional: true '@esbuild/android-x64@0.23.1': optional: true - '@esbuild/android-x64@0.25.0': + '@esbuild/android-x64@0.25.5': optional: true '@esbuild/darwin-arm64@0.23.1': optional: true - '@esbuild/darwin-arm64@0.25.0': + '@esbuild/darwin-arm64@0.25.5': optional: true '@esbuild/darwin-x64@0.23.1': optional: true - '@esbuild/darwin-x64@0.25.0': + '@esbuild/darwin-x64@0.25.5': optional: true '@esbuild/freebsd-arm64@0.23.1': optional: true - '@esbuild/freebsd-arm64@0.25.0': + '@esbuild/freebsd-arm64@0.25.5': optional: true '@esbuild/freebsd-x64@0.23.1': optional: true - '@esbuild/freebsd-x64@0.25.0': + '@esbuild/freebsd-x64@0.25.5': optional: true '@esbuild/linux-arm64@0.23.1': optional: true - '@esbuild/linux-arm64@0.25.0': + '@esbuild/linux-arm64@0.25.5': optional: true '@esbuild/linux-arm@0.23.1': optional: true - '@esbuild/linux-arm@0.25.0': + '@esbuild/linux-arm@0.25.5': optional: true '@esbuild/linux-ia32@0.23.1': optional: true - '@esbuild/linux-ia32@0.25.0': + '@esbuild/linux-ia32@0.25.5': optional: true '@esbuild/linux-loong64@0.23.1': optional: true - '@esbuild/linux-loong64@0.25.0': + '@esbuild/linux-loong64@0.25.5': optional: true '@esbuild/linux-mips64el@0.23.1': optional: true - '@esbuild/linux-mips64el@0.25.0': + '@esbuild/linux-mips64el@0.25.5': optional: true '@esbuild/linux-ppc64@0.23.1': optional: true - '@esbuild/linux-ppc64@0.25.0': + '@esbuild/linux-ppc64@0.25.5': optional: true '@esbuild/linux-riscv64@0.23.1': optional: true - '@esbuild/linux-riscv64@0.25.0': + '@esbuild/linux-riscv64@0.25.5': optional: true '@esbuild/linux-s390x@0.23.1': optional: true - '@esbuild/linux-s390x@0.25.0': + '@esbuild/linux-s390x@0.25.5': optional: true '@esbuild/linux-x64@0.23.1': optional: true - '@esbuild/linux-x64@0.25.0': + '@esbuild/linux-x64@0.25.5': optional: true - '@esbuild/netbsd-arm64@0.25.0': + '@esbuild/netbsd-arm64@0.25.5': optional: true '@esbuild/netbsd-x64@0.23.1': optional: true - '@esbuild/netbsd-x64@0.25.0': + '@esbuild/netbsd-x64@0.25.5': optional: true '@esbuild/openbsd-arm64@0.23.1': optional: true - '@esbuild/openbsd-arm64@0.25.0': + '@esbuild/openbsd-arm64@0.25.5': optional: true '@esbuild/openbsd-x64@0.23.1': optional: true - '@esbuild/openbsd-x64@0.25.0': + '@esbuild/openbsd-x64@0.25.5': optional: true '@esbuild/sunos-x64@0.23.1': optional: true - '@esbuild/sunos-x64@0.25.0': + '@esbuild/sunos-x64@0.25.5': optional: true '@esbuild/win32-arm64@0.23.1': optional: true - '@esbuild/win32-arm64@0.25.0': + '@esbuild/win32-arm64@0.25.5': optional: true '@esbuild/win32-ia32@0.23.1': optional: true - '@esbuild/win32-ia32@0.25.0': + '@esbuild/win32-ia32@0.25.5': optional: true '@esbuild/win32-x64@0.23.1': optional: true - '@esbuild/win32-x64@0.25.0': + '@esbuild/win32-x64@0.25.5': optional: true - '@eslint-community/eslint-plugin-eslint-comments@4.4.1(eslint@9.23.0(jiti@2.4.2))': + '@eslint-community/eslint-plugin-eslint-comments@4.5.0(eslint@9.30.1(jiti@2.4.2))': dependencies: escape-string-regexp: 4.0.0 - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) ignore: 5.3.2 - '@eslint-community/eslint-utils@4.4.1(eslint@9.23.0(jiti@2.4.2))': + '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@2.4.2))': dependencies: - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} - '@eslint/compat@1.2.6(eslint@9.23.0(jiti@2.4.2))': + '@eslint/compat@1.3.1(eslint@9.30.1(jiti@2.4.2))': optionalDependencies: - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) - '@eslint/config-array@0.19.2': + '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.0 + debug: 4.4.1 minimatch: 3.1.2 transitivePeerDependencies: - supports-color - '@eslint/config-helpers@0.2.0': {} + '@eslint/config-helpers@0.3.0': {} + + '@eslint/core@0.13.0': + dependencies: + '@types/json-schema': 7.0.15 - '@eslint/core@0.10.0': + '@eslint/core@0.14.0': dependencies: '@types/json-schema': 7.0.15 - '@eslint/core@0.12.0': + '@eslint/core@0.15.1': dependencies: '@types/json-schema': 7.0.15 '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.0 - espree: 10.3.0 + debug: 4.4.1 + espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 - import-fresh: 3.3.0 + import-fresh: 3.3.1 js-yaml: 4.1.0 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color - '@eslint/js@9.23.0': {} + '@eslint/js@9.30.1': {} - '@eslint/markdown@6.3.0': + '@eslint/markdown@6.6.0': dependencies: - '@eslint/core': 0.10.0 - '@eslint/plugin-kit': 0.2.7 + '@eslint/core': 0.14.0 + '@eslint/plugin-kit': 0.3.3 + github-slugger: 2.0.0 mdast-util-from-markdown: 2.0.2 - mdast-util-gfm: 3.0.0 + mdast-util-frontmatter: 2.0.1 + mdast-util-gfm: 3.1.0 + micromark-extension-frontmatter: 2.0.0 micromark-extension-gfm: 3.0.0 transitivePeerDependencies: - supports-color '@eslint/object-schema@2.1.6': {} - '@eslint/plugin-kit@0.2.7': + '@eslint/plugin-kit@0.2.8': + dependencies: + '@eslint/core': 0.13.0 + levn: 0.4.1 + + '@eslint/plugin-kit@0.3.3': dependencies: - '@eslint/core': 0.12.0 + '@eslint/core': 0.15.1 levn: 0.4.1 '@formkit/auto-animate@0.8.2': {} @@ -4768,13 +4617,13 @@ snapshots: '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.2': {} + '@humanwhocodes/retry@0.4.3': {} '@iconify-json/fa@1.2.1': dependencies: '@iconify/types': 2.0.0 - '@iconify-json/tabler@1.2.17': + '@iconify-json/tabler@1.2.19': dependencies: '@iconify/types': 2.0.0 @@ -4783,7 +4632,7 @@ snapshots: '@iconify/types': 2.0.0 '@iconify/utils': 2.3.0 '@types/tar': 6.1.13 - axios: 1.8.4 + axios: 1.10.0 cheerio: 1.0.0 domhandler: 5.0.3 extract-zip: 2.0.1 @@ -4799,21 +4648,39 @@ snapshots: '@iconify/utils@2.3.0': dependencies: - '@antfu/install-pkg': 1.0.0 - '@antfu/utils': 8.1.0 + '@antfu/install-pkg': 1.1.0 + '@antfu/utils': 8.1.1 '@iconify/types': 2.0.0 - debug: 4.4.0 - globals: 15.14.0 + debug: 4.4.1 + globals: 15.15.0 kolorist: 1.8.0 - local-pkg: 1.0.0 + local-pkg: 1.1.1 mlly: 1.7.4 transitivePeerDependencies: - supports-color - '@iconify/vue@4.3.0(vue@3.5.13(typescript@5.8.2))': + '@iconify/vue@5.0.0(vue@3.5.17(typescript@5.8.3))': dependencies: '@iconify/types': 2.0.0 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) + + '@intlify/core-base@11.1.7': + dependencies: + '@intlify/message-compiler': 11.1.7 + '@intlify/shared': 11.1.7 + + '@intlify/message-compiler@11.1.7': + dependencies: + '@intlify/shared': 11.1.7 + source-map-js: 1.2.1 + + '@intlify/shared@11.1.7': {} + + '@isaacs/balanced-match@4.0.1': {} + + '@isaacs/brace-expansion@5.0.0': + dependencies: + '@isaacs/balanced-match': 4.0.1 '@isaacs/cliui@8.0.2': dependencies: @@ -4824,27 +4691,24 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@jridgewell/gen-mapping@0.3.8': + '@jridgewell/gen-mapping@0.3.12': dependencies: - '@jridgewell/set-array': 1.2.1 - '@jridgewell/sourcemap-codec': 1.5.0 - '@jridgewell/trace-mapping': 0.3.25 + '@jridgewell/sourcemap-codec': 1.5.4 + '@jridgewell/trace-mapping': 0.3.29 '@jridgewell/resolve-uri@3.1.2': {} - '@jridgewell/set-array@1.2.1': {} - - '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.4': {} - '@jridgewell/trace-mapping@0.3.25': + '@jridgewell/trace-mapping@0.3.29': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.4 - '@napi-rs/wasm-runtime@0.2.7': + '@napi-rs/wasm-runtime@0.2.11': dependencies: - '@emnapi/core': 1.3.1 - '@emnapi/runtime': 1.3.1 + '@emnapi/core': 1.4.3 + '@emnapi/runtime': 1.4.3 '@tybys/wasm-util': 0.9.0 optional: true @@ -4858,164 +4722,126 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.1 + fastq: 1.19.1 - '@nuxt/kit@3.14.1592(rollup@4.34.6)': + '@nuxt/kit@3.17.5': dependencies: - '@nuxt/schema': 3.14.1592(rollup@4.34.6) - c12: 2.0.1 - consola: 3.2.3 + c12: 3.0.4 + consola: 3.4.2 defu: 6.1.4 - destr: 2.0.3 - globby: 14.0.2 - hash-sum: 2.0.0 - ignore: 6.0.2 - jiti: 2.4.1 + destr: 2.0.5 + errx: 0.1.0 + exsolve: 1.0.7 + ignore: 7.0.5 + jiti: 2.4.2 klona: 2.0.6 - knitwork: 1.1.0 + knitwork: 1.2.0 mlly: 1.7.4 - pathe: 1.1.2 - pkg-types: 1.3.1 - scule: 1.3.0 - semver: 7.6.3 - ufo: 1.5.4 - unctx: 2.4.0 - unimport: 3.14.5(rollup@4.34.6) - untyped: 1.5.1 - transitivePeerDependencies: - - magicast - - rollup - - supports-color - - '@nuxt/schema@3.14.1592(rollup@4.34.6)': - dependencies: - c12: 2.0.1 - compatx: 0.1.8 - consola: 3.2.3 - defu: 6.1.4 - hookable: 5.5.3 - pathe: 1.1.2 - pkg-types: 1.3.1 + ohash: 2.0.11 + pathe: 2.0.3 + pkg-types: 2.2.0 scule: 1.3.0 - std-env: 3.8.0 - ufo: 1.5.4 - uncrypto: 0.1.3 - unimport: 3.14.5(rollup@4.34.6) - untyped: 1.5.1 + semver: 7.7.2 + std-env: 3.9.0 + tinyglobby: 0.2.14 + ufo: 1.6.1 + unctx: 2.4.1 + unimport: 5.1.0 + untyped: 2.0.0 transitivePeerDependencies: - magicast - - rollup - - supports-color - - '@pkgjs/parseargs@0.11.0': optional: true - '@pkgr/core@0.1.1': {} - - '@polka/url@1.0.0-next.28': {} - - '@rollup/pluginutils@5.1.4(rollup@4.34.6)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.34.6 + '@oxc-project/runtime@0.75.0': {} - '@rollup/rollup-android-arm-eabi@4.34.6': - optional: true + '@oxc-project/types@0.75.0': {} - '@rollup/rollup-android-arm64@4.34.6': + '@pkgjs/parseargs@0.11.0': optional: true - '@rollup/rollup-darwin-arm64@4.34.6': - optional: true + '@pkgr/core@0.2.7': {} - '@rollup/rollup-darwin-x64@4.34.6': - optional: true + '@polka/url@1.0.0-next.29': {} - '@rollup/rollup-freebsd-arm64@4.34.6': - optional: true + '@quansync/fs@0.1.3': + dependencies: + quansync: 0.2.10 - '@rollup/rollup-freebsd-x64@4.34.6': + '@rolldown/binding-darwin-arm64@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.34.6': + '@rolldown/binding-darwin-x64@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.34.6': + '@rolldown/binding-freebsd-x64@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-arm64-gnu@4.34.6': + '@rolldown/binding-linux-arm-gnueabihf@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-arm64-musl@4.34.6': + '@rolldown/binding-linux-arm64-gnu@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-loongarch64-gnu@4.34.6': + '@rolldown/binding-linux-arm64-musl@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-powerpc64le-gnu@4.34.6': + '@rolldown/binding-linux-x64-gnu@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.34.6': + '@rolldown/binding-linux-x64-musl@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-s390x-gnu@4.34.6': + '@rolldown/binding-wasm32-wasi@1.0.0-beta.23': + dependencies: + '@napi-rs/wasm-runtime': 0.2.11 optional: true - '@rollup/rollup-linux-x64-gnu@4.34.6': + '@rolldown/binding-win32-arm64-msvc@1.0.0-beta.23': optional: true - '@rollup/rollup-linux-x64-musl@4.34.6': + '@rolldown/binding-win32-ia32-msvc@1.0.0-beta.23': optional: true - '@rollup/rollup-win32-arm64-msvc@4.34.6': + '@rolldown/binding-win32-x64-msvc@1.0.0-beta.23': optional: true - '@rollup/rollup-win32-ia32-msvc@4.34.6': - optional: true + '@rolldown/pluginutils@1.0.0-beta.19': {} - '@rollup/rollup-win32-x64-msvc@4.34.6': - optional: true + '@rolldown/pluginutils@1.0.0-beta.23': {} '@simonwep/pickr@1.8.2': dependencies: - core-js: 3.39.0 + core-js: 3.43.0 nanopop: 2.4.2 '@simplewebauthn/browser@13.1.0': {} - '@sindresorhus/merge-streams@2.3.0': {} - - '@stylistic/eslint-plugin@4.2.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + '@stylistic/eslint-plugin@5.1.0(eslint@9.30.1(jiti@2.4.2))': dependencies: - '@typescript-eslint/utils': 8.26.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - eslint: 9.23.0(jiti@2.4.2) - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/types': 8.35.1 + eslint: 9.30.1(jiti@2.4.2) + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.2 - transitivePeerDependencies: - - supports-color - - typescript - '@svgdotjs/svg.draggable.js@3.0.4(@svgdotjs/svg.js@3.2.4)': + '@svgdotjs/svg.draggable.js@3.0.6(@svgdotjs/svg.js@3.2.4)': dependencies: '@svgdotjs/svg.js': 3.2.4 - '@svgdotjs/svg.filter.js@3.0.8': + '@svgdotjs/svg.filter.js@3.0.9': dependencies: '@svgdotjs/svg.js': 3.2.4 '@svgdotjs/svg.js@3.2.4': {} - '@svgdotjs/svg.resize.js@2.0.5(@svgdotjs/svg.js@3.2.4)(@svgdotjs/svg.select.js@4.0.2(@svgdotjs/svg.js@3.2.4))': + '@svgdotjs/svg.resize.js@2.0.5(@svgdotjs/svg.js@3.2.4)(@svgdotjs/svg.select.js@4.0.3(@svgdotjs/svg.js@3.2.4))': dependencies: '@svgdotjs/svg.js': 3.2.4 - '@svgdotjs/svg.select.js': 4.0.2(@svgdotjs/svg.js@3.2.4) + '@svgdotjs/svg.select.js': 4.0.3(@svgdotjs/svg.js@3.2.4) - '@svgdotjs/svg.select.js@4.0.2(@svgdotjs/svg.js@3.2.4)': + '@svgdotjs/svg.select.js@4.0.3(@svgdotjs/svg.js@3.2.4)': dependencies: '@svgdotjs/svg.js': 3.2.4 @@ -5028,39 +4854,32 @@ snapshots: '@types/debug@4.1.12': dependencies: - '@types/ms': 0.7.34 - - '@types/doctrine@0.0.9': {} - - '@types/eslint@9.6.1': - dependencies: - '@types/estree': 1.0.6 - '@types/json-schema': 7.0.15 + '@types/ms': 2.1.0 - '@types/estree@1.0.6': {} + '@types/estree@1.0.8': {} '@types/glob@7.2.0': dependencies: - '@types/minimatch': 5.1.2 - '@types/node': 22.10.2 + '@types/minimatch': 6.0.0 + '@types/node': 24.0.10 '@types/json-schema@7.0.15': {} - '@types/lodash@4.17.16': {} + '@types/lodash@4.17.20': {} '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 - '@types/minimatch@5.1.2': {} + '@types/minimatch@6.0.0': + dependencies: + minimatch: 10.0.3 - '@types/ms@0.7.34': {} + '@types/ms@2.1.0': {} - '@types/node@22.10.2': + '@types/node@24.0.10': dependencies: - undici-types: 6.20.0 - - '@types/normalize-package-data@2.4.4': {} + undici-types: 7.8.0 '@types/nprogress@0.2.3': {} @@ -5070,7 +4889,7 @@ snapshots: '@types/tar@6.1.13': dependencies: - '@types/node': 22.10.2 + '@types/node': 24.0.10 minipass: 4.2.8 '@types/trusted-types@2.0.7': @@ -5082,407 +4901,382 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.10.2 + '@types/node': 24.0.10 optional: true - '@typescript-eslint/eslint-plugin@8.27.0(@typescript-eslint/parser@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + '@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/scope-manager': 8.27.0 - '@typescript-eslint/type-utils': 8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/utils': 8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.27.0 - eslint: 9.23.0(jiti@2.4.2) + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/type-utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.1 + eslint: 9.30.1(jiti@2.4.2) graphemer: 1.4.0 - ignore: 5.3.2 + ignore: 7.0.5 natural-compare: 1.4.0 - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + '@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/scope-manager': 8.27.0 - '@typescript-eslint/types': 8.27.0 - '@typescript-eslint/typescript-estree': 8.27.0(typescript@5.8.2) - '@typescript-eslint/visitor-keys': 8.27.0 - debug: 4.4.0 - eslint: 9.23.0(jiti@2.4.2) - typescript: 5.8.2 + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + '@typescript-eslint/visitor-keys': 8.35.1 + debug: 4.4.1 + eslint: 9.30.1(jiti@2.4.2) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.26.1': + '@typescript-eslint/project-service@8.35.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 - - '@typescript-eslint/scope-manager@8.27.0': - dependencies: - '@typescript-eslint/types': 8.27.0 - '@typescript-eslint/visitor-keys': 8.27.0 - - '@typescript-eslint/type-utils@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': - dependencies: - '@typescript-eslint/typescript-estree': 8.27.0(typescript@5.8.2) - '@typescript-eslint/utils': 8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - debug: 4.4.0 - eslint: 9.23.0(jiti@2.4.2) - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) + '@typescript-eslint/types': 8.35.1 + debug: 4.4.1 + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.26.1': {} + '@typescript-eslint/scope-manager@8.35.1': + dependencies: + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/visitor-keys': 8.35.1 - '@typescript-eslint/types@8.27.0': {} + '@typescript-eslint/tsconfig-utils@8.35.1(typescript@5.8.3)': + dependencies: + typescript: 5.8.3 - '@typescript-eslint/typescript-estree@8.26.1(typescript@5.8.2)': + '@typescript-eslint/type-utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/visitor-keys': 8.26.1 - debug: 4.4.0 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + debug: 4.4.1 + eslint: 9.30.1(jiti@2.4.2) + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.27.0(typescript@5.8.2)': + '@typescript-eslint/types@8.35.1': {} + + '@typescript-eslint/typescript-estree@8.35.1(typescript@5.8.3)': dependencies: - '@typescript-eslint/types': 8.27.0 - '@typescript-eslint/visitor-keys': 8.27.0 - debug: 4.4.0 + '@typescript-eslint/project-service': 8.35.1(typescript@5.8.3) + '@typescript-eslint/tsconfig-utils': 8.35.1(typescript@5.8.3) + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/visitor-keys': 8.35.1 + debug: 4.4.1 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 - semver: 7.7.1 - ts-api-utils: 2.0.1(typescript@5.8.2) - typescript: 5.8.2 - transitivePeerDependencies: - - supports-color - - '@typescript-eslint/utils@8.26.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': - dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.26.1 - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/typescript-estree': 8.26.1(typescript@5.8.2) - eslint: 9.23.0(jiti@2.4.2) - typescript: 5.8.2 + semver: 7.7.2 + ts-api-utils: 2.1.0(typescript@5.8.3) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + '@typescript-eslint/utils@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.27.0 - '@typescript-eslint/types': 8.27.0 - '@typescript-eslint/typescript-estree': 8.27.0(typescript@5.8.2) - eslint: 9.23.0(jiti@2.4.2) - typescript: 5.8.2 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/scope-manager': 8.35.1 + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/typescript-estree': 8.35.1(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) + typescript: 5.8.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.26.1': - dependencies: - '@typescript-eslint/types': 8.26.1 - eslint-visitor-keys: 4.2.0 - - '@typescript-eslint/visitor-keys@8.27.0': + '@typescript-eslint/visitor-keys@8.35.1': dependencies: - '@typescript-eslint/types': 8.27.0 - eslint-visitor-keys: 4.2.0 + '@typescript-eslint/types': 8.35.1 + eslint-visitor-keys: 4.2.1 - '@unocss/astro@66.0.0(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@unocss/astro@66.3.2(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: - '@unocss/core': 66.0.0 - '@unocss/reset': 66.0.0 - '@unocss/vite': 66.0.0(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + '@unocss/core': 66.3.2 + '@unocss/reset': 66.3.2 + '@unocss/vite': 66.3.2(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) optionalDependencies: - vite: 6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0) + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) transitivePeerDependencies: - vue - '@unocss/cli@66.0.0': + '@unocss/cli@66.3.2': dependencies: '@ampproject/remapping': 2.3.0 - '@unocss/config': 66.0.0 - '@unocss/core': 66.0.0 - '@unocss/preset-uno': 66.0.0 + '@unocss/config': 66.3.2 + '@unocss/core': 66.3.2 + '@unocss/preset-uno': 66.3.2 cac: 6.7.14 chokidar: 3.6.0 colorette: 2.0.20 - consola: 3.4.0 + consola: 3.4.2 magic-string: 0.30.17 pathe: 2.0.3 perfect-debounce: 1.0.0 - tinyglobby: 0.2.12 + tinyglobby: 0.2.14 unplugin-utils: 0.2.4 - '@unocss/config@66.0.0': + '@unocss/config@66.3.2': dependencies: - '@unocss/core': 66.0.0 - unconfig: 7.0.0 + '@unocss/core': 66.3.2 + unconfig: 7.3.2 - '@unocss/core@66.0.0': {} + '@unocss/core@66.3.2': {} - '@unocss/extractor-arbitrary-variants@66.0.0': + '@unocss/extractor-arbitrary-variants@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 - '@unocss/inspector@66.0.0(vue@3.5.13(typescript@5.8.2))': + '@unocss/inspector@66.3.2(vue@3.5.17(typescript@5.8.3))': dependencies: - '@unocss/core': 66.0.0 - '@unocss/rule-utils': 66.0.0 + '@unocss/core': 66.3.2 + '@unocss/rule-utils': 66.3.2 colorette: 2.0.20 gzip-size: 6.0.0 - sirv: 3.0.0 - vue-flow-layout: 0.1.1(vue@3.5.13(typescript@5.8.2)) + sirv: 3.0.1 + vue-flow-layout: 0.1.1(vue@3.5.17(typescript@5.8.3)) transitivePeerDependencies: - vue - '@unocss/postcss@66.0.0(postcss@8.5.3)': + '@unocss/postcss@66.3.2(postcss@8.5.6)': dependencies: - '@unocss/config': 66.0.0 - '@unocss/core': 66.0.0 - '@unocss/rule-utils': 66.0.0 + '@unocss/config': 66.3.2 + '@unocss/core': 66.3.2 + '@unocss/rule-utils': 66.3.2 css-tree: 3.1.0 - postcss: 8.5.3 - tinyglobby: 0.2.12 + postcss: 8.5.6 + tinyglobby: 0.2.14 - '@unocss/preset-attributify@66.0.0': + '@unocss/preset-attributify@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 - '@unocss/preset-icons@66.0.0': + '@unocss/preset-icons@66.3.2': dependencies: '@iconify/utils': 2.3.0 - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 ofetch: 1.4.1 transitivePeerDependencies: - supports-color - '@unocss/preset-mini@66.0.0': + '@unocss/preset-mini@66.3.2': dependencies: - '@unocss/core': 66.0.0 - '@unocss/extractor-arbitrary-variants': 66.0.0 - '@unocss/rule-utils': 66.0.0 + '@unocss/core': 66.3.2 + '@unocss/extractor-arbitrary-variants': 66.3.2 + '@unocss/rule-utils': 66.3.2 - '@unocss/preset-tagify@66.0.0': + '@unocss/preset-tagify@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 - '@unocss/preset-typography@66.0.0': + '@unocss/preset-typography@66.3.2': dependencies: - '@unocss/core': 66.0.0 - '@unocss/preset-mini': 66.0.0 - '@unocss/rule-utils': 66.0.0 + '@unocss/core': 66.3.2 + '@unocss/preset-mini': 66.3.2 + '@unocss/rule-utils': 66.3.2 - '@unocss/preset-uno@66.0.0': + '@unocss/preset-uno@66.3.2': dependencies: - '@unocss/core': 66.0.0 - '@unocss/preset-wind3': 66.0.0 + '@unocss/core': 66.3.2 + '@unocss/preset-wind3': 66.3.2 - '@unocss/preset-web-fonts@66.0.0': + '@unocss/preset-web-fonts@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 ofetch: 1.4.1 - '@unocss/preset-wind3@66.0.0': + '@unocss/preset-wind3@66.3.2': dependencies: - '@unocss/core': 66.0.0 - '@unocss/preset-mini': 66.0.0 - '@unocss/rule-utils': 66.0.0 + '@unocss/core': 66.3.2 + '@unocss/preset-mini': 66.3.2 + '@unocss/rule-utils': 66.3.2 - '@unocss/preset-wind@66.0.0': + '@unocss/preset-wind4@66.3.2': dependencies: - '@unocss/core': 66.0.0 - '@unocss/preset-wind3': 66.0.0 + '@unocss/core': 66.3.2 + '@unocss/extractor-arbitrary-variants': 66.3.2 + '@unocss/rule-utils': 66.3.2 - '@unocss/reset@66.0.0': {} + '@unocss/preset-wind@66.3.2': + dependencies: + '@unocss/core': 66.3.2 + '@unocss/preset-wind3': 66.3.2 + + '@unocss/reset@66.3.2': {} - '@unocss/rule-utils@66.0.0': + '@unocss/rule-utils@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 magic-string: 0.30.17 - '@unocss/transformer-attributify-jsx@66.0.0': + '@unocss/transformer-attributify-jsx@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 - '@unocss/transformer-compile-class@66.0.0': + '@unocss/transformer-compile-class@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 - '@unocss/transformer-directives@66.0.0': + '@unocss/transformer-directives@66.3.2': dependencies: - '@unocss/core': 66.0.0 - '@unocss/rule-utils': 66.0.0 + '@unocss/core': 66.3.2 + '@unocss/rule-utils': 66.3.2 css-tree: 3.1.0 - '@unocss/transformer-variant-group@66.0.0': + '@unocss/transformer-variant-group@66.3.2': dependencies: - '@unocss/core': 66.0.0 + '@unocss/core': 66.3.2 - '@unocss/vite@66.0.0(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@unocss/vite@66.3.2(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: '@ampproject/remapping': 2.3.0 - '@unocss/config': 66.0.0 - '@unocss/core': 66.0.0 - '@unocss/inspector': 66.0.0(vue@3.5.13(typescript@5.8.2)) + '@unocss/config': 66.3.2 + '@unocss/core': 66.3.2 + '@unocss/inspector': 66.3.2(vue@3.5.17(typescript@5.8.3)) chokidar: 3.6.0 magic-string: 0.30.17 - tinyglobby: 0.2.12 + pathe: 2.0.3 + tinyglobby: 0.2.14 unplugin-utils: 0.2.4 - vite: 6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0) + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) transitivePeerDependencies: - vue - '@unrs/rspack-resolver-binding-darwin-arm64@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-darwin-x64@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-freebsd-x64@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-linux-arm-gnueabihf@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-linux-arm64-gnu@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-linux-arm64-musl@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-linux-x64-gnu@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-linux-x64-musl@1.2.2': - optional: true - - '@unrs/rspack-resolver-binding-wasm32-wasi@1.2.2': + '@uozi-admin/curd@4.3.12(@ant-design/icons-vue@7.0.1(vue@3.5.17(typescript@5.8.3)))(ant-design-vue@4.2.6(vue@3.5.17(typescript@5.8.3)))(dayjs@1.11.13)(lodash-es@4.17.21)(vue-router@4.5.1(vue@3.5.17(typescript@5.8.3)))(vue@3.5.17(typescript@5.8.3))': dependencies: - '@napi-rs/wasm-runtime': 0.2.7 - optional: true - - '@unrs/rspack-resolver-binding-win32-arm64-msvc@1.2.2': - optional: true + '@ant-design/icons-vue': 7.0.1(vue@3.5.17(typescript@5.8.3)) + '@vueuse/core': 13.5.0(vue@3.5.17(typescript@5.8.3)) + ant-design-vue: 4.2.6(vue@3.5.17(typescript@5.8.3)) + dayjs: 1.11.13 + lodash-es: 4.17.21 + scroll-into-view-if-needed: 3.1.0 + sortablejs: 1.15.6 + vue: 3.5.17(typescript@5.8.3) + vue-i18n: 11.1.7(vue@3.5.17(typescript@5.8.3)) + vue-router: 4.5.1(vue@3.5.17(typescript@5.8.3)) + vue-types: 6.0.0(vue@3.5.17(typescript@5.8.3)) + xlsx: https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz - '@unrs/rspack-resolver-binding-win32-x64-msvc@1.2.2': - optional: true + '@uozi-admin/request@2.8.1(lodash-es@4.17.21)': + dependencies: + axios: 1.10.0 + lodash-es: 4.17.21 + transitivePeerDependencies: + - debug - '@vitejs/plugin-vue-jsx@4.1.2(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vitejs/plugin-vue-jsx@5.0.1(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: - '@babel/core': 7.26.10 - '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.26.10) - '@vue/babel-plugin-jsx': 1.2.5(@babel/core@7.26.10) - vite: 6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0) - vue: 3.5.13(typescript@5.8.2) + '@babel/core': 7.28.0 + '@babel/plugin-transform-typescript': 7.28.0(@babel/core@7.28.0) + '@rolldown/pluginutils': 1.0.0-beta.23 + '@vue/babel-plugin-jsx': 1.4.0(@babel/core@7.28.0) + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) + vue: 3.5.17(typescript@5.8.3) transitivePeerDependencies: - supports-color - '@vitejs/plugin-vue@5.2.3(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2))': + '@vitejs/plugin-vue@6.0.0(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3))': dependencies: - vite: 6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0) - vue: 3.5.13(typescript@5.8.2) + '@rolldown/pluginutils': 1.0.0-beta.19 + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) + vue: 3.5.17(typescript@5.8.3) - '@vitest/eslint-plugin@1.1.38(@typescript-eslint/utils@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2)': + '@vitest/eslint-plugin@1.3.4(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3)': dependencies: - '@typescript-eslint/utils': 8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - eslint: 9.23.0(jiti@2.4.2) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 + transitivePeerDependencies: + - supports-color - '@volar/language-core@2.4.11': + '@volar/language-core@2.4.17': dependencies: - '@volar/source-map': 2.4.11 + '@volar/source-map': 2.4.17 - '@volar/source-map@2.4.11': {} + '@volar/source-map@2.4.17': {} - '@volar/typescript@2.4.11': + '@volar/typescript@2.4.17': dependencies: - '@volar/language-core': 2.4.11 + '@volar/language-core': 2.4.17 path-browserify: 1.0.1 - vscode-uri: 3.0.8 + vscode-uri: 3.1.0 - '@vue-macros/common@1.16.1(vue@3.5.13(typescript@5.8.2))': + '@vue-macros/common@1.16.1(vue@3.5.17(typescript@5.8.3))': dependencies: - '@vue/compiler-sfc': 3.5.13 - ast-kit: 1.4.0 + '@vue/compiler-sfc': 3.5.17 + ast-kit: 1.4.3 local-pkg: 1.1.1 - magic-string-ast: 0.7.0 + magic-string-ast: 0.7.1 pathe: 2.0.3 picomatch: 4.0.2 optionalDependencies: - vue: 3.5.13(typescript@5.8.2) - - '@vue/babel-helper-vue-transform-on@1.2.5': {} - - '@vue/babel-plugin-jsx@1.2.5(@babel/core@7.26.10)': - dependencies: - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.10) - '@babel/template': 7.25.9 - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.5 - '@vue/babel-helper-vue-transform-on': 1.2.5 - '@vue/babel-plugin-resolve-type': 1.2.5(@babel/core@7.26.10) - html-tags: 3.3.1 - svg-tags: 1.0.0 + vue: 3.5.17(typescript@5.8.3) + + '@vue/babel-helper-vue-transform-on@1.4.0': {} + + '@vue/babel-plugin-jsx@1.4.0(@babel/core@7.28.0)': + dependencies: + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.0) + '@babel/template': 7.27.2 + '@babel/traverse': 7.28.0 + '@babel/types': 7.28.0 + '@vue/babel-helper-vue-transform-on': 1.4.0 + '@vue/babel-plugin-resolve-type': 1.4.0(@babel/core@7.28.0) + '@vue/shared': 3.5.17 optionalDependencies: - '@babel/core': 7.26.10 + '@babel/core': 7.28.0 transitivePeerDependencies: - supports-color - '@vue/babel-plugin-resolve-type@1.2.5(@babel/core@7.26.10)': + '@vue/babel-plugin-resolve-type@1.4.0(@babel/core@7.28.0)': dependencies: - '@babel/code-frame': 7.26.2 - '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/parser': 7.26.5 - '@vue/compiler-sfc': 3.5.13 + '@babel/code-frame': 7.27.1 + '@babel/core': 7.28.0 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/parser': 7.28.0 + '@vue/compiler-sfc': 3.5.17 transitivePeerDependencies: - supports-color - '@vue/compiler-core@3.5.13': + '@vue/compiler-core@3.5.17': dependencies: - '@babel/parser': 7.26.3 - '@vue/shared': 3.5.13 + '@babel/parser': 7.28.0 + '@vue/shared': 3.5.17 entities: 4.5.0 estree-walker: 2.0.2 source-map-js: 1.2.1 - '@vue/compiler-dom@3.5.13': + '@vue/compiler-dom@3.5.17': dependencies: - '@vue/compiler-core': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-core': 3.5.17 + '@vue/shared': 3.5.17 - '@vue/compiler-sfc@3.5.13': + '@vue/compiler-sfc@3.5.17': dependencies: - '@babel/parser': 7.26.3 - '@vue/compiler-core': 3.5.13 - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 + '@babel/parser': 7.28.0 + '@vue/compiler-core': 3.5.17 + '@vue/compiler-dom': 3.5.17 + '@vue/compiler-ssr': 3.5.17 + '@vue/shared': 3.5.17 estree-walker: 2.0.2 - magic-string: 0.30.15 - postcss: 8.5.3 + magic-string: 0.30.17 + postcss: 8.5.6 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.13': + '@vue/compiler-ssr@3.5.17': dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.5.17 + '@vue/shared': 3.5.17 '@vue/compiler-vue2@2.7.16': dependencies: @@ -5491,96 +5285,96 @@ snapshots: '@vue/devtools-api@6.6.4': {} - '@vue/devtools-api@7.7.2': + '@vue/devtools-api@7.7.7': dependencies: - '@vue/devtools-kit': 7.7.2 + '@vue/devtools-kit': 7.7.7 - '@vue/devtools-kit@7.7.2': + '@vue/devtools-kit@7.7.7': dependencies: - '@vue/devtools-shared': 7.7.2 - birpc: 0.2.19 + '@vue/devtools-shared': 7.7.7 + birpc: 2.4.0 hookable: 5.5.3 mitt: 3.0.1 perfect-debounce: 1.0.0 speakingurl: 14.0.1 superjson: 2.2.2 - '@vue/devtools-shared@7.7.2': + '@vue/devtools-shared@7.7.7': dependencies: rfdc: 1.4.1 - '@vue/language-core@2.2.8(typescript@5.8.2)': + '@vue/language-core@3.0.1(typescript@5.8.3)': dependencies: - '@volar/language-core': 2.4.11 - '@vue/compiler-dom': 3.5.13 + '@volar/language-core': 2.4.17 + '@vue/compiler-dom': 3.5.17 '@vue/compiler-vue2': 2.7.16 - '@vue/shared': 3.5.13 - alien-signals: 1.0.3 - minimatch: 9.0.5 + '@vue/shared': 3.5.17 + alien-signals: 2.0.5 + minimatch: 10.0.3 muggle-string: 0.4.1 path-browserify: 1.0.1 optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 - '@vue/reactivity@3.5.13': + '@vue/reactivity@3.5.17': dependencies: - '@vue/shared': 3.5.13 + '@vue/shared': 3.5.17 - '@vue/runtime-core@3.5.13': + '@vue/runtime-core@3.5.17': dependencies: - '@vue/reactivity': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/reactivity': 3.5.17 + '@vue/shared': 3.5.17 - '@vue/runtime-dom@3.5.13': + '@vue/runtime-dom@3.5.17': dependencies: - '@vue/reactivity': 3.5.13 - '@vue/runtime-core': 3.5.13 - '@vue/shared': 3.5.13 + '@vue/reactivity': 3.5.17 + '@vue/runtime-core': 3.5.17 + '@vue/shared': 3.5.17 csstype: 3.1.3 - '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.8.2))': + '@vue/server-renderer@3.5.17(vue@3.5.17(typescript@5.8.3))': dependencies: - '@vue/compiler-ssr': 3.5.13 - '@vue/shared': 3.5.13 - vue: 3.5.13(typescript@5.8.2) + '@vue/compiler-ssr': 3.5.17 + '@vue/shared': 3.5.17 + vue: 3.5.17(typescript@5.8.3) - '@vue/shared@3.5.13': {} + '@vue/shared@3.5.17': {} - '@vue/tsconfig@0.7.0(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2))': + '@vue/tsconfig@0.7.0(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3))': optionalDependencies: - typescript: 5.8.2 - vue: 3.5.13(typescript@5.8.2) + typescript: 5.8.3 + vue: 3.5.17(typescript@5.8.3) - '@vueuse/components@13.0.0(vue@3.5.13(typescript@5.8.2))': + '@vueuse/components@13.5.0(vue@3.5.17(typescript@5.8.3))': dependencies: - '@vueuse/core': 13.0.0(vue@3.5.13(typescript@5.8.2)) - '@vueuse/shared': 13.0.0(vue@3.5.13(typescript@5.8.2)) - vue: 3.5.13(typescript@5.8.2) + '@vueuse/core': 13.5.0(vue@3.5.17(typescript@5.8.3)) + '@vueuse/shared': 13.5.0(vue@3.5.17(typescript@5.8.3)) + vue: 3.5.17(typescript@5.8.3) - '@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2))': + '@vueuse/core@13.5.0(vue@3.5.17(typescript@5.8.3))': dependencies: '@types/web-bluetooth': 0.0.21 - '@vueuse/metadata': 13.0.0 - '@vueuse/shared': 13.0.0(vue@3.5.13(typescript@5.8.2)) - vue: 3.5.13(typescript@5.8.2) + '@vueuse/metadata': 13.5.0 + '@vueuse/shared': 13.5.0(vue@3.5.17(typescript@5.8.3)) + vue: 3.5.17(typescript@5.8.3) - '@vueuse/integrations@13.0.0(async-validator@4.2.5)(axios@1.8.4)(nprogress@0.2.0)(sortablejs@1.15.6)(universal-cookie@8.0.1)(vue@3.5.13(typescript@5.8.2))': + '@vueuse/integrations@13.5.0(async-validator@4.2.5)(axios@1.10.0)(nprogress@0.2.0)(sortablejs@1.15.6)(universal-cookie@8.0.1)(vue@3.5.17(typescript@5.8.3))': dependencies: - '@vueuse/core': 13.0.0(vue@3.5.13(typescript@5.8.2)) - '@vueuse/shared': 13.0.0(vue@3.5.13(typescript@5.8.2)) - vue: 3.5.13(typescript@5.8.2) + '@vueuse/core': 13.5.0(vue@3.5.17(typescript@5.8.3)) + '@vueuse/shared': 13.5.0(vue@3.5.17(typescript@5.8.3)) + vue: 3.5.17(typescript@5.8.3) optionalDependencies: async-validator: 4.2.5 - axios: 1.8.4 + axios: 1.10.0 nprogress: 0.2.0 sortablejs: 1.15.6 universal-cookie: 8.0.1 - '@vueuse/metadata@13.0.0': {} + '@vueuse/metadata@13.5.0': {} - '@vueuse/shared@13.0.0(vue@3.5.13(typescript@5.8.2))': + '@vueuse/shared@13.5.0(vue@3.5.17(typescript@5.8.3))': dependencies: - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) '@xterm/addon-attach@0.11.0(@xterm/xterm@5.5.0)': dependencies: @@ -5594,15 +5388,13 @@ snapshots: '@yr/monotone-cubic-spline@1.0.3': {} - ace-builds@1.39.1: {} + ace-builds@1.43.1: {} - acorn-jsx@5.3.2(acorn@8.14.0): + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: - acorn: 8.14.0 - - acorn@8.14.0: {} + acorn: 8.15.0 - acorn@8.14.1: {} + acorn@8.15.0: {} ajv@6.12.6: dependencies: @@ -5611,7 +5403,7 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - alien-signals@1.0.3: {} + alien-signals@2.0.5: {} ansi-regex@5.0.1: {} @@ -5623,13 +5415,13 @@ snapshots: ansi-styles@6.2.1: {} - ansis@3.17.0: {} + ansis@4.1.0: {} - ant-design-vue@4.2.6(vue@3.5.13(typescript@5.8.2)): + ant-design-vue@4.2.6(vue@3.5.17(typescript@5.8.3)): dependencies: '@ant-design/colors': 6.0.0 - '@ant-design/icons-vue': 7.0.1(vue@3.5.13(typescript@5.8.2)) - '@babel/runtime': 7.26.0 + '@ant-design/icons-vue': 7.0.1(vue@3.5.17(typescript@5.8.3)) + '@babel/runtime': 7.27.6 '@ctrl/tinycolor': 3.6.1 '@emotion/hash': 0.9.2 '@emotion/unitless': 0.8.1 @@ -5645,10 +5437,10 @@ snapshots: resize-observer-polyfill: 1.5.1 scroll-into-view-if-needed: 2.2.31 shallow-equal: 1.2.1 - stylis: 4.3.4 + stylis: 4.3.6 throttle-debounce: 5.0.2 - vue: 3.5.13(typescript@5.8.2) - vue-types: 3.0.2(vue@3.5.13(typescript@5.8.2)) + vue: 3.5.17(typescript@5.8.3) + vue-types: 3.0.2(vue@3.5.17(typescript@5.8.3)) warning: 4.0.3 anymatch@3.1.3: @@ -5656,13 +5448,13 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 - apexcharts@4.5.0: + apexcharts@4.7.0: dependencies: - '@svgdotjs/svg.draggable.js': 3.0.4(@svgdotjs/svg.js@3.2.4) - '@svgdotjs/svg.filter.js': 3.0.8 + '@svgdotjs/svg.draggable.js': 3.0.6(@svgdotjs/svg.js@3.2.4) + '@svgdotjs/svg.filter.js': 3.0.9 '@svgdotjs/svg.js': 3.2.4 - '@svgdotjs/svg.resize.js': 2.0.5(@svgdotjs/svg.js@3.2.4)(@svgdotjs/svg.select.js@4.0.2(@svgdotjs/svg.js@3.2.4)) - '@svgdotjs/svg.select.js': 4.0.2(@svgdotjs/svg.js@3.2.4) + '@svgdotjs/svg.resize.js': 2.0.5(@svgdotjs/svg.js@3.2.4)(@svgdotjs/svg.select.js@4.0.3(@svgdotjs/svg.js@3.2.4)) + '@svgdotjs/svg.select.js': 4.0.3(@svgdotjs/svg.js@3.2.4) '@yr/monotone-cubic-spline': 1.0.3 are-docs-informative@0.0.2: {} @@ -5671,54 +5463,52 @@ snapshots: array-back@3.1.0: {} - array-buffer-byte-length@1.0.1: + array-buffer-byte-length@1.0.2: dependencies: - call-bind: 1.0.8 - is-array-buffer: 3.0.4 + call-bound: 1.0.4 + is-array-buffer: 3.0.5 - array-includes@3.1.8: + array-includes@3.1.9: dependencies: call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.5 - es-object-atoms: 1.0.0 - get-intrinsic: 1.2.6 - is-string: 1.1.0 + es-abstract: 1.24.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 array-tree-filter@2.1.0: {} - array.prototype.flat@1.3.2: + array.prototype.flat@1.3.3: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 - es-shim-unscopables: 1.0.2 + es-abstract: 1.24.0 + es-shim-unscopables: 1.1.0 - arraybuffer.prototype.slice@1.0.3: + arraybuffer.prototype.slice@1.0.4: dependencies: - array-buffer-byte-length: 1.0.1 + array-buffer-byte-length: 1.0.2 call-bind: 1.0.8 define-properties: 1.2.1 - es-abstract: 1.23.5 + es-abstract: 1.24.0 es-errors: 1.3.0 - get-intrinsic: 1.2.6 - is-array-buffer: 3.0.4 - is-shared-array-buffer: 1.0.3 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 - ast-kit@1.3.2: + ast-kit@1.4.3: dependencies: - '@babel/parser': 7.26.5 - pathe: 1.1.2 - - ast-kit@1.4.0: - dependencies: - '@babel/parser': 7.26.5 + '@babel/parser': 7.28.0 pathe: 2.0.3 ast-walker-scope@0.6.2: dependencies: - '@babel/parser': 7.26.3 - ast-kit: 1.3.2 + '@babel/parser': 7.28.0 + ast-kit: 1.4.3 + + async-function@1.0.0: {} async-lock@1.4.1: {} @@ -5726,24 +5516,24 @@ snapshots: asynckit@0.4.0: {} - autoprefixer@10.4.21(postcss@8.5.3): + autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001704 + browserslist: 4.25.1 + caniuse-lite: 1.0.30001726 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 - postcss: 8.5.3 + postcss: 8.5.6 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: dependencies: - possible-typed-array-names: 1.0.0 + possible-typed-array-names: 1.1.0 - axios@1.8.4: + axios@1.10.0: dependencies: follow-redirects: 1.15.9 - form-data: 4.0.1 + form-data: 4.0.3 proxy-from-env: 1.1.0 transitivePeerDependencies: - debug @@ -5752,16 +5542,16 @@ snapshots: binary-extensions@2.3.0: {} - birpc@0.2.19: {} + birpc@2.4.0: {} boolbase@1.0.0: {} - brace-expansion@1.1.11: + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.0.1: + brace-expansion@2.0.2: dependencies: balanced-match: 1.0.2 @@ -5769,58 +5559,63 @@ snapshots: dependencies: fill-range: 7.1.1 - browserslist@4.24.4: + browserslist@4.25.1: dependencies: - caniuse-lite: 1.0.30001704 - electron-to-chromium: 1.5.73 + caniuse-lite: 1.0.30001726 + electron-to-chromium: 1.5.178 node-releases: 2.0.19 - update-browserslist-db: 1.1.1(browserslist@4.24.4) + update-browserslist-db: 1.1.3(browserslist@4.25.1) buffer-crc32@0.2.13: {} builtin-modules@3.3.0: {} - builtin-modules@4.0.0: {} + builtin-modules@5.0.0: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.0.0 bytes@3.1.2: {} - c12@2.0.1: + c12@3.0.4: dependencies: - chokidar: 4.0.1 - confbox: 0.1.8 + chokidar: 4.0.3 + confbox: 0.2.2 defu: 6.1.4 - dotenv: 16.4.7 - giget: 1.2.3 - jiti: 2.4.1 - mlly: 1.7.4 - ohash: 1.1.4 - pathe: 1.1.2 + dotenv: 16.6.1 + exsolve: 1.0.7 + giget: 2.0.0 + jiti: 2.4.2 + ohash: 2.0.11 + pathe: 2.0.3 perfect-debounce: 1.0.0 - pkg-types: 1.3.1 + pkg-types: 2.2.0 rc9: 2.1.2 + optional: true cac@6.7.14: {} - call-bind-apply-helpers@1.0.1: + call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 function-bind: 1.1.2 call-bind@1.0.8: dependencies: - call-bind-apply-helpers: 1.0.1 + call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 - get-intrinsic: 1.2.6 + get-intrinsic: 1.3.0 set-function-length: 1.2.2 - call-bound@1.0.2: + call-bound@1.0.4: dependencies: - call-bind: 1.0.8 - get-intrinsic: 1.2.6 + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 callsites@3.1.0: {} - caniuse-lite@1.0.30001704: {} + caniuse-lite@1.0.30001726: {} ccount@2.0.1: {} @@ -5834,24 +5629,24 @@ snapshots: cheerio-select@2.1.0: dependencies: boolbase: 1.0.0 - css-select: 5.1.0 - css-what: 6.1.0 + css-select: 5.2.2 + css-what: 6.2.2 domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 cheerio@1.0.0: dependencies: cheerio-select: 2.1.0 dom-serializer: 2.0.0 domhandler: 5.0.3 - domutils: 3.1.0 - encoding-sniffer: 0.2.0 + domutils: 3.2.2 + encoding-sniffer: 0.2.1 htmlparser2: 9.1.0 - parse5: 7.2.1 + parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 6.21.0 + undici: 6.21.3 whatwg-mimetype: 4.0.0 chokidar@3.6.0: @@ -5866,17 +5661,19 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - chokidar@4.0.1: + chokidar@4.0.3: dependencies: - readdirp: 4.0.2 + readdirp: 4.1.2 + optional: true chownr@2.0.0: {} - ci-info@4.1.0: {} + ci-info@4.2.0: {} citty@0.1.6: dependencies: - consola: 3.4.0 + consola: 3.4.2 + optional: true clean-git-ref@2.0.1: {} @@ -5907,19 +5704,17 @@ snapshots: comment-parser@1.4.1: {} - compatx@0.1.8: {} - compute-scroll-into-view@1.0.20: {} + compute-scroll-into-view@3.1.1: {} + concat-map@0.0.1: {} confbox@0.1.8: {} - confbox@0.2.1: {} + confbox@0.2.2: {} - consola@3.2.3: {} - - consola@3.4.0: {} + consola@3.4.2: {} convert-source-map@2.0.0: {} @@ -5933,20 +5728,20 @@ snapshots: dependencies: is-what: 4.1.16 - core-js-compat@3.40.0: + core-js-compat@3.43.0: dependencies: - browserslist: 4.24.4 + browserslist: 4.25.1 - core-js@3.39.0: {} + core-js@3.43.0: {} - cosmiconfig@9.0.0(typescript@5.8.2): + cosmiconfig@9.0.0(typescript@5.8.3): dependencies: env-paths: 2.2.1 - import-fresh: 3.3.0 + import-fresh: 3.3.1 js-yaml: 4.1.0 parse-json: 5.2.0 optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 crc-32@1.2.2: {} @@ -5956,12 +5751,12 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-select@5.1.0: + css-select@5.2.2: dependencies: boolbase: 1.0.0 - css-what: 6.1.0 + css-what: 6.2.2 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 nth-check: 2.1.1 css-selector-parser@1.4.1: {} @@ -5981,7 +5776,7 @@ snapshots: mdn-data: 2.12.2 source-map-js: 1.2.1 - css-what@6.1.0: {} + css-what@6.2.2: {} cssesc@3.0.0: {} @@ -5991,21 +5786,21 @@ snapshots: csstype@3.1.3: {} - data-view-buffer@1.0.1: + data-view-buffer@1.0.2: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 - data-view-byte-length@1.0.1: + data-view-byte-length@1.0.2: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 - data-view-byte-offset@1.0.0: + data-view-byte-offset@1.0.1: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 es-errors: 1.3.0 is-data-view: 1.0.2 @@ -6013,15 +5808,11 @@ snapshots: de-indent@1.0.2: {} - debug@3.2.7: - dependencies: - ms: 2.1.3 - - debug@4.4.0: + debug@4.4.1: dependencies: ms: 2.1.3 - decode-named-character-reference@1.0.2: + decode-named-character-reference@1.2.0: dependencies: character-entities: 2.0.2 @@ -6033,12 +5824,21 @@ snapshots: deep-pick-omit@1.2.1: {} + default-browser-id@5.0.0: {} + + default-browser@5.2.1: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.0 + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 es-errors: 1.3.0 gopd: 1.2.0 + define-lazy-prop@3.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -6051,7 +5851,9 @@ snapshots: dequal@2.0.3: {} - destr@2.0.3: {} + destr@2.0.5: {} + + detect-libc@2.0.4: {} devlop@1.1.0: dependencies: @@ -6059,10 +5861,6 @@ snapshots: diff3@0.0.3: {} - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - dom-align@1.12.4: {} dom-scroll-into-view@2.0.1: {} @@ -6079,21 +5877,22 @@ snapshots: dependencies: domelementtype: 2.3.0 - dompurify@3.2.3: + dompurify@3.2.6: optionalDependencies: '@types/trusted-types': 2.0.7 - domutils@3.1.0: + domutils@3.2.2: dependencies: dom-serializer: 2.0.0 domelementtype: 2.3.0 domhandler: 5.0.3 - dotenv@16.4.7: {} + dotenv@16.6.1: + optional: true - dunder-proto@1.0.0: + dunder-proto@1.0.1: dependencies: - call-bind-apply-helpers: 1.0.1 + call-bind-apply-helpers: 1.0.2 es-errors: 1.3.0 gopd: 1.2.0 @@ -6101,28 +5900,30 @@ snapshots: eastasianwidth@0.2.0: {} - electron-to-chromium@1.5.73: {} + electron-to-chromium@1.5.178: {} emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} - encoding-sniffer@0.2.0: + encoding-sniffer@0.2.1: dependencies: iconv-lite: 0.6.3 whatwg-encoding: 3.1.1 - end-of-stream@1.4.4: + end-of-stream@1.4.5: dependencies: once: 1.4.0 - enhanced-resolve@5.17.1: + enhanced-resolve@5.18.2: dependencies: graceful-fs: 4.2.11 - tapable: 2.2.1 + tapable: 2.2.2 entities@4.5.0: {} + entities@6.0.1: {} + env-paths@2.2.1: {} errno@0.1.8: @@ -6134,23 +5935,30 @@ snapshots: dependencies: is-arrayish: 0.2.1 - es-abstract@1.23.5: + error-stack-parser-es@1.0.5: {} + + errx@0.1.0: + optional: true + + es-abstract@1.24.0: dependencies: - array-buffer-byte-length: 1.0.1 - arraybuffer.prototype.slice: 1.0.3 + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 available-typed-arrays: 1.0.7 call-bind: 1.0.8 - data-view-buffer: 1.0.1 - data-view-byte-length: 1.0.1 - data-view-byte-offset: 1.0.0 + 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.0.0 - es-set-tostringtag: 2.0.3 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 es-to-primitive: 1.3.0 - function.prototype.name: 1.1.6 - get-intrinsic: 1.2.6 - get-symbol-description: 1.0.2 + 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 @@ -6158,48 +5966,53 @@ snapshots: has-symbols: 1.1.0 hasown: 2.0.2 internal-slot: 1.1.0 - is-array-buffer: 3.0.4 + 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-shared-array-buffer: 1.0.3 - is-string: 1.1.0 - is-typed-array: 1.1.13 - is-weakref: 1.1.0 - object-inspect: 1.13.3 + 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.5 - regexp.prototype.flags: 1.5.3 + 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.2 - typed-array-byte-length: 1.0.1 - typed-array-byte-offset: 1.0.3 + 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.0.2 - which-typed-array: 1.1.16 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.19 es-define-property@1.0.1: {} es-errors@1.3.0: {} - es-module-lexer@1.5.4: {} - - es-object-atoms@1.0.0: + es-object-atoms@1.1.1: dependencies: es-errors: 1.3.0 - es-set-tostringtag@2.0.3: + es-set-tostringtag@2.1.0: dependencies: - get-intrinsic: 1.2.6 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 hasown: 2.0.2 - es-shim-unscopables@1.0.2: + es-shim-unscopables@1.1.0: dependencies: hasown: 2.0.2 @@ -6237,33 +6050,34 @@ snapshots: '@esbuild/win32-x64': 0.23.1 optional: true - esbuild@0.25.0: + esbuild@0.25.5: optionalDependencies: - '@esbuild/aix-ppc64': 0.25.0 - '@esbuild/android-arm': 0.25.0 - '@esbuild/android-arm64': 0.25.0 - '@esbuild/android-x64': 0.25.0 - '@esbuild/darwin-arm64': 0.25.0 - '@esbuild/darwin-x64': 0.25.0 - '@esbuild/freebsd-arm64': 0.25.0 - '@esbuild/freebsd-x64': 0.25.0 - '@esbuild/linux-arm': 0.25.0 - '@esbuild/linux-arm64': 0.25.0 - '@esbuild/linux-ia32': 0.25.0 - '@esbuild/linux-loong64': 0.25.0 - '@esbuild/linux-mips64el': 0.25.0 - '@esbuild/linux-ppc64': 0.25.0 - '@esbuild/linux-riscv64': 0.25.0 - '@esbuild/linux-s390x': 0.25.0 - '@esbuild/linux-x64': 0.25.0 - '@esbuild/netbsd-arm64': 0.25.0 - '@esbuild/netbsd-x64': 0.25.0 - '@esbuild/openbsd-arm64': 0.25.0 - '@esbuild/openbsd-x64': 0.25.0 - '@esbuild/sunos-x64': 0.25.0 - '@esbuild/win32-arm64': 0.25.0 - '@esbuild/win32-ia32': 0.25.0 - '@esbuild/win32-x64': 0.25.0 + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + optional: true escalade@3.2.0: {} @@ -6273,262 +6087,251 @@ snapshots: escape-string-regexp@5.0.0: {} - eslint-compat-utils@0.5.1(eslint@9.23.0(jiti@2.4.2)): + eslint-compat-utils@0.5.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.23.0(jiti@2.4.2) - semver: 7.7.1 + eslint: 9.30.1(jiti@2.4.2) + semver: 7.7.2 - eslint-compat-utils@0.6.4(eslint@9.23.0(jiti@2.4.2)): + eslint-compat-utils@0.6.5(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.23.0(jiti@2.4.2) - semver: 7.7.1 + eslint: 9.30.1(jiti@2.4.2) + semver: 7.7.2 - eslint-config-flat-gitignore@2.1.0(eslint@9.23.0(jiti@2.4.2)): + eslint-config-flat-gitignore@2.1.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@eslint/compat': 1.2.6(eslint@9.23.0(jiti@2.4.2)) - eslint: 9.23.0(jiti@2.4.2) + '@eslint/compat': 1.3.1(eslint@9.30.1(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) - eslint-flat-config-utils@2.0.1: + eslint-flat-config-utils@2.1.0: dependencies: pathe: 2.0.3 - eslint-import-resolver-node@0.3.9: - dependencies: - debug: 3.2.7 - is-core-module: 2.16.0 - resolve: 1.22.9 - transitivePeerDependencies: - - supports-color - - eslint-json-compat-utils@0.2.1(eslint@9.23.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0): + eslint-json-compat-utils@0.2.1(eslint@9.30.1(jiti@2.4.2))(jsonc-eslint-parser@2.4.0): dependencies: - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) esquery: 1.6.0 jsonc-eslint-parser: 2.4.0 - eslint-merge-processors@2.0.0(eslint@9.23.0(jiti@2.4.2)): + eslint-merge-processors@2.0.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) - eslint-plugin-antfu@3.1.1(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-antfu@3.1.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) - eslint-plugin-command@3.2.0(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-command@3.3.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@es-joy/jsdoccomment': 0.50.0 - eslint: 9.23.0(jiti@2.4.2) + '@es-joy/jsdoccomment': 0.50.2 + eslint: 9.30.1(jiti@2.4.2) - eslint-plugin-es-x@7.8.0(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-es-x@7.8.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 - eslint: 9.23.0(jiti@2.4.2) - eslint-compat-utils: 0.5.1(eslint@9.23.0(jiti@2.4.2)) - - eslint-plugin-import-x@4.9.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2): - dependencies: - '@types/doctrine': 0.0.9 - '@typescript-eslint/utils': 8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - debug: 4.4.0 - doctrine: 3.0.0 - eslint: 9.23.0(jiti@2.4.2) - eslint-import-resolver-node: 0.3.9 - get-tsconfig: 4.10.0 - is-glob: 4.0.3 - minimatch: 10.0.1 - rspack-resolver: 1.2.2 - semver: 7.7.1 - stable-hash: 0.0.5 - tslib: 2.8.1 - transitivePeerDependencies: - - supports-color - - typescript + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.5.1(eslint@9.30.1(jiti@2.4.2)) + + eslint-plugin-import-lite@0.3.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): + dependencies: + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/types': 8.35.1 + eslint: 9.30.1(jiti@2.4.2) + optionalDependencies: + typescript: 5.8.3 - eslint-plugin-jsdoc@50.6.8(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-jsdoc@51.3.2(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@es-joy/jsdoccomment': 0.49.0 + '@es-joy/jsdoccomment': 0.52.0 are-docs-informative: 0.0.2 comment-parser: 1.4.1 - debug: 4.4.0 + debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint: 9.23.0(jiti@2.4.2) - espree: 10.3.0 + eslint: 9.30.1(jiti@2.4.2) + espree: 10.4.0 esquery: 1.6.0 - parse-imports: 2.2.1 - semver: 7.7.1 + parse-imports-exports: 0.2.4 + semver: 7.7.2 spdx-expression-parse: 4.0.0 - synckit: 0.9.2 transitivePeerDependencies: - supports-color - eslint-plugin-jsonc@2.19.1(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-jsonc@2.20.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) - eslint: 9.23.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.23.0(jiti@2.4.2)) - eslint-json-compat-utils: 0.2.1(eslint@9.23.0(jiti@2.4.2))(jsonc-eslint-parser@2.4.0) - espree: 9.6.1 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.6.5(eslint@9.30.1(jiti@2.4.2)) + eslint-json-compat-utils: 0.2.1(eslint@9.30.1(jiti@2.4.2))(jsonc-eslint-parser@2.4.0) + espree: 10.4.0 graphemer: 1.4.0 jsonc-eslint-parser: 2.4.0 natural-compare: 1.4.0 - synckit: 0.6.2 + synckit: 0.11.8 transitivePeerDependencies: - '@eslint/json' - eslint-plugin-n@17.16.2(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-n@17.20.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) - enhanced-resolve: 5.17.1 - eslint: 9.23.0(jiti@2.4.2) - eslint-plugin-es-x: 7.8.0(eslint@9.23.0(jiti@2.4.2)) - get-tsconfig: 4.8.1 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + enhanced-resolve: 5.18.2 + eslint: 9.30.1(jiti@2.4.2) + eslint-plugin-es-x: 7.8.0(eslint@9.30.1(jiti@2.4.2)) + get-tsconfig: 4.10.1 globals: 15.15.0 ignore: 5.3.2 minimatch: 9.0.5 - semver: 7.7.1 + semver: 7.7.2 + ts-declaration-location: 1.0.7(typescript@5.8.3) + transitivePeerDependencies: + - supports-color + - typescript eslint-plugin-no-only-tests@3.3.0: {} - eslint-plugin-perfectionist@4.10.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2): + eslint-plugin-perfectionist@4.15.0(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3): dependencies: - '@typescript-eslint/types': 8.26.1 - '@typescript-eslint/utils': 8.26.1(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) - eslint: 9.23.0(jiti@2.4.2) + '@typescript-eslint/types': 8.35.1 + '@typescript-eslint/utils': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) + eslint: 9.30.1(jiti@2.4.2) natural-orderby: 5.0.0 transitivePeerDependencies: - supports-color - typescript - eslint-plugin-pnpm@0.3.1(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-pnpm@0.3.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) find-up-simple: 1.0.1 jsonc-eslint-parser: 2.4.0 pathe: 2.0.3 pnpm-workspace-yaml: 0.3.1 - tinyglobby: 0.2.12 + tinyglobby: 0.2.14 yaml-eslint-parser: 1.3.0 - eslint-plugin-regexp@2.7.0(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-regexp@2.9.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 comment-parser: 1.4.1 - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) jsdoc-type-pratt-parser: 4.1.0 refa: 0.12.1 regexp-ast-analysis: 0.7.1 scslre: 0.3.0 - eslint-plugin-sonarjs@3.0.2(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-sonarjs@3.0.4(eslint@9.30.1(jiti@2.4.2)): dependencies: '@eslint-community/regexpp': 4.12.1 builtin-modules: 3.3.0 bytes: 3.1.2 - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) functional-red-black-tree: 1.0.1 jsx-ast-utils: 3.3.5 + lodash.merge: 4.6.2 minimatch: 9.0.5 scslre: 0.3.0 - semver: 7.7.1 - typescript: 5.8.2 + semver: 7.7.2 + typescript: 5.8.3 - eslint-plugin-toml@0.12.0(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-toml@0.12.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - debug: 4.4.0 - eslint: 9.23.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.23.0(jiti@2.4.2)) + debug: 4.4.1 + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.6.5(eslint@9.30.1(jiti@2.4.2)) lodash: 4.17.21 toml-eslint-parser: 0.10.0 transitivePeerDependencies: - supports-color - eslint-plugin-unicorn@57.0.0(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-unicorn@59.0.1(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@babel/helper-validator-identifier': 7.25.9 - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) - ci-info: 4.1.0 + '@babel/helper-validator-identifier': 7.27.1 + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + '@eslint/plugin-kit': 0.2.8 + ci-info: 4.2.0 clean-regexp: 1.0.0 - core-js-compat: 3.40.0 - eslint: 9.23.0(jiti@2.4.2) + core-js-compat: 3.43.0 + eslint: 9.30.1(jiti@2.4.2) esquery: 1.6.0 - globals: 15.15.0 + find-up-simple: 1.0.1 + globals: 16.3.0 indent-string: 5.0.0 - is-builtin-module: 4.0.0 + is-builtin-module: 5.0.0 jsesc: 3.1.0 pluralize: 8.0.0 - read-package-up: 11.0.0 regexp-tree: 0.1.27 regjsparser: 0.12.0 - semver: 7.7.1 + semver: 7.7.2 strip-indent: 4.0.0 - eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.27.0(@typescript-eslint/parser@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2)): dependencies: - eslint: 9.23.0(jiti@2.4.2) + eslint: 9.30.1(jiti@2.4.2) optionalDependencies: - '@typescript-eslint/eslint-plugin': 8.27.0(@typescript-eslint/parser@8.27.0(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2))(eslint@9.23.0(jiti@2.4.2))(typescript@5.8.2) + '@typescript-eslint/eslint-plugin': 8.35.1(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-vue@10.0.0(eslint@9.23.0(jiti@2.4.2))(vue-eslint-parser@10.1.1(eslint@9.23.0(jiti@2.4.2))): + eslint-plugin-vue@10.3.0(@typescript-eslint/parser@8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3))(eslint@9.30.1(jiti@2.4.2))(vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2))): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) - eslint: 9.23.0(jiti@2.4.2) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) natural-compare: 1.4.0 nth-check: 2.1.1 postcss-selector-parser: 6.1.2 - semver: 7.7.1 - vue-eslint-parser: 10.1.1(eslint@9.23.0(jiti@2.4.2)) + semver: 7.7.2 + vue-eslint-parser: 10.2.0(eslint@9.30.1(jiti@2.4.2)) xml-name-validator: 4.0.0 + optionalDependencies: + '@typescript-eslint/parser': 8.35.1(eslint@9.30.1(jiti@2.4.2))(typescript@5.8.3) - eslint-plugin-yml@1.17.0(eslint@9.23.0(jiti@2.4.2)): + eslint-plugin-yml@1.18.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - debug: 4.4.0 + debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint: 9.23.0(jiti@2.4.2) - eslint-compat-utils: 0.6.4(eslint@9.23.0(jiti@2.4.2)) + eslint: 9.30.1(jiti@2.4.2) + eslint-compat-utils: 0.6.5(eslint@9.30.1(jiti@2.4.2)) natural-compare: 1.4.0 yaml-eslint-parser: 1.3.0 transitivePeerDependencies: - supports-color - eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.13)(eslint@9.23.0(jiti@2.4.2)): + eslint-processor-vue-blocks@2.0.0(@vue/compiler-sfc@3.5.17)(eslint@9.30.1(jiti@2.4.2)): dependencies: - '@vue/compiler-sfc': 3.5.13 - eslint: 9.23.0(jiti@2.4.2) + '@vue/compiler-sfc': 3.5.17 + eslint: 9.30.1(jiti@2.4.2) - eslint-scope@8.3.0: + eslint-scope@8.4.0: dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 eslint-visitor-keys@3.4.3: {} - eslint-visitor-keys@4.2.0: {} + eslint-visitor-keys@4.2.1: {} - eslint@9.23.0(jiti@2.4.2): + eslint@9.30.1(jiti@2.4.2): dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.23.0(jiti@2.4.2)) + '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.4.2)) '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.19.2 - '@eslint/config-helpers': 0.2.0 - '@eslint/core': 0.12.0 + '@eslint/config-array': 0.21.0 + '@eslint/config-helpers': 0.3.0 + '@eslint/core': 0.14.0 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.23.0 - '@eslint/plugin-kit': 0.2.7 + '@eslint/js': 9.30.1 + '@eslint/plugin-kit': 0.3.3 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.2 - '@types/estree': 1.0.6 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 '@types/json-schema': 7.0.15 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.0 + debug: 4.4.1 escape-string-regexp: 4.0.0 - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -6548,16 +6351,16 @@ snapshots: transitivePeerDependencies: - supports-color - espree@10.3.0: + espree@10.4.0: dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) - eslint-visitor-keys: 4.2.0 + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) + eslint-visitor-keys: 4.2.1 espree@9.6.1: dependencies: - acorn: 8.14.0 - acorn-jsx: 5.3.2(acorn@8.14.0) + acorn: 8.15.0 + acorn-jsx: 5.3.2(acorn@8.15.0) eslint-visitor-keys: 3.4.3 esquery@1.6.0: @@ -6574,27 +6377,15 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.6 + '@types/estree': 1.0.8 esutils@2.0.3: {} - execa@8.0.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 8.0.1 - human-signals: 5.0.0 - is-stream: 3.0.0 - merge-stream: 2.0.0 - npm-run-path: 5.3.0 - onetime: 6.0.0 - signal-exit: 4.1.0 - strip-final-newline: 3.0.0 - - exsolve@1.0.4: {} + exsolve@1.0.7: {} extract-zip@2.0.1: dependencies: - debug: 4.4.0 + debug: 4.4.1 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -6616,15 +6407,19 @@ snapshots: fast-levenshtein@2.0.6: {} - fastq@1.17.1: + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fault@2.0.1: dependencies: - reusify: 1.0.4 + format: 0.2.2 fd-slicer@1.1.0: dependencies: pend: 1.2.0 - fdir@6.4.3(picomatch@4.0.2): + fdir@6.4.6(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 @@ -6649,28 +6444,32 @@ snapshots: flat-cache@4.0.1: dependencies: - flatted: 3.3.2 + flatted: 3.3.3 keyv: 4.5.4 - flatted@3.3.2: {} + flatted@3.3.3: {} follow-redirects@1.15.9: {} - for-each@0.3.3: + for-each@0.3.5: dependencies: is-callable: 1.2.7 - foreground-child@3.3.0: + foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 - form-data@4.0.1: + form-data@4.0.3: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 mime-types: 2.1.35 + format@0.2.2: {} + fraction.js@4.3.7: {} fs-minipass@2.1.0: @@ -6684,12 +6483,14 @@ snapshots: function-bind@1.1.2: {} - function.prototype.name@1.1.6: + function.prototype.name@1.1.8: dependencies: call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 - es-abstract: 1.23.5 functions-have-names: 1.2.3 + hasown: 2.0.2 + is-callable: 1.2.7 functional-red-black-tree@1.0.1: {} @@ -6697,36 +6498,35 @@ snapshots: gensync@1.0.0-beta.2: {} - get-intrinsic@1.2.6: + get-intrinsic@1.3.0: dependencies: - call-bind-apply-helpers: 1.0.1 - dunder-proto: 1.0.0 + call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.0.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.0.0 + math-intrinsics: 1.1.0 - get-stream@5.2.0: + get-proto@1.0.1: dependencies: - pump: 3.0.2 - - get-stream@8.0.1: {} + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 - get-symbol-description@1.0.2: + get-stream@5.2.0: dependencies: - call-bind: 1.0.8 - es-errors: 1.3.0 - get-intrinsic: 1.2.6 + pump: 3.0.3 - get-tsconfig@4.10.0: + get-symbol-description@1.1.0: dependencies: - resolve-pkg-maps: 1.0.0 + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 - get-tsconfig@4.8.1: + get-tsconfig@4.10.1: dependencies: resolve-pkg-maps: 1.0.0 @@ -6738,21 +6538,22 @@ snapshots: glob: 7.2.3 parse5: 6.0.1 pofile: 1.0.11 - typescript: 5.8.2 + typescript: 5.8.3 - giget@1.2.3: + giget@2.0.0: dependencies: citty: 0.1.6 - consola: 3.4.0 + consola: 3.4.2 defu: 6.1.4 - node-fetch-native: 1.6.4 - nypm: 0.3.12 - ohash: 1.1.4 - pathe: 1.1.2 - tar: 6.2.1 + node-fetch-native: 1.6.6 + nypm: 0.6.0 + pathe: 2.0.3 + optional: true github-buttons@2.29.1: {} + github-slugger@2.0.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -6763,7 +6564,7 @@ snapshots: glob@10.4.5: dependencies: - foreground-child: 3.3.0 + foreground-child: 3.3.1 jackspeak: 3.4.3 minimatch: 9.0.5 minipass: 7.1.2 @@ -6779,30 +6580,17 @@ snapshots: once: 1.4.0 path-is-absolute: 1.0.1 - globals@11.12.0: {} - globals@14.0.0: {} - globals@15.14.0: {} - globals@15.15.0: {} - globals@16.0.0: {} + globals@16.3.0: {} globalthis@1.0.4: dependencies: define-properties: 1.2.1 gopd: 1.2.0 - globby@14.0.2: - dependencies: - '@sindresorhus/merge-streams': 2.3.0 - fast-glob: 3.3.3 - ignore: 5.3.2 - path-type: 5.0.0 - slash: 5.1.0 - unicorn-magic: 0.1.0 - gopd@1.2.0: {} graceful-fs@4.2.11: {} @@ -6813,7 +6601,7 @@ snapshots: dependencies: duplexer: 0.1.2 - has-bigints@1.0.2: {} + has-bigints@1.1.0: {} has-flag@4.0.0: {} @@ -6823,7 +6611,7 @@ snapshots: has-proto@1.2.0: dependencies: - dunder-proto: 1.0.0 + dunder-proto: 1.0.1 has-symbols@1.1.0: {} @@ -6831,8 +6619,6 @@ snapshots: dependencies: has-symbols: 1.1.0 - hash-sum@2.0.0: {} - hasown@2.0.2: dependencies: function-bind: 1.1.2 @@ -6843,33 +6629,25 @@ snapshots: hookable@5.5.3: {} - hosted-git-info@7.0.2: - dependencies: - lru-cache: 10.4.3 - - html-tags@3.3.1: {} - htmlparser2@9.1.0: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 - domutils: 3.1.0 + domutils: 3.2.2 entities: 4.5.0 - human-signals@5.0.0: {} - iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 ignore@5.3.2: {} - ignore@6.0.2: {} + ignore@7.0.5: {} image-size@0.5.5: optional: true - import-fresh@3.3.0: + import-fresh@3.3.1: dependencies: parent-module: 1.0.1 resolve-from: 4.0.0 @@ -6878,8 +6656,6 @@ snapshots: indent-string@5.0.0: {} - index-to-position@0.1.2: {} - inflight@1.0.6: dependencies: once: 1.4.0 @@ -6893,74 +6669,84 @@ snapshots: hasown: 2.0.2 side-channel: 1.1.0 - is-array-buffer@3.0.4: + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 - get-intrinsic: 1.2.6 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 is-arrayish@0.2.1: {} - is-async-function@2.0.0: + 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.0.2 + has-bigints: 1.1.0 is-binary-path@2.1.0: dependencies: binary-extensions: 2.3.0 - is-boolean-object@1.2.1: + is-boolean-object@1.2.2: dependencies: - call-bound: 1.0.2 + call-bound: 1.0.4 has-tostringtag: 1.0.2 - is-builtin-module@4.0.0: + is-builtin-module@5.0.0: dependencies: - builtin-modules: 4.0.0 + builtin-modules: 5.0.0 is-callable@1.2.7: {} - is-core-module@2.16.0: - dependencies: - hasown: 2.0.2 - is-data-view@1.0.2: dependencies: - call-bound: 1.0.2 - get-intrinsic: 1.2.6 - is-typed-array: 1.1.13 + 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.2 + call-bound: 1.0.4 has-tostringtag: 1.0.2 + is-docker@3.0.0: {} + is-extglob@2.1.1: {} - is-finalizationregistry@1.1.0: + is-finalizationregistry@1.1.1: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 is-fullwidth-code-point@3.0.0: {} - is-generator-function@1.0.10: + is-generator-function@1.1.0: dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-map@2.0.3: {} is-negative-zero@2.0.3: {} - is-number-object@1.1.0: + is-number-object@1.1.1: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 has-tostringtag: 1.0.2 is-number@7.0.0: {} @@ -6969,54 +6755,56 @@ snapshots: is-regex@1.2.1: dependencies: - call-bound: 1.0.2 + call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 hasown: 2.0.2 is-set@2.0.3: {} - is-shared-array-buffer@1.0.3: + is-shared-array-buffer@1.0.4: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 - is-stream@3.0.0: {} - - is-string@1.1.0: + is-string@1.1.1: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 has-tostringtag: 1.0.2 is-symbol@1.1.1: dependencies: - call-bound: 1.0.2 + call-bound: 1.0.4 has-symbols: 1.1.0 safe-regex-test: 1.1.0 - is-typed-array@1.1.13: + is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.16 + which-typed-array: 1.1.19 is-weakmap@2.0.2: {} - is-weakref@1.1.0: + is-weakref@1.1.1: dependencies: - call-bound: 1.0.2 + call-bound: 1.0.4 - is-weakset@2.0.3: + is-weakset@2.0.4: dependencies: - call-bind: 1.0.8 - get-intrinsic: 1.2.6 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 is-what@3.14.1: {} is-what@4.1.16: {} + is-wsl@3.1.0: + dependencies: + is-inside-container: 1.0.0 + isarray@2.0.5: {} isexe@2.0.0: {} - isomorphic-git@1.27.2: + isomorphic-git@1.32.1: dependencies: async-lock: 1.4.1 clean-git-ref: 2.0.1 @@ -7028,7 +6816,7 @@ snapshots: path-browserify: 1.0.1 pify: 4.0.1 readable-stream: 3.6.2 - sha.js: 2.4.11 + sha.js: 2.4.12 simple-get: 4.0.1 jackspeak@3.4.3: @@ -7037,8 +6825,6 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jiti@2.4.1: {} - jiti@2.4.2: {} js-tokens@4.0.0: {} @@ -7069,29 +6855,31 @@ snapshots: jsonc-eslint-parser@2.4.0: dependencies: - acorn: 8.14.0 + acorn: 8.15.0 eslint-visitor-keys: 3.4.3 espree: 9.6.1 - semver: 7.7.1 + semver: 7.7.2 jsx-ast-utils@3.3.5: dependencies: - array-includes: 3.1.8 - array.prototype.flat: 1.3.2 - object.assign: 4.1.5 - object.values: 1.2.0 + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 keyv@4.5.4: dependencies: json-buffer: 3.0.1 - klona@2.0.6: {} + klona@2.0.6: + optional: true - knitwork@1.1.0: {} + knitwork@1.2.0: + optional: true kolorist@1.8.0: {} - less@4.2.2: + less@4.3.0: dependencies: copy-anything: 2.0.6 parse-node-version: 1.0.1 @@ -7110,14 +6898,54 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - lines-and-columns@1.2.4: {} + lightningcss-darwin-arm64@1.30.1: + optional: true - local-pkg@0.5.1: + lightningcss-darwin-x64@1.30.1: + optional: true + + lightningcss-freebsd-x64@1.30.1: + optional: true + + lightningcss-linux-arm-gnueabihf@1.30.1: + optional: true + + lightningcss-linux-arm64-gnu@1.30.1: + optional: true + + lightningcss-linux-arm64-musl@1.30.1: + optional: true + + lightningcss-linux-x64-gnu@1.30.1: + optional: true + + lightningcss-linux-x64-musl@1.30.1: + optional: true + + lightningcss-win32-arm64-msvc@1.30.1: + optional: true + + lightningcss-win32-x64-msvc@1.30.1: + optional: true + + lightningcss@1.30.1: dependencies: - mlly: 1.7.4 - pkg-types: 1.3.1 + detect-libc: 2.0.4 + optionalDependencies: + lightningcss-darwin-arm64: 1.30.1 + lightningcss-darwin-x64: 1.30.1 + lightningcss-freebsd-x64: 1.30.1 + lightningcss-linux-arm-gnueabihf: 1.30.1 + lightningcss-linux-arm64-gnu: 1.30.1 + lightningcss-linux-arm64-musl: 1.30.1 + lightningcss-linux-x64-gnu: 1.30.1 + lightningcss-linux-x64-musl: 1.30.1 + lightningcss-win32-arm64-msvc: 1.30.1 + lightningcss-win32-x64-msvc: 1.30.1 + + lines-and-columns@1.2.4: {} - local-pkg@1.0.0: + local-pkg@0.5.1: dependencies: mlly: 1.7.4 pkg-types: 1.3.1 @@ -7125,8 +6953,8 @@ snapshots: local-pkg@1.1.1: dependencies: mlly: 1.7.4 - pkg-types: 2.1.0 - quansync: 0.2.8 + pkg-types: 2.2.0 + quansync: 0.2.10 locate-path@6.0.0: dependencies: @@ -7152,17 +6980,13 @@ snapshots: dependencies: yallist: 3.1.1 - magic-string-ast@0.7.0: + magic-string-ast@0.7.1: dependencies: magic-string: 0.30.17 - magic-string@0.30.15: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.17: dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/sourcemap-codec': 1.5.4 make-dir@2.1.0: dependencies: @@ -7172,15 +6996,15 @@ snapshots: markdown-table@3.0.4: {} - marked-highlight@2.2.1(marked@15.0.7): + marked-highlight@2.2.2(marked@16.0.0): dependencies: - marked: 15.0.7 + marked: 16.0.0 - marked@15.0.7: {} + marked@16.0.0: {} - math-intrinsics@1.0.0: {} + math-intrinsics@1.1.0: {} - mdast-util-find-and-replace@3.0.1: + mdast-util-find-and-replace@3.0.2: dependencies: '@types/mdast': 4.0.4 escape-string-regexp: 5.0.0 @@ -7191,28 +7015,39 @@ snapshots: dependencies: '@types/mdast': 4.0.4 '@types/unist': 3.0.3 - decode-named-character-reference: 1.0.2 + decode-named-character-reference: 1.2.0 devlop: 1.1.0 mdast-util-to-string: 4.0.0 - micromark: 4.0.1 + micromark: 4.0.2 micromark-util-decode-numeric-character-reference: 2.0.2 micromark-util-decode-string: 2.0.1 micromark-util-normalize-identifier: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 unist-util-stringify-position: 4.0.0 transitivePeerDependencies: - supports-color + mdast-util-frontmatter@2.0.1: + dependencies: + '@types/mdast': 4.0.4 + devlop: 1.1.0 + escape-string-regexp: 5.0.0 + mdast-util-from-markdown: 2.0.2 + mdast-util-to-markdown: 2.1.2 + micromark-extension-frontmatter: 2.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-gfm-autolink-literal@2.0.1: dependencies: '@types/mdast': 4.0.4 ccount: 2.0.1 devlop: 1.1.0 - mdast-util-find-and-replace: 3.0.1 + mdast-util-find-and-replace: 3.0.2 micromark-util-character: 2.1.1 - mdast-util-gfm-footnote@2.0.0: + mdast-util-gfm-footnote@2.1.0: dependencies: '@types/mdast': 4.0.4 devlop: 1.1.0 @@ -7249,11 +7084,11 @@ snapshots: transitivePeerDependencies: - supports-color - mdast-util-gfm@3.0.0: + mdast-util-gfm@3.1.0: dependencies: mdast-util-from-markdown: 2.0.2 mdast-util-gfm-autolink-literal: 2.0.1 - mdast-util-gfm-footnote: 2.0.0 + mdast-util-gfm-footnote: 2.1.0 mdast-util-gfm-strikethrough: 2.0.0 mdast-util-gfm-table: 2.0.0 mdast-util-gfm-task-list-item: 2.0.0 @@ -7288,13 +7123,11 @@ snapshots: mdn-data@2.12.2: {} - merge-stream@2.0.0: {} - merge2@1.4.1: {} - micromark-core-commonmark@2.0.2: + micromark-core-commonmark@2.0.3: dependencies: - decode-named-character-reference: 1.0.2 + decode-named-character-reference: 1.2.0 devlop: 1.1.0 micromark-factory-destination: 2.0.1 micromark-factory-label: 2.0.1 @@ -7307,27 +7140,34 @@ snapshots: micromark-util-html-tag-name: 2.0.1 micromark-util-normalize-identifier: 2.0.1 micromark-util-resolve-all: 2.0.1 - micromark-util-subtokenize: 2.0.3 + micromark-util-subtokenize: 2.1.0 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-frontmatter@2.0.0: + dependencies: + fault: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 micromark-extension-gfm-autolink-literal@2.1.0: dependencies: micromark-util-character: 2.1.1 micromark-util-sanitize-uri: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-extension-gfm-footnote@2.1.0: dependencies: devlop: 1.1.0 - micromark-core-commonmark: 2.0.2 + micromark-core-commonmark: 2.0.3 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-normalize-identifier: 2.0.1 micromark-util-sanitize-uri: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-extension-gfm-strikethrough@2.1.0: dependencies: @@ -7336,19 +7176,19 @@ snapshots: micromark-util-classify-character: 2.0.1 micromark-util-resolve-all: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 - micromark-extension-gfm-table@2.1.0: + micromark-extension-gfm-table@2.1.1: dependencies: devlop: 1.1.0 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-extension-gfm-tagfilter@2.0.0: dependencies: - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-extension-gfm-task-list-item@2.1.0: dependencies: @@ -7356,55 +7196,55 @@ snapshots: micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-extension-gfm@3.0.0: dependencies: micromark-extension-gfm-autolink-literal: 2.1.0 micromark-extension-gfm-footnote: 2.1.0 micromark-extension-gfm-strikethrough: 2.1.0 - micromark-extension-gfm-table: 2.1.0 + micromark-extension-gfm-table: 2.1.1 micromark-extension-gfm-tagfilter: 2.0.0 micromark-extension-gfm-task-list-item: 2.1.0 micromark-util-combine-extensions: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-factory-destination@2.0.1: dependencies: micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-factory-label@2.0.1: dependencies: devlop: 1.1.0 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-factory-space@2.0.1: dependencies: micromark-util-character: 2.1.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-factory-title@2.0.1: dependencies: micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-factory-whitespace@2.0.1: dependencies: micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-util-character@2.1.1: dependencies: micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-util-chunked@2.0.1: dependencies: @@ -7414,12 +7254,12 @@ snapshots: dependencies: micromark-util-character: 2.1.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-util-combine-extensions@2.0.1: dependencies: micromark-util-chunked: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-util-decode-numeric-character-reference@2.0.2: dependencies: @@ -7427,7 +7267,7 @@ snapshots: micromark-util-decode-string@2.0.1: dependencies: - decode-named-character-reference: 1.0.2 + decode-named-character-reference: 1.2.0 micromark-util-character: 2.1.1 micromark-util-decode-numeric-character-reference: 2.0.2 micromark-util-symbol: 2.0.1 @@ -7442,7 +7282,7 @@ snapshots: micromark-util-resolve-all@2.0.1: dependencies: - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-util-sanitize-uri@2.0.1: dependencies: @@ -7450,24 +7290,24 @@ snapshots: micromark-util-encode: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-subtokenize@2.0.3: + micromark-util-subtokenize@2.1.0: dependencies: devlop: 1.1.0 micromark-util-chunked: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 micromark-util-symbol@2.0.1: {} - micromark-util-types@2.0.1: {} + micromark-util-types@2.0.2: {} - micromark@4.0.1: + micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.0 - decode-named-character-reference: 1.0.2 + debug: 4.4.1 + decode-named-character-reference: 1.2.0 devlop: 1.1.0 - micromark-core-commonmark: 2.0.2 + micromark-core-commonmark: 2.0.3 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 micromark-util-chunked: 2.0.1 @@ -7477,9 +7317,9 @@ snapshots: micromark-util-normalize-identifier: 2.0.1 micromark-util-resolve-all: 2.0.1 micromark-util-sanitize-uri: 2.0.1 - micromark-util-subtokenize: 2.0.3 + micromark-util-subtokenize: 2.1.0 micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.1 + micromark-util-types: 2.0.2 transitivePeerDependencies: - supports-color @@ -7497,23 +7337,21 @@ snapshots: mime@1.6.0: optional: true - mimic-fn@4.0.0: {} - mimic-response@3.1.0: {} min-indent@1.0.1: {} - minimatch@10.0.1: + minimatch@10.0.3: dependencies: - brace-expansion: 2.0.1 + '@isaacs/brace-expansion': 5.0.0 minimatch@3.1.2: dependencies: - brace-expansion: 1.1.11 + brace-expansion: 1.1.12 minimatch@9.0.5: dependencies: - brace-expansion: 2.0.1 + brace-expansion: 2.0.2 minimist@1.2.8: {} @@ -7542,20 +7380,18 @@ snapshots: mlly@1.7.4: dependencies: - acorn: 8.14.0 + acorn: 8.15.0 pathe: 2.0.3 pkg-types: 1.3.1 - ufo: 1.5.4 - - mri@1.2.0: {} + ufo: 1.6.1 - mrmime@2.0.0: {} + mrmime@2.0.1: {} ms@2.1.3: {} muggle-string@0.4.1: {} - nanoid@3.3.8: {} + nanoid@3.3.11: {} nanopop@2.4.2: {} @@ -7569,73 +7405,69 @@ snapshots: sax: 1.4.1 optional: true - node-fetch-native@1.6.4: {} + node-fetch-native@1.6.6: {} - node-object-hash@3.0.0: {} + node-object-hash@3.1.1: {} node-releases@2.0.19: {} - normalize-package-data@6.0.2: - dependencies: - hosted-git-info: 7.0.2 - semver: 7.7.1 - validate-npm-package-license: 3.0.4 - normalize-path@3.0.0: {} normalize-range@0.1.2: {} - npm-run-path@5.3.0: - dependencies: - path-key: 4.0.0 - nprogress@0.2.0: {} nth-check@2.1.1: dependencies: boolbase: 1.0.0 - nypm@0.3.12: + nypm@0.6.0: dependencies: citty: 0.1.6 - consola: 3.4.0 - execa: 8.0.1 - pathe: 1.1.2 - pkg-types: 1.3.1 - ufo: 1.5.4 + consola: 3.4.2 + pathe: 2.0.3 + pkg-types: 2.2.0 + tinyexec: 0.3.2 + optional: true - object-inspect@1.13.3: {} + object-inspect@1.13.4: {} object-keys@1.1.1: {} - object.assign@4.1.5: + 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 - object.values@1.2.0: + object.values@1.2.1: dependencies: call-bind: 1.0.8 + call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + es-object-atoms: 1.1.1 ofetch@1.4.1: dependencies: - destr: 2.0.3 - node-fetch-native: 1.6.4 - ufo: 1.5.4 + destr: 2.0.5 + node-fetch-native: 1.6.6 + ufo: 1.6.1 - ohash@1.1.4: {} + ohash@2.0.11: {} once@1.4.0: dependencies: wrappy: 1.0.2 - onetime@6.0.0: + open@10.1.2: dependencies: - mimic-fn: 4.0.0 + default-browser: 5.2.1 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + is-wsl: 3.1.0 optionator@0.9.4: dependencies: @@ -7646,6 +7478,12 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 @@ -7656,7 +7494,7 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@0.2.8: {} + package-manager-detector@1.3.0: {} pako@1.0.11: {} @@ -7666,26 +7504,21 @@ snapshots: parse-gitignore@2.0.0: {} - parse-imports@2.2.1: + parse-imports-exports@0.2.4: dependencies: - es-module-lexer: 1.5.4 - slashes: 3.0.12 + parse-statements: 1.0.11 parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.26.2 + '@babel/code-frame': 7.27.1 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 - parse-json@8.1.0: - dependencies: - '@babel/code-frame': 7.26.2 - index-to-position: 0.1.2 - type-fest: 4.35.0 - parse-node-version@1.0.1: {} + parse-statements@1.0.11: {} + parse5-htmlparser2-tree-adapter@6.0.1: dependencies: parse5: 6.0.1 @@ -7693,17 +7526,17 @@ snapshots: parse5-htmlparser2-tree-adapter@7.1.0: dependencies: domhandler: 5.0.3 - parse5: 7.2.1 + parse5: 7.3.0 parse5-parser-stream@7.1.2: dependencies: - parse5: 7.2.1 + parse5: 7.3.0 parse5@6.0.1: {} - parse5@7.2.1: + parse5@7.3.0: dependencies: - entities: 4.5.0 + entities: 6.0.1 path-browserify@1.0.1: {} @@ -7713,17 +7546,11 @@ snapshots: path-key@3.1.1: {} - path-key@4.0.0: {} - - path-parse@1.0.7: {} - path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 minipass: 7.1.2 - path-type@5.0.0: {} - pathe@1.1.2: {} pathe@2.0.3: {} @@ -7740,25 +7567,21 @@ snapshots: pify@4.0.1: {} - pinia-plugin-persistedstate@4.2.0(pinia@3.0.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)))(rollup@4.34.6): + pinia-plugin-persistedstate@4.4.1(@nuxt/kit@3.17.5)(pinia@3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3))): dependencies: - '@nuxt/kit': 3.14.1592(rollup@4.34.6) deep-pick-omit: 1.2.1 defu: 6.1.4 - destr: 2.0.3 + destr: 2.0.5 optionalDependencies: - pinia: 3.0.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)) - transitivePeerDependencies: - - magicast - - rollup - - supports-color + '@nuxt/kit': 3.17.5 + pinia: 3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)) - pinia@3.0.1(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)): + pinia@3.0.3(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)): dependencies: - '@vue/devtools-api': 7.7.2 - vue: 3.5.13(typescript@5.8.2) + '@vue/devtools-api': 7.7.7 + vue: 3.5.17(typescript@5.8.3) optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 pkg-types@1.3.1: dependencies: @@ -7766,23 +7589,23 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 - pkg-types@2.1.0: + pkg-types@2.2.0: dependencies: - confbox: 0.2.1 - exsolve: 1.0.4 + confbox: 0.2.2 + exsolve: 1.0.7 pathe: 2.0.3 pluralize@8.0.0: {} pnpm-workspace-yaml@0.3.1: dependencies: - yaml: 2.7.0 + yaml: 2.8.0 pofile@1.0.11: {} pofile@1.1.4: {} - possible-typed-array-names@1.0.0: {} + possible-typed-array-names@1.1.0: {} postcss-selector-parser@6.1.2: dependencies: @@ -7791,9 +7614,9 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.5.3: + postcss@8.5.6: dependencies: - nanoid: 3.3.8 + nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -7804,35 +7627,22 @@ snapshots: prr@1.0.1: optional: true - pump@3.0.2: + pump@3.0.3: dependencies: - end-of-stream: 1.4.4 + end-of-stream: 1.4.5 once: 1.4.0 punycode@2.3.1: {} - quansync@0.2.8: {} + quansync@0.2.10: {} queue-microtask@1.2.3: {} rc9@2.1.2: dependencies: defu: 6.1.4 - destr: 2.0.3 - - read-package-up@11.0.0: - dependencies: - find-up-simple: 1.0.1 - read-pkg: 9.0.1 - type-fest: 4.35.0 - - read-pkg@9.0.1: - dependencies: - '@types/normalize-package-data': 2.4.4 - normalize-package-data: 6.0.2 - parse-json: 8.1.0 - type-fest: 4.35.0 - unicorn-magic: 0.1.0 + destr: 2.0.5 + optional: true readable-stream@3.6.2: dependencies: @@ -7844,7 +7654,8 @@ snapshots: dependencies: picomatch: 2.3.1 - readdirp@4.0.2: {} + readdirp@4.1.2: + optional: true reconnecting-websocket@4.4.0: {} @@ -7852,19 +7663,17 @@ snapshots: dependencies: '@eslint-community/regexpp': 4.12.1 - reflect.getprototypeof@1.0.8: + reflect.getprototypeof@1.0.10: dependencies: call-bind: 1.0.8 define-properties: 1.2.1 - dunder-proto: 1.0.0 - es-abstract: 1.23.5 + es-abstract: 1.24.0 es-errors: 1.3.0 - get-intrinsic: 1.2.6 - gopd: 1.2.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 which-builtin-type: 1.2.1 - regenerator-runtime@0.14.1: {} - regexp-ast-analysis@0.7.1: dependencies: '@eslint-community/regexpp': 4.12.1 @@ -7872,11 +7681,13 @@ snapshots: regexp-tree@0.1.27: {} - regexp.prototype.flags@1.5.3: + 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 regjsparser@0.12.0: @@ -7889,54 +7700,49 @@ snapshots: resolve-pkg-maps@1.0.0: {} - resolve@1.22.9: - dependencies: - is-core-module: 2.16.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.0.4: {} + reusify@1.1.0: {} rfdc@1.4.1: {} - rollup@4.34.6: + rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0): dependencies: - '@types/estree': 1.0.6 + '@oxc-project/runtime': 0.75.0 + fdir: 6.4.6(picomatch@4.0.2) + lightningcss: 1.30.1 + picomatch: 4.0.2 + postcss: 8.5.6 + rolldown: 1.0.0-beta.23 + tinyglobby: 0.2.14 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.34.6 - '@rollup/rollup-android-arm64': 4.34.6 - '@rollup/rollup-darwin-arm64': 4.34.6 - '@rollup/rollup-darwin-x64': 4.34.6 - '@rollup/rollup-freebsd-arm64': 4.34.6 - '@rollup/rollup-freebsd-x64': 4.34.6 - '@rollup/rollup-linux-arm-gnueabihf': 4.34.6 - '@rollup/rollup-linux-arm-musleabihf': 4.34.6 - '@rollup/rollup-linux-arm64-gnu': 4.34.6 - '@rollup/rollup-linux-arm64-musl': 4.34.6 - '@rollup/rollup-linux-loongarch64-gnu': 4.34.6 - '@rollup/rollup-linux-powerpc64le-gnu': 4.34.6 - '@rollup/rollup-linux-riscv64-gnu': 4.34.6 - '@rollup/rollup-linux-s390x-gnu': 4.34.6 - '@rollup/rollup-linux-x64-gnu': 4.34.6 - '@rollup/rollup-linux-x64-musl': 4.34.6 - '@rollup/rollup-win32-arm64-msvc': 4.34.6 - '@rollup/rollup-win32-ia32-msvc': 4.34.6 - '@rollup/rollup-win32-x64-msvc': 4.34.6 + '@types/node': 24.0.10 + esbuild: 0.25.5 fsevents: 2.3.3 + jiti: 2.4.2 + less: 4.3.0 + tsx: 4.19.2 + yaml: 2.8.0 - rspack-resolver@1.2.2: + rolldown@1.0.0-beta.23: + dependencies: + '@oxc-project/runtime': 0.75.0 + '@oxc-project/types': 0.75.0 + '@rolldown/pluginutils': 1.0.0-beta.23 + ansis: 4.1.0 optionalDependencies: - '@unrs/rspack-resolver-binding-darwin-arm64': 1.2.2 - '@unrs/rspack-resolver-binding-darwin-x64': 1.2.2 - '@unrs/rspack-resolver-binding-freebsd-x64': 1.2.2 - '@unrs/rspack-resolver-binding-linux-arm-gnueabihf': 1.2.2 - '@unrs/rspack-resolver-binding-linux-arm64-gnu': 1.2.2 - '@unrs/rspack-resolver-binding-linux-arm64-musl': 1.2.2 - '@unrs/rspack-resolver-binding-linux-x64-gnu': 1.2.2 - '@unrs/rspack-resolver-binding-linux-x64-musl': 1.2.2 - '@unrs/rspack-resolver-binding-wasm32-wasi': 1.2.2 - '@unrs/rspack-resolver-binding-win32-arm64-msvc': 1.2.2 - '@unrs/rspack-resolver-binding-win32-x64-msvc': 1.2.2 + '@rolldown/binding-darwin-arm64': 1.0.0-beta.23 + '@rolldown/binding-darwin-x64': 1.0.0-beta.23 + '@rolldown/binding-freebsd-x64': 1.0.0-beta.23 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-beta.23 + '@rolldown/binding-linux-arm64-gnu': 1.0.0-beta.23 + '@rolldown/binding-linux-arm64-musl': 1.0.0-beta.23 + '@rolldown/binding-linux-x64-gnu': 1.0.0-beta.23 + '@rolldown/binding-linux-x64-musl': 1.0.0-beta.23 + '@rolldown/binding-wasm32-wasi': 1.0.0-beta.23 + '@rolldown/binding-win32-arm64-msvc': 1.0.0-beta.23 + '@rolldown/binding-win32-ia32-msvc': 1.0.0-beta.23 + '@rolldown/binding-win32-x64-msvc': 1.0.0-beta.23 + + run-applescript@7.0.0: {} run-parallel@1.2.0: dependencies: @@ -7945,16 +7751,21 @@ snapshots: safe-array-concat@1.1.3: dependencies: call-bind: 1.0.8 - call-bound: 1.0.2 - get-intrinsic: 1.2.6 + 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.2 + call-bound: 1.0.4 es-errors: 1.3.0 is-regex: 1.2.1 @@ -7967,6 +7778,10 @@ snapshots: dependencies: compute-scroll-into-view: 1.0.20 + scroll-into-view-if-needed@3.1.0: + dependencies: + compute-scroll-into-view: 3.1.1 + scslre@0.3.0: dependencies: '@eslint-community/regexpp': 4.12.1 @@ -7980,16 +7795,14 @@ snapshots: semver@6.3.1: {} - semver@7.6.3: {} - - semver@7.7.1: {} + semver@7.7.2: {} set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 - get-intrinsic: 1.2.6 + get-intrinsic: 1.3.0 gopd: 1.2.0 has-property-descriptors: 1.0.2 @@ -8000,10 +7813,17 @@ snapshots: functions-have-names: 1.2.3 has-property-descriptors: 1.0.2 - sha.js@2.4.11: + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + sha.js@2.4.12: dependencies: inherits: 2.0.4 safe-buffer: 5.2.1 + to-buffer: 1.2.1 shallow-equal@1.2.1: {} @@ -8016,27 +7836,27 @@ snapshots: side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 - object-inspect: 1.13.3 + object-inspect: 1.13.4 side-channel-map@1.0.1: dependencies: - call-bound: 1.0.2 + call-bound: 1.0.4 es-errors: 1.3.0 - get-intrinsic: 1.2.6 - object-inspect: 1.13.3 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 side-channel-weakmap@1.0.2: dependencies: - call-bound: 1.0.2 + call-bound: 1.0.4 es-errors: 1.3.0 - get-intrinsic: 1.2.6 - object-inspect: 1.13.3 + 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.3 + object-inspect: 1.13.4 side-channel-list: 1.0.0 side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 @@ -8051,18 +7871,14 @@ snapshots: once: 1.4.0 simple-concat: 1.0.1 - sirv@3.0.0: + sirv@3.0.1: dependencies: - '@polka/url': 1.0.0-next.28 - mrmime: 2.0.0 + '@polka/url': 1.0.0-next.29 + mrmime: 2.0.1 totalist: 3.0.1 sisteransi@1.0.5: {} - slash@5.1.0: {} - - slashes@3.0.12: {} - sortablejs@1.14.0: {} sortablejs@1.15.6: {} @@ -8072,32 +7888,30 @@ snapshots: source-map@0.6.1: optional: true - spdx-correct@3.2.0: - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.20 - spdx-exceptions@2.5.0: {} - spdx-expression-parse@3.0.1: - dependencies: - spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.20 - spdx-expression-parse@4.0.0: dependencies: spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.20 + spdx-license-ids: 3.0.21 - spdx-license-ids@3.0.20: {} + spdx-license-ids@3.0.21: {} speakingurl@14.0.1: {} + splitpanes@4.0.4(vue@3.5.17(typescript@5.8.3)): + dependencies: + vue: 3.5.17(typescript@5.8.3) + sse.js@2.6.0: {} - stable-hash@0.0.5: {} + std-env@3.9.0: + optional: true - std-env@3.8.0: {} + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 string-width@4.2.3: dependencies: @@ -8114,25 +7928,25 @@ snapshots: string.prototype.trim@1.2.10: dependencies: call-bind: 1.0.8 - call-bound: 1.0.2 + call-bound: 1.0.4 define-data-property: 1.1.4 define-properties: 1.2.1 - es-abstract: 1.23.5 - es-object-atoms: 1.0.0 + es-abstract: 1.24.0 + 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.2 + call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.0.0 + 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.0.0 + es-object-atoms: 1.1.1 string_decoder@1.3.0: dependencies: @@ -8146,23 +7960,17 @@ snapshots: dependencies: ansi-regex: 6.1.0 - strip-final-newline@3.0.0: {} - strip-indent@4.0.0: dependencies: min-indent: 1.0.1 strip-json-comments@3.1.1: {} - strip-literal@2.1.1: - dependencies: - js-tokens: 9.0.1 - strip-literal@3.0.0: dependencies: js-tokens: 9.0.1 - stylis@4.3.4: {} + stylis@4.3.6: {} superjson@2.2.2: dependencies: @@ -8172,30 +7980,21 @@ snapshots: dependencies: has-flag: 4.0.0 - supports-preserve-symlinks-flag@1.0.0: {} - - svg-tags@1.0.0: {} - svgo@3.3.2: dependencies: '@trysound/sax': 0.2.0 commander: 7.2.0 - css-select: 5.1.0 + css-select: 5.2.2 css-tree: 2.3.1 - css-what: 6.1.0 + css-what: 6.2.2 csso: 5.0.5 picocolors: 1.1.1 - synckit@0.6.2: - dependencies: - tslib: 2.8.1 - - synckit@0.9.2: + synckit@0.11.8: dependencies: - '@pkgr/core': 0.1.1 - tslib: 2.8.1 + '@pkgr/core': 0.2.7 - tapable@2.2.1: {} + tapable@2.2.2: {} tar@6.2.1: dependencies: @@ -8208,13 +8007,22 @@ snapshots: throttle-debounce@5.0.2: {} - tinyexec@0.3.2: {} + tinyexec@0.3.2: + optional: true + + tinyexec@1.0.1: {} - tinyglobby@0.2.12: + tinyglobby@0.2.14: dependencies: - fdir: 6.4.3(picomatch@4.0.2) + fdir: 6.4.6(picomatch@4.0.2) picomatch: 4.0.2 + to-buffer@1.2.1: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -8225,16 +8033,21 @@ snapshots: totalist@3.0.1: {} - ts-api-utils@2.0.1(typescript@5.8.2): + ts-api-utils@2.1.0(typescript@5.8.3): dependencies: - typescript: 5.8.2 + typescript: 5.8.3 + + ts-declaration-location@1.0.7(typescript@5.8.3): + dependencies: + picomatch: 4.0.2 + typescript: 5.8.3 tslib@2.8.1: {} tsx@4.19.2: dependencies: esbuild: 0.23.1 - get-tsconfig: 4.10.0 + get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 optional: true @@ -8243,97 +8056,91 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@4.35.0: {} - - typed-array-buffer@1.0.2: + typed-array-buffer@1.0.3: dependencies: - call-bind: 1.0.8 + call-bound: 1.0.4 es-errors: 1.3.0 - is-typed-array: 1.1.13 + is-typed-array: 1.1.15 - typed-array-byte-length@1.0.1: + typed-array-byte-length@1.0.3: dependencies: call-bind: 1.0.8 - for-each: 0.3.3 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 - is-typed-array: 1.1.13 + is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.3: + typed-array-byte-offset@1.0.4: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 - for-each: 0.3.3 + for-each: 0.3.5 gopd: 1.2.0 has-proto: 1.2.0 - is-typed-array: 1.1.13 - reflect.getprototypeof: 1.0.8 + 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.3 + for-each: 0.3.5 gopd: 1.2.0 - is-typed-array: 1.1.13 - possible-typed-array-names: 1.0.0 - reflect.getprototypeof: 1.0.8 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 - typescript@5.8.2: {} + typescript@5.8.3: {} typical@4.0.0: {} - ufo@1.5.4: {} + ufo@1.6.1: {} - unbox-primitive@1.0.2: + unbox-primitive@1.1.0: dependencies: - call-bind: 1.0.8 - has-bigints: 1.0.2 + call-bound: 1.0.4 + has-bigints: 1.1.0 has-symbols: 1.1.0 - which-boxed-primitive: 1.1.0 + which-boxed-primitive: 1.1.1 - unconfig@7.0.0: + unconfig@7.3.2: dependencies: - '@antfu/utils': 8.1.0 + '@quansync/fs': 0.1.3 defu: 6.1.4 jiti: 2.4.2 + quansync: 0.2.10 - uncrypto@0.1.3: {} - - unctx@2.4.0: + unctx@2.4.1: dependencies: - acorn: 8.14.0 + acorn: 8.15.0 estree-walker: 3.0.3 magic-string: 0.30.17 - unplugin: 2.2.0 - - undici-types@6.20.0: {} + unplugin: 2.3.5 + optional: true - undici@6.21.0: {} + undici-types@7.8.0: {} - unicorn-magic@0.1.0: {} + undici@6.21.3: {} - unimport@3.14.5(rollup@4.34.6): + unimport@4.2.0: dependencies: - '@rollup/pluginutils': 5.1.4(rollup@4.34.6) - acorn: 8.14.0 + acorn: 8.15.0 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 - fast-glob: 3.3.3 - local-pkg: 0.5.1 + local-pkg: 1.1.1 magic-string: 0.30.17 mlly: 1.7.4 - pathe: 1.1.2 + pathe: 2.0.3 picomatch: 4.0.2 - pkg-types: 1.3.1 + pkg-types: 2.2.0 scule: 1.3.0 - strip-literal: 2.1.1 - unplugin: 1.16.1 - transitivePeerDependencies: - - rollup + strip-literal: 3.0.0 + tinyglobby: 0.2.14 + unplugin: 2.3.5 + unplugin-utils: 0.2.4 - unimport@4.1.2: + unimport@5.1.0: dependencies: - acorn: 8.14.0 + acorn: 8.15.0 escape-string-regexp: 5.0.0 estree-walker: 3.0.3 local-pkg: 1.1.1 @@ -8341,12 +8148,13 @@ snapshots: mlly: 1.7.4 pathe: 2.0.3 picomatch: 4.0.2 - pkg-types: 1.3.1 + pkg-types: 2.2.0 scule: 1.3.0 strip-literal: 3.0.0 - tinyglobby: 0.2.12 - unplugin: 2.2.2 + tinyglobby: 0.2.14 + unplugin: 2.3.5 unplugin-utils: 0.2.4 + optional: true unist-util-is@6.0.0: dependencies: @@ -8371,70 +8179,71 @@ snapshots: dependencies: cookie: 1.0.2 - unocss@66.0.0(postcss@8.5.3)(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)): - dependencies: - '@unocss/astro': 66.0.0(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) - '@unocss/cli': 66.0.0 - '@unocss/core': 66.0.0 - '@unocss/postcss': 66.0.0(postcss@8.5.3) - '@unocss/preset-attributify': 66.0.0 - '@unocss/preset-icons': 66.0.0 - '@unocss/preset-mini': 66.0.0 - '@unocss/preset-tagify': 66.0.0 - '@unocss/preset-typography': 66.0.0 - '@unocss/preset-uno': 66.0.0 - '@unocss/preset-web-fonts': 66.0.0 - '@unocss/preset-wind': 66.0.0 - '@unocss/preset-wind3': 66.0.0 - '@unocss/transformer-attributify-jsx': 66.0.0 - '@unocss/transformer-compile-class': 66.0.0 - '@unocss/transformer-directives': 66.0.0 - '@unocss/transformer-variant-group': 66.0.0 - '@unocss/vite': 66.0.0(vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.8.2)) + unocss@66.3.2(postcss@8.5.6)(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)): + dependencies: + '@unocss/astro': 66.3.2(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) + '@unocss/cli': 66.3.2 + '@unocss/core': 66.3.2 + '@unocss/postcss': 66.3.2(postcss@8.5.6) + '@unocss/preset-attributify': 66.3.2 + '@unocss/preset-icons': 66.3.2 + '@unocss/preset-mini': 66.3.2 + '@unocss/preset-tagify': 66.3.2 + '@unocss/preset-typography': 66.3.2 + '@unocss/preset-uno': 66.3.2 + '@unocss/preset-web-fonts': 66.3.2 + '@unocss/preset-wind': 66.3.2 + '@unocss/preset-wind3': 66.3.2 + '@unocss/preset-wind4': 66.3.2 + '@unocss/transformer-attributify-jsx': 66.3.2 + '@unocss/transformer-compile-class': 66.3.2 + '@unocss/transformer-directives': 66.3.2 + '@unocss/transformer-variant-group': 66.3.2 + '@unocss/vite': 66.3.2(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0))(vue@3.5.17(typescript@5.8.3)) optionalDependencies: - vite: 6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0) + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) transitivePeerDependencies: - postcss - supports-color - vue - unplugin-auto-import@19.1.2(@nuxt/kit@3.14.1592(rollup@4.34.6))(@vueuse/core@13.0.0(vue@3.5.13(typescript@5.8.2))): + unplugin-auto-import@19.3.0(@nuxt/kit@3.17.5)(@vueuse/core@13.5.0(vue@3.5.17(typescript@5.8.3))): dependencies: local-pkg: 1.1.1 magic-string: 0.30.17 picomatch: 4.0.2 - unimport: 4.1.2 - unplugin: 2.2.2 + unimport: 4.2.0 + unplugin: 2.3.5 unplugin-utils: 0.2.4 optionalDependencies: - '@nuxt/kit': 3.14.1592(rollup@4.34.6) - '@vueuse/core': 13.0.0(vue@3.5.13(typescript@5.8.2)) + '@nuxt/kit': 3.17.5 + '@vueuse/core': 13.5.0(vue@3.5.17(typescript@5.8.3)) unplugin-utils@0.2.4: dependencies: pathe: 2.0.3 picomatch: 4.0.2 - unplugin-vue-components@28.4.1(@babel/parser@7.26.10)(@nuxt/kit@3.14.1592(rollup@4.34.6))(vue@3.5.13(typescript@5.8.2)): + unplugin-vue-components@28.8.0(@babel/parser@7.28.0)(@nuxt/kit@3.17.5)(vue@3.5.17(typescript@5.8.3)): dependencies: chokidar: 3.6.0 - debug: 4.4.0 - local-pkg: 1.0.0 + debug: 4.4.1 + local-pkg: 1.1.1 magic-string: 0.30.17 mlly: 1.7.4 - tinyglobby: 0.2.12 - unplugin: 2.2.0 + tinyglobby: 0.2.14 + unplugin: 2.3.5 unplugin-utils: 0.2.4 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) optionalDependencies: - '@babel/parser': 7.26.10 - '@nuxt/kit': 3.14.1592(rollup@4.34.6) + '@babel/parser': 7.28.0 + '@nuxt/kit': 3.17.5 transitivePeerDependencies: - supports-color - unplugin-vue-define-options@1.5.5(vue@3.5.13(typescript@5.8.2)): + unplugin-vue-define-options@1.5.5(vue@3.5.17(typescript@5.8.3)): dependencies: - '@vue-macros/common': 1.16.1(vue@3.5.13(typescript@5.8.2)) + '@vue-macros/common': 1.16.1(vue@3.5.17(typescript@5.8.3)) ast-walker-scope: 0.6.2 unplugin: 1.16.1 transitivePeerDependencies: @@ -8442,34 +8251,27 @@ snapshots: unplugin@1.16.1: dependencies: - acorn: 8.14.0 - webpack-virtual-modules: 0.6.2 - - unplugin@2.2.0: - dependencies: - acorn: 8.14.0 + acorn: 8.15.0 webpack-virtual-modules: 0.6.2 - unplugin@2.2.2: + unplugin@2.3.5: dependencies: - acorn: 8.14.1 + acorn: 8.15.0 + picomatch: 4.0.2 webpack-virtual-modules: 0.6.2 - untyped@1.5.1: + untyped@2.0.0: dependencies: - '@babel/core': 7.26.0 - '@babel/standalone': 7.26.4 - '@babel/types': 7.26.5 + citty: 0.1.6 defu: 6.1.4 - jiti: 2.4.1 - mri: 1.2.0 + jiti: 2.4.2 + knitwork: 1.2.0 scule: 1.3.0 - transitivePeerDependencies: - - supports-color + optional: true - update-browserslist-db@1.1.1(browserslist@4.24.4): + update-browserslist-db@1.1.3(browserslist@4.25.1): dependencies: - browserslist: 4.24.4 + browserslist: 4.25.1 escalade: 3.2.0 picocolors: 1.1.1 @@ -8479,120 +8281,141 @@ snapshots: util-deprecate@1.0.2: {} - validate-npm-package-license@3.0.4: + uuid@11.1.0: {} + + vite-dev-rpc@1.1.0(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0)): dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 + birpc: 2.4.0 + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) + vite-hot-client: 2.1.0(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0)) + + vite-hot-client@2.1.0(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0)): + dependencies: + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) vite-plugin-build-id@0.5.0: dependencies: - isomorphic-git: 1.27.2 - node-object-hash: 3.0.0 + isomorphic-git: 1.32.1 + node-object-hash: 3.1.1 picocolors: 1.1.1 - typescript: 5.8.2 + typescript: 5.8.3 - vite-svg-loader@5.1.0(vue@3.5.13(typescript@5.8.2)): + vite-plugin-inspect@11.3.0(@nuxt/kit@3.17.5)(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0)): dependencies: - svgo: 3.3.2 - vue: 3.5.13(typescript@5.8.2) + ansis: 4.1.0 + debug: 4.4.1 + error-stack-parser-es: 1.0.5 + ohash: 2.0.11 + open: 10.1.2 + perfect-debounce: 1.0.0 + sirv: 3.0.1 + unplugin-utils: 0.2.4 + vite: rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0) + vite-dev-rpc: 1.1.0(rolldown-vite@7.0.4(@types/node@24.0.10)(esbuild@0.25.5)(jiti@2.4.2)(less@4.3.0)(tsx@4.19.2)(yaml@2.8.0)) + optionalDependencies: + '@nuxt/kit': 3.17.5 + transitivePeerDependencies: + - supports-color - vite@6.2.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.2)(tsx@4.19.2)(yaml@2.7.0): + vite-svg-loader@5.1.0(vue@3.5.17(typescript@5.8.3)): dependencies: - esbuild: 0.25.0 - postcss: 8.5.3 - rollup: 4.34.6 - optionalDependencies: - '@types/node': 22.10.2 - fsevents: 2.3.3 - jiti: 2.4.2 - less: 4.2.2 - tsx: 4.19.2 - yaml: 2.7.0 + svgo: 3.3.2 + vue: 3.5.17(typescript@5.8.3) - vscode-uri@3.0.8: {} + vscode-uri@3.1.0: {} - vue-dompurify-html@5.2.0(vue@3.5.13(typescript@5.8.2)): + vue-dompurify-html@5.3.0(vue@3.5.17(typescript@5.8.3)): dependencies: - dompurify: 3.2.3 - vue: 3.5.13(typescript@5.8.2) + dompurify: 3.2.6 + vue: 3.5.17(typescript@5.8.3) - vue-eslint-parser@10.1.1(eslint@9.23.0(jiti@2.4.2)): + vue-eslint-parser@10.2.0(eslint@9.30.1(jiti@2.4.2)): dependencies: - debug: 4.4.0 - eslint: 9.23.0(jiti@2.4.2) - eslint-scope: 8.3.0 - eslint-visitor-keys: 4.2.0 - espree: 10.3.0 + debug: 4.4.1 + eslint: 9.30.1(jiti@2.4.2) + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 esquery: 1.6.0 - lodash: 4.17.21 - semver: 7.7.1 + semver: 7.7.2 transitivePeerDependencies: - supports-color - vue-flow-layout@0.1.1(vue@3.5.13(typescript@5.8.2)): + vue-flow-layout@0.1.1(vue@3.5.17(typescript@5.8.3)): + dependencies: + vue: 3.5.17(typescript@5.8.3) + + vue-i18n@11.1.7(vue@3.5.17(typescript@5.8.3)): dependencies: - vue: 3.5.13(typescript@5.8.2) + '@intlify/core-base': 11.1.7 + '@intlify/shared': 11.1.7 + '@vue/devtools-api': 6.6.4 + vue: 3.5.17(typescript@5.8.3) - vue-router@4.5.0(vue@3.5.13(typescript@5.8.2)): + vue-router@4.5.1(vue@3.5.17(typescript@5.8.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) - vue-tsc@2.2.8(typescript@5.8.2): + vue-tsc@3.0.1(typescript@5.8.3): dependencies: - '@volar/typescript': 2.4.11 - '@vue/language-core': 2.2.8(typescript@5.8.2) - typescript: 5.8.2 + '@volar/typescript': 2.4.17 + '@vue/language-core': 3.0.1(typescript@5.8.3) + typescript: 5.8.3 - vue-types@3.0.2(vue@3.5.13(typescript@5.8.2)): + vue-types@3.0.2(vue@3.5.17(typescript@5.8.3)): dependencies: is-plain-object: 3.0.1 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) + + vue-types@6.0.0(vue@3.5.17(typescript@5.8.3)): + optionalDependencies: + vue: 3.5.17(typescript@5.8.3) - vue3-ace-editor@2.2.4(ace-builds@1.39.1)(vue@3.5.13(typescript@5.8.2)): + vue3-ace-editor@2.2.4(ace-builds@1.43.1)(vue@3.5.17(typescript@5.8.3)): dependencies: - ace-builds: 1.39.1 + ace-builds: 1.43.1 resize-observer-polyfill: 1.5.1 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) - vue3-apexcharts@1.5.3(apexcharts@4.5.0)(vue@3.5.13(typescript@5.8.2)): + vue3-apexcharts@1.5.3(apexcharts@4.7.0)(vue@3.5.17(typescript@5.8.3)): dependencies: - apexcharts: 4.5.0 - vue: 3.5.13(typescript@5.8.2) + apexcharts: 4.7.0 + vue: 3.5.17(typescript@5.8.3) - vue3-gettext@3.0.0-beta.6(@vue/compiler-sfc@3.5.13)(typescript@5.8.2)(vue@3.5.13(typescript@5.8.2)): + vue3-gettext@3.0.0-beta.6(@vue/compiler-sfc@3.5.17)(typescript@5.8.3)(vue@3.5.17(typescript@5.8.3)): dependencies: - '@vue/compiler-sfc': 3.5.13 + '@vue/compiler-sfc': 3.5.17 chalk: 4.1.2 command-line-args: 5.2.1 - cosmiconfig: 9.0.0(typescript@5.8.2) + cosmiconfig: 9.0.0(typescript@5.8.3) gettext-extractor: 3.8.0 glob: 10.4.5 parse5: 6.0.1 parse5-htmlparser2-tree-adapter: 6.0.1 pofile: 1.1.4 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) transitivePeerDependencies: - typescript - vue3-otp-input@0.5.21(vue@3.5.13(typescript@5.8.2)): + vue3-otp-input@0.5.40(vue@3.5.17(typescript@5.8.3)): dependencies: - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) - vue@3.5.13(typescript@5.8.2): + vue@3.5.17(typescript@5.8.3): dependencies: - '@vue/compiler-dom': 3.5.13 - '@vue/compiler-sfc': 3.5.13 - '@vue/runtime-dom': 3.5.13 - '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.8.2)) - '@vue/shared': 3.5.13 + '@vue/compiler-dom': 3.5.17 + '@vue/compiler-sfc': 3.5.17 + '@vue/runtime-dom': 3.5.17 + '@vue/server-renderer': 3.5.17(vue@3.5.17(typescript@5.8.3)) + '@vue/shared': 3.5.17 optionalDependencies: - typescript: 5.8.2 + typescript: 5.8.3 - vuedraggable@4.1.0(vue@3.5.13(typescript@5.8.2)): + vuedraggable@4.1.0(vue@3.5.17(typescript@5.8.3)): dependencies: sortablejs: 1.14.0 - vue: 3.5.13(typescript@5.8.2) + vue: 3.5.17(typescript@5.8.3) warning@4.0.3: dependencies: @@ -8606,42 +8429,44 @@ snapshots: whatwg-mimetype@4.0.0: {} - which-boxed-primitive@1.1.0: + which-boxed-primitive@1.1.1: dependencies: is-bigint: 1.1.0 - is-boolean-object: 1.2.1 - is-number-object: 1.1.0 - is-string: 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.2 - function.prototype.name: 1.1.6 + call-bound: 1.0.4 + function.prototype.name: 1.1.8 has-tostringtag: 1.0.2 - is-async-function: 2.0.0 + is-async-function: 2.1.1 is-date-object: 1.1.0 - is-finalizationregistry: 1.1.0 - is-generator-function: 1.0.10 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.0 is-regex: 1.2.1 - is-weakref: 1.1.0 + is-weakref: 1.1.1 isarray: 2.0.5 - which-boxed-primitive: 1.1.0 + which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.16 + 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.3 + is-weakset: 2.0.4 - which-typed-array@1.1.16: + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.8 - for-each: 0.3.3 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 gopd: 1.2.0 has-tostringtag: 1.0.2 @@ -8665,6 +8490,8 @@ snapshots: wrappy@1.0.2: {} + xlsx@https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz: {} + xml-name-validator@4.0.0: {} yallist@3.1.1: {} @@ -8674,9 +8501,9 @@ snapshots: yaml-eslint-parser@1.3.0: dependencies: eslint-visitor-keys: 3.4.3 - yaml: 2.7.0 + yaml: 2.8.0 - yaml@2.7.0: {} + yaml@2.8.0: {} yauzl@2.10.0: dependencies: diff --git a/app/src/App.vue b/app/src/App.vue index 747a9c1a0..e6818b3aa 100644 --- a/app/src/App.vue +++ b/app/src/App.vue @@ -1,14 +1,11 @@ @@ -74,8 +74,13 @@ watch(() => props.forceDnsChallenge, v => { - - + + props.forceDnsChallenge, v => { + + + + diff --git a/app/src/views/site/cert/components/DNSChallenge.vue b/app/src/components/AutoCertForm/DNSChallenge.vue similarity index 87% rename from app/src/views/site/cert/components/DNSChallenge.vue rename to app/src/components/AutoCertForm/DNSChallenge.vue index a6692cf20..4549c36b5 100644 --- a/app/src/views/site/cert/components/DNSChallenge.vue +++ b/app/src/components/AutoCertForm/DNSChallenge.vue @@ -1,7 +1,8 @@ diff --git a/app/src/components/AutoCertForm/index.ts b/app/src/components/AutoCertForm/index.ts new file mode 100644 index 000000000..63d69d71a --- /dev/null +++ b/app/src/components/AutoCertForm/index.ts @@ -0,0 +1,3 @@ +import AutoCertForm from './AutoCertForm.vue' + +export default AutoCertForm diff --git a/app/src/components/BaseEditor/BaseEditor.vue b/app/src/components/BaseEditor/BaseEditor.vue new file mode 100644 index 000000000..e070dc06b --- /dev/null +++ b/app/src/components/BaseEditor/BaseEditor.vue @@ -0,0 +1,87 @@ + + + + + + + diff --git a/app/src/components/BaseEditor/index.ts b/app/src/components/BaseEditor/index.ts new file mode 100644 index 000000000..8b3edbdfd --- /dev/null +++ b/app/src/components/BaseEditor/index.ts @@ -0,0 +1,4 @@ +import BaseEditor from './BaseEditor.vue' + +export { BaseEditor } +export default BaseEditor diff --git a/app/src/components/Breadcrumb/index.ts b/app/src/components/Breadcrumb/index.ts new file mode 100644 index 000000000..4211b0d72 --- /dev/null +++ b/app/src/components/Breadcrumb/index.ts @@ -0,0 +1,3 @@ +import Breadcrumb from './Breadcrumb.vue' + +export default Breadcrumb diff --git a/app/src/views/site/cert/CertInfo.vue b/app/src/components/CertInfo/CertInfo.vue similarity index 95% rename from app/src/views/site/cert/CertInfo.vue rename to app/src/components/CertInfo/CertInfo.vue index b5cd3cd0f..ad63d299c 100644 --- a/app/src/views/site/cert/CertInfo.vue +++ b/app/src/components/CertInfo/CertInfo.vue @@ -44,5 +44,7 @@ const isValid = computed(() => dayjs().isAfter(props.cert?.not_before) && dayjs( diff --git a/app/src/components/CertInfo/index.ts b/app/src/components/CertInfo/index.ts new file mode 100644 index 000000000..682ee3cad --- /dev/null +++ b/app/src/components/CertInfo/index.ts @@ -0,0 +1,3 @@ +import CertInfo from './CertInfo.vue' + +export default CertInfo diff --git a/app/src/components/Chart/AreaChart.vue b/app/src/components/Chart/AreaChart.vue index 1c3e8e952..4b3e8415d 100644 --- a/app/src/components/Chart/AreaChart.vue +++ b/app/src/components/Chart/AreaChart.vue @@ -1,9 +1,9 @@ diff --git a/app/src/components/ChatGPT/ChatMessage.vue b/app/src/components/ChatGPT/ChatMessage.vue new file mode 100644 index 000000000..41f2ab953 --- /dev/null +++ b/app/src/components/ChatGPT/ChatMessage.vue @@ -0,0 +1,292 @@ + + + + + diff --git a/app/src/components/ChatGPT/ChatMessageInput.vue b/app/src/components/ChatGPT/ChatMessageInput.vue new file mode 100644 index 000000000..8880c9dfe --- /dev/null +++ b/app/src/components/ChatGPT/ChatMessageInput.vue @@ -0,0 +1,81 @@ + + + + + diff --git a/app/src/components/ChatGPT/ChatMessageList.vue b/app/src/components/ChatGPT/ChatMessageList.vue new file mode 100644 index 000000000..dba81eadc --- /dev/null +++ b/app/src/components/ChatGPT/ChatMessageList.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/app/src/components/ChatGPT/chatService.ts b/app/src/components/ChatGPT/chatService.ts new file mode 100644 index 000000000..a1bddc7ce --- /dev/null +++ b/app/src/components/ChatGPT/chatService.ts @@ -0,0 +1,114 @@ +import type { CodeBlockState } from './types' +import type { ChatComplicationMessage } from '@/api/openai' +import { storeToRefs } from 'pinia' +import { urlJoin } from '@/lib/helper' +import { useUserStore } from '@/pinia' +import { updateCodeBlockState } from './utils' + +export class ChatService { + private buffer = '' + private lastChunkStr = '' + private codeBlockState: CodeBlockState = reactive({ + isInCodeBlock: false, + backtickCount: 0, + }) + + // applyChunk: Process one SSE chunk and update content directly + private applyChunk(input: Uint8Array, targetMsg: ChatComplicationMessage) { + const decoder = new TextDecoder('utf-8') + const raw = decoder.decode(input) + // SSE default split by segment + const lines = raw.split('\n\n') + + for (const line of lines) { + if (!line.startsWith('event:message\ndata:')) + continue + + const dataStr = line.slice('event:message\ndata:'.length) + if (!dataStr) + continue + + const content = JSON.parse(dataStr).content as string + if (!content || content.trim() === '') + continue + if (content === this.lastChunkStr) + continue + + this.lastChunkStr = content + + // Only detect substrings + updateCodeBlockState(content, this.codeBlockState) + + // Directly append content to buffer + this.buffer += content + + // Update message content immediately - typewriter effect is handled in ChatMessage.vue + targetMsg.content = this.buffer + } + } + + // request: Send messages to server, receive SSE, and process chunks + async request( + path: string | undefined, + messages: ChatComplicationMessage[], + onProgress?: (message: ChatComplicationMessage) => void, + ): Promise { + // Reset buffer flags each time + this.buffer = '' + this.lastChunkStr = '' + this.codeBlockState.isInCodeBlock = false + this.codeBlockState.backtickCount = 0 + + const user = useUserStore() + const { token } = storeToRefs(user) + + // Filter out empty assistant messages for the request + const requestMessages = messages.filter(msg => + msg.role === 'user' || (msg.role === 'assistant' && msg.content.trim() !== ''), + ) + + const res = await fetch(urlJoin(window.location.pathname, '/api/chatgpt'), { + method: 'POST', + headers: { + Accept: 'text/event-stream', + Authorization: token.value, + }, + body: JSON.stringify({ + filepath: path, + messages: requestMessages, + }), + }) + + if (!res.body) { + throw new Error('No response body') + } + + const reader = res.body.getReader() + + // Create assistant message for streaming updates + const assistantMessage: ChatComplicationMessage = { + role: 'assistant', + content: '', + } + + while (true) { + try { + const { done, value } = await reader.read() + if (done) { + break + } + if (value) { + // Process each chunk + this.applyChunk(value, assistantMessage) + onProgress?.(assistantMessage) + } + } + catch { + // In case of error + break + } + } + + return assistantMessage + } +} diff --git a/app/src/components/ChatGPT/chatgpt.ts b/app/src/components/ChatGPT/chatgpt.ts new file mode 100644 index 000000000..e42c19d2d --- /dev/null +++ b/app/src/components/ChatGPT/chatgpt.ts @@ -0,0 +1,281 @@ +import type { ChatComplicationMessage } from '@/api/openai' +import { defineStore } from 'pinia' +import { computed, nextTick, ref } from 'vue' +import openai from '@/api/openai' +import { ChatService } from './chatService' + +export const useChatGPTStore = defineStore('chatgpt', () => { + // State + const path = ref('') // Path to the chat record file + const messages = ref([]) + const messageContainerRef = ref() + const loading = ref(false) + const editingIdx = ref(-1) + const editValue = ref('') + const askBuffer = ref('') + const streamingMessageIndex = ref(-1) // Track which message is currently streaming + + // Getters + const isEditing = computed(() => editingIdx.value !== -1) + const currentEditingMessage = computed(() => { + if (editingIdx.value !== -1 && messages.value[editingIdx.value]) { + return messages.value[editingIdx.value] + } + return null + }) + const hasMessages = computed(() => messages.value.length > 0) + const shouldShowStartButton = computed(() => messages.value.length === 0) + + // Actions + // Initialize messages for a specific file path + async function initMessages(filePath?: string) { + messages.value = [] + if (filePath) { + try { + const record = await openai.get_record(filePath) + messages.value = record.content || [] + } + catch (error) { + console.error('Failed to load chat record:', error) + } + path.value = filePath + } + } + + // Start editing a message at the specified index + function startEdit(index: number) { + if (index >= 0 && index < messages.value.length) { + editingIdx.value = index + editValue.value = messages.value[index].content + } + } + + // Save the edited message + function saveEdit() { + if (editingIdx.value !== -1 && messages.value[editingIdx.value]) { + messages.value[editingIdx.value].content = editValue.value + editingIdx.value = -1 + editValue.value = '' + } + } + + // Cancel editing and reset state + function cancelEdit() { + editingIdx.value = -1 + editValue.value = '' + } + + // Add a new user message + function addUserMessage(content: string) { + messages.value.push({ + role: 'user', + content, + }) + } + + // Add a new assistant message + function addAssistantMessage(content: string = '') { + messages.value.push({ + role: 'assistant', + content, + }) + } + + // Update the last assistant message content (for streaming) + function updateLastAssistantMessage(content: string) { + const lastMessage = messages.value[messages.value.length - 1] + if (lastMessage && lastMessage.role === 'assistant') { + lastMessage.content = content + } + } + + // Remove messages after the specified index for regeneration + function prepareRegenerate(index: number) { + messages.value = messages.value.slice(0, index) + cancelEdit() + } + + // Clear all messages + function clearMessages() { + messages.value = [] + cancelEdit() + } + + // Store chat record to server + async function storeRecord() { + if (!path.value) + return + + try { + // Filter out empty messages before storing + const validMessages = messages.value.filter(msg => msg.content.trim() !== '') + await openai.store_record({ + file_name: path.value, + messages: validMessages, + }) + } + catch (error) { + console.error('Failed to store chat record:', error) + } + } + + // Clear chat record on server + async function clearRecord() { + if (!path.value) + return + + try { + await openai.store_record({ + file_name: path.value, + messages: [], + }) + clearMessages() + } + catch (error) { + console.error('Failed to clear chat record:', error) + } + } + + // Set loading state + function setLoading(loadingState: boolean) { + loading.value = loadingState + } + + // Set ask buffer + function setAskBuffer(buffer: string) { + askBuffer.value = buffer + } + + // Clear ask buffer + function clearAskBuffer() { + askBuffer.value = '' + } + + // scroll to bottom + function scrollToBottom() { + messageContainerRef.value?.scrollTo({ + top: messageContainerRef.value.scrollHeight, + behavior: 'smooth', + }) + } + + // Set streaming message index + function setStreamingMessageIndex(index: number) { + streamingMessageIndex.value = index + } + + // Clear streaming message index + function clearStreamingMessageIndex() { + streamingMessageIndex.value = -1 + } + + // Request: Send messages to server using chat service + async function request() { + setLoading(true) + + // Set the streaming message index to the last message (assistant message) + setStreamingMessageIndex(messages.value.length - 1) + + try { + const chatService = new ChatService() + const assistantMessage = await chatService.request( + path.value, + messages.value.slice(0, -1), // Exclude the empty assistant message + message => { + // Update the current assistant message in real-time + updateLastAssistantMessage(message.content) + }, + ) + + // Update the final content + updateLastAssistantMessage(assistantMessage.content) + + // Auto scroll to bottom after response + await nextTick() + scrollToBottom() + } + catch (error) { + console.error('Chat request failed:', error) + // Remove the empty assistant message on error + if (messages.value.length > 0 && messages.value[messages.value.length - 1].content === '') { + messages.value.pop() + } + } + finally { + setLoading(false) + clearStreamingMessageIndex() // Clear streaming state + await storeRecord() + } + } + + // Send: Add user message into messages then call request + async function send(content: string, currentLanguage?: string) { + if (messages.value.length === 0) { + // The first message + addUserMessage(`${content}\n\nCurrent Language Code: ${currentLanguage}`) + } + else { + // Append user's new message + addUserMessage(askBuffer.value) + clearAskBuffer() + } + + // Add empty assistant message for real-time updates + addAssistantMessage('') + + await request() + } + + // Regenerate: Removes messages after index and re-request the answer + async function regenerate(index: number) { + prepareRegenerate(index) + + // Add empty assistant message for real-time updates + addAssistantMessage('') + + await request() + } + + watch(messages, () => { + scrollToBottom() + }, { immediate: true }) + // Return all state, getters, and actions + return { + // State + messages, + loading, + editingIdx, + editValue, + askBuffer, + messageContainerRef, + streamingMessageIndex, + + // Getters + isEditing, + currentEditingMessage, + hasMessages, + shouldShowStartButton, + + // Actions + initMessages, + startEdit, + saveEdit, + cancelEdit, + addUserMessage, + addAssistantMessage, + updateLastAssistantMessage, + prepareRegenerate, + clearMessages, + storeRecord, + clearRecord, + setLoading, + setAskBuffer, + clearAskBuffer, + setStreamingMessageIndex, + clearStreamingMessageIndex, + request, + send, + regenerate, + scrollToBottom, + } +}) diff --git a/app/src/components/ChatGPT/composables/useTypewriter.ts b/app/src/components/ChatGPT/composables/useTypewriter.ts new file mode 100644 index 000000000..11bbc628e --- /dev/null +++ b/app/src/components/ChatGPT/composables/useTypewriter.ts @@ -0,0 +1,110 @@ +import type { Ref } from 'vue' + +interface TypewriterOptions { + baseSpeed?: number + fastSpeed?: number + scrollInterval?: number +} + +export function useTypewriter(options: TypewriterOptions = {}) { + const { + baseSpeed = 35, + fastSpeed = 25, + scrollInterval = 150, + } = options + + let isTyping = false + let typeQueue: string[] = [] + let scrollTimer: number | null = null + let rafId: number | null = null + + const typeText = async ( + content: string, + targetRef: Ref, + onScroll?: () => void, + isFastMode = false, + ): Promise => { + return new Promise(resolve => { + if (isTyping) { + typeQueue.push(content) + resolve() + return + } + + isTyping = true + const chars = content.split('') + let charIndex = 0 + + const typeNextChars = () => { + if (charIndex >= chars.length) { + isTyping = false + + // Process queued content + if (typeQueue.length > 0) { + const nextContent = typeQueue.shift()! + typeText(nextContent, targetRef, onScroll, isFastMode).then(resolve) + } + else { + resolve() + } + return + } + + // 一个字符一个字符地添加 + targetRef.value += chars[charIndex] + charIndex++ + + // Throttled scrolling - 减少滚动频率 + if (onScroll && !scrollTimer) { + scrollTimer = window.setTimeout(() => { + onScroll() + scrollTimer = null + }, scrollInterval) + } + + // Dynamic speed based on mode + const delay = isFastMode ? fastSpeed : baseSpeed + + rafId = requestAnimationFrame(() => { + setTimeout(typeNextChars, delay) + }) + } + + typeNextChars() + }) + } + + const resetTypewriter = () => { + isTyping = false + typeQueue = [] + + if (scrollTimer) { + clearTimeout(scrollTimer) + scrollTimer = null + } + + if (rafId) { + cancelAnimationFrame(rafId) + rafId = null + } + } + + const pauseTypewriter = () => { + if (rafId) { + cancelAnimationFrame(rafId) + rafId = null + } + } + + const resumeTypewriter = () => { + // Typewriter will resume automatically when next content is queued + } + + return { + typeText, + resetTypewriter, + pauseTypewriter, + resumeTypewriter, + isTyping: readonly(ref(isTyping)), + } +} diff --git a/app/src/components/ChatGPT/index.ts b/app/src/components/ChatGPT/index.ts new file mode 100644 index 000000000..614cf4ddf --- /dev/null +++ b/app/src/components/ChatGPT/index.ts @@ -0,0 +1,10 @@ +import ChatGPT from './ChatGPT.vue' + +export { default as ChatMessage } from './ChatMessage.vue' +export { default as ChatMessageInput } from './ChatMessageInput.vue' +export { default as ChatMessageList } from './ChatMessageList.vue' +export { ChatService } from './chatService' +export { marked } from './markdown' +export * from './types' +export * from './utils' +export default ChatGPT diff --git a/app/src/components/ChatGPT/markdown.ts b/app/src/components/ChatGPT/markdown.ts new file mode 100644 index 000000000..619ad2030 --- /dev/null +++ b/app/src/components/ChatGPT/markdown.ts @@ -0,0 +1,26 @@ +import hljs from 'highlight.js' +import nginx from 'highlight.js/lib/languages/nginx' +import { Marked } from 'marked' +import { markedHighlight } from 'marked-highlight' +import 'highlight.js/styles/vs2015.css' + +// Register nginx language for highlight.js +hljs.registerLanguage('nginx', nginx) + +// Markdown renderer +export const marked = new Marked( + markedHighlight({ + langPrefix: 'hljs language-', + highlight(code, lang) { + const language = hljs.getLanguage(lang) ? lang : 'nginx' + return hljs.highlight(code, { language }).value + }, + }), +) + +// Basic marked options +marked.setOptions({ + pedantic: false, + gfm: true, + breaks: false, +}) diff --git a/app/src/components/ChatGPT/types.ts b/app/src/components/ChatGPT/types.ts new file mode 100644 index 000000000..7e78ac955 --- /dev/null +++ b/app/src/components/ChatGPT/types.ts @@ -0,0 +1,9 @@ +export interface CodeBlockState { + isInCodeBlock: boolean + backtickCount: number +} + +export interface ChatGPTProps { + content: string + path?: string +} diff --git a/app/src/components/ChatGPT/utils.ts b/app/src/components/ChatGPT/utils.ts new file mode 100644 index 000000000..1f8c1b0c7 --- /dev/null +++ b/app/src/components/ChatGPT/utils.ts @@ -0,0 +1,86 @@ +import type { CodeBlockState } from './types' + +/** + * transformReasonerThink: if appears but is not paired with , it will be automatically supplemented, and the entire text will be converted to a Markdown quote + */ +export function transformReasonerThink(rawText: string): string { + // 1. Count number of vs + const openThinkRegex = //gi + const closeThinkRegex = /<\/think>/gi + + const openCount = (rawText.match(openThinkRegex) || []).length + const closeCount = (rawText.match(closeThinkRegex) || []).length + + // 2. If open tags exceed close tags, append missing at the end + if (openCount > closeCount) { + const diff = openCount - closeCount + rawText += ''.repeat(diff) + } + + // 3. Replace ... blocks with Markdown blockquote ("> ...") + return rawText.replace(/([\s\S]*?)<\/think>/g, (match, p1) => { + // Split the inner text by line, prefix each with "> " + const lines = p1.trim().split('\n') + const blockquoted = lines.map(line => `> ${line}`).join('\n') + // Return the replaced Markdown quote + return `\n${blockquoted}\n` + }) +} + +/** + * transformText: transform the text + */ +export function transformText(rawText: string): string { + return transformReasonerThink(rawText) +} + +/** + * updateCodeBlockState: The number of unnecessary scans is reduced by changing the scanning method of incremental content + */ +export function updateCodeBlockState(chunk: string, codeBlockState: CodeBlockState) { + // count all ``` in chunk + // note to distinguish how many "backticks" are not paired + + const regex = /```/g + + while (regex.exec(chunk) !== null) { + codeBlockState.backtickCount++ + // if backtickCount is even -> closed + codeBlockState.isInCodeBlock = codeBlockState.backtickCount % 2 !== 0 + } +} + +// Global scroll debouncing +let scrollTimeoutId: number | null = null + +/** + * scrollToBottom: Scroll container to bottom with optimized performance + */ +export function scrollToBottom() { + // 更简单的防抖,避免过度优化导致的卡顿 + if (scrollTimeoutId) { + return + } + + scrollTimeoutId = window.setTimeout(() => { + const container = document.querySelector('.right-settings .ant-card-body') + if (container) { + // 直接设置scrollTop,避免动画导致的卡顿 + container.scrollTop = container.scrollHeight + } + scrollTimeoutId = null + }, 50) // 减少到50ms,提高响应性 +} + +/** + * scrollToBottomSmooth: Smooth scroll version for manual interactions + */ +export function scrollToBottomSmooth() { + const container = document.querySelector('.right-settings .ant-card-body') + if (container) { + container.scrollTo({ + top: container.scrollHeight, + behavior: 'smooth', + }) + } +} diff --git a/app/src/components/CodeEditor/CodeCompletion.ts b/app/src/components/CodeEditor/CodeCompletion.ts new file mode 100644 index 000000000..58c3b3c12 --- /dev/null +++ b/app/src/components/CodeEditor/CodeCompletion.ts @@ -0,0 +1,286 @@ +import type { Editor } from 'ace-builds' +import type { Point } from 'ace-builds-internal/document' +import type ReconnectingWebSocket from 'reconnecting-websocket' +import { debounce } from 'lodash' +import { v4 as uuidv4 } from 'uuid' +import openai from '@/api/openai' + +// eslint-disable-next-line ts/no-explicit-any +function debug(...args: any[]) { + if (import.meta.env.DEV) { + // eslint-disable-next-line no-console + console.debug(`[CodeEditor]`, ...args) + } +} + +// Config file patterns and extensions +const CONFIG_FILE_EXTENSIONS = ['.conf', '.config'] +const SENSITIVE_CONTENT_PATTERNS = [ + /-----BEGIN [A-Z ]+ PRIVATE KEY-----/, + /-----BEGIN CERTIFICATE-----/, + /apiKey\s*[:=]\s*["'][a-zA-Z0-9]+["']/, + /password\s*[:=]\s*["'][^"']+["']/, + /secret\s*[:=]\s*["'][^"']+["']/, +] + +function useCodeCompletion() { + const editorRef = ref() + const currentGhostText = ref('') + const isConfigFile = ref(false) + + const ws = shallowRef() + + // Check if the current file is a configuration file + function checkIfConfigFile(filename: string, content: string): boolean { + // Check file extension + const hasConfigExtension = CONFIG_FILE_EXTENSIONS.some(ext => filename.toLowerCase().endsWith(ext)) + + // Check if it's an Nginx configuration file based on common patterns + const hasNginxPatterns = /server\s*\{|location\s*\/|http\s*\{|upstream\s*[\w-]+\s*\{/.test(content) + + return hasConfigExtension || hasNginxPatterns + } + + // Check if content contains sensitive information that shouldn't be sent + function containsSensitiveContent(content: string): boolean { + return SENSITIVE_CONTENT_PATTERNS.some(pattern => pattern.test(content)) + } + + function getAISuggestions(code: string, context: string, position: Point, callback: (suggestion: string) => void, language: string = 'nginx', suffix: string = '', requestId: string) { + if (!ws.value || ws.value.readyState !== WebSocket.OPEN) { + debug('WebSocket is not open') + return + } + + if (!code.trim()) { + debug('Code is empty') + return + } + + // Skip if not a config file or contains sensitive content + if (!isConfigFile.value) { + debug('Skipping AI suggestions for non-config file') + return + } + + if (containsSensitiveContent(context)) { + debug('Skipping AI suggestions due to sensitive content') + return + } + + const message = { + context, + code, + suffix, + language, + position, + request_id: requestId, + } + + debug('Sending message', message) + + ws.value.send(JSON.stringify(message)) + + ws.value.onmessage = event => { + const data = JSON.parse(event.data) + debug(`Received message`, data, requestId) + if (data.request_id === requestId) { + callback(data.code) + } + } + } + + function applyGhostText() { + if (!editorRef.value) { + debug('Editor instance not available yet') + return + } + + if (!isConfigFile.value) { + debug('Skipping ghost text for non-config file') + return + } + + try { + const currentText = editorRef.value.getValue() + + // Skip if content contains sensitive information + if (containsSensitiveContent(currentText)) { + debug('Skipping ghost text due to sensitive content') + return + } + + const cursorPosition = editorRef.value.getCursorPosition() + + // Get all text before the current cursor position as the code part for the request + const allLines = currentText.split('\n') + const currentLine = allLines[cursorPosition.row] + const textUpToCursor = allLines.slice(0, cursorPosition.row).join('\n') + + (cursorPosition.row > 0 ? '\n' : '') + + currentLine.substring(0, cursorPosition.column) + + // Get text after cursor position as suffix + const textAfterCursor = currentLine.substring(cursorPosition.column) + + (cursorPosition.row < allLines.length - 1 ? '\n' : '') + + allLines.slice(cursorPosition.row + 1).join('\n') + + // Generate new request ID + const requestId = uuidv4() + + // Clear existing ghost text before making the request + clearGhostText() + + // Get AI suggestions + getAISuggestions( + textUpToCursor, + currentText, + cursorPosition, + suggestion => { + debug(`AI suggestions applied: ${suggestion}`) + + // If there's a suggestion, set ghost text + if (suggestion && typeof editorRef.value!.setGhostText === 'function') { + clearGhostText() + + // Get current cursor position (may have changed during async process) + const newPosition = editorRef.value!.getCursorPosition() + + editorRef.value!.setGhostText(suggestion, { + column: newPosition.column, + row: newPosition.row, + }) + debug(`Ghost text set: ${suggestion}`) + currentGhostText.value = suggestion + } + else if (suggestion) { + debug('setGhostText method not available on editor instance') + } + }, + editorRef.value.session.getMode()?.path?.split('/').pop() || 'text', + textAfterCursor, // Pass text after cursor as suffix + requestId, // Pass request ID + ) + } + catch (error) { + debug(`Error in applyGhostText: ${error}`) + } + } + + // Accept the ghost text suggestion with Tab key + function setupTabHandler(editor: Editor) { + if (!editor) { + debug('Editor not available in setupTabHandler') + return + } + + debug('Setting up Tab key handler') + + // Remove existing command to avoid conflicts + const existingCommand = editor.commands.byName.acceptGhostText + if (existingCommand) { + editor.commands.removeCommand(existingCommand) + } + + // Register new Tab key handler command with highest priority + editor.commands.addCommand({ + name: 'acceptGhostText', + bindKey: { win: 'Tab', mac: 'Tab' }, + exec: (editor: Editor) => { + // Use our saved ghost text, not dependent on editor.ghostText + if (currentGhostText.value) { + debug(`Accepting ghost text: ${currentGhostText.value}`) + + const position = editor.getCursorPosition() + const text = currentGhostText.value + + // Insert text through session API + editor.session.insert(position, text) + + clearGhostText() + + debug('Ghost text inserted successfully') + return true // Prevent event propagation + } + + debug('No ghost text to accept, allowing default tab behavior') + return false // Allow default Tab behavior + }, + readOnly: false, + }) + + debug('Tab key handler set up successfully') + } + + // Clear ghost text and reset state + function clearGhostText() { + if (!editorRef.value) + return + + if (typeof editorRef.value.removeGhostText === 'function') { + editorRef.value.removeGhostText() + } + currentGhostText.value = '' + } + + const debouncedApplyGhostText = debounce(applyGhostText, 1000, { leading: false, trailing: true }) + + debug('Editor initialized') + + async function init(editor: Editor, filename: string = '') { + const { enabled } = await openai.get_code_completion_enabled_status() + if (!enabled) { + debug('Code completion is not enabled') + return + } + + ws.value = openai.code_completion() + + editorRef.value = editor + + // Determine if the current file is a configuration file + const content = editor.getValue() + isConfigFile.value = checkIfConfigFile(filename, content) + debug(`File type check: isConfigFile=${isConfigFile.value}, filename=${filename}`) + + // Set up Tab key handler + setupTabHandler(editor) + + setTimeout(() => { + editor.on('change', (e: { action: string }) => { + debug(`Editor change event: ${e.action}`) + // If change is caused by user input, interrupt current completion + clearGhostText() + + if (e.action === 'insert' || e.action === 'remove') { + // Clear current ghost text + if (isConfigFile.value) { + debouncedApplyGhostText() + } + } + }) + + // Listen for cursor changes, using debounce + editor.selection.on('changeCursor', () => { + debug('Cursor changed') + clearGhostText() + if (isConfigFile.value) { + debouncedApplyGhostText() + } + }) + }, 2000) + } + + function cleanUp() { + if (ws.value) { + ws.value.close() + } + debug('CodeCompletion unmounted') + } + + return { + init, + cleanUp, + } +} + +export default useCodeCompletion diff --git a/app/src/components/CodeEditor/CodeEditor.vue b/app/src/components/CodeEditor/CodeEditor.vue index 7eb159ab4..2b1c21d77 100644 --- a/app/src/components/CodeEditor/CodeEditor.vue +++ b/app/src/components/CodeEditor/CodeEditor.vue @@ -1,42 +1,57 @@ @@ -45,4 +60,9 @@ ace.config.setModuleUrl('ace/ext/searchbox', extSearchboxUrl) z-index: 1; position: relative; } + +:deep(.ace_ghost-text) { + color: #6a737d; + opacity: 0.8; +} diff --git a/app/src/components/ConfigHistory/ConfigHistory.vue b/app/src/components/ConfigHistory/ConfigHistory.vue new file mode 100644 index 000000000..9687a5070 --- /dev/null +++ b/app/src/components/ConfigHistory/ConfigHistory.vue @@ -0,0 +1,221 @@ + + + + + diff --git a/app/src/components/ConfigHistory/DiffViewer.vue b/app/src/components/ConfigHistory/DiffViewer.vue new file mode 100644 index 000000000..04464ec38 --- /dev/null +++ b/app/src/components/ConfigHistory/DiffViewer.vue @@ -0,0 +1,465 @@ + + + + + diff --git a/app/src/components/ConfigHistory/index.ts b/app/src/components/ConfigHistory/index.ts new file mode 100644 index 000000000..bd89b8b49 --- /dev/null +++ b/app/src/components/ConfigHistory/index.ts @@ -0,0 +1,5 @@ +import ConfigHistory from './ConfigHistory.vue' +import DiffViewer from './DiffViewer.vue' + +export { ConfigHistory, DiffViewer } +export default ConfigHistory diff --git a/app/src/components/EnvGroupTabs/EnvGroupTabs.vue b/app/src/components/EnvGroupTabs/EnvGroupTabs.vue new file mode 100644 index 000000000..bf69df6ce --- /dev/null +++ b/app/src/components/EnvGroupTabs/EnvGroupTabs.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/app/src/components/EnvGroupTabs/index.ts b/app/src/components/EnvGroupTabs/index.ts new file mode 100644 index 000000000..d38d49cb2 --- /dev/null +++ b/app/src/components/EnvGroupTabs/index.ts @@ -0,0 +1,3 @@ +import EnvGroupTabs from './EnvGroupTabs.vue' + +export default EnvGroupTabs diff --git a/app/src/components/EnvIndicator/EnvIndicator.vue b/app/src/components/EnvIndicator/EnvIndicator.vue index b820ceaaf..b547e860c 100644 --- a/app/src/components/EnvIndicator/EnvIndicator.vue +++ b/app/src/components/EnvIndicator/EnvIndicator.vue @@ -1,8 +1,8 @@ + + + + diff --git a/app/src/views/site/ngx_conf/LogEntry.vue b/app/src/components/NgxConfigEditor/LogEntry.vue similarity index 58% rename from app/src/views/site/ngx_conf/LogEntry.vue rename to app/src/components/NgxConfigEditor/LogEntry.vue index 6b6d18453..4d00fa4f3 100644 --- a/app/src/views/site/ngx_conf/LogEntry.vue +++ b/app/src/components/NgxConfigEditor/LogEntry.vue @@ -1,23 +1,32 @@ + + + + diff --git a/app/src/components/NgxConfigEditor/NgxServer.vue b/app/src/components/NgxConfigEditor/NgxServer.vue new file mode 100644 index 000000000..134d3b22d --- /dev/null +++ b/app/src/components/NgxConfigEditor/NgxServer.vue @@ -0,0 +1,160 @@ + + + + + diff --git a/app/src/views/site/ngx_conf/NgxUpstream.vue b/app/src/components/NgxConfigEditor/NgxUpstream.vue similarity index 52% rename from app/src/views/site/ngx_conf/NgxUpstream.vue rename to app/src/components/NgxConfigEditor/NgxUpstream.vue index a16dacefb..abad109cf 100644 --- a/app/src/views/site/ngx_conf/NgxUpstream.vue +++ b/app/src/components/NgxConfigEditor/NgxUpstream.vue @@ -1,31 +1,34 @@
- + -
- -
+
+ + + +
- {{ $gettext('Create') }} + + {{ $gettext('Add Upstream') }}
@@ -171,7 +193,7 @@ watch(ngx_directives, () => { v-model:open="open" :title="$gettext('Upstream Name')" centered - @ok="ok" + @ok="renameOK" > @@ -183,5 +205,12 @@ watch(ngx_directives, () => { diff --git a/app/src/components/NgxConfigEditor/README.md b/app/src/components/NgxConfigEditor/README.md new file mode 100644 index 000000000..2aba82d93 --- /dev/null +++ b/app/src/components/NgxConfigEditor/README.md @@ -0,0 +1,3 @@ +# NgxConfigEditor + +Designed by [@0xJacky](https://github.com/0xJacky) diff --git a/app/src/views/site/ngx_conf/directive/DirectiveAdd.vue b/app/src/components/NgxConfigEditor/directive/DirectiveAdd.vue similarity index 67% rename from app/src/views/site/ngx_conf/directive/DirectiveAdd.vue rename to app/src/components/NgxConfigEditor/directive/DirectiveAdd.vue index bdd415420..22aca4323 100644 --- a/app/src/views/site/ngx_conf/directive/DirectiveAdd.vue +++ b/app/src/components/NgxConfigEditor/directive/DirectiveAdd.vue @@ -1,29 +1,17 @@ + + + + diff --git a/app/src/components/NgxConfigEditor/directive/DirectiveEditor.vue b/app/src/components/NgxConfigEditor/directive/DirectiveEditor.vue new file mode 100644 index 000000000..1e69299d6 --- /dev/null +++ b/app/src/components/NgxConfigEditor/directive/DirectiveEditor.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/app/src/views/site/ngx_conf/directive/DirectiveEditorItem.vue b/app/src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue similarity index 73% rename from app/src/views/site/ngx_conf/directive/DirectiveEditorItem.vue rename to app/src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue index ea6f5f715..18ab484f0 100644 --- a/app/src/views/site/ngx_conf/directive/DirectiveEditorItem.vue +++ b/app/src/components/NgxConfigEditor/directive/DirectiveEditorItem.vue @@ -1,29 +1,33 @@