diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..d8c48e5 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,19 @@ +## 变更描述 + + +## 关联需求 + + +## 变更类型 +- [ ] Feature +- [ ] Bugfix +- [ ] Hotfix +- [ ] Refactor + +## 自检清单 +- [ ] 代码已通过 Pre-commit 检查(后端 ruff / 前端 lint-staged) +- [ ] 已添加必要的测试 +- [ ] 文档已更新(如需) + +## Reviewer 备注 + diff --git a/.gitignore b/.gitignore index 12bc2b3..d5e0305 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,11 @@ .vscode/ web/package-lock.json -*.bat \ No newline at end of file +*.bat + +# GSD planning files +.planning/ + +# Superpowers files +docs/superpowers/ +.pids/ \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 876ba83..57feb91 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,39 +1,4 @@ -stages: - - deploy - -deploy-to-server: - stage: deploy - tags: - - pis-deploy-code # 使用指定标签的 runner - image: alpine:latest # 轻量级基础镜像 - before_script: - # 更换 Alpine 镜像源为阿里云(国内加速) - - sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories - # 安装 rsync - - apk add --no-cache rsync - # 确保目标目录存在(若不存在则创建,用于后续判断和备份逻辑的基础) - - mkdir -p /mnt/data/pis/python3/DV3Admin - script: - # --- 新增:备份逻辑 --- - # 定义变量 - - TARGET_DIR="/mnt/data/pis/python3/DV3Admin" - - BACKUP_DATE=$(date +%Y%m%d) - - BACKUP_DIR="${TARGET_DIR}_bak_${BACKUP_DATE}" - - # 检查目标目录是否为空或是否存在有效文件,若存在则进行备份 - # 使用 ls -A 检查目录下是否有非隐藏文件或所有文件(包括隐藏),如果有内容则备份 - - if [ -d "$TARGET_DIR" ] && [ "$(ls -A $TARGET_DIR)" ]; then - echo "备份文件至路径 $BACKUP_DIR"; - cp -a "$TARGET_DIR" "$BACKUP_DIR"; - mkdir -p "$TARGET_DIR"; - else - echo "没有文件需要部署或文件夹为空"; - fi - - # --- 新增:代码同步逻辑(排除特定文件) --- - # 修复:将多行合并为一行,避免反斜杠被当作文件名处理 - - rsync -avz --delete --exclude='.git/' --exclude='.gitignore' --exclude='.gitattributes' --exclude='.gitlab-ci.yml' ./ "$TARGET_DIR/" - - - echo "代码部署成功" +# Jenkins 接管 CI/CD,禁用 GitLab CI +workflow: rules: - - when: manual # 手动触发流水线 \ No newline at end of file + - when: never diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..466cbf4 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +cd web && npx lint-staged diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..978c5f1 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,105 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is **django-vue3-admin** based project with custom procurement/supplier management modules. + +- **Backend**: Django 4.2.14 + Django REST Framework +- **Frontend**: Vue 3 + TypeScript + Vite + Element Plus + FastCRUD +- **Database**: MySQL 8.0 (configured via `backend/conf/env.py`) +- **Cache/Queue**: Redis + Celery +- **Real-time**: Django Channels (WebSocket) +- **Auth**: JWT via SimpleJWT + +## Directory Structure + +``` +pis/ +├── backend/ +│ ├── application/ # Django project settings +│ │ ├── settings.py # Main settings (imports from conf/env.py) +│ │ ├── urls.py # Root URL routing +│ │ ├── asgi.py # ASGI config (WebSocket support) +│ │ ├── wsgi.py # WSGI config +│ │ └── celery.py # Celery configuration +│ ├── apps/ +│ │ ├── pisadmin/ # Custom procurement app +│ │ │ ├── basicinfo/ # Company, currency, supplier, unit, system no +│ │ │ └── miscprocurement/ # RFQ, price templates, cost sections +│ │ └── pissupplier/ # Supplier quotation module +│ ├── dvadmin/ # Core RBAC system +│ │ └── system/ # Users, roles, menus, departments, logs +│ └── conf/ +│ └── env.py # Environment configuration (DB, Redis credentials) +├── web/ # Vue 3 frontend +│ └── src/ +│ ├── views/pisadmin/ # Custom procurement pages +│ ├── views/pissupplier/# Supplier pages +│ └── views/system/ # Admin system pages +└── docker-compose.yml # Docker deployment +``` + +## Common Commands + +### Backend +```bash +cd backend + +# Make migrations for custom apps +python manage.py makemigrations apps.pisadmin.apps.pisadmin +python manage.py makemigrations apps.pissupplier + +# Apply migrations +python manage.py migrate + +# Create superuser +python manage.py init + +# Initialize area data +python manage.py init_area + +# Run development server +python manage.py runserver 0.0.0.0:8000 + +# Run with uvicorn (production-like) +uvicorn application.asgi:application --port 8000 --host 0.0.0.0 --workers 8 +``` + +### Frontend +```bash +cd web +yarn install +yarn dev # Development server (port 8080) +yarn build # Production build +yarn build:dev # Development build +yarn lint-fix # Lint and fix +``` + +### Docker +```bash +docker-compose up -d +docker exec dvadmin3-django python manage.py makemigrations +docker exec dvadmin3-django python manage.py migrate +docker exec dvadmin3-django python manage.py init +``` + +## Configuration + +Backend settings are split: +- `application/settings.py` - Django defaults +- `conf/env.py` - Environment-specific config (database, Redis, secrets) + +## Key Dependencies + +**Backend**: Django 4.2.14, djangorestframework 3.15.2, channels 4.1.0, celery, SimpleJWT + +**Frontend**: Vue 3.4, Element Plus 2.8, FastCRUD 1.21, Vite 5.4, Pinia, Vue Router 4.4 + +## Notes + +- Custom apps (`pisadmin`, `pissupplier`) extend the base `dvadmin` RBAC system +- The `miscprocurement` app handles询价 (RFQ) and cost template building +- Supplier quotations are managed in `pissupplier` app +- Default demo credentials: `superadmin` / `admin123456` diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b506438 --- /dev/null +++ b/Makefile @@ -0,0 +1,206 @@ +# ============================================================ +# PIS Project Startup Script - Makefile +# PIS 项目启动脚本 +# ============================================================ +# 使用方法: +# make help 查看所有可用命令 +# make dev 启动开发环境(前端 + 后端 + Celery) +# make dev-backend 仅启动后端 +# make dev-frontend 仅启动前端 +# make dev-celery 仅启动 Celery +# make stop 停止所有服务 +# make status 查看服务状态 +# make logs 查看所有日志 +# make logs-backend 查看后端日志 +# make logs-frontend 查看前端日志 +# make logs-celery 查看 Celery 日志 +# make restart 重启所有服务 +# make restart-celery 重启 Celery +# ============================================================ + +# 默认环境 +ENV ?= dev + +# 路径配置 +PROJECT_ROOT := $(shell pwd) +BACKEND_DIR := $(PROJECT_ROOT)/backend +FRONTEND_DIR := $(PROJECT_ROOT)/web +SCRIPTS_DIR := $(PROJECT_ROOT)/scripts +LOG_DIR := $(BACKEND_DIR)/logs + +# PID 文件目录 +PID_DIR := $(PROJECT_ROOT)/.pids + +# 后端服务端口 +BACKEND_PORT := 8000 +FRONTEND_PORT := 8080 + +# 帮助信息 +.PHONY: help +help: + @echo "" + @echo "========================================" + @echo " PIS 项目启动脚本 (ENV=$(ENV))" + @echo "========================================" + @echo "" + @echo " 启动命令:" + @echo " make dev 启动开发环境(前端+后端+Celery)" + @echo " make dev-backend 仅启动后端服务" + @echo " make dev-frontend 仅启动前端服务" + @echo " make dev-celery 仅启动 Celery" + @echo "" + @echo " 停止/重启:" + @echo " make stop 停止所有服务" + @echo " make restart 重启所有服务" + @echo " make restart-celery 重启 Celery" + @echo "" + @echo " 日志查看:" + @echo " make logs 查看所有日志" + @echo " make logs-backend 查看后端日志" + @echo " make logs-frontend 查看前端日志" + @echo " make logs-celery 查看 Celery 日志" + @echo "" + @echo " 状态查看:" + @echo " make status 查看所有服务状态" + @echo "" + @echo " 环境切换:" + @echo " ENV=prod make dev 使用生产环境配置启动" + @echo "" + @echo "========================================" + +# ============================================================ +# 创建必要的目录 +# ============================================================ +$(PID_DIR): + @mkdir -p $(PID_DIR) + +$(LOG_DIR): + @mkdir -p $(LOG_DIR) + +# ============================================================ +# 启动开发环境 - 全部服务 +# ============================================================ +.PHONY: dev +dev: $(PID_DIR) $(LOG_DIR) + @echo "========================================" + @echo " 启动开发环境 (ENV=$(ENV))" + @echo "========================================" + @echo "" + @echo " 后端: http://localhost:$(BACKEND_PORT)" + @echo " 前端: http://localhost:$(FRONTEND_PORT)" + @echo " Celery: Worker + Beat" + @echo "" + @bash $(SCRIPTS_DIR)/start-backend.sh $(ENV) + @bash $(SCRIPTS_DIR)/start-frontend.sh $(ENV) + @bash $(SCRIPTS_DIR)/start-celery.sh $(ENV) + +# ============================================================ +# 启动后端 +# ============================================================ +.PHONY: dev-backend +dev-backend: $(PID_DIR) $(LOG_DIR) + @echo "启动后端服务 (ENV=$(ENV))..." + @bash $(SCRIPTS_DIR)/start-backend.sh $(ENV) + +# ============================================================ +# 启动前端 +# ============================================================ +.PHONY: dev-frontend +dev-frontend: + @echo "启动前端服务 (ENV=$(ENV))..." + @bash $(SCRIPTS_DIR)/start-frontend.sh $(ENV) + +# ============================================================ +# 启动 Celery +# ============================================================ +.PHONY: dev-celery +dev-celery: $(PID_DIR) $(LOG_DIR) + @echo "启动 Celery (ENV=$(ENV))..." + @bash $(SCRIPTS_DIR)/start-celery.sh $(ENV) + +# ============================================================ +# 停止所有服务 +# ============================================================ +.PHONY: stop +stop: + @echo "停止所有服务..." + @bash $(SCRIPTS_DIR)/stop-all.sh + @echo "所有服务已停止" + +# ============================================================ +# 重启所有服务 +# ============================================================ +.PHONY: restart +restart: + @echo "重启所有服务..." + @$(MAKE) stop + @sleep 2 + @$(MAKE) dev + +# ============================================================ +# 重启 Celery +# ============================================================ +.PHONY: restart-celery +restart-celery: + @bash $(SCRIPTS_DIR)/stop-celery.sh + @sleep 1 + @bash $(SCRIPTS_DIR)/start-celery.sh $(ENV) + +# ============================================================ +# 查看日志 +# ============================================================ +.PHONY: logs +logs: + @echo "========================================" + @echo " 查看所有日志 (Ctrl+C 退出)" + @echo "========================================" + @bash $(SCRIPTS_DIR)/view-logs.sh all + +.PHONY: logs-backend +logs-backend: + @echo "========================================" + @echo " 查看后端日志 (Ctrl+C 退出)" + @echo "========================================" + @bash $(SCRIPTS_DIR)/view-logs.sh backend + +.PHONY: logs-frontend +logs-frontend: + @echo "========================================" + @echo " 查看前端日志 (Ctrl+C 退出)" + @echo "========================================" + @bash $(SCRIPTS_DIR)/view-logs.sh frontend + +.PHONY: logs-celery +logs-celery: + @echo "========================================" + @echo " 查看 Celery 日志 (Ctrl+C 退出)" + @echo "========================================" + @bash $(SCRIPTS_DIR)/view-logs.sh celery + +# ============================================================ +# 查看服务状态 +# ============================================================ +.PHONY: status +status: + @echo "========================================" + @echo " 服务状态检查" + @echo "========================================" + @bash $(SCRIPTS_DIR)/check-status.sh + +# ============================================================ +# 清理日志 +# ============================================================ +.PHONY: clean-logs +clean-logs: + @echo "清理日志文件..." + @find $(LOG_DIR) -type f -name "*.log" -exec rm -f {} \; 2>/dev/null || true + @echo "日志已清理" + +# ============================================================ +# 清理 PID 文件(强制停止) +# ============================================================ +.PHONY: clean-pids +clean-pids: + @echo "清理 PID 文件..." + @rm -f $(PID_DIR)/*.pid 2>/dev/null || true + @echo "PID 文件已清理" diff --git a/backend/.pre-commit-config.yaml b/backend/.pre-commit-config.yaml new file mode 100644 index 0000000..bdbf3cd --- /dev/null +++ b/backend/.pre-commit-config.yaml @@ -0,0 +1,20 @@ +# 后端 pre-commit hooks 配置 +# 安装方式:pip install pre-commit && pre-commit install +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + args: ['--maxkb=5000'] + - id: check-merge-conflict + - id: debug-statements + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.9.0 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..d8b5393 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,52 @@ +# 第一阶段:构建 +FROM docker.1ms.run/python:3.10-slim as builder + +WORKDIR /backend + +# 安装系统依赖(合并为一个RUN减少层数) +RUN apt-get update && apt-get install -y \ + bash git curl gnupg ca-certificates \ + libjpeg-dev libmariadb-dev-compat default-libmysqlclient-dev \ + build-essential libffi-dev libssl-dev zlib1g-dev libbz2-dev \ + libpcre2-dev libncurses5-dev libreadline-dev tk-dev libpq-dev unixodbc-dev \ + && rm -rf /var/lib/apt/lists/* \ + && curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/microsoft.gpg \ + && echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-focal-prod focal main" > /etc/apt/sources.list.d/mssql-release.list \ + && apt-get update \ + && ACCEPT_EULA=Y apt-get install -y msodbcsql18 \ + && rm -rf /var/lib/apt/lists/* + +# 先复制依赖文件,利用缓存 +COPY ./backend/requirements.txt . + +# 安装 Python 依赖(带缓存加速) +RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple/ -r requirements.txt + +# 复制剩余代码 +COPY ./backend/ . + +# 配置 +RUN ls ./conf/ \ + && awk 'BEGIN { cmd="cp -i ./conf/env.example.py ./conf/env.py "; print "n" |cmd; }' \ + && sed -i "s|DATABASE_HOST = '127.0.0.1'|DATABASE_HOST = '177.10.0.1'|g" ./conf/env.py \ + && sed -i "s|REDIS_HOST = '127.0.0.1'|REDIS_HOST = '177.10.0.1'|g" ./conf/env.py + +# 第二阶段:运行时镜像 +FROM docker.1ms.run/python:3.10-slim + +RUN apt-get update && apt-get install -y \ + unixodbc libodbc2 \ + libssl3 libkrb5-3 krb5-user \ + && rm -rf /var/lib/apt/lists/* + +COPY --from=builder /usr/local/lib/python3.10/site-packages /usr/local/lib/python3.10/site-packages +COPY --from=builder /usr/local/bin /usr/local/bin +COPY --from=builder /opt/microsoft/msodbcsql18 /opt/microsoft/msodbcsql18 +COPY --from=builder /backend /backend + +# 设置库路径并注册 ODBC Driver 18 +ENV LD_LIBRARY_PATH=/opt/microsoft/msodbcsql18/lib64:${LD_LIBRARY_PATH} +RUN cat /opt/microsoft/msodbcsql18/etc/odbcinst.ini >> /etc/odbcinst.ini || true + +WORKDIR /backend +CMD ["sh","docker_start.sh"] diff --git a/backend/Jenkinsfile b/backend/Jenkinsfile new file mode 100644 index 0000000..1ebab16 --- /dev/null +++ b/backend/Jenkinsfile @@ -0,0 +1,60 @@ +pipeline { + agent any + + environment { + HARBOR_URL = '192.168.80.90:8090' + HARBOR_PROJECT = 'pis' + IMAGE_NAME = 'pis-backend' + CREDENTIALS_ID = 'harbor-credentials' + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build Image') { + steps { + script { + def imageTag = "${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:${BUILD_NUMBER}" + env.IMAGE_TAG = imageTag + sh """ + docker build -f backend/Dockerfile \ + -t ${imageTag} . + """ + } + } + } + + stage('Push to Harbor') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: CREDENTIALS_ID, + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASS' + )]) { + sh """ + echo ${HARBOR_PASS} | docker login ${HARBOR_URL} -u ${HARBOR_USER} --password-stdin + docker push ${IMAGE_TAG} || true + docker tag ${IMAGE_TAG} ${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest + docker push ${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest || true + docker logout ${HARBOR_URL} + """ + } + } + } + } + } + + post { + failure { + echo "Backend Pipeline failed! Check Jenkins logs." + } + success { + echo "Backend image pushed to Harbor: ${IMAGE_TAG}" + } + } +} diff --git a/backend/application/settings.py b/backend/application/settings.py index 9167cf7..454c759 100644 --- a/backend/application/settings.py +++ b/backend/application/settings.py @@ -62,6 +62,7 @@ INSTALLED_APPS = [ "dvadmin.system", "apps.pisadmin.miscprocurement", "apps.pisadmin.basicinfo", + "apps.pisadmin.dashboard", "apps.pissupplier", ] @@ -385,7 +386,17 @@ API_MODEL_MAP = { } DJANGO_CELERY_BEAT_TZ_AWARE = False +from celery.schedules import crontab + CELERY_TIMEZONE = "Asia/Shanghai" # celery 时区问题 + +CELERY_BEAT_SCHEDULE = { + "check-quote-deadline-expired": { + "task": "apps.pisadmin.miscprocurement.tasks.check_quote_deadline_expired", + "schedule": crontab(minute="*/5"), # 每5分钟 + }, +} + # 静态页面压缩 STATICFILES_STORAGE = "whitenoise.storage.CompressedStaticFilesStorage" diff --git a/backend/application/test_settings.py b/backend/application/test_settings.py new file mode 100644 index 0000000..3e0a967 --- /dev/null +++ b/backend/application/test_settings.py @@ -0,0 +1,31 @@ +""" +测试专用 Django Settings +使用已存在的 pisdb 数据库运行测试,测试之间有事务隔离。 +不创建/删除测试库,直接使用 pisdb。 +""" +import os +import sys +from application.settings import * # noqa + +# Patch MSSQL creation class BEFORE any database connections are made +# 这必须在 Django settings 加载之后、任何 DB 操作之前完成 +import mssql.base +from mssql.creation import DatabaseCreation + + +class NoCreateTestDatabase(DatabaseCreation): + """跳过 CREATE/DROP DATABASE 的 MSSQL 创建逻辑""" + + def _create_test_db(self, verbosity=1, autoclobber=False, keepdb=False): + return self.connection.settings_dict["NAME"] + + def _destroy_test_db(self, test_db_name, verbosity=1, keepdb=False): + pass + + +mssql.base.DatabaseWrapper.creation_class = NoCreateTestDatabase + +# 配置测试数据库 +DATABASES["default"]["TEST"] = { + "NAME": DATABASE_NAME, +} diff --git a/backend/application/urls.py b/backend/application/urls.py index fbf71af..869f837 100644 --- a/backend/application/urls.py +++ b/backend/application/urls.py @@ -32,7 +32,8 @@ from dvadmin.system.views.login import ( CaptchaView, ApiLogin, LogoutView, - LoginTokenView + LoginTokenView, + SupplierLoginView, ) from dvadmin.system.views.system_config import InitSettingsViewSet from dvadmin.utils.swagger import CustomOpenAPISchemaGenerator @@ -103,9 +104,11 @@ urlpatterns = ( ), path("api/pisadmin/miscprocurement/", include("apps.pisadmin.miscprocurement.urls")), path("api/pisadmin/basicinfo/", include("apps.pisadmin.basicinfo.urls")), + path("api/pisadmin/dashboard/", include("apps.pisadmin.dashboard.urls")), path("api/pissupplier/", include("apps.pissupplier.urls")), path("api/system/", include("dvadmin.system.urls")), path("api/login/", LoginView.as_view(), name="token_obtain_pair"), + path("api/login/supplier/", SupplierLoginView.as_view(), name="supplier_login"), path("api/logout/", LogoutView.as_view(), name="token_obtain_pair"), path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), re_path( diff --git a/backend/apps/pisadmin/basicinfo/factories.py b/backend/apps/pisadmin/basicinfo/factories.py new file mode 100644 index 0000000..39fb433 --- /dev/null +++ b/backend/apps/pisadmin/basicinfo/factories.py @@ -0,0 +1,32 @@ +import factory +import factory.django +from apps.pisadmin.basicinfo.models import Currency, Unit + + +class CurrencyFactory(factory.django.DjangoModelFactory): + """ + Currency 模型测试数据工厂 + + 注意: 模型字段名为 'factory',与 factory_boy 模块名冲突, + 故使用 model= (非 factory=) 并通过 LazyAttribute 赋值。 + """ + + class Meta: + model = Currency + # 用 model= 而非 factory= 避免 factory 模块名冲突 + + currencyname = factory.Faker("currency_name") + currencycode = factory.Faker("currency_code") + currencysymbol = factory.Faker("currency_symbol") + # 模型字段 factory 有 null=True,故此处直接赋值为 None + tax = factory.Faker("pydecimal", left_digits=2, right_digits=2, positive=True) + status = 1 + + +class UnitFactory(factory.django.DjangoModelFactory): + class Meta: + model = Unit + + unitname = factory.Faker("word") + unitcode = factory.Faker("random_element", elements=["PC", "KG", "BOX", "SET"]) + status = 1 diff --git a/backend/apps/pisadmin/basicinfo/migrations/0003_systemnorule.py b/backend/apps/pisadmin/basicinfo/migrations/0003_systemnorule.py new file mode 100644 index 0000000..96e1edc --- /dev/null +++ b/backend/apps/pisadmin/basicinfo/migrations/0003_systemnorule.py @@ -0,0 +1,48 @@ +# Generated by Django 4.2.14 on 2026-03-25 11:40 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('basicinfo', '0002_initial'), + ] + + operations = [ + migrations.CreateModel( + name='SystemNoRule', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('company_code', models.CharField(help_text='交易厂区(公司)', max_length=20, verbose_name='交易厂区')), + ('rule_code', models.CharField(choices=[('miscQTS', '杂采报价单'), ('miscRFS', '杂采询价单')], help_text='标识一组单号规则', max_length=50, verbose_name='生成单据标识号')), + ('reset_cycle', models.CharField(choices=[('yy', 'YY'), ('yyyy', 'YYYY'), ('yymm', 'YYMM'), ('yyyymm', 'YYYYMM'), ('yymmdd', 'YYMMDD'), ('yyyymmdd', 'YYYYMMDD')], help_text='重置粒度', max_length=16, verbose_name='流水码重置类别')), + ('prefix', models.CharField(blank=True, help_text='单据开头固定字符', max_length=20, null=True, verbose_name='单据头')), + ('factory_code', models.CharField(blank=True, help_text='厂区区分码', max_length=20, null=True, verbose_name='厂区区分码')), + ('seq_length', models.IntegerField(default=4, help_text='流水码长度', verbose_name='流水码长度')), + ('createuser', models.CharField(blank=True, help_text='单据创建人', max_length=50, null=True, verbose_name='单据创建人')), + ('updateuser', models.CharField(blank=True, help_text='单据修改人', max_length=50, null=True, verbose_name='单据修改人')), + ('sequence_date', models.CharField(blank=True, help_text='与 reset_cycle 对应的日期段(如 yymmdd→260324);新建/改重置类别时由服务端写入', max_length=12, null=True, verbose_name='流水日期')), + ('prev_sequence', models.IntegerField(default=0, help_text='上一笔已成功发放的流水号;未发过为 0,与「下一流水码」相差 1', verbose_name='上一流水码')), + ('current_sequence', models.IntegerField(default=1, help_text='下一笔待发流水号;新建/重置周期后为 1,每次取号成功后 +1', verbose_name='下一流水码')), + ('last_generate_user', models.CharField(blank=True, help_text='最后产生人', max_length=50, null=True, verbose_name='单据最后产生人')), + ('last_generate_time', models.DateTimeField(blank=True, help_text='最后产生时间', null=True, verbose_name='单据最后产生时间')), + ('creator', models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '系统单号规则', + 'verbose_name_plural': '系统单号规则', + 'db_table': 'pis_system_no_rules', + 'ordering': ('-create_datetime',), + 'unique_together': {('company_code', 'rule_code')}, + }, + ), + ] diff --git a/backend/apps/pisadmin/basicinfo/migrations/0004_emailnotice.py b/backend/apps/pisadmin/basicinfo/migrations/0004_emailnotice.py new file mode 100644 index 0000000..9f4d718 --- /dev/null +++ b/backend/apps/pisadmin/basicinfo/migrations/0004_emailnotice.py @@ -0,0 +1,49 @@ +# Generated by Django 4.2.14 on 2026-03-25 17:25 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('basicinfo', '0003_systemnorule'), + ] + + operations = [ + migrations.CreateModel( + name='EmailNotice', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('subject', models.CharField(max_length=256, verbose_name='邮件主题')), + ('body', models.TextField(blank=True, null=True, verbose_name='邮件正文')), + ('to_emails', models.JSONField(default=list, verbose_name='收件人')), + ('cc_emails', models.JSONField(default=list, verbose_name='抄送')), + ('bcc_emails', models.JSONField(default=list, verbose_name='密送')), + ('attachments', models.JSONField(default=list, verbose_name='附件')), + ('biz_type', models.CharField(blank=True, max_length=64, null=True, verbose_name='业务类型')), + ('biz_id', models.CharField(blank=True, max_length=128, null=True, verbose_name='业务标识')), + ('status', models.CharField(choices=[('pending', 'pending'), ('sending', 'sending'), ('success', 'success'), ('failed', 'failed')], db_index=True, default='pending', max_length=16, verbose_name='发送状态')), + ('sent_at', models.DateTimeField(blank=True, null=True, verbose_name='发送时间')), + ('message_id', models.CharField(blank=True, max_length=128, null=True, verbose_name='消息ID')), + ('last_error', models.TextField(blank=True, null=True, verbose_name='失败原因')), + ('payload', models.JSONField(default=dict, verbose_name='发送参数')), + ('response', models.JSONField(default=dict, verbose_name='服务端响应')), + ('retry_count', models.IntegerField(default=0, verbose_name='重试次数')), + ('creator', models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '邮件通知', + 'verbose_name_plural': '邮件通知', + 'db_table': 'pis_proc_email_notice', + 'ordering': ('-update_datetime', '-id'), + }, + ), + ] diff --git a/backend/apps/pisadmin/basicinfo/tests/__init__.py b/backend/apps/pisadmin/basicinfo/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/pisadmin/basicinfo/tests/test_serializers.py b/backend/apps/pisadmin/basicinfo/tests/test_serializers.py new file mode 100644 index 0000000..0f650ed --- /dev/null +++ b/backend/apps/pisadmin/basicinfo/tests/test_serializers.py @@ -0,0 +1,118 @@ +import pytest +from apps.pisadmin.basicinfo.factories import CurrencyFactory +from apps.pisadmin.basicinfo.views.currency import CurrencySerializer, CurrencyCreateUpdateSerializer + + +# DRF 的 django_restql DynamicFieldsMixin 使用 model verbose_name 作为 error key +# 例如 currencyname 字段的 error key 是 "货币名称"(模型的 verbose_name) +# 以下是字段名到 error key 的映射 +FIELD_ERROR_KEYS = { + "currencyname": "货币名称", + "currencycode": "货币代码", + "currencysymbol": "货币符号", + "tax": "税率", +} + + +@pytest.mark.django_db +class TestCurrencyCreateUpdateSerializer: + + def test_create_currency_success(self): + """合法数据应创建成功""" + data = { + "currencyname": "人民币", + "currencycode": "CNY", + "currencysymbol": "¥", + "tax": "6.5", + } + serializer = CurrencyCreateUpdateSerializer(data=data) + assert serializer.is_valid(), serializer.errors + instance = serializer.save() + assert instance.currencyname == "人民币" + assert instance.currencycode == "CNY" + + def test_currencyname_required(self): + """currencyname 必填""" + data = { + "currencycode": "CNY", + "currencysymbol": "¥", + "tax": "6.5", + } + serializer = CurrencyCreateUpdateSerializer(data=data) + assert not serializer.is_valid() + assert FIELD_ERROR_KEYS["currencyname"] in serializer.errors + + def test_currencysymbol_required(self): + """currencysymbol 必填""" + data = { + "currencyname": "美元", + "currencycode": "USD", + "tax": "6.5", + } + serializer = CurrencyCreateUpdateSerializer(data=data) + assert not serializer.is_valid() + assert FIELD_ERROR_KEYS["currencysymbol"] in serializer.errors + + def test_tax_required(self): + """tax 必填""" + data = { + "currencyname": "日元", + "currencycode": "JPY", + "currencysymbol": "¥", + } + serializer = CurrencyCreateUpdateSerializer(data=data) + assert not serializer.is_valid() + assert FIELD_ERROR_KEYS["tax"] in serializer.errors + + @pytest.mark.parametrize( + "field,invalid_value", + [ + ("currencyname", ""), # 空字符串 + ("currencyname", "A" * 100), # 超过 max_length=50 + ("currencycode", "A" * 100), # 超过 max_length=20 + ("currencysymbol", "A" * 100), # 超过 max_length=10 + ], + ) + def test_field_max_length_validation(self, field, invalid_value): + """字段长度超限应返回 ValidationError""" + data = { + "currencyname": "测试", + "currencycode": "CNY", + "currencysymbol": "¥", + "tax": "6.5", + } + data[field] = invalid_value + serializer = CurrencyCreateUpdateSerializer(data=data) + assert not serializer.is_valid() + assert FIELD_ERROR_KEYS[field] in serializer.errors + + def test_update_currency_success(self, db): + """更新已有记录""" + existing = CurrencyFactory(currencyname="旧名称") + data = { + "currencyname": "新名称", + "currencycode": "USD", + "currencysymbol": "$", + "tax": "5.0", + } + serializer = CurrencyCreateUpdateSerializer(instance=existing, data=data) + assert serializer.is_valid(), serializer.errors + updated = serializer.save() + assert updated.currencyname == "新名称" + + +@pytest.mark.django_db +class TestCurrencySerializer: + + def test_serialize_currency(self): + """序列化输出包含所有字段""" + currency = CurrencyFactory( + currencyname="欧元", + currencycode="EUR", + currencysymbol="€", + ) + serializer = CurrencySerializer(currency) + data = serializer.data + assert data["currencyname"] == "欧元" + assert data["currencycode"] == "EUR" + assert data["currencysymbol"] == "€" diff --git a/backend/apps/pisadmin/basicinfo/tests/test_views.py b/backend/apps/pisadmin/basicinfo/tests/test_views.py new file mode 100644 index 0000000..af14447 --- /dev/null +++ b/backend/apps/pisadmin/basicinfo/tests/test_views.py @@ -0,0 +1,99 @@ +import pytest +from apps.pisadmin.basicinfo.factories import CurrencyFactory +from apps.pisadmin.basicinfo.models import Currency + + +# API 统一响应格式: { "code": 2000, "data": ..., "msg": ... } +# code=2000 表示成功, code=4000 表示认证/权限/参数错误 +CODE_SUCCESS = 2000 +CODE_ERROR = 4000 + + +@pytest.mark.django_db +class TestCurrencyViewSet: + + def test_list_currencies(self, authenticate): + """GET 列表返回成功 + 分页结构""" + CurrencyFactory.create_batch(3) + response = authenticate.get("/api/pisadmin/basicinfo/currencies/") + assert response.data["code"] == CODE_SUCCESS + + def test_create_currency_success(self, authenticate): + """POST 创建返回成功 + DB 记录""" + payload = { + "currencyname": "英镑", + "currencycode": "GBP", + "currencysymbol": "£", + "tax": "20.0", + } + response = authenticate.post( + "/api/pisadmin/basicinfo/currencies/", data=payload, format="json" + ) + assert response.data["code"] == CODE_SUCCESS + assert Currency.objects.filter(currencycode="GBP").exists() + + def test_create_currency_unauthenticated(self, api_client): + """未认证请求返回错误码""" + payload = { + "currencyname": "英镑", + "currencycode": "GBP", + "currencysymbol": "£", + "tax": "20.0", + } + response = api_client.post( + "/api/pisadmin/basicinfo/currencies/", data=payload, format="json" + ) + assert response.data["code"] == CODE_ERROR + + def test_retrieve_currency(self, authenticate): + """GET 详情返回成功 + 完整字段""" + currency = CurrencyFactory(currencyname="澳元", currencycode="AUD") + response = authenticate.get( + f"/api/pisadmin/basicinfo/currencies/{currency.id}/" + ) + assert response.data["code"] == CODE_SUCCESS + assert response.data["data"]["currencyname"] == "澳元" + + def test_update_currency_put(self, authenticate): + """PUT 全量更新返回成功""" + currency = CurrencyFactory(currencyname="旧货币") + payload = { + "currencyname": "新货币", + "currencycode": "NEW", + "currencysymbol": "N", + "tax": "10.0", + } + response = authenticate.put( + f"/api/pisadmin/basicinfo/currencies/{currency.id}/", + data=payload, + format="json", + ) + assert response.data["code"] == CODE_SUCCESS + currency.refresh_from_db() + assert currency.currencyname == "新货币" + + def test_delete_currency(self, authenticate): + """DELETE 返回成功 + 记录消失""" + currency = CurrencyFactory() + response = authenticate.delete( + f"/api/pisadmin/basicinfo/currencies/{currency.id}/" + ) + assert response.data["code"] == CODE_SUCCESS + assert not Currency.objects.filter(id=currency.id).exists() + + def test_delete_currency_unauthenticated_forbidden(self, api_client): + """未认证删除返回错误码""" + currency = CurrencyFactory() + response = api_client.delete( + f"/api/pisadmin/basicinfo/currencies/{currency.id}/" + ) + assert response.data["code"] == CODE_ERROR + + def test_create_currency_invalid_data(self, authenticate): + """非法数据返回错误码 + 错误信息""" + payload = {"currencyname": ""} # 缺少必填字段 + response = authenticate.post( + "/api/pisadmin/basicinfo/currencies/", data=payload, format="json" + ) + assert response.data["code"] == CODE_ERROR + assert "货币名称" in response.data["msg"] diff --git a/backend/apps/pisadmin/basicinfo/views/email_template.py b/backend/apps/pisadmin/basicinfo/views/email_template.py index fc263a4..3b429b9 100644 --- a/backend/apps/pisadmin/basicinfo/views/email_template.py +++ b/backend/apps/pisadmin/basicinfo/views/email_template.py @@ -27,6 +27,8 @@ TEMPLATE_BIDS_PUBLISH = "Bids_publish" TEMPLATE_QUOTE_ENDED = "Quote_ended" # 报价截止后无待报价/报价中单 → 询价单收口为「报价结束」(典型:sync_expired)— 询价截止提醒 TEMPLATE_QUOTE_TIMEOUT = "Quote_timeout" +# 报价截止时间到期提醒(多个供应商合并一封邮件,按询价单维度) +TEMPLATE_QUOTE_DEADLINE_EXPIRED = "Quote_deadline_expired" def _for_local_display(dt: Any): @@ -363,6 +365,51 @@ def build_context_quote_timeout(inquiry: Any) -> Dict[str, Any]: } +def build_context_quote_deadline_expired( + inquiry: Any, + expired_suppliers: list, +) -> Dict[str, Any]: + """ + 报价截止到期提醒(采购端):按询价单合并多个已到期未报价供应商,发送一封邮件。 + expired_suppliers: list[{"supplier_name", "contact_person", "quote_deadline", "status"}, ...] + """ + from apps.pisadmin.miscprocurement.models import InquirySupplier + + inquiry_no = (getattr(inquiry, "inquiry_no", None) or "").strip() + title = (getattr(inquiry, "title", None) or "").strip() + inquiry_name = title or "—" + + purchaser_name = _quote_ended_purchaser_name(inquiry) + material_or_project_name = _quote_ended_material_or_project_name(inquiry) + + invited_count = ( + InquirySupplier.objects.filter(inquiry_no=inquiry) + .values_list("supplier_code", flat=True) + .distinct() + .count() + ) + + base = admin_portal_base_url() + pk = getattr(inquiry, "pk", None) or getattr(inquiry, "id", None) + comparison_page_url = "" + if base and pk is not None: + comparison_page_url = f"{base}/pisadmin/miscprocurement/rfqmiscellaneous/comparePrice/{pk}" + + return { + "purchaser_name": purchaser_name, + "inquiry_no": inquiry_no, + "inquiry_name": inquiry_name, + "material_or_project_name": material_or_project_name, + "supplier_count": len(expired_suppliers), + "expired_suppliers": expired_suppliers, + "invited_count": invited_count, + "comparison_page_url": comparison_page_url, + "current_date": _for_local_display(timezone.now()).strftime("%Y-%m-%d"), + "admin_link": comparison_page_url or base, + "system_name": system_brand_name(), + } + + # --------------------------------------------------------------------------- # 可选:template_key -> (subject 相对 templates/, body 相对 templates/),由 render_template_pair 渲染。 # 内置场景均已改为单文件 *_template.html,见 _CUSTOM_RENDERERS。 diff --git a/backend/apps/pisadmin/dashboard/__init__.py b/backend/apps/pisadmin/dashboard/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/pisadmin/dashboard/apps.py b/backend/apps/pisadmin/dashboard/apps.py new file mode 100644 index 0000000..3569efc --- /dev/null +++ b/backend/apps/pisadmin/dashboard/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class DashboardConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'apps.pisadmin.dashboard' diff --git a/backend/apps/pisadmin/dashboard/serializers.py b/backend/apps/pisadmin/dashboard/serializers.py new file mode 100644 index 0000000..4691603 --- /dev/null +++ b/backend/apps/pisadmin/dashboard/serializers.py @@ -0,0 +1,66 @@ +from rest_framework import serializers + + +class BuyerKPISerializer(serializers.Serializer): + total_inquiries = serializers.IntegerField() + pending_inquiries = serializers.IntegerField() + completed_quotes = serializers.IntegerField() + total_suppliers = serializers.IntegerField() + + +class BuyerTaskSerializer(serializers.Serializer): + id = serializers.IntegerField() + title = serializers.CharField() + inquiry_no = serializers.CharField() + status = serializers.CharField() + created_at = serializers.DateTimeField() + + +class SupplierKPISerializer(serializers.Serializer): + total_quotes = serializers.IntegerField() + pending_quotes = serializers.IntegerField() + won_quotes = serializers.IntegerField() + conversion_rate = serializers.FloatField() + + +class SupplierQuoteSerializer(serializers.Serializer): + id = serializers.IntegerField() + inquiry_no = serializers.CharField() + item_name = serializers.CharField() + quantity = serializers.IntegerField() + unit = serializers.CharField() + deadline = serializers.DateTimeField() + + +class MessageSerializer(serializers.Serializer): + id = serializers.IntegerField() + title = serializers.CharField() + content = serializers.CharField() + is_read = serializers.BooleanField() + created_at = serializers.DateTimeField() + + +class TrendSerializer(serializers.Serializer): + month = serializers.CharField() + count = serializers.IntegerField(required=False) + quotes = serializers.IntegerField(required=False) + won = serializers.IntegerField(required=False) + + +class BuyerDashboardSerializer(serializers.Serializer): + kpi = BuyerKPISerializer() + tasks = BuyerTaskSerializer(many=True) + messages = MessageSerializer(many=True) + trend = TrendSerializer(many=True) + + +class SupplierDashboardSerializer(serializers.Serializer): + kpi = SupplierKPISerializer() + pending_quotes = SupplierQuoteSerializer(many=True) + messages = MessageSerializer(many=True) + trend = TrendSerializer(many=True) + + +class DashboardResponseSerializer(serializers.Serializer): + buyer = BuyerDashboardSerializer(allow_null=True) + supplier = SupplierDashboardSerializer(allow_null=True) diff --git a/backend/apps/pisadmin/dashboard/urls.py b/backend/apps/pisadmin/dashboard/urls.py new file mode 100644 index 0000000..4587499 --- /dev/null +++ b/backend/apps/pisadmin/dashboard/urls.py @@ -0,0 +1,6 @@ +from django.urls import path +from .views import DashboardView + +urlpatterns = [ + path('', DashboardView.as_view(), name='dashboard'), +] diff --git a/backend/apps/pisadmin/dashboard/views.py b/backend/apps/pisadmin/dashboard/views.py new file mode 100644 index 0000000..dc7e0a2 --- /dev/null +++ b/backend/apps/pisadmin/dashboard/views.py @@ -0,0 +1,367 @@ +from datetime import timedelta + +from django.utils import timezone +from django.db.models import Count, F +from django.db.models.functions import TruncMonth +from rest_framework import serializers, views +from rest_framework.response import Response + +from apps.pisadmin.miscprocurement.models import Inquiry +from apps.pissupplier.models import QuotationMaster +from apps.pisadmin.basicinfo.models import Supplier + + +class BuyerKPISerializer(serializers.Serializer): + total_inquiries = serializers.IntegerField() + pending_inquiries = serializers.IntegerField() + completed_quotes = serializers.IntegerField() + total_suppliers = serializers.IntegerField() + quote_timely_rate = serializers.FloatField() + + +class BuyerTaskSerializer(serializers.Serializer): + id = serializers.IntegerField() + title = serializers.CharField() + inquiry_no = serializers.CharField() + status = serializers.CharField() + created_at = serializers.DateTimeField() + + +class SupplierKPISerializer(serializers.Serializer): + total_quotes = serializers.IntegerField() + pending_quotes = serializers.IntegerField() + won_quotes = serializers.IntegerField() + conversion_rate = serializers.FloatField() + quote_timely_rate = serializers.FloatField() + on_time_quotes = serializers.IntegerField() + overdue_quotes = serializers.IntegerField() + + +class SupplierQuoteSerializer(serializers.Serializer): + id = serializers.IntegerField() + inquiry_no = serializers.CharField() + item_name = serializers.CharField() + unit = serializers.CharField() + deadline = serializers.DateTimeField() + status = serializers.IntegerField() + + +class MessageSerializer(serializers.Serializer): + id = serializers.IntegerField() + title = serializers.CharField() + content = serializers.CharField() + is_read = serializers.BooleanField() + created_at = serializers.DateTimeField() + + +class TrendSerializer(serializers.Serializer): + month = serializers.CharField() + count = serializers.IntegerField(required=False) + quotes = serializers.IntegerField(required=False) + won = serializers.IntegerField(required=False) + + +class BuyerDashboardSerializer(serializers.Serializer): + kpi = BuyerKPISerializer() + tasks = BuyerTaskSerializer(many=True) + messages = MessageSerializer(many=True) + trend = TrendSerializer(many=True) + + +class SupplierDashboardSerializer(serializers.Serializer): + kpi = SupplierKPISerializer() + pending_quotes = SupplierQuoteSerializer(many=True) + messages = MessageSerializer(many=True) + trend = TrendSerializer(many=True) + + +class DashboardResponseSerializer(serializers.Serializer): + buyer = BuyerDashboardSerializer(allow_null=True) + supplier = SupplierDashboardSerializer(allow_null=True) + + +class DashboardView(views.APIView): + """看板数据视图""" + + def get_buyer_kpi(self, user): + """采购方 KPI 计算""" + total_inquiries = Inquiry.objects.filter(create_user=user.username).count() + pending_inquiries = Inquiry.objects.filter( + create_user=user.username, status__in=[1, 2, 3] + ).count() + completed_quotes = QuotationMaster.objects.filter( + inquiry_no__in=Inquiry.objects.filter( + create_user=user.username + ).values('inquiry_no') + ).count() + total_suppliers = Supplier.objects.count() + + # 供应商报价及时率 = 在截止时间前提交的报价数 / 总报价数 + buyer_quotations = QuotationMaster.objects.filter( + inquiry_no__in=Inquiry.objects.filter( + create_user=user.username + ).values('inquiry_no') + ) + total_quotes = buyer_quotations.count() + timely_quotes = buyer_quotations.filter( + quotetime__isnull=False, + quote_deadline__isnull=False, + quotetime__lte=F('quote_deadline') + ).count() + quote_timely_rate = round(timely_quotes / total_quotes * 100, 1) if total_quotes > 0 else 0.0 + + return { + 'total_inquiries': total_inquiries, + 'pending_inquiries': pending_inquiries, + 'completed_quotes': completed_quotes, + 'total_suppliers': total_suppliers, + 'quote_timely_rate': quote_timely_rate, + } + + def get_buyer_tasks(self, user): + """采购方待办任务""" + inquiries = Inquiry.objects.filter( + create_user=user.username, + status__in=[1, 2, 3] + ).order_by('-create_time')[:10] + return [ + { + 'id': i.id, + 'title': i.title, + 'inquiry_no': i.inquiry_no, + 'status': dict(Inquiry.STATUS_CHOICES).get(i.status, str(i.status)), + 'created_at': i.create_time, + } + for i in inquiries + ] + + def get_supplier_kpi(self, user): + """供应商 KPI 计算""" + # 超级管理员看到所有供应商汇总数据 + if user.is_superuser: + total_quotes = QuotationMaster.objects.count() + pending_quotes = QuotationMaster.objects.filter(status__in=[1, 2]).count() + won_quotes = QuotationMaster.objects.filter(is_awarded=1).count() + else: + total_quotes = QuotationMaster.objects.filter(supplier_code=user.username).count() + pending_quotes = QuotationMaster.objects.filter( + supplier_code=user.username, status__in=[1, 2] + ).count() + won_quotes = QuotationMaster.objects.filter( + supplier_code=user.username, is_awarded=1 + ).count() + conversion_rate = (won_quotes / total_quotes * 100) if total_quotes > 0 else 0.0 + + # 及时率计算 + if user.is_superuser: + all_quotes = QuotationMaster.objects.all() + else: + all_quotes = QuotationMaster.objects.filter(supplier_code=user.username) + total_with_deadline = all_quotes.filter(quote_deadline__isnull=False).count() + on_time_quotes = all_quotes.filter( + quotetime__isnull=False, + quote_deadline__isnull=False, + quotetime__lte=F('quote_deadline') + ).count() + overdue_quotes = total_with_deadline - on_time_quotes + quote_timely_rate = round(on_time_quotes / total_with_deadline * 100, 1) if total_with_deadline > 0 else 0.0 + + return { + 'total_quotes': total_quotes, + 'pending_quotes': pending_quotes, + 'won_quotes': won_quotes, + 'conversion_rate': round(conversion_rate, 2), + 'quote_timely_rate': quote_timely_rate, + 'on_time_quotes': on_time_quotes, + 'overdue_quotes': overdue_quotes, + } + + def get_supplier_pending_quotes(self, user): + """供应商待报价清单""" + # 超级管理员看到所有待报价,供应商只看自己的 + if user.is_superuser: + quotes = QuotationMaster.objects.filter(status__in=[1, 2]).order_by('-creattime')[:10] + else: + quotes = QuotationMaster.objects.filter( + supplier_code=user.username, + status__in=[1, 2] + ).order_by('-creattime')[:10] + result = [] + for q in quotes: + inquiry = Inquiry.objects.filter(inquiry_no=q.inquiry_no).first() + # 获取询价单中的数量 + quantity = '' + quantity = '' + unit = '' + if inquiry: + from apps.pisadmin.miscprocurement.models import InquiryRfqItem + item = InquiryRfqItem.objects.filter(inquiry_no=q.inquiry_no).first() + if item: + quantity = item.qty + unit = item.unit or '' + result.append({ + 'id': q.autoid, + 'inquiry_no': q.inquiry_no, + 'item_name': inquiry.title if inquiry else '', + 'quantity': quantity, + 'unit': unit, + 'deadline': q.quote_deadline, + 'status': q.status, + }) + return result + + def get_trend_data(self, user, is_buyer=True): + """近6个月趋势数据""" + six_months_ago = timezone.now() - timedelta(days=180) + if is_buyer: + data = ( + Inquiry.objects.filter( + create_user=user.username, + create_time__gte=six_months_ago + ) + .annotate(month=TruncMonth('create_time')) + .values('month') + .annotate(count=Count('id')) + .order_by('month') + ) + return [ + {'month': d['month'].strftime('%Y-%m'), 'count': d['count']} + for d in data + ] + else: + # 超级管理员看到所有供应商汇总趋势 + if user.is_superuser: + data = ( + QuotationMaster.objects.filter(creattime__gte=six_months_ago) + .annotate(month=TruncMonth('creattime')) + .values('month') + .annotate(quotes=Count('autoid')) + .order_by('month') + ) + result = [] + for d in data: + won = QuotationMaster.objects.filter( + creattime__month=d['month'].month, + creattime__year=d['month'].year, + is_awarded=1 + ).count() + result.append({ + 'month': d['month'].strftime('%Y-%m'), + 'quotes': d['quotes'], + 'won': won, + }) + return result + else: + data = ( + QuotationMaster.objects.filter( + supplier_code=user.username, + creattime__gte=six_months_ago + ) + .annotate(month=TruncMonth('creattime')) + .values('month') + .annotate(quotes=Count('autoid')) + .order_by('month') + ) + result = [] + for d in data: + won = QuotationMaster.objects.filter( + supplier_code=user.username, + creattime__month=d['month'].month, + creattime__year=d['month'].year, + is_awarded=1 + ).count() + result.append({ + 'month': d['month'].strftime('%Y-%m'), + 'quotes': d['quotes'], + 'won': won, + }) + return result + + def get_messages(self, user): + """消息通知 - 占位实现,后续接入通知系统""" + return [] + + def get_buyer_data(self, user): + """获取采购方看板数据""" + return { + 'kpi': self.get_buyer_kpi(user), + 'tasks': self.get_buyer_tasks(user), + 'messages': self.get_messages(user), + 'trend': self.get_trend_data(user, is_buyer=True), + } + + def get_supplier_data(self, user): + """获取供应商看板数据""" + return { + 'kpi': self.get_supplier_kpi(user), + 'pending_quotes': self.get_supplier_pending_quotes(user), + 'messages': self.get_messages(user), + 'trend': self.get_trend_data(user, is_buyer=False), + } + + def get(self, request): + """获取看板数据 + + Returns role-based dashboard data based on user's permissions. + - Buyer role: returns buyer dashboard data + - Supplier role: returns supplier dashboard data + - Both roles: returns both + - Superadmin or no business data: returns empty structure + """ + user = request.user + if not user or not user.is_authenticated: + return Response({'buyer': None, 'supplier': None}) + + # 分别判断用户角色,避免一个表不存在影响另一个 + has_supplier_role = False + has_buyer_role = False + + try: + has_supplier_role = QuotationMaster.objects.filter( + supplier_code=user.username + ).exists() + except Exception: + pass + + try: + has_buyer_role = Inquiry.objects.filter( + create_user=user.username + ).exists() + except Exception: + pass + + # 超级管理员或有任何角色,始终返回对应看板数据结构 + buyer_data = None + supplier_data = None + + # 采购方看板:超级管理员或有任何采购记录的用户 + if user.is_superuser or has_buyer_role: + try: + buyer_data = self.get_buyer_data(user) + except Exception: + buyer_data = { + 'kpi': {'total_inquiries': 0, 'pending_inquiries': 0, 'completed_quotes': 0, 'total_suppliers': 0, 'quote_timely_rate': 0}, + 'tasks': [], + 'messages': [], + 'trend': [], + } + + # 供应商看板:超级管理员或有任何供应商记录的用户 + if user.is_superuser or has_supplier_role: + try: + supplier_data = self.get_supplier_data(user) + except Exception: + supplier_data = { + 'kpi': {'total_quotes': 0, 'pending_quotes': 0, 'won_quotes': 0, 'conversion_rate': 0}, + 'pending_quotes': [], + 'messages': [], + 'trend': [], + } + + response_data = {'buyer': buyer_data, 'supplier': supplier_data} + + # 使用序列化器验证响应数据 + serializer = DashboardResponseSerializer(data=response_data) + serializer.is_valid(raise_exception=True) + + return Response(serializer.validated_data) diff --git a/backend/apps/pisadmin/miscprocurement/migrations/0003_remove_pricetemplate_creator_and_more.py b/backend/apps/pisadmin/miscprocurement/migrations/0003_remove_pricetemplate_creator_and_more.py new file mode 100644 index 0000000..c0c2d63 --- /dev/null +++ b/backend/apps/pisadmin/miscprocurement/migrations/0003_remove_pricetemplate_creator_and_more.py @@ -0,0 +1,57 @@ +# Generated by Django 4.2.14 on 2026-03-24 14:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('miscprocurement', '0002_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='pricetemplate', + name='creator', + ), + migrations.AddField( + model_name='costestimatetemplatebody', + name='version', + field=models.IntegerField(db_column='Version', default=1, verbose_name='版本号'), + ), + migrations.AddField( + model_name='costestimatetemplatehead', + name='status', + field=models.IntegerField(choices=[(0, '未确认'), (1, '已确认'), (2, '作废')], db_column='Status', default=0, verbose_name='状态'), + ), + migrations.AddField( + model_name='costestimatetemplatehead', + name='version', + field=models.IntegerField(db_column='Version', default=1, verbose_name='版本号'), + ), + migrations.AlterField( + model_name='costestimatetemplatebody', + name='template_no', + field=models.CharField(db_column='TemplateNo', max_length=20, verbose_name='模板编号'), + ), + migrations.AlterField( + model_name='costestimatetemplatehead', + name='template_no', + field=models.CharField(db_column='TemplateNo', db_index=True, max_length=20, verbose_name='模板编号'), + ), + migrations.AddIndex( + model_name='costestimatetemplatebody', + index=models.Index(fields=['template_no', 'version'], name='idx_cost_template_body_no_ver'), + ), + migrations.AddIndex( + model_name='costestimatetemplatehead', + index=models.Index(fields=['template_no', 'version'], name='idx_cost_template_head_no_ver'), + ), + migrations.AddConstraint( + model_name='costestimatetemplatehead', + constraint=models.UniqueConstraint(fields=('template_no', 'version'), name='uq_cost_template_head_no_ver'), + ), + migrations.DeleteModel( + name='PriceTemplate', + ), + ] diff --git a/backend/apps/pisadmin/miscprocurement/migrations/0004_inquiry_template_version_inquirymaterialcost_weight.py b/backend/apps/pisadmin/miscprocurement/migrations/0004_inquiry_template_version_inquirymaterialcost_weight.py new file mode 100644 index 0000000..e330044 --- /dev/null +++ b/backend/apps/pisadmin/miscprocurement/migrations/0004_inquiry_template_version_inquirymaterialcost_weight.py @@ -0,0 +1,24 @@ +# Generated by Django 4.2.14 on 2026-03-26 10:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('miscprocurement', '0003_remove_pricetemplate_creator_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='inquiry', + name='template_version', + field=models.IntegerField(db_column='TemplateVersion', default=1, help_text='与 template 共同锁定成本估算模板主表版本(CostEstimateTemplateHead.version);发布与供应商报价结构均以此为准。', verbose_name='模板版本号'), + preserve_default=False, + ), + migrations.AddField( + model_name='inquirymaterialcost', + name='weight', + field=models.DecimalField(blank=True, db_column='Weight', decimal_places=4, max_digits=12, null=True, verbose_name='重量'), + ), + ] diff --git a/backend/apps/pisadmin/miscprocurement/migrations/0005_alter_inquiry_template_version.py b/backend/apps/pisadmin/miscprocurement/migrations/0005_alter_inquiry_template_version.py new file mode 100644 index 0000000..bebdc0c --- /dev/null +++ b/backend/apps/pisadmin/miscprocurement/migrations/0005_alter_inquiry_template_version.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.14 on 2026-03-26 15:41 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('miscprocurement', '0004_inquiry_template_version_inquirymaterialcost_weight'), + ] + + operations = [ + migrations.AlterField( + model_name='inquiry', + name='template_version', + field=models.IntegerField(db_column='TemplateVersion', default=1, help_text='与 template 共同锁定成本估算模板主表版本(CostEstimateTemplateHead.version);发布与供应商报价结构均以此为准。', verbose_name='模板版本号'), + ), + ] diff --git a/backend/apps/pisadmin/miscprocurement/migrations/0006_inquiry_bid_end_time_inquiry_bid_start_time_and_more.py b/backend/apps/pisadmin/miscprocurement/migrations/0006_inquiry_bid_end_time_inquiry_bid_start_time_and_more.py new file mode 100644 index 0000000..f9b0b50 --- /dev/null +++ b/backend/apps/pisadmin/miscprocurement/migrations/0006_inquiry_bid_end_time_inquiry_bid_start_time_and_more.py @@ -0,0 +1,140 @@ +# Generated by Django 4.2.14 on 2026-03-27 16:02 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('miscprocurement', '0005_alter_inquiry_template_version'), + ] + + operations = [ + migrations.AddField( + model_name='inquiry', + name='bid_end_time', + field=models.DateTimeField(blank=True, null=True, verbose_name='投标截止时间'), + ), + migrations.AddField( + model_name='inquiry', + name='bid_start_time', + field=models.DateTimeField(blank=True, null=True, verbose_name='投标开始时间'), + ), + migrations.AddField( + model_name='inquiry', + name='buying_method', + field=models.IntegerField(blank=True, choices=[(1, '询价'), (2, '招标')], null=True, verbose_name='采购方式(寻源方式)'), + ), + migrations.CreateModel( + name='RFQOperationLogs', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('operation_type', models.CharField(choices=[(1, '询价单创建'), (2, '询价单确认'), (3, '询价单发布'), (4, '询价单还原'), (5, '询价发送通知'), (6, '报价'), (7, '比议价'), (8, '议价审核提交'), (9, '议价审核完成'), (10, '议价审核驳回')], db_column='OperationType', max_length=20, verbose_name='操作类型')), + ('operation_user', models.CharField(blank=True, db_column='OperationUser', max_length=20, null=True, verbose_name='操作人')), + ('operation_time', models.DateTimeField(blank=True, db_column='OperationTime', null=True, verbose_name='操作时间')), + ('operation_desc', models.TextField(blank=True, db_column='OperationDesc', max_length=200, null=True, verbose_name='操作描述')), + ('inquiry_no', models.CharField(db_column='InquiryNo', db_index=True, max_length=20, verbose_name='询价单号')), + ('quotation_no', models.CharField(db_column='QuotationNo', db_index=True, max_length=20, verbose_name='报价单号')), + ('per_status', models.CharField(blank=True, db_column='PerStatus', max_length=50, null=True, verbose_name='作业前状态')), + ('cur_status', models.TextField(blank=True, db_column='CurStatus', max_length=100, null=True, verbose_name='作业后状态')), + ('is_show_user', models.IntegerField(blank=True, db_column='IsShowUser', help_text='履历显示否(1:是 0:否)', null=True, verbose_name='履历显示否')), + ('purchase_type', models.IntegerField(choices=[(1, '策采'), (2, '杂采')], db_column='PurchaseType', help_text='采购类别(1:策采 2:杂采)', verbose_name='采购类别')), + ('creator', models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '询价单操作日志', + 'verbose_name_plural': '询价单操作日志', + 'db_table': 'pis_rfq_operation_logs', + 'ordering': ('-create_datetime', 'id'), + 'indexes': [models.Index(fields=['inquiry_no', 'quotation_no'], name='pis_rfq_ope_Inquiry_57e005_idx')], + }, + ), + migrations.CreateModel( + name='MiscNegotiationRecords', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('inquiry_no', models.CharField(db_column='inquiry_no', db_index=True, max_length=20, verbose_name='询价单号')), + ('part_id', models.CharField(db_column='PartId', max_length=50, verbose_name='产品料号')), + ('supplier_code', models.CharField(blank=True, db_column='SupplierCode', max_length=50, null=True, verbose_name='供应商代码')), + ('bargaining_price', models.DecimalField(blank=True, decimal_places=4, default=0, max_digits=12, null=True, verbose_name='议价后价格')), + ('bargaining_time', models.DateTimeField(blank=True, null=True, verbose_name='议价时间')), + ('bargaining_user', models.CharField(blank=True, db_column='BargainingUser', max_length=20, null=True, verbose_name='议价人')), + ('is_awarded', models.IntegerField(blank=True, default=0, help_text='是否中标(1:是 0:否)', null=True, verbose_name='是否中标')), + ('quotation_no', models.CharField(blank=True, db_column='QuotationNo', max_length=20, null=True, verbose_name='报价单号')), + ('total_price_excl_tax', models.DecimalField(blank=True, decimal_places=4, default=0, max_digits=12, null=True, verbose_name='议价前不含税总价')), + ('total_price_incl_tax', models.DecimalField(blank=True, decimal_places=4, default=0, max_digits=12, null=True, verbose_name='议价前含税总价')), + ('creator', models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '杂采议价记录表', + 'verbose_name_plural': '杂采议价记录表', + 'db_table': 'pis_misc_negotiation_records', + 'ordering': ('-create_datetime', 'id'), + 'indexes': [models.Index(fields=['inquiry_no', 'part_id'], name='pis_misc_ne_inquiry_5d842e_idx'), models.Index(fields=['inquiry_no', 'part_id', 'quotation_no'], name='pis_misc_ne_inq_part_qtn_idx')], + }, + ), + migrations.CreateModel( + name='MiscLowPriceHeader', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('inquiry_no', models.CharField(db_column='inquiry_no', db_index=True, help_text='业务主键列之一;逻辑主键与 id 并存', max_length=20, verbose_name='询价单号')), + ('part_id', models.CharField(db_column='PartId', max_length=50, verbose_name='产品料号')), + ('souce_no', models.CharField(blank=True, db_column='SouceNo', max_length=20, null=True, verbose_name='来源单号(报价单&询价单)')), + ('cost_type', models.CharField(choices=[('1', '材料'), ('2', '加工'), ('3', '包装费'), ('4', '运输费'), ('5', '管销研费用'), ('6', '利润率')], db_column='CostType', max_length=50, verbose_name='成本类别')), + ('item_no', models.CharField(db_column='ItemNo', help_text='如:铝等项次名称', max_length=100, verbose_name='项次名')), + ('min_price', models.CharField(db_column='MinPrice', help_text='表结构为 varchar,若需参与运算可在业务层转换', max_length=10, verbose_name='最低价格')), + ('creator', models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '比价-制程最低价记录主表', + 'verbose_name_plural': '比价-制程最低价记录主表', + 'db_table': 'pis_misc_low_price_header', + 'ordering': ('-create_datetime', 'id'), + 'indexes': [models.Index(fields=['inquiry_no', 'part_id'], name='pis_misc_lo_inquiry_51eb98_idx')], + }, + ), + migrations.CreateModel( + name='MiscLowPriceDetail', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('inquiry_no', models.CharField(db_column='inquiry_no', db_index=True, max_length=20, verbose_name='询价单号')), + ('part_id', models.CharField(db_column='PartId', max_length=50, verbose_name='产品料号')), + ('cost_type', models.CharField(db_column='CostType', help_text='仅支持1-材料', max_length=50, verbose_name='成本类别')), + ('material_spec', models.CharField(db_column='materialspec', max_length=50, verbose_name='材料规格')), + ('item_no', models.CharField(choices=[(1, '重量'), (2, '单价')], db_column='ItemNo', help_text='策采:重量、损耗、单价;杂采:重量、单价', max_length=100, verbose_name='项次名')), + ('value', models.CharField(db_column='Value', max_length=10, verbose_name='最小值')), + ('souce_no', models.CharField(db_column='SouceNo', max_length=20, verbose_name='来源单号(报价单&询价单)')), + ('creator', models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人')), + ], + options={ + 'verbose_name': '比价-制程最低价记录次表', + 'verbose_name_plural': '比价-制程最低价记录次表', + 'db_table': 'pis_misc_low_price_detail', + 'ordering': ('-create_datetime', 'id'), + 'indexes': [models.Index(fields=['inquiry_no', 'part_id'], name='pis_misc_lo_inquiry_005d6d_idx')], + }, + ), + ] diff --git a/backend/apps/pisadmin/miscprocurement/migrations/0007_alter_misclowpriceheader_item_no.py b/backend/apps/pisadmin/miscprocurement/migrations/0007_alter_misclowpriceheader_item_no.py new file mode 100644 index 0000000..de4eac2 --- /dev/null +++ b/backend/apps/pisadmin/miscprocurement/migrations/0007_alter_misclowpriceheader_item_no.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.14 on 2026-03-29 19:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('miscprocurement', '0006_inquiry_bid_end_time_inquiry_bid_start_time_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='misclowpriceheader', + name='item_no', + field=models.CharField(db_column='ItemNo', help_text='根据成本类别获取询价单对应子表数据行,材料类别 - 材料成本的产品料号 part_id, 加工类别 - 加工工站 process_station', max_length=100, verbose_name='项次名'), + ), + ] diff --git a/backend/apps/pisadmin/miscprocurement/tasks.py b/backend/apps/pisadmin/miscprocurement/tasks.py new file mode 100644 index 0000000..db44d93 --- /dev/null +++ b/backend/apps/pisadmin/miscprocurement/tasks.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +""" +Celery 定时任务:报价截止时间到期邮件通知采购。 +""" +import logging +from typing import Dict, Any, List + +from django.utils import timezone + +from application.celery import app +from apps.pissupplier.models import QuotationMaster +from apps.pisadmin.miscprocurement.models import Inquiry + +logger = logging.getLogger(__name__) + + +def _is_in_cooldown(inquiry_no: str, cooldown_hours: int = 24) -> bool: + """ + 检查该询价单是否在冷却期内(24h内已成功发送过)。 + 复用 email_utils 的冷却判断逻辑。 + """ + from apps.pisadmin.basicinfo.views.email_utils import should_send_quote_timeout_reminder + return not should_send_quote_timeout_reminder(inquiry_no, cooldown_hours=cooldown_hours) + + +def _get_purchaser_emails(inquiry_no: str) -> List[str]: + """根据询价单号获取采购负责人邮箱列表。""" + from apps.pisadmin.basicinfo.views.email_utils import resolve_inquiry_purchaser_emails + inquiry = Inquiry.objects.filter(inquiry_no=inquiry_no).first() + if not inquiry: + return [] + return resolve_inquiry_purchaser_emails(inquiry) + + +def _build_expired_supplier_list(inquiry_no: str) -> List[Dict[str, Any]]: + """ + 构建某询价单下所有已到期未报价供应商列表。 + """ + now = timezone.now() + rows = QuotationMaster.objects.filter( + inquiry_no=inquiry_no, + status__in=(1, 2), # 1=待报价, 2=报价中 + quote_deadline__lt=now, + ).values("supplier_name", "contact_person", "contact_phone", "quote_deadline", "status") + + result = [] + for row in rows: + deadline_local = row["quote_deadline"] + if deadline_local and timezone.is_aware(deadline_local): + from django.utils.timezone import localtime + deadline_display = localtime(deadline_local).strftime("%Y-%m-%d %H:%M") + else: + deadline_display = str(deadline_local or "—") + + result.append({ + "supplier_name": row["supplier_name"] or "—", + "contact_person": row["contact_person"] or None, + "quote_deadline": deadline_display, + "status": row["status"], + }) + return result + + +def _send_deadline_expired_email(inquiry: Inquiry, expired_suppliers: List[Dict[str, Any]]) -> bool: + """ + 渲染并发送单封报价截止到期邮件(一个询价单合并所有供应商)。 + 复用 email_utils 的 send_email_notice 底层。 + """ + from apps.pisadmin.basicinfo.views.email_template import ( + TEMPLATE_QUOTE_DEADLINE_EXPIRED, + build_context_quote_deadline_expired, + render_email, + ) + from apps.pisadmin.basicinfo.views.email_utils import send_email_notice + from apps.pisadmin.basicinfo.models import EmailNotice + + to_list = _get_purchaser_emails(inquiry.inquiry_no) + if not to_list: + logger.warning("报价截止提醒无法找到采购负责人邮箱,inquiry_no=%s", inquiry.inquiry_no) + return False + + ctx = build_context_quote_deadline_expired(inquiry, expired_suppliers) + subject, body = render_email(TEMPLATE_QUOTE_DEADLINE_EXPIRED, ctx) + + notice = EmailNotice.objects.create( + subject=subject, + body=body, + to_emails=to_list, + cc_emails=[], + bcc_emails=[], + attachments=[], + biz_type="inquiry_quote_timeout", # 复用现有 biz_type 用于冷却期判断 + biz_id=inquiry.inquiry_no, + status="pending", + payload={ + "template_key": TEMPLATE_QUOTE_DEADLINE_EXPIRED, + "is_html": True, + "inquiry_no": ctx.get("inquiry_no"), + "supplier_count": ctx.get("supplier_count"), + }, + ) + notice.status = "sending" + notice.save(update_fields=["status", "update_datetime"]) + + success, detail = send_email_notice(notice) + notice.response = detail or {} + if success: + notice.status = "success" + notice.sent_at = timezone.now() + notice.last_error = None + else: + notice.status = "failed" + notice.last_error = detail.get("error") if isinstance(detail, dict) else str(detail) + + notice.save(update_fields=["status", "sent_at", "response", "last_error", "update_datetime"]) + return success + + +@app.task(bind=True, max_retries=3, default_retry_delay=180) +def check_quote_deadline_expired(self) -> Dict[str, int]: + """ + Celery Beat 定时任务:轮询报价截止时间已到期的报价单, + 按询价单合并发送邮件通知采购负责人,每天最多一次。 + + 查询条件:status ∈ {1, 2}(待报价/报价中)且 quote_deadline < now + + Returns: {"checked": N, "sent": M, "skipped": K, "errors": E} + """ + now = timezone.now() + + # 1. 找出所有已到期但未报价的报价单 + expired_qs = QuotationMaster.objects.filter( + status__in=(1, 2), + quote_deadline__isnull=False, + quote_deadline__lt=now, + ).values_list("inquiry_no", flat=True).distinct() + + # 2. 按 inquiry_no 分组 + inquiry_nos = list(expired_qs) + + checked = len(inquiry_nos) + sent = 0 + skipped = 0 + errors = 0 + + for inq_no in inquiry_nos: + # 3. 检查24h冷却期 + if _is_in_cooldown(inq_no, cooldown_hours=24): + skipped += 1 + continue + + # 4. 获取 Inquiry 对象 + inquiry = Inquiry.objects.filter(inquiry_no=inq_no).first() + if not inquiry: + logger.warning("报价截止提醒未找到询价单,inquiry_no=%s", inq_no) + skipped += 1 + continue + + # 5. 构建到期供应商列表 + expired_suppliers = _build_expired_supplier_list(inq_no) + if not expired_suppliers: + skipped += 1 + continue + + # 6. 发送邮件 + try: + if _send_deadline_expired_email(inquiry, expired_suppliers): + sent += 1 + else: + errors += 1 + except Exception: + logger.exception("报价截止提醒邮件发送异常,inquiry_no=%s", inq_no) + errors += 1 + + logger.info( + "报价截止提醒任务完成: checked=%d, sent=%d, skipped=%d, errors=%d", + checked, sent, skipped, errors, + ) + return {"checked": checked, "sent": sent, "skipped": skipped, "errors": errors} diff --git a/backend/apps/pissupplier/migrations/0002_quotationmaster_validity_days_and_more.py b/backend/apps/pissupplier/migrations/0002_quotationmaster_validity_days_and_more.py new file mode 100644 index 0000000..e06e690 --- /dev/null +++ b/backend/apps/pissupplier/migrations/0002_quotationmaster_validity_days_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.14 on 2026-03-24 14:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pissupplier', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='quotationmaster', + name='validity_days', + field=models.IntegerField(blank=True, null=True, verbose_name='有效天数'), + ), + migrations.AlterField( + model_name='quotationprocess', + name='unit', + field=models.CharField(blank=True, db_column='Unit', max_length=20, null=True, verbose_name='单位'), + ), + ] diff --git a/backend/apps/pissupplier/migrations/0003_quotationmaterial_weight_and_more.py b/backend/apps/pissupplier/migrations/0003_quotationmaterial_weight_and_more.py new file mode 100644 index 0000000..35ce847 --- /dev/null +++ b/backend/apps/pissupplier/migrations/0003_quotationmaterial_weight_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.2.14 on 2026-03-26 10:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pissupplier', '0002_quotationmaster_validity_days_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='quotationmaterial', + name='weight', + field=models.DecimalField(blank=True, db_column='Weight', decimal_places=4, max_digits=12, null=True, verbose_name='重量'), + ), + migrations.AlterField( + model_name='quotationattachment', + name='file_name', + field=models.CharField(db_column='file_name', max_length=100, verbose_name='文件名称'), + ), + migrations.AlterField( + model_name='quotationattachment', + name='file_path', + field=models.CharField(blank=True, db_column='file_path', max_length=200, null=True, verbose_name='文件路径'), + ), + migrations.AlterField( + model_name='quotationmaster', + name='status', + field=models.IntegerField(blank=True, choices=[(1, '待报价'), (2, '报价中'), (3, '已报价'), (4, '已过期')], default=1, help_text='1 待报价 2 已报价 3 已过期;置为已报价请走供应商端 POST quotation_master/{id}/submit/', null=True, verbose_name='状态'), + ), + ] diff --git a/backend/apps/pissupplier/migrations/0004_quotationmaster_bid_end_time_and_more.py b/backend/apps/pissupplier/migrations/0004_quotationmaster_bid_end_time_and_more.py new file mode 100644 index 0000000..0795e18 --- /dev/null +++ b/backend/apps/pissupplier/migrations/0004_quotationmaster_bid_end_time_and_more.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.14 on 2026-03-27 16:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pissupplier', '0003_quotationmaterial_weight_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='quotationmaster', + name='bid_end_time', + field=models.DateTimeField(blank=True, null=True, verbose_name='投标截止时间'), + ), + migrations.AddField( + model_name='quotationmaster', + name='bid_start_time', + field=models.DateTimeField(blank=True, null=True, verbose_name='投标开始时间'), + ), + migrations.AddField( + model_name='quotationmaster', + name='buying_method', + field=models.IntegerField(blank=True, choices=[(1, '询价'), (2, '招标')], null=True, verbose_name='采购方式(寻源方式)'), + ), + ] diff --git a/backend/apps/pissupplier/migrations/0005_alter_quotationmaster_quote_deadline_and_more.py b/backend/apps/pissupplier/migrations/0005_alter_quotationmaster_quote_deadline_and_more.py new file mode 100644 index 0000000..2a9354c --- /dev/null +++ b/backend/apps/pissupplier/migrations/0005_alter_quotationmaster_quote_deadline_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.14 on 2026-03-29 19:34 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pissupplier', '0004_quotationmaster_bid_end_time_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='quotationmaster', + name='quote_deadline', + field=models.DateTimeField(blank=True, null=True, verbose_name='报价截止时间'), + ), + migrations.AlterField( + model_name='quotationmaster', + name='status', + field=models.IntegerField(blank=True, choices=[(1, '待报价'), (2, '报价中'), (3, '已报价'), (4, '已过期')], default=1, help_text='1 待报价 2 报价中 3 已报价 4 已过期;置为已报价请走 POST quotation_master/{id}/submit/;超时批量置过期及询价单收口见 sync_expired / Inquiry.sync_to_quote_closed_when_no_open_quotations;名单内供应商均已提交见 submit 与 Inquiry.sync_to_quote_closed_when_all_suppliers_quoted。', null=True, verbose_name='状态'), + ), + ] diff --git a/backend/conf/env.py b/backend/conf/env.py index 3be8fbe..d71cdf6 100644 --- a/backend/conf/env.py +++ b/backend/conf/env.py @@ -31,7 +31,7 @@ TABLE_PREFIX = "pis_" # Procurement Inquiry System REDIS_DB = 1 CELERY_BROKER_DB = 3 REDIS_PASSWORD = 'redis_5pGXn2' -REDIS_HOST = '177.10.0.15' +REDIS_HOST = '192.168.80.90' REDIS_URL = f'redis://:{REDIS_PASSWORD or ""}@{REDIS_HOST}:6379' # ================================================= # # ****************** 功能 启停 ******************* # @@ -48,3 +48,22 @@ LOGIN_NO_CAPTCHA_AUTH = True ALLOWED_HOSTS = ["*"] # 列权限中排除App应用 COLUMN_EXCLUDE_APPS = [] + + +# ================================================= # +# ****************** 邮件 配置 ******************* # +# ================================================= # +# 发送邮箱地址(From 显示) +EMAIL_FROM = "eip@avc.co" +# SMTP 登录账号(服务器不支持认证,留空) +EMAIL_HOST_USER = "" +# SMTP 登录密码/授权码(服务器不支持认证,留空) +EMAIL_HOST_PASSWORD = "" +# SMTP 服务器地址 +EMAIL_HOST = "mailflow.avc.co" +# SMTP 端口 +EMAIL_PORT = 25 +# 是否使用 SSL(如果走 STARTTLS,将 EMAIL_USE_SSL 设为 False,EMAIL_USE_TLS=True) +# 服务器不支持STARTTLS,使用纯明文连接 +EMAIL_USE_SSL = False +EMAIL_USE_TLS = False diff --git a/backend/conftest.py b/backend/conftest.py new file mode 100644 index 0000000..edf0766 --- /dev/null +++ b/backend/conftest.py @@ -0,0 +1,34 @@ +import pytest +from rest_framework.test import APIClient + + +@pytest.fixture +def api_client(): + """匿名 API 客户端""" + return APIClient() + + +@pytest.fixture +def authenticate(api_client, admin_user): + """已认证的 API 客户端(管理员)""" + api_client.force_authenticate(user=admin_user) + return api_client + + +@pytest.fixture +def admin_user(db): + """创建管理员用户(每次调用自动 rollback,username 使用 Sequence 确保唯一)""" + from tests.factories.system_factory import UserFactory + + user = UserFactory(admin=True) + return user + + +@pytest.fixture +def normal_user(db): + """创建普通用户""" + from tests.factories.system_factory import UserFactory + + user = UserFactory() + return user + diff --git a/backend/dvadmin/system/urls.py b/backend/dvadmin/system/urls.py index 6c4cc5a..7c0afd3 100644 --- a/backend/dvadmin/system/urls.py +++ b/backend/dvadmin/system/urls.py @@ -7,6 +7,7 @@ from dvadmin.system.views.clause import PrivacyView, TermsServiceView from dvadmin.system.views.dept import DeptViewSet from dvadmin.system.views.dictionary import DictionaryViewSet from dvadmin.system.views.file_list import FileViewSet +from dvadmin.system.views.login import SupplierLoginView from dvadmin.system.views.login_log import LoginLogViewSet from dvadmin.system.views.menu import MenuViewSet from dvadmin.system.views.menu_button import MenuButtonViewSet @@ -53,5 +54,7 @@ urlpatterns = [ # path('dept_lazy_tree/', DeptViewSet.as_view({'get': 'dept_lazy_tree'})), path('clause/privacy.html', PrivacyView.as_view()), path('clause/terms_service.html', TermsServiceView.as_view()), + # 供应商登录 + path('login/supplier/', SupplierLoginView.as_view(), name='supplier_login'), ] urlpatterns += system_url.urls diff --git a/backend/dvadmin/system/views/login.py b/backend/dvadmin/system/views/login.py index aa5b207..da39cf2 100644 --- a/backend/dvadmin/system/views/login.py +++ b/backend/dvadmin/system/views/login.py @@ -140,6 +140,99 @@ class LoginSerializer(TokenObtainPairSerializer): return {"code": 2000, "msg": "请求成功", "data": data} +class SupplierLoginSerializer(TokenObtainPairSerializer): + """ + 供应商登录的序列化器 + 复用 LoginSerializer 的验证逻辑,额外校验 role.key = 'supplier' + """ + captcha = serializers.CharField( + max_length=6, required=False, allow_null=True, allow_blank=True + ) + + class Meta: + model = Users + fields = "__all__" + read_only_fields = ["id"] + + default_error_messages = {"no_active_account": _("账号/密码错误")} + + def validate(self, attrs): + captcha = self.initial_data.get("captcha", None) + if dispatch.get_system_config_values("base.captcha_state"): + if captcha is None: + raise CustomValidationError("验证码不能为空") + self.image_code = CaptchaStore.objects.filter( + id=self.initial_data["captchaKey"] + ).first() + five_minute_ago = datetime.now() - timedelta(hours=0, minutes=5, seconds=0) + if self.image_code and five_minute_ago > self.image_code.expiration: + self.image_code and self.image_code.delete() + raise CustomValidationError("验证码过期") + else: + if self.image_code and ( + self.image_code.response == captcha + or self.image_code.challenge == captcha + ): + self.image_code and self.image_code.delete() + else: + self.image_code and self.image_code.delete() + raise CustomValidationError("图片验证码错误") + try: + user = Users.objects.get( + Q(username=attrs['username']) | Q(email=attrs['username']) | Q(mobile=attrs['username'])) + except Users.DoesNotExist: + raise CustomValidationError("您登录的账号不存在") + except Users.MultipleObjectsReturned: + raise CustomValidationError("您登录的账号存在多个,请联系管理员检查登录账号唯一性") + if not user.is_active: + raise CustomValidationError("账号已被锁定,联系管理员解锁") + # 必须重置用户名为username,否则使用邮箱手机号登录会提示密码错误 + attrs['username'] = user.username + + # 校验用户角色是否为供应商 + user_roles = user.role.all() + role_keys = [r.key for r in user_roles] + if 'supplier' not in role_keys: + raise CustomValidationError("该账号不是供应商账号,请使用采购方入口登录") + + try: + data = super().validate(attrs) + except Exception as e: + user.login_error_count += 1 + if user.login_error_count >= 5: + user.is_active = False + user.save() + raise CustomValidationError("账号已被锁定,联系管理员解锁") + user.save() + count = 5 - user.login_error_count + raise CustomValidationError(f"账号/密码错误;重试{count}次后将被锁定~") + data["username"] = self.user.username + data["name"] = self.user.name + data["userId"] = self.user.id + data["avatar"] = self.user.avatar + data['user_type'] = self.user.user_type + data['pwd_change_count'] = self.user.pwd_change_count + dept = Dept.objects.filter(id=self.user.dept_id).values("id", "name").first() if self.user.dept_id else None + if dept: + data['dept_info'] = { + 'dept_id': dept["id"], + 'dept_name': dept["name"], + } + role = getattr(self.user, 'role', None) + if role: + data['role_info'] = role.values('id', 'name', 'key') + request = self.context.get("request") + if request is not None: + request.user = self.user + try: + save_login_log(request=request) + except Exception: + logger.exception("记录登录日志失败: %s", self.user.username) + user.login_error_count = 0 + user.save() + return {"code": 2000, "msg": "请求成功", "data": data} + + class LoginView(TokenObtainPairView): """ 登录接口 @@ -147,6 +240,14 @@ class LoginView(TokenObtainPairView): serializer_class = LoginSerializer permission_classes = [] + +class SupplierLoginView(TokenObtainPairView): + """ + 供应商登录接口 + """ + serializer_class = SupplierLoginSerializer + permission_classes = [] + # def post(self, request, *args, **kwargs): # # username可能携带的不止是用户名,可能还是用户的其它唯一标识 手机号 邮箱 # username = request.data.get('username',None) diff --git a/backend/pytest.ini b/backend/pytest.ini new file mode 100644 index 0000000..84b63b2 --- /dev/null +++ b/backend/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +DJANGO_SETTINGS_MODULE = application.test_settings +python_files = test_*.py +python_classes = Test* +python_functions = test_* +addopts = -v --tb=short +testpaths = apps tests diff --git a/backend/requirements.txt b/backend/requirements.txt index dfa27c4..6c4ae3a 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -1,3 +1,4 @@ +setuptools>=69.0.0,<70 Django==4.2.14 django-comment-migrate==0.1.7 django-cors-headers==4.4.0 @@ -10,7 +11,6 @@ django-timezone-field==7.0 djangorestframework_simplejwt==5.4.0 drf-yasg==1.21.7 mssql-django==1.7 -mysqlclient==2.2.0 pypinyin==0.51.0 ua-parser==0.18.0 pyparsing==3.1.2 @@ -23,7 +23,6 @@ channels-redis==4.2.0 user-agents==2.2.0 six==1.16.0 whitenoise==6.7.0 -psycopg2==2.9.9 uvicorn==0.30.3 gunicorn==23.0.0 gevent==24.2.1 @@ -31,4 +30,8 @@ Pillow==10.4.0 pyinstaller==6.9.0 dvadmin3-celery==3.1.6 oss2==2.19.1 -cos-python-sdk-v5==1.9.37 \ No newline at end of file +cos-python-sdk-v5==1.9.37 + +# Git hooks +pre-commit>=3.0.0 +ruff>=0.9.0 \ No newline at end of file diff --git a/backend/templates/emails/quote_deadline_expired_body.html b/backend/templates/emails/quote_deadline_expired_body.html new file mode 100644 index 0000000..2f49a5a --- /dev/null +++ b/backend/templates/emails/quote_deadline_expired_body.html @@ -0,0 +1,42 @@ + + + + +

尊敬的 {{ purchaser_name }}:

+

您好!

+

您负责的询价单(编号:{{ inquiry_no }})有 {{ supplier_count }} 家供应商报价已到期但尚未提交报价,具体信息如下:

+ + + + + + + + + + + + {% for supplier in expired_suppliers %} + + + + + + + {% endfor %} + +
供应商名称联系人报价截止时间当前状态
{{ supplier.supplier_name }}{{ supplier.contact_person|default:"—" }}{{ supplier.quote_deadline }}{% if supplier.status == 1 %}待报价{% else %}报价中{% endif %}
+ + {% if comparison_page_url %} +

+ 点击此处进入比价页面 +

+

若链接无法打开,请复制以下地址到浏览器:

+

{{ comparison_page_url }}

+ {% else %} +

系统未配置采购端门户地址,请登录系统进入「比价/议价」页面处理。

+ {% endif %} + +

此邮件由系统自动发送,请勿直接回复。

+ + diff --git a/backend/templates/emails/quote_deadline_expired_subject.txt b/backend/templates/emails/quote_deadline_expired_subject.txt new file mode 100644 index 0000000..dfd17f7 --- /dev/null +++ b/backend/templates/emails/quote_deadline_expired_subject.txt @@ -0,0 +1 @@ +{% autoescape off %}【报价截止提醒】询价单 {{ inquiry_no }} 有 {{ supplier_count }} 家供应商已到期未报价,请及时处理{% endautoescape %} diff --git a/backend/tests/__init__.py b/backend/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py new file mode 100644 index 0000000..017389e --- /dev/null +++ b/backend/tests/conftest.py @@ -0,0 +1,41 @@ +import pytest +from rest_framework.test import APIClient + + +@pytest.fixture +def api_client(): + """匿名 API 客户端""" + return APIClient() + + +@pytest.fixture +def authenticate(api_client, admin_user): + """已认证的 API 客户端(管理员)""" + api_client.force_authenticate(user=admin_user) + return api_client + + +@pytest.fixture +def admin_user(db): + """创建管理员用户(每个测试独立事务,测试后自动 rollback)""" + from dvadmin.system.models import Users + + user = Users.objects.create_user( + username="test_admin", + password="testpass123", + is_superuser=True, + ) + return user + + +@pytest.fixture +def normal_user(db): + """创建普通用户""" + from dvadmin.system.models import Users + + user = Users.objects.create_user( + username="test_normal_user", + password="testpass123", + is_superuser=False, + ) + return user diff --git a/backend/tests/factories/__init__.py b/backend/tests/factories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/factories/system_factory.py b/backend/tests/factories/system_factory.py new file mode 100644 index 0000000..36832b3 --- /dev/null +++ b/backend/tests/factories/system_factory.py @@ -0,0 +1,15 @@ +import factory +from dvadmin.system.models import Users + + +class UserFactory(factory.django.DjangoModelFactory): + class Meta: + model = Users + + username = factory.Sequence(lambda n: f"user_{n}") + password = factory.Faker("password", length=12) + is_active = True + is_superuser = False + + class Params: + admin = factory.Trait(is_superuser=True) diff --git a/docker-compose-副本.yml b/docker-compose-副本.yml deleted file mode 100644 index 65d7a52..0000000 --- a/docker-compose-副本.yml +++ /dev/null @@ -1,117 +0,0 @@ -version: "3" -services: - dvadmin3-web: - container_name: dvadmin3-web - ports: - - "8080:8080" - build: - context: ./ - dockerfile: ./docker_env/web/Dockerfile - environment: - TZ: Asia/Shanghai - volumes: - - ./docker_env/nginx/my.conf:/etc/nginx/conf.d/my.conf - - ./backend/media:/backend/media - expose: - - "8080" - restart: always - networks: - network: - ipv4_address: 177.10.0.11 - - dvadmin3-django: - build: - context: . - dockerfile: ./docker_env/django/Dockerfile - container_name: dvadmin3-django - working_dir: /backend - depends_on: - - dvadmin3-mysql - environment: - PYTHONUNBUFFERED: 1 - DATABASE_HOST: dvadmin3-mysql - TZ: Asia/Shanghai - volumes: - - ./backend:/backend - - ./logs/log:/var/log - ports: - - "8000:8000" - expose: - - "8000" - restart: always - networks: - network: - ipv4_address: 177.10.0.12 - - dvadmin3-mysql: - image: mysql:8.0 - container_name: dvadmin3-mysql - privileged: true - restart: always - ports: - - "3306:3306" - environment: - MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD} - MYSQL_DATABASE: "django-vue3-admin" - TZ: Asia/Shanghai - command: - --wait_timeout=31536000 - --interactive_timeout=31536000 - --max_connections=1000 - --default-authentication-plugin=mysql_native_password - volumes: - - "./docker_env/mysql/data:/var/lib/mysql" - - "./docker_env/mysql/conf.d:/etc/mysql/conf.d" - - "./docker_env/mysql/logs:/logs" - networks: - network: - ipv4_address: 177.10.0.13 - - - dvadmin3-celery: - build: - context: . - dockerfile: ./docker_env/celery/Dockerfile - container_name: dvadmin3-celery - working_dir: /backend - depends_on: - - dvadmin3-mysql - environment: - PYTHONUNBUFFERED: 1 - DATABASE_HOST: dvadmin3-mysql - TZ: Asia/Shanghai - volumes: - - ./backend:/backend - - ./logs/log:/var/log - restart: always - networks: - network: - ipv4_address: 177.10.0.14 - - - dvadmin3-redis: - image: redis:6.2.6-alpine # 指定服务镜像,最好是与之前下载的redis配置文件保持一致 - container_name: dvadmin3-redis # 容器名称 - restart: always - environment: - - TZ=Asia/Shanghai # 设置时区 - volumes: # 配置数据卷 - - ./docker_env/redis/data:/data - - ./docker_env/redis/redis.conf:/etc/redis/redis.conf - ports: # 映射端口 - - "6379:6379" - sysctls: # 设置容器中的内核参数 - - net.core.somaxconn=1024 - command: /bin/sh -c "echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf && redis-server /etc/redis/redis.conf --appendonly yes --requirepass ${REDIS_PASSWORD}" # 指定配置文件并开启持久化 - privileged: true # 使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限 - networks: - network: - ipv4_address: 177.10.0.15 - - -networks: - network: - ipam: - driver: default - config: - - subnet: '177.10.0.0/16' \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index e06b461..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,114 +0,0 @@ -version: "3" -services: - # dvadmin3-web: - # container_name: dvadmin3-web - # ports: - # - "8080:8080" - # build: - # context: ./ - # dockerfile: ./docker_env/web/Dockerfile - # environment: - # TZ: Asia/Shanghai - # volumes: - # - ./docker_env/nginx/my.conf:/etc/nginx/conf.d/my.conf - # - ./backend/media:/backend/media - # expose: - # - "8080" - # restart: always - # networks: - # network: - # ipv4_address: 177.10.0.11 - - dvadmin3-django: - build: - context: . - dockerfile: ./docker_env/django/Dockerfile - container_name: dvadmin3-django - working_dir: /backend - environment: - PYTHONUNBUFFERED: 1 - TZ: Asia/Shanghai - volumes: - - ./backend:/backend - - ./logs/log:/var/log - ports: - - "8000:8000" - expose: - - "8000" - restart: always - networks: - network: - ipv4_address: 177.10.0.12 - - dvadmin3-mysql: - image: mysql:8.0 - container_name: dvadmin3-mysql - privileged: true - restart: always - ports: - - "3306:3306" - environment: - MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD} - MYSQL_DATABASE: "django-vue3-admin" - TZ: Asia/Shanghai - command: - --wait_timeout=31536000 - --interactive_timeout=31536000 - --max_connections=1000 - --default-authentication-plugin=mysql_native_password - volumes: - - "./docker_env/mysql/data:/var/lib/mysql" - - "./docker_env/mysql/conf.d:/etc/mysql/conf.d" - - "./docker_env/mysql/logs:/logs" - networks: - network: - ipv4_address: 177.10.0.13 - - - dvadmin3-celery: - build: - context: . - dockerfile: ./docker_env/celery/Dockerfile - container_name: dvadmin3-celery - working_dir: /backend - depends_on: - - dvadmin3-mysql - environment: - PYTHONUNBUFFERED: 1 - DATABASE_HOST: dvadmin3-mysql - TZ: Asia/Shanghai - volumes: - - ./backend:/backend - - ./logs/log:/var/log - restart: always - networks: - network: - ipv4_address: 177.10.0.14 - - - dvadmin3-redis: - image: redis:6.2.6-alpine # 指定服务镜像,最好是与之前下载的redis配置文件保持一致 - container_name: dvadmin3-redis # 容器名称 - restart: always - environment: - - TZ=Asia/Shanghai # 设置时区 - volumes: # 配置数据卷 - - ./docker_env/redis/data:/data - - ./docker_env/redis/redis.conf:/etc/redis/redis.conf - ports: # 映射端口 - - "6379:6379" - sysctls: # 设置容器中的内核参数 - - net.core.somaxconn=1024 - command: /bin/sh -c "echo 'vm.overcommit_memory = 1' >> /etc/sysctl.conf && redis-server /etc/redis/redis.conf --appendonly yes --requirepass ${REDIS_PASSWORD}" # 指定配置文件并开启持久化 - privileged: true # 使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部的一个普通用户权限 - networks: - network: - ipv4_address: 177.10.0.15 - - -networks: - network: - ipam: - driver: default - config: - - subnet: '177.10.0.0/16' \ No newline at end of file diff --git a/docker_env/README.md b/docker_env/README.md deleted file mode 100644 index f281ab5..0000000 --- a/docker_env/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# docker 镜像打包 - -### 打包web基础Build包 - -~~~sh -# 编译打包到本地 -docker build -f ./docker_env/web/DockerfileBuild -t registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/dvadmin3-base-web:16.19-alpine . -# 上传到阿里云仓库 -docker push registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/dvadmin3-base-web:16.19-alpine - -~~~ - -### 打包Backend基础Build包 - -~~~sh -# 编译打包到本地 -docker build -f ./docker_env/django/DockerfileBuild -t registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/dvadmin3-base-backend:latest . -# 上传到阿里云仓库 -docker push registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/dvadmin3-base-backend:latest -~~~ - -### 运行前端 - -~~~ -docker build -f ./docker_env/web/Dockerfile -t dvadmin-pro-web . -~~~ - -### 运行后端 - -~~~ -docker build -f ./docker_env/django/Dockerfile -t dvadmin-pro-django . -~~~ - -### 运行celery - -~~~ -docker build -f ./docker_env/celery/Dockerfile -t dvadmin-pro-celery . -~~~ - -## docker-compose 运行 - -~~~ -# 先安装docker-compose (自行百度安装),执行此命令等待安装,如有使用celery插件请打开docker-compose.yml中celery 部分注释 -docker-compose up -d -# 初始化后端数据(第一次执行即可) -docker exec -ti dvadmin-django bash -python manage.py makemigrations -python manage.py migrate -python manage.py init -y -exit - -前端地址:http://127.0.0.1:8080 -后端地址:http://127.0.0.1:8000 -# 在服务器上请把127.0.0.1 换成自己公网ip -账号:superadmin 密码:admin123456 - -# docker-compose 停止 -docker-compose down -# docker-compose 重启 -docker-compose restart -# docker-compose 启动时重新进行 build -docker-compose up -d --build - -~~~ - diff --git a/docker_env/celery/Dockerfile b/docker_env/celery/Dockerfile deleted file mode 100644 index 7d57c7a..0000000 --- a/docker_env/celery/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/dvadmin3-base-backend:latest -WORKDIR /backend -COPY ./backend/ . -RUN awk 'BEGIN { cmd="cp -i ./conf/env.example.py ./conf/env.py "; print "n" |cmd; }' -RUN python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ -r requirements.txt -CMD ["celery", "-A", "application", "worker", "-B", "--loglevel=info"] - diff --git a/docker_env/django/Dockerfile b/docker_env/django/Dockerfile deleted file mode 100644 index e11bdf0..0000000 --- a/docker_env/django/Dockerfile +++ /dev/null @@ -1,43 +0,0 @@ -# 使用非Alpine源,兼容SQL Server安装 -FROM python:3.10-slim - -# 3. 安装系统依赖 (替换原来的 apk 命令) -# 注意:这里安装了构建依赖和微软驱动所需的依赖 -RUN apt-get update && apt-get install -y \ - bash \ - git \ - curl \ - gnupg \ - ca-certificates \ - # 以下为原 apk 中的开发库对应的 apt 包名 (可能需微调) - libjpeg-dev \ - libmariadb-dev-compat \ - default-libmysqlclient-dev \ - build-essential \ - libffi-dev \ - libssl-dev \ - zlib1g-dev \ - libbz2-dev \ - libpcre2-dev \ - libncurses5-dev \ - libreadline-dev \ - tk-dev \ - libpq-dev \ - unixodbc-dev \ - && rm -rf /var/lib/apt/lists/* - -# 4. 添加微软软件源和密钥 (解决 msodbcsql17 安装问题) -RUN curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/microsoft.gpg \ - && echo "deb [arch=amd64] https://packages.microsoft.com/repos/microsoft-ubuntu-focal-prod focal main" > /etc/apt/sources.list.d/mssql-release.list \ - && apt-get update \ - && ACCEPT_EULA=Y apt-get install -y msodbcsql17 \ - && rm -rf /var/lib/apt/lists/* - -WORKDIR /backend -COPY ./backend/ . -RUN ls ./conf/ -RUN awk 'BEGIN { cmd="cp -i ./conf/env.example.py ./conf/env.py "; print "n" |cmd; }' -RUN sed -i "s|DATABASE_HOST = '127.0.0.1'|DATABASE_HOST = '177.10.0.1'|g" ./conf/env.py -RUN sed -i "s|REDIS_HOST = '127.0.0.1'|REDIS_HOST = '177.10.0.1'|g" ./conf/env.py -RUN python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ -r requirements.txt -CMD ["sh","docker_start.sh"] diff --git a/docker_env/django/DockerfileBuild b/docker_env/django/DockerfileBuild deleted file mode 100644 index 53e5049..0000000 --- a/docker_env/django/DockerfileBuild +++ /dev/null @@ -1,6 +0,0 @@ -FROM python:3.10-alpine -RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories -RUN apk update && apk add bash bash-doc bash-completion git freetds-dev jpeg-dev linux-headers mysql-client mariadb-dev build-base libffi-dev openssl-dev zlib-dev bzip2-dev pcre-dev ncurses-dev readline-dev tk-dev postgresql-dev -WORKDIR /backend -COPY ./backend/requirements.txt . -RUN python3 -m pip install -i https://mirrors.aliyun.com/pypi/simple/ -r requirements.txt diff --git a/docker_env/mysql/conf.d/my.cnf b/docker_env/mysql/conf.d/my.cnf deleted file mode 100644 index 469af8b..0000000 --- a/docker_env/mysql/conf.d/my.cnf +++ /dev/null @@ -1,33 +0,0 @@ -[mysql] -#设置mysql客户端默认字符集 -default-character-set=utf8 -socket=/var/lib/mysql/mysql.sock - - -[mysqld] -# skip-grant-tables -#mysql5.7以后的不兼容问题处理 -sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES -datadir=/var/lib/mysql -socket=/var/lib/mysql/mysql.sock - -# Disabling symbolic-links is recommended to prevent assorted security risks -symbolic-links=0 -# Settings user and group are ignored when systemd is used. -# If you need to run mysqld under a different user or group, -# customize your systemd unit file for mariadb according to the -# instructions in http://fedoraproject.org/wiki/Systemdd -#允许最大连接数 -max_connections=1000 -#服务端使用的字符集默认为8比特编码的latin1字符集 -character-set-server=utf8 -#创建新表时将使用的默认存储引擎 -default-storage-engine=INNODB -lower_case_table_names=1 -max_allowed_packet=16M -#设置时区 -default-time_zone='+8:00' - -[mysqld_safe] -log-error=/var/log/mariadb/mariadb.log -pid-file=/var/lib/mariadb/mariadb.pid diff --git a/docker_env/mysql/launch.sh b/docker_env/mysql/launch.sh deleted file mode 100644 index 31b3687..0000000 --- a/docker_env/mysql/launch.sh +++ /dev/null @@ -1,5 +0,0 @@ -cur_path=`pwd` -docker rm mysql -# docker pull mysql:5.7 -# docker pull mysql:5.5 -docker run -p 3306:3306 --privileged=true --name mysql -v $cur_path/logs:/logs -v $cur_path/data:/var/lib/mysql -v $cur_path/conf.d/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -v $cur_path/run/:/var/run/mysql -e MYSQL_ROOT_PASSWORD=q1w2e3r4 -d mysql:5.7 diff --git a/docker_env/nginx/my-80.conf b/docker_env/nginx/my-80.conf deleted file mode 100644 index b69923a..0000000 --- a/docker_env/nginx/my-80.conf +++ /dev/null @@ -1,33 +0,0 @@ -server { - listen 80; - server_name localhost; - client_max_body_size 100M; - # 配置前端静态文件目录 - location / { - index index.html index.htm; - root /usr/share/nginx/html; - try_files $uri $uri/ /index.html; - # 禁止缓存html文件,避免前端页面不及时更新,需要用户手动刷新的情况 - if ($request_uri ~* "^/$|^/index.html|^/index.htm") { - add_header Cache-Control "no-store"; - } - } - - location ~ ^/api/ { - proxy_http_version 1.1; - proxy_set_header Host $http_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_set_header X-Nginx-Proxy true; - set_real_ip_from 0.0.0.0/0; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_connect_timeout 600s; - proxy_read_timeout 600s; - proxy_send_timeout 600s; - real_ip_header X-Forwarded-For; - # 保留 /api/ 前缀,让后端 application.urls.py 的 path("api/...") 正常命中 - proxy_pass http://177.10.0.12:8000; # 设置代理服务器的协议和地址 - } - } diff --git a/docker_env/nginx/my.conf b/docker_env/nginx/my.conf deleted file mode 100644 index 9b34d68..0000000 --- a/docker_env/nginx/my.conf +++ /dev/null @@ -1,54 +0,0 @@ -server { - listen 8080; - server_name localhost; - client_max_body_size 100M; - location / { - proxy_set_header Host $http_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 https; - set_real_ip_from 0.0.0.0/0; - real_ip_header X-Forwarded-For; - root /usr/share/nginx/html; - index index.html index.php index.htm; - # 禁止缓存html文件,避免前端页面不及时更新,需要用户手动刷新的情况 - if ($request_uri ~* "^/$|^/index.html|^/index.htm") { - add_header Cache-Control "no-store"; - } - } - - location /api/ { - proxy_http_version 1.1; - proxy_set_header Host $http_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_set_header X-Nginx-Proxy true; - set_real_ip_from 0.0.0.0/0; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_connect_timeout 600s; - proxy_read_timeout 600s; - proxy_send_timeout 600s; - real_ip_header X-Forwarded-For; - proxy_pass http://dvadmin3-django:8000; # 反向代理到后端(保留 /api/ 前缀) - } - location /media { - alias /backend/media; - expires 7d; - gzip on; - gzip_min_length 1k; - gzip_comp_level 2; - gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; - gzip_vary on; - } - location /api/media { - alias /backend/media; - expires 7d; - gzip on; - gzip_min_length 1k; - gzip_comp_level 2; - gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png; - gzip_vary on; - } - } diff --git a/docker_env/redis/redis.conf b/docker_env/redis/redis.conf deleted file mode 100644 index 7995fd4..0000000 --- a/docker_env/redis/redis.conf +++ /dev/null @@ -1,24 +0,0 @@ -### 指定redis绑定的主机地址,注释掉这部分,使redis可以外部访问 -# bind 127.0.0.1 -::1 -### 指定访问redis服务端的端口 -port 6379 -### 指定客户端连接redis服务器时,当闲置的时间为多少(如300)秒时关闭连接(0表示禁用) -timeout 0 -### 默认情况下,Redis不作为守护进程运行。如果需要,请使用“yes” -daemonize no -### 给redis设置密码,不需要密码的话则注释 -# requirepass dvadmin -### 开启redis持久化,默认为no -appendonly yes -### 防止出现远程主机强迫关闭了一个现有的连接的错误 默认是300 -tcp-keepalive 300 -### 指定redis数据库的日志级别,常用的日志级别有debug、verbose、notice、warning,不进行修改的情况下默认的是notice -loglevel notice -### 指定redis数据库多长时间内(s)有多少次(c)更新操作时就把缓存中的数据同步到本地库,比如:save 600 2,指的是10分钟内有2次更新操作,就同步到本地库 -save 600 2 -### 指定redis的最大内存。由于Redis 在启动时会把数据加载到内存中,当数据达到最大内存时,redis会自动把已经到期和即将到期的key值。所以可以根据需求调整自己的所需的最大内存 -maxmemory 500mb -### 设置了maxmemory的选项,redis内存使用达到上限。可以通过设置LRU算法来删除部分key,释放空间。默认是按照过期时间的,如果set时候没有加上过期时间就会导致数据写满maxmemory -maxmemory-policy volatile-lru -### 设置外部网络连接redis服务,开启需配置bind ip或者设置访问密码,关闭此时外部网络可以直接访问 -# protected-mode yes diff --git a/docker_env/web/Dockerfile b/docker_env/web/Dockerfile deleted file mode 100644 index a10f353..0000000 --- a/docker_env/web/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM node:20-alpine -WORKDIR /web/ -COPY web/. . -RUN yarn install --registry=https://registry.npmmirror.com -RUN yarn build - -FROM nginx:alpine -COPY ./docker_env/nginx/my.conf /etc/nginx/conf.d/my.conf -COPY --from=0 /web/dist /usr/share/nginx/html diff --git a/docker_env/web/DockerfileBuild b/docker_env/web/DockerfileBuild deleted file mode 100644 index 1f725ca..0000000 --- a/docker_env/web/DockerfileBuild +++ /dev/null @@ -1,4 +0,0 @@ -FROM node:16.19-alpine -WORKDIR / -COPY ./web/package.json . -RUN yarn install --registry=https://registry.npmmirror.com diff --git a/docs/scripts-documentation.md b/docs/scripts-documentation.md new file mode 100644 index 0000000..05088be --- /dev/null +++ b/docs/scripts-documentation.md @@ -0,0 +1,295 @@ +# 脚本文档 + +PIS 项目跨平台服务管理脚本。 + +## 概述 + +| 脚本 | Windows (PowerShell) | Unix/Linux/macOS (Bash) | +|------|---------------------|------------------------| +| 启动后端 | `start-backend.ps1` | `start-backend.sh` | +| 启动前端 | `start-frontend.ps1` | `start-frontend.sh` | +| 启动 Celery | `start-celery.ps1` | `start-celery.sh` | +| 停止所有 | `stop-all.ps1` | `stop-all.sh` | +| 停止 Celery | `stop-celery.ps1` | `stop-celery.sh` | +| 查看日志 | `view-logs.ps1` | `view-logs.sh` | +| 检查状态 | `check-status.ps1` | `check-status.sh` | + +## 快速开始 + +### Windows (PowerShell) + +```powershell +# 启动所有服务 +.\make.ps1 dev + +# 停止所有服务 +.\make.ps1 stop + +# 查看日志 +.\make.ps1 logs + +# 检查状态 +.\make.ps1 status +``` + +### Unix/Linux/macOS (Bash) + +```bash +# 启动所有服务 +make dev + +# 停止所有服务 +make stop + +# 查看日志 +make logs + +# 检查状态 +make status +``` + +## 使用方法 + +### make.ps1 命令 (Windows PowerShell) + +| 命令 | 说明 | +|------|------| +| `.\make.ps1 help` | 显示所有可用命令 | +| `.\make.ps1 dev` | 启动开发环境(前端 + 后端 + Celery) | +| `.\make.ps1 dev-backend` | 仅启动后端 | +| `.\make.ps1 dev-frontend` | 仅启动前端 | +| `.\make.ps1 dev-celery` | 仅启动 Celery | +| `.\make.ps1 stop` | 停止所有服务 | +| `.\make.ps1 restart` | 重启所有服务 | +| `.\make.ps1 restart-celery` | 仅重启 Celery | +| `.\make.ps1 logs` | 查看所有日志 | +| `.\make.ps1 logs-backend` | 查看后端日志 | +| `.\make.ps1 logs-frontend` | 查看前端日志 | +| `.\make.ps1 logs-celery` | 查看 Celery 日志 | +| `.\make.ps1 status` | 检查服务状态 | +| `.\make.ps1 clean-logs` | 清理日志文件 | +| `.\make.ps1 clean-pids` | 清理 PID 文件 | + +### make 命令 (Unix/Linux/macOS Bash) + +| 命令 | 说明 | +|------|------| +| `make help` | 显示所有可用命令 | +| `make dev` | 启动开发环境(前端 + 后端 + Celery) | +| `make dev-backend` | 仅启动后端 | +| `make dev-frontend` | 仅启动前端 | +| `make dev-celery` | 仅启动 Celery | +| `make stop` | 停止所有服务 | +| `make restart` | 重启所有服务 | +| `make restart-celery` | 仅重启 Celery | +| `make logs` | 查看所有日志 | +| `make logs-backend` | 查看后端日志 | +| `make logs-frontend` | 查看前端日志 | +| `make logs-celery` | 查看 Celery 日志 | +| `make status` | 检查服务状态 | +| `make clean-logs` | 清理日志文件 | +| `make clean-pids` | 清理 PID 文件 | + +## 直接调用脚本 + +### Windows PowerShell + +```powershell +# 启动后端 +.\scripts\start-backend.ps1 [dev|prod] + +# 启动前端 +.\scripts\start-frontend.ps1 [dev|prod] + +# 启动 Celery +.\scripts\start-celery.ps1 [dev|prod] + +# 停止所有服务 +.\scripts\stop-all.ps1 + +# 仅停止 Celery +.\scripts\stop-celery.ps1 + +# 查看日志 +.\scripts\view-logs.ps1 [backend|frontend|celery|all] + +# 检查状态 +.\scripts\check-status.ps1 +``` + +### Unix/Linux/macOS Bash + +```bash +# 启动后端 +./scripts/start-backend.sh [dev|prod] + +# 启动前端 +./scripts/start-frontend.sh [dev|prod] + +# 启动 Celery +./scripts/start-celery.sh [dev|prod] + +# 停止所有服务 +./scripts/stop-all.sh + +# 仅停止 Celery +./scripts/stop-celery.sh + +# 查看日志 +./scripts/view-logs.sh [backend|frontend|celery|all] + +# 检查状态 +./scripts/check-status.sh +``` + +## 环境参数 + +- `dev`(默认):开发模式,带热重载 +- `prod`:生产模式,使用优化构建 + +### Windows PowerShell +```powershell +.\make.ps1 dev -ENV prod +``` + +### Unix/Linux/macOS +```bash +ENV=prod make dev +``` + +## 端口 + +| 服务 | 端口 | +|------|------| +| 后端 (Django) | 8000 | +| 前端 (Vue) | 8080 | + +## 日志文件 + +日志存储在 `backend/logs/`: + +- `backend.log` - 后端应用日志 +- `frontend.log` - 前端应用日志 +- `celery_worker.log` - Celery Worker 日志 +- `celery_beat.log` - Celery Beat 调度器日志 + +## PID 文件 + +PID 文件存储在 `.pids/`: + +- `backend.pid` +- `frontend.pid` +- `celery_worker.pid` +- `celery_beat.pid` + +## 跨平台兼容性 + +### Windows PowerShell +- 支持 Windows PowerShell 5.1 及 PowerShell 7+ +- 使用 `System.Net.Sockets.TcpClient` 检查端口 +- 使用 WMI 查询检测进程(兼容 PS 5.1 和 PS 7+) +- 所有输出使用英文(避免编码问题) + +### Unix/Linux/macOS +- 需要 Bash 4.0+ +- 使用 `nc`(netcat)检查端口(如果可用) +- 使用 `pgrep` 和 `pkill` 管理进程 +- 输出使用中文 + +### Windows PowerShell Celery 已知问题 + +**Celery 在 Windows PowerShell 上有已知的兼容性问题。** + +问题原因:PowerShell 的 `Start-Process` 与 Celery 的多进程池(billiard)不兼容,导致以下错误: +- `PermissionError: [WinError 5] 拒绝访问` +- `OSError: [WinError 6] 句柄无效` + +**推荐解决方案:使用 Git Bash** + +在 Windows 上,推荐使用 Git Bash 运行 Celery 脚本: + +```bash +# 启动 Celery (推荐) +bash scripts/start-celery.sh + +# 停止 Celery +bash scripts/stop-celery.sh +``` + +Git Bash 使用 `nohup` 和 `&` 后台运行,与 Celery 的多进程机制完全兼容。 + +**如需使用 PowerShell:** + +可以尝试使用 `--pool solo` 参数(单进程模式): + +```powershell +.\scripts\start-celery.ps1 +``` + +但这可能会影响 Celery 的性能和稳定性。 + +## 依赖要求 + +### 后端 +- Python 3.10+ +- Django 4.2.14 +- uvicorn(开发)或 gunicorn(生产) +- Celery + Redis broker + +### 前端 +- Node.js 18+ +- Yarn 或 npm + +### Celery +- Redis 服务运行中 +- django-celery-beat + +## 故障排除 + +### 后端无法启动 +1. 检查端口 8000 是否被占用 +2. 检查 Python 依赖是否安装 +3. 检查 Django 配置:确保 `backend/conf/env.py` 已配置 + +### 前端无法启动 +1. 检查 Node.js 是否安装 +2. 安装依赖:`cd web && yarn install` +3. 检查端口 8080 是否被占用 + +### Celery 无法启动 +1. 检查 Redis 是否运行 +2. 执行数据库迁移:`python manage.py migrate` +3. 查看 Celery 日志 +4. **Windows 用户**:如果使用 PowerShell 启动失败,请改用 Git Bash: + ```bash + bash scripts/start-celery.sh + ``` + 这是 Windows 上的已知问题,PowerShell 的进程管理机制与 Celery 不兼容。 + +### 编码问题 +如果 PowerShell 显示乱码,确保使用 UTF-8 with BOM 编码保存的脚本文件。 + +## 脚本架构 + +``` +scripts/ +├── start-backend.ps1/.sh # 启动 Django 后端服务 +├── start-frontend.ps1/.sh # 启动 Vue 前端开发服务器 +├── start-celery.ps1/.sh # 启动 Celery worker 和 beat +├── stop-all.ps1/.sh # 停止所有服务 +├── stop-celery.ps1/.sh # 仅停止 Celery 服务 +├── view-logs.ps1/.sh # 查看和跟踪日志文件 +├── check-status.ps1/.sh # 检查服务运行状态 +├── Makefile # Unix/Linux/macOS 编排 +└── make.ps1 # Windows PowerShell 编排 +``` + +## 注意事项 + +- 所有脚本都是幂等的 - 多次运行是安全的 +- 脚本会检测服务是否已运行,已运行则跳过启动 +- 使用 PID 文件实现优雅关闭 +- 停止时会清理残留进程 +- PowerShell 脚本输出使用英文,避免编码问题 +- Bash 脚本输出使用中文 +- **Windows 用户**:建议使用 Git Bash 运行 Celery 脚本,以避免进程兼容性问题 diff --git a/docs/superpowers/plans/2026-04-03-git-collaboration-plan.md b/docs/superpowers/plans/2026-04-03-git-collaboration-plan.md new file mode 100644 index 0000000..28c0ee8 --- /dev/null +++ b/docs/superpowers/plans/2026-04-03-git-collaboration-plan.md @@ -0,0 +1,281 @@ +# Git 协作规范实施计划 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**目标:** 建立标准 Git 协作规范,包含 Git Flow 分支模型、PR 模板、Code Review 流程、Git Hooks(后端 pre-commit + 前端 husky) + +**架构概述:** +- 后端 Python 项目使用 `pre-commit` + `ruff` 管理 Git Hooks +- 前端 Node.js 项目使用 `husky` + `lint-staged` 管理 Git Hooks +- PR 模板放在 `.github/` 目录(GitHub 自动识别) +- Jenkins CI 配置在各自的 Jenkinsfile 中(后端已存在) + +**技术栈:** pre-commit, ruff, husky, lint-staged + +--- + +## 文件结构 + +``` +backend/ + ├── .pre-commit-config.yaml # 新建:pre-commit hooks 配置 + └── requirements.txt # 修改:添加 pre-commit, ruff + +web/ + ├── .husky/ # 新建:husky git hooks 目录 + │ └── pre-commit # 新建:pre-commit hook script + ├── .lintstagedrc.json # 新建:lint-staged 配置 + └── package.json # 修改:添加 husky, lint-staged + +.github/ + └── PULL_REQUEST_TEMPLATE.md # 新建:PR 模板 +``` + +--- + +## 任务清单 + +### 任务 1:后端 pre-commit 配置(ruff) + +**文件:** +- 创建:`backend/.pre-commit-config.yaml` +- 修改:`backend/requirements.txt` + +- [ ] **Step 1: 创建 backend/.pre-commit-config.yaml** + +```yaml +# 后端 pre-commit hooks 配置 +# 安装方式:pip install pre-commit && pre-commit install +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + args: ['--maxkb=5000'] + - id: check-merge-conflict + - id: debug-statements + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.9.0 + hooks: + - id: ruff + args: [--fix] + - id: ruff-format +``` + +- [ ] **Step 2: 验证文件创建** + +命令:`cat backend/.pre-commit-config.yaml` +预期:显示上述 yaml 内容 + +- [ ] **Step 3: 添加依赖到 requirements.txt** + +在 `backend/requirements.txt` 末尾添加: + +``` +# Git hooks +pre-commit>=3.0.0 +ruff>=0.9.0 +``` + +- [ ] **Step 4: 验证 requirements.txt 更新** + +命令:`grep -E "pre-commit|ruff" backend/requirements.txt` +预期:显示 pre-commit 和 ruff 两行 + +- [ ] **Step 5: 提交** + +```bash +git add backend/.pre-commit-config.yaml backend/requirements.txt +git commit -m "feat(git): add pre-commit with ruff for backend + +- Add .pre-commit-config.yaml with ruff (lint + format) +- Add pre-commit and ruff to requirements.txt +- Ruff replaces flake8 + black + isort (10-100x faster)" +``` + +--- + +### 任务 2:前端 husky + lint-staged 配置 + +**文件:** +- 创建:`web/.husky/pre-commit` +- 创建:`web/.lintstagedrc.json` +- 修改:`web/package.json` + +- [ ] **Step 1: 安装 husky 和 lint-staged** + +```bash +cd web +npm install husky lint-staged -D +``` + +- [ ] **Step 2: 初始化 husky** + +```bash +cd web +npx husky install +``` + +- [ ] **Step 3: 创建 .lintstagedrc.json** + +```json +{ + "*.{js,vue,ts,jsx,tsx}": [ + "eslint --fix", + "prettier --write" + ], + "*.{css,scss,vue}": [ + "prettier --write" + ] +} +``` + +- [ ] **Step 4: 添加 husky pre-commit hook** + +```bash +cd web +npx husky add .husky/pre-commit "npx lint-staged" +``` + +- [ ] **Step 5: 验证 .husky/pre-commit 内容** + +命令:`cat web/.husky/pre-commit` +预期:包含 `npx lint-staged` + +- [ ] **Step 6: 更新 package.json 添加 prepare script** + +在 `web/package.json` 的 `scripts` 中添加: + +```json +"prepare": "cd .. && husky install" +``` + +原有 scripts 示例: +```json +"scripts": { + "dev": "vite --force", + "prepare": "cd .. && husky install", + ... +} +``` + +- [ ] **Step 7: 验证 lint-staged 配置** + +命令:`cat web/.lintstagedrc.json` +预期:显示上述 json 内容 + +- [ ] **Step 8: 提交** + +```bash +git add web/package.json web/.lintstagedrc.json web/.husky/ +git commit -m "feat(git): add husky + lint-staged for frontend + +- Add .husky/pre-commit hook running lint-staged +- Add .lintstagedrc.json for staged file linting +- Add prepare script for husky setup on npm install" +``` + +--- + +### 任务 3:PR 模板 + +**文件:** +- 创建:`.github/PULL_REQUEST_TEMPLATE.md` + +- [ ] **Step 1: 创建 .github 目录** + +```bash +mkdir -p .github +``` + +- [ ] **Step 2: 创建 .github/PULL_REQUEST_TEMPLATE.md** + +```markdown +## 变更描述 + + +## 关联需求 + + +## 变更类型 +- [ ] Feature +- [ ] Bugfix +- [ ] Hotfix +- [ ] Refactor + +## 自检清单 +- [ ] 代码已通过 Pre-commit 检查(后端 ruff / 前端 lint-staged) +- [ ] 已添加必要的测试 +- [ ] 文档已更新(如需) + +## Reviewer 备注 + +``` + +- [ ] **Step 3: 验证模板创建** + +命令:`cat .github/PULL_REQUEST_TEMPLATE.md` +预期:显示上述 markdown 内容 + +- [ ] **Step 4: 提交** + +```bash +git add .github/PULL_REQUEST_TEMPLATE.md +git commit -m "docs: add PR template for standardized pull requests + +- Add change description, related issues +- Add change type checklist (Feature/Bugfix/Hotfix/Refactor) +- Add self-check checklist for pre-commit compliance +- Add reviewer notes section" +``` + +--- + +## 实施后验证 + +所有任务完成后,验证步骤: + +### 后端验证 + +```bash +cd backend +pip install pre-commit ruff +pre-commit install +# 测试运行 +pre-commit run --all-files +``` + +预期:ruff 检查通过(无 error) + +### 前端验证 + +```bash +cd web +# 首次 clone 后安装依赖 +npm install +# 测试 pre-commit hook +git add . +git commit -m "test: verify husky hook" +``` + +预期:lint-staged 运行,eslint + prettier 检查通过 + +--- + +## Spec 覆盖检查 + +- ✅ 分支模型:规范文档(已在 spec 中定义,无需代码实现) +- ✅ PR/MR 模板:任务 3 创建 `.github/PULL_REQUEST_TEMPLATE.md` +- ✅ Code Review 规范:规范文档(已在 spec 中定义,无需代码实现) +- ✅ Git Hooks 后端(pre-commit + ruff):任务 1 +- ✅ Git Hooks 前端(husky + lint-staged):任务 2 +- ✅ CI/CD 联动:Jenkinsfile 已存在(后端 `backend/Jenkinsfile`),无需修改 +- ✅ 分支保护规则:GitHub/GitLab 界面配置,不在代码库中 + +## 占位符扫描 + +无占位符,所有步骤均包含完整配置和命令。 diff --git a/docs/superpowers/specs/2026-04-02-ai-agent-design.md b/docs/superpowers/specs/2026-04-02-ai-agent-design.md new file mode 100644 index 0000000..6a294d4 --- /dev/null +++ b/docs/superpowers/specs/2026-04-02-ai-agent-design.md @@ -0,0 +1,322 @@ +# AVC 内部 Agent 开发设计方案 + +**日期**: 2026-04-02 +**状态**: 设计中 + +--- + +## 一、需求概述 + +### 1.1 背景 + +为 AVC 内部设计开发 AI Agent 平台,用于: +- 智能助手/问答(查询政策、制度、流程文档) +- 业务流程自动化(审批、数据录入、报表生成) +- 数据分析/决策支持 +- 客户服务/工单处理 + +### 1.2 约束条件 + +- 大型企业(500-2000人) +- 完全私有化部署,数据不出公司 +- **国产 LLM**(通义千问/Qwen、智谱/ChatGLM 等)在本地 GPU 运行 +- 多端访问:网页 + 嵌入现有后台 + 企业IM + API +- 全数据源接入:文档、数据库(SQL Server)、业务系统API、文件 +- 单租户架构(多租户后期考虑) + +--- + +## 二、整体架构 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 多端访问层 │ +│ (Web客户端 │ 嵌入现有后台 │ 企业IM(钉钉/飞书) │ REST API) │ +└─────────────────────────┬───────────────────────────────────────┘ + │ +┌─────────────────────────▼───────────────────────────────────────┐ +│ API 网关层 │ +│ (认证 · 鉴权 · 限流 · 日志) │ +└─────────────────────────┬───────────────────────────────────────┘ + │ +┌─────────────────────────▼───────────────────────────────────────┐ +│ LangChain Agent 编排层 │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ 问答 Agent │ │ 自动化 Agent │ │ 分析 Agent │ │ +│ │ (RAG+Vector) │ │ (RPA+Tools) │ │ (DB+API) │ │ +│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ +│ │ │ │ │ +│ ┌──────▼─────────────────▼─────────────────▼───────┐ │ +│ │ LangChain Core / LangGraph │ │ +│ │ (Agent Executor · Tool Router) │ │ +│ └─────────────────────────┬─────────────────────────┘ │ +└─────────────────────────────┼─────────────────────────────────────┘ + │ +┌─────────────────────────────▼─────────────────────────────────────┐ +│ 工具层 (Tools) │ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ SQL Svr │ │ HTTP API│ │File Parse│ │ RAG搜索 │ ... │ +│ │ Query │ │ Call │ │(Excel/ │ │ (向量检索)│ │ +│ │ │ │ │ │Word/PDF) │ │ │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ ┌──────────┐ ┌──────────┐ │ +│ │ Python │ │ Msg │ │ +│ │ Script │ │ Send │ │ +│ └──────────┘ └──────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 三、核心组件 + +| 组件 | 技术选型 | 职责 | +|------|---------|------| +| **Agent 框架** | LangChain / LangGraph | Agent 编排、推理循环、Tool 调度 | +| **RAG 引擎** | LangChain VectorStore + Embedding | 企业知识库检索 | +| **向量数据库** | Milvus | 文本向量存储与检索 | +| **Embedding 模型** | 本地 BGE / XInference | 文本向量化 | +| **LLM 推理** | vLLM + 国产模型(Qwen/ChatGLM) | 大语言模型推理(国产化) | +| **工具层** | LangChain Tools | DB查询、API调用、文件处理等 | +| **API 服务** | FastAPI | 对外接口、多端接入 | +| **任务队列** | Celery + Redis | 异步任务处理 | +| **主数据库** | SQL Server | Agent 记忆、对话历史、配置存储 | + +--- + +## 四、Router 设计 + +### 4.1 混合路由策略 + +采用 **规则 + 小模型 LLM 混合路由**,优先级: + +1. **规则优先匹配**:高频、明确意图(如"发邮件"、"查考勤") +2. **小模型意图分类**:中频、可描述的意图 +3. **大模型路由兜底**:复杂、模糊意图 + +### 4.2 意图分类 + +| 意图类型 | 标识 | 示例 | +|---------|------|------| +| 问答类 | `qa` | "年假有多少天?"、"如何申请设备维修?" | +| 自动化类 | `automation` | "帮我给张三发邮件说会议改到下午3点" | +| 分析类 | `analysis` | "统计一下各部门本月报销金额" | + +### 4.3 路由实现伪代码 + +```python +def classify_intent(query: str) -> str: + """ + 规则优先,匹配则直接返回 + 未命中则调用小模型分类 + """ + # 规则匹配 + for rule in intent_rules: + if rule.matches(query): + return rule.intent + + # 小模型分类 + return llm_small.invoke( + f"判断意图类型:qa/automation/analysis\n问题:{query}" + ).content.strip() +``` + +### 4.4 插件化扩展 + +```python +class BaseAgent(ABC): + name: str + description: str + tools: list[BaseTool] + + @abstractmethod + def run(self, query: str) -> str: + pass + +class AgentRegistry: + _agents: dict[str, BaseAgent] = {} + + @classmethod + def register(cls, agent: BaseAgent): + cls._agents[agent.name] = agent +``` + +新增 Agent 只需: +```python +@AgentRegistry.register +class NewAgent(BaseAgent): + name = "new_agent" + description = "处理XXX类型问题" + tools = [tool1, tool2] +``` + +--- + +## 五、工具层设计 + +### 5.1 工具列表 + +| 工具 | 输入 | 输出 | 说明 | +|------|------|------|------| +| **MySQLQueryTool** | SQL 查询语句 | JSON 数组 | 只读查询,支持超时保护 | +| **HttpApiTool** | URL + Method + Body | JSON 响应 | 封装常见 HTTP 方法,自动重试 | +| **FileParserTool** | 文件路径 | 文本内容 | 支持 xlsx/docx/pdf/txt,自动提取结构化数据 | +| **RAGSearchTool** | 自然语言查询 | Top-K 相关文本块 | 配合向量库,返回知识库检索结果 | +| **PythonScriptTool** | 脚本内容 + 参数 | JSON 结果 | 沙箱执行,用于复杂数据处理 | +| **MessageSendTool** | 接收人 + 内容 + 渠道 | 发送状态 | 支持邮件/钉钉/飞书/企业微信 | + +### 5.2 工具架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ Tools 层 │ +├─────────────┬─────────────┬─────────────┬─────────────────┤ +│ SQL Server │ HTTP API │ File Parse │ RAG Search │ +│ Query │ Call │ (Excel/ │ (Milvus) │ +│ │ │ Word/PDF) │ │ +├─────────────┼─────────────┼─────────────┼─────────────────┤ +│ Script Run │ Msg Send │ ...更多工具可扩展 │ +│ (Python) │ (邮件/IM) │ │ │ +└─────────────┴─────────────┴─────────────┴─────────────────┘ +``` + +--- + +## 六、数据流设计 + +### 6.1 用户查询完整流程 + +``` +用户输入 + │ + ▼ +┌─────────────┐ +│ FastAPI │ ← 限流、日志记录 +└──────┬──────┘ + │ + ▼ +┌─────────────┐ +│ Router │ ← 规则匹配 → 小模型分类 +└──────┬──────┘ + │ + ▼ +┌─────────────────────────────────────────┐ +│ LangGraph Agent │ +│ │ +│ ┌─────────────────────────────────┐ │ +│ │ LLM (国产模型: Qwen/ChatGLM) │ │ +│ │ reasoning + tool calling │ │ +│ └───────────────┬─────────────────┘ │ +│ │ │ +│ ┌────────▼────────┐ │ +│ │ Tool Router │ │ +│ │ (选择合适的tool)│ │ +│ └────────┬────────┘ │ +│ │ │ +│ ┌────────▼────────┐ │ +│ │ Tool Executor │ │ +│ │ (并行执行tools) │ │ +│ └────────┬────────┘ │ +│ │ │ +│ ┌────────▼────────┐ │ +│ │ Response │ │ +│ │ Synthesizer │ │ +│ │ (整合tool结果) │ │ +│ └─────────────────┘ │ +└──────────────────┬──────────────────────┘ + │ + ▼ + ┌─────────────┐ + │ 返回用户 │ + └─────────────┘ +``` + +--- + +## 七、错误处理策略 + +| 错误类型 | 处理策略 | +|---------|---------| +| **LLM 超时/宕机** | 自动切换备用模型;返回"服务暂时不可用,请稍后重试" | +| **Tool 执行失败** | 重试 3 次 → 失败则返回错误信息 + 部分结果 | +| **数据库连接失败** | 返回"数据库暂时不可用";记录错误日志 | +| **文件解析失败** | 返回"文件格式不支持或文件损坏" | +| **RAG 检索为空** | 返回"未找到相关内容,建议换个问法" | +| **恶意注入攻击** | SQL/指令注入检测;敏感操作需二次确认 | + +--- + +## 八、存储层设计 + +| 用途 | 技术选型 | 说明 | +|------|---------|------| +| **向量数据库** | Milvus | 企业文档向量存储,RAG 检索用 | +| **知识库原始文档** | MinIO / 本地文件系统 | 存储原始文档(PDF/Word/Excel) | +| **主业务数据库** | SQL Server | Agent 记忆、对话历史、配置存储 | +| **任务状态** | Redis + Celery | 异步任务队列、任务状态 | +| **日志存储** | Elasticsearch + Loki | 请求日志、Agent 执行日志 | + +--- + +## 九、部署架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 内网环境 │ +│ │ +│ ┌─────────────┐ │ +│ │ 用户端 │ ← Web / 嵌入后台 / 钉钉 / API │ +│ └──────┬──────┘ │ +│ │ │ +│ ┌──────▼──────┐ │ +│ │ FastAPI │ │ +│ └──────┬──────┘ │ +│ │ │ +│ ┌──────▼──────┐ │ +│ │ Router │ ← 规则 + 小模型混合路由 │ +│ └──────┬──────┘ │ +│ │ │ +│ ┌──────▼──────────────────────────────┐ │ +│ │ LangChain Agent 集群 │ │ +│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ +│ │ │ QA Agent │ │Auto Agent│ │Analysis │ │ │ +│ │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ +│ └───────┼────────────┼────────────┼───────┘ │ +│ │ │ │ │ +│ ┌───────▼────────────▼────────────▼───────┐ │ +│ │ Tools 层 │ │ +│ │ (SQL Server │ API │ 文件解析 │ RAG) │ │ +│ └──────────────────────────────────────────┘ │ +│ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ vLLM │ │ Milvus │ │ SQL Server │ │ +│ │ (国产模型) │ │ (向量库) │ │ (主库) │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +└─────────────────────────────────────────────────────────────┘ +``` + +--- + +## 十、技术选型总结 + +| 模块 | 技术选型 | +|------|---------| +| Agent 框架 | LangChain / LangGraph | +| Router | 规则 + 小模型混合意图分类 | +| Agent 类型 | QA Agent、Automation Agent、Analysis Agent | +| 工具层 | SQL Server 查询、HTTP API 调用、文件解析、RAG 检索、脚本执行、消息发送 | +| 向量库 | Milvus | +| LLM 推理 | vLLM + 国产模型(Qwen 通义千问 / 智谱 ChatGLM) | +| 主数据库 | SQL Server | +| 任务队列 | Redis + Celery | +| 访问端 | Web + 嵌入后台 + 钉钉/飞书 + API | + +--- + +## 十一、后续步骤 + +1. 编写详细实现方案(implementation plan) +2. 确定开发优先级和里程碑 +3. 开始原型开发 diff --git a/docs/superpowers/specs/2026-04-02-quote-deadline-email-notification-design.md b/docs/superpowers/specs/2026-04-02-quote-deadline-email-notification-design.md new file mode 100644 index 0000000..8991936 --- /dev/null +++ b/docs/superpowers/specs/2026-04-02-quote-deadline-email-notification-design.md @@ -0,0 +1,93 @@ +# 报价截止时间到期邮件通知采购 — 设计文档 + +## 1. 需求概述 + +每 5 分钟轮询 `pissupplier.QuotationMaster`,找出已到期(`quote_deadline < now`)但仍未报价(`status ∈ {1 待报价, 2 报价中}`)的报价单,按**询价单维度**合并发送一封邮件给采购负责人,每天最多一次。 + +## 2. 触发条件 + +- **字段**:`pissupplier.QuotationMaster.quote_deadline` 和 `status` +- **逻辑**:`quote_deadline < now` 且 `status in (1, 2)` +- **轮询间隔**:Celery Beat 每 5 分钟 + +## 3. 通知逻辑 + +### 3.1 合并规则 +- 按 `inquiry_no` 分组,同一询价单下所有到期未报价的供应商合并到一封邮件 +- 避免邮件轰炸 + +### 3.2 去重规则 +- 复用现有 `should_send_quote_timeout_reminder(inquiry_no, cooldown_hours=24)` 按 `inquiry_no` 做 24 小时冷却期 +- 已发送过(EmailNotice.biz_type="inquiry_quote_timeout" + status="success")的询价单跳过 + +### 3.3 收件人 +- 仅「采购负责人」(buyer),对应 Inquiry.buyer 字段 +- 复用现有 `resolve_inquiry_purchaser_emails` 函数 + +### 3.4 邮件内容 +- 字段:询价单名称、编号、报价截止时间、到期供应商列表、比价页面链接 +- 模板:参考 `backend/templates/emails/quote_timeout_body.html` + +## 4. 数据流 + +``` +Celery Beat (每5分钟) + └── check_quote_deadline_expired() [Celery Task] + ├── 查询所有 status∈{1,2} 且 quote_deadline < now 的 QuotationMaster + ├── 按 inquiry_no 分组 + ├── 对每个 inquiry_no: + │ ├── 检查24h冷却期(should_send_quote_timeout_reminder) + │ ├── 查找 Inquiry,获取采购负责人邮箱 + │ ├── 渲染邮件内容(过期供应商列表) + │ └── 发送邮件(send_email_notice) + └── 写 EmailNotice 记录(biz_type="inquiry_quote_timeout") +``` + +## 5. 新增文件 + +| 文件路径 | 说明 | +|---|---| +| `backend/apps/pisadmin/miscprocurement/tasks.py` | Celery 定时任务:轮询报价截止时间、发送邮件 | + +## 6. 修改文件 + +| 文件路径 | 修改内容 | +|---|---| +| `backend/application/celery.py` | 注册 Celery Beat Schedule(新增 `check_quote_deadline_expired` 任务) | + +## 7. 核心任务函数签名 + +```python +@app.task +def check_quote_deadline_expired() -> dict: + """ + Celery Beat 定时任务:轮询报价截止时间已到期的报价单, + 按询价单合并发送邮件通知采购负责人,每天最多一次。 + + Returns: {"checked": N, "sent": M, "skipped": K} + """ +``` + +## 8. Celery Beat Schedule 配置 + +```python +CELERY_BEAT_SCHEDULE = { + "check-quote-deadline-expired": { + "task": "apps.pisadmin.miscprocurement.tasks.check_quote_deadline_expired", + "schedule": crontab(minute="*/5"), # 每5分钟 + }, +} +``` + +## 9. 已有可复用代码 + +- `apps.pisadmin.basicinfo.views.email_utils.send_quote_timeout_notice_to_purchaser` — 单封邮件发送 +- `apps.pisadmin.basicinfo.views.email_utils.should_send_quote_timeout_reminder` — 24h冷却期判断 +- `apps.pisadmin.basicinfo.views.email_utils.resolve_inquiry_purchaser_emails` — 采购负责人邮箱解析 +- `apps.pisadmin.basicinfo.views.email_utils.send_email_notice` — 邮件发送底层 +- `backend/templates/emails/quote_timeout_body.html` — 邮件模板 + +## 10. 异常处理 + +- 邮件发送失败不影响其他询价单处理,记录异常日志 +- Celery 任务失败自动重试(最多3次,间隔3分钟) diff --git a/docs/superpowers/specs/2026-04-03-git-collaboration-design.md b/docs/superpowers/specs/2026-04-03-git-collaboration-design.md new file mode 100644 index 0000000..3e3683c --- /dev/null +++ b/docs/superpowers/specs/2026-04-03-git-collaboration-design.md @@ -0,0 +1,270 @@ +# Git 协作规范设计 + +> 创建日期:2026-04-03 +> 状态:已批准 +> 关联:Git 协作标准化 + +--- + +## 1. 分支模型 + +采用标准 Git Flow。 + +``` +main ──────────────────────────── 生产环境(受保护,禁止直接 push) + ↑ + │ ← hotfix/xxx(从 main 分出,修复完成需合并回 main + develop) + │ +develop ───────────────────────── 开发集成主线(受保护,禁止直接 push) + ↑ + │ ← feature/xxx(从 develop 分出,功能完成后合并回 develop) + │ ← bugfix/xxx(从 develop 分出,develop 上的 bug 修复) +``` + +### 分支命名规范 + +| 分支类型 | 命名格式 | 示例 | +|---------|---------|------| +| Feature | `feature/功能描述` 或 `feature/ISSUE号-功能描述` | `feature/PIS-123-user-auth` | +| Bugfix | `bugfix/问题描述` 或 `bugfix/ISSUE号-修复描述` | `bugfix/PIS-456-login-timeout` | +| Hotfix | `hotfix/紧急修复描述` | `hotfix/critical-payment-fix` | + +### 分支生命周期 + +- **创建**:`git checkout develop && git pull && git checkout -b feature/xxx` +- **同步上游**:`git merge develop` 或 `git rebase develop` +- **完成合并后**:分支自动删除(GitHub/GitLab 设置 `delete branch after merge`) + +--- + +## 2. PR/MR 流程 + +### 标准流程 + +``` +1. 从 develop 创建分支 +2. 开发并 commit(保持原子性) +3. Push 到远程 +4. 创建 PR,填写模板 +5. 指定 Reviewer +6. 等待 Review 通过 +7. Jenkins CI 构建通过 +8. 合并到 develop +9. 分支自动删除 +``` + +### PR 模板 + +```markdown +## 变更描述 + + +## 关联需求 + + +## 变更类型 +- [ ] Feature +- [ ] Bugfix +- [ ] Hotfix +- [ ] Refactor + +## 自检清单 +- [ ] 代码已通过 Pre-commit 检查 +- [ ] 已添加必要的测试 +- [ ] 文档已更新(如需) + +## Reviewer 备注 + +``` + +### 合并标准 + +- 至少 **1 人** Approve +- **Jenkins CI** 构建通过 +- 无未解决的 Conversation +- 分支已最新(解决与目标分支的冲突) + +--- + +## 3. Code Review 规范 + +### 作者职责 + +- 代码逻辑复杂处添加必要注释 +- 准备好回复 Review 意见 +- **不要在 Review 前自行合并** +- 不要在 PR 中混入不相关的改动 + +### Reviewer 职责 + +- **24 小时内**完成 Review +- 聚焦:逻辑正确性、代码风格、安全隐患 +- 评价客观,避免个人偏好带入 +- 确认 Jenkins CI 状态 + +### 合并门槛 + +``` +最低 1 人 Approve + CI 通过 → 可合并 +``` + +--- + +## 4. Git Hooks + +后端和前端分开管理,各自使用最合适的工具。 + +### 后端(Python)— pre-commit + +**安装方式:** +```bash +cd backend +pip install pre-commit commitlint +pre-commit install +``` + +**检查内容:** +- Python:`flake8`、`black` +- 通用:禁止 debug 代码、敏感信息检查 + +**.pre-commit-config.yaml 示例:** +```yaml +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: check-yaml + - id: check-added-large-files + + - repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + args: [--max-line-length=120] +``` + +### 前端(Node.js)— husky + +**安装方式:** +```bash +cd web +npm install husky lint-staged -D +npx husky install +npx husky add .husky/pre-commit "npx lint-staged" +``` + +**package.json lint-staged 配置:** +```json +{ + "lint-staged": { + "*.{js,vue,ts}": ["eslint --fix", "prettier --write"] + } +} +``` + +--- + +## 5. Git Etiquette + +### 鼓励的行为 + +``` +✅ Commit Often — 小步提交,每次有清晰改动 +✅ 保持 commit 原子性 — 一个 commit 只做一件事 +✅ 提交前本地跑测试 — 不要把坏代码推向远程 +✅ Review 通过后再合并 — 不要绕过 Review +✅ 功能完成后及时开 PR — 不要等代码变坏 +✅ 同步上游分支 — 经常 pull/rebase develop 减少冲突 +``` + +### 禁止的行为 + +``` +❌ 不要 push WIP(未完成的工作)到远程主分支 +❌ 不要强制 push(git push --force)到 main/develop +❌ 不要在 PR 里混入不相关的改动 +❌ 不要跳过 Pre-commit 直接 commit +``` + +--- + +## 6. CI/CD 联动(Jenkins) + +### Pre-commit(本地) + +- 在开发者本地运行 +- 不阻塞远程,但作为质量门槛 +- 失败则无法 commit(可 --no-verify 绕过,但不推荐) + +### Jenkins Pipeline + +``` +Push → 自动触发 Jenkins Build + ├── Backend + │ ├── 单元测试 (pytest) + │ ├── 代码检查 (flake8) + │ └── 构建 + │ + ├── Frontend + │ ├── 依赖安装 + │ ├── ESLint 检查 + │ ├── 构建 + │ └── 预览部署 + │ + └── 结果通知(可选:邮件/Slack) +``` + +### 部署规则 + +| 合并目标 | 触发动作 | +|---------|---------| +| `main` | 自动部署到生产环境(可选,视团队节奏) | +| `develop` | 自动部署到测试环境 | + +--- + +## 7. 分支保护规则 + +### main(生产环境) + +- ❌ 禁止直接 push +- ❌ 禁止 force push +- ✅ 必须通过 PR 合并 +- ✅ 必须有 CI 通过 +- ✅ 必须有 1 人 Approve + +### develop(开发主线) + +- ❌ 禁止直接 push +- ❌ 禁止 force push +- ✅ 必须通过 PR 合并 +- ✅ 必须有 CI 通过 + +### feature/bugfix/hotfix + +- 可直接 push +- 鼓励通过 PR 协作 + +--- + +## 8. 工具链汇总 + +| 环节 | 工具 | 适用范围 | +|-----|------|---------| +| Git Hooks(后端) | pre-commit | backend/ | +| Git Hooks(前端) | husky + lint-staged | web/ | +| CI/CD | Jenkins | 全项目 | +| 代码风格(后端) | flake8, black | backend/ | +| 代码风格(前端) | eslint, prettier | web/ | + +--- + +## 设计决策 + +1. **分支模型**:标准 Git Flow,平衡了规范性和灵活性 +2. **Review 门槛**:1 人 Approve,门槛适中不过度拖延 +3. **Hook 管理**:后端 pre-commit、前端 husky,各自用最合适的工具 +4. **分支合并后自动删除**:保持仓库整洁 +5. **CI 联动**:Jenkins 覆盖构建和测试,不重复造轮子 diff --git a/make.ps1 b/make.ps1 new file mode 100644 index 0000000..bd20567 --- /dev/null +++ b/make.ps1 @@ -0,0 +1,202 @@ +# ============================================================ +# PIS Project Startup Script - Windows PowerShell Makefile +# ============================================================ +# Usage: +# .\make.ps1 help Show all commands +# .\make.ps1 dev Start dev environment (frontend + backend + Celery) +# .\make.ps1 dev-backend Start backend only +# .\make.ps1 dev-frontend Start frontend only +# .\make.ps1 dev-celery Start Celery only +# .\make.ps1 stop Stop all services +# .\make.ps1 status Check service status +# .\make.ps1 logs View all logs +# .\make.ps1 logs-backend View backend logs +# .\make.ps1 logs-frontend View frontend logs +# .\make.ps1 logs-celery View Celery logs +# .\make.ps1 restart Restart all services +# .\make.ps1 restart-celery Restart Celery +# ============================================================ + +param( + [string]$Target = "help", + [string]$ENV = "dev" +) + +$ErrorActionPreference = "Continue" +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = $ScriptDir +$ScriptsDir = Join-Path $ProjectRoot "scripts" + +# Path configuration +$PID_DIR = Join-Path $ProjectRoot ".pids" +$LOG_DIR = Join-Path $ProjectRoot "backend\logs" + +function Ensure-Directories { + if (!(Test-Path $PID_DIR)) { New-Item -ItemType Directory -Path $PID_DIR -Force | Out-Null } + if (!(Test-Path $LOG_DIR)) { New-Item -ItemType Directory -Path $LOG_DIR -Force | Out-Null } +} + +function Run-Script { + param([string]$ScriptName) + $scriptPath = Join-Path $ScriptsDir "$ScriptName.ps1" + if (Test-Path $scriptPath) { + & $scriptPath $ENV + } else { + # fallback to bash if ps1 doesn't exist + $bashPath = Join-Path $ScriptsDir "$ScriptName.sh" + if (Test-Path $bashPath) { + bash $bashPath $ENV + } else { + Write-Host "[ERROR] Script not found: $ScriptName" + exit 1 + } + } +} + +switch ($Target.ToLower()) { + "help" { + Write-Host "" + Write-Host "========================================" + Write-Host " PIS Project Startup Script (ENV=$ENV)" + Write-Host "========================================" + Write-Host "" + Write-Host " Startup Commands:" + Write-Host " .\make.ps1 dev Start dev environment (frontend+backend+Celery)" + Write-Host " .\make.ps1 dev-backend Start backend only" + Write-Host " .\make.ps1 dev-frontend Start frontend only" + Write-Host " .\make.ps1 dev-celery Start Celery only" + Write-Host "" + Write-Host " Stop/Restart:" + Write-Host " .\make.ps1 stop Stop all services" + Write-Host " .\make.ps1 restart Restart all services" + Write-Host " .\make.ps1 restart-celery Restart Celery" + Write-Host "" + Write-Host " View Logs:" + Write-Host " .\make.ps1 logs View all logs" + Write-Host " .\make.ps1 logs-backend View backend logs" + Write-Host " .\make.ps1 logs-frontend View frontend logs" + Write-Host " .\make.ps1 logs-celery View Celery logs" + Write-Host "" + Write-Host " Status:" + Write-Host " .\make.ps1 status Check service status" + Write-Host "" + Write-Host " Environment:" + Write-Host " .\make.ps1 -ENV prod dev Use production environment" + Write-Host "" + Write-Host "========================================" + } + + "dev" { + Ensure-Directories + Write-Host "========================================" + Write-Host " Starting Dev Environment (ENV=$ENV)" + Write-Host "========================================" + Write-Host "" + Write-Host " Backend: http://localhost:8000" + Write-Host " Frontend: http://localhost:8080" + Write-Host " Celery: Worker + Beat" + Write-Host "" + Run-Script "start-backend" + Run-Script "start-frontend" + Run-Script "start-celery" + } + + "dev-backend" { + Ensure-Directories + Write-Host "Starting backend service (ENV=$ENV)..." + Run-Script "start-backend" + } + + "dev-frontend" { + Write-Host "Starting frontend service (ENV=$ENV)..." + Run-Script "start-frontend" + } + + "dev-celery" { + Ensure-Directories + Write-Host "Starting Celery (ENV=$ENV)..." + Run-Script "start-celery" + } + + "stop" { + Write-Host "Stopping all services..." + Run-Script "stop-all" + Write-Host "All services stopped" + } + + "restart" { + Write-Host "Restarting all services..." + Run-Script "stop-all" + Start-Sleep -Seconds 2 + Ensure-Directories + Run-Script "start-backend" + Run-Script "start-frontend" + Run-Script "start-celery" + } + + "restart-celery" { + Run-Script "stop-celery" + Start-Sleep -Seconds 1 + Ensure-Directories + Run-Script "start-celery" + } + + "logs" { + Write-Host "========================================" + Write-Host " Viewing All Logs (Ctrl+C to exit)" + Write-Host "========================================" + Run-Script "view-logs" + } + + "logs-backend" { + Write-Host "========================================" + Write-Host " Viewing Backend Logs (Ctrl+C to exit)" + Write-Host "========================================" + & (Join-Path $ScriptsDir "view-logs.ps1") backend + } + + "logs-frontend" { + Write-Host "========================================" + Write-Host " Viewing Frontend Logs (Ctrl+C to exit)" + Write-Host "========================================" + & (Join-Path $ScriptsDir "view-logs.ps1") frontend + } + + "logs-celery" { + Write-Host "========================================" + Write-Host " Viewing Celery Logs (Ctrl+C to exit)" + Write-Host "========================================" + & (Join-Path $ScriptsDir "view-logs.ps1") celery + } + + "status" { + Write-Host "========================================" + Write-Host " Service Status Check" + Write-Host "========================================" + Run-Script "check-status" + } + + "clean-logs" { + Write-Host "Cleaning log files..." + if (Test-Path $LOG_DIR) { + Get-ChildItem $LOG_DIR -Filter "*.log" | Remove-Item -Force -ErrorAction SilentlyContinue + } + Write-Host "Logs cleaned" + } + + "clean-pids" { + Write-Host "Cleaning PID files..." + if (Test-Path $PID_DIR) { + Get-ChildItem $PID_DIR -Filter "*.pid" | Remove-Item -Force -ErrorAction SilentlyContinue + } + Write-Host "PID files cleaned" + } + + default { + Write-Host "[ERROR] Unknown command: $Target" + Write-Host "Run '.\make.ps1 help' to see available commands" + exit 1 + } +} + +exit 0 diff --git a/scripts/check-status.ps1 b/scripts/check-status.ps1 new file mode 100644 index 0000000..52fdb1d --- /dev/null +++ b/scripts/check-status.ps1 @@ -0,0 +1,103 @@ +# ============================================================ +# Check Service Status (Windows PowerShell) +# ============================================================ + +$ErrorActionPreference = "Continue" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +$PID_DIR = Join-Path $ProjectRoot ".pids" + +function Test-ServicePort { + param([int]$Port) + try { + $tcpClient = New-Object System.Net.Sockets.TcpClient + $tcpClient.Connect("localhost", $Port) + $tcpClient.Close() + return $true + } catch { + return $false + } +} + +function Check-Service { + param([string]$Name, [int]$Port = 0) + + Write-Host -NoNewline " $Name`: " + + $pidFile = Join-Path $PID_DIR "$Name.pid" + + if (Test-Path $pidFile) { + $pid = Get-Content $pidFile -ErrorAction SilentlyContinue + if ($pid) { + $proc = Get-Process -Id $pid -ErrorAction SilentlyContinue + if ($proc) { + Write-Host "Running (PID: $pid)" + return 0 + } + } + } + + # Check process name - PowerShell 5.1 compatible using WMI + $patterns = @{ + "backend" = @("uvicorn", "gunicorn", "python") + "frontend" = @("node", "npm") + "celery_worker" = @("celery") + "celery_beat" = @("celery") + } + + if ($patterns.ContainsKey($Name)) { + foreach ($pattern in $patterns[$Name]) { + # Use WMI for reliable cross-version process matching + $wmiQuery = "SELECT ProcessId, Name, CommandLine FROM Win32_Process WHERE Name LIKE '%$pattern%'" + $procs = Get-WmiObject -Query $wmiQuery -ErrorAction SilentlyContinue | Select-Object -First 1 + if ($procs) { + Write-Host "Running (PID: $($procs.ProcessId))" + return 0 + } + } + } + + # Check port + if ($Port -gt 0) { + if (Test-ServicePort -Port $Port) { + Write-Host "Running (Port: $Port)" + return 0 + } + } + + Write-Host "Not running" + return 1 +} + +Write-Host "" +Write-Host "========================================" +Write-Host " Service Status Check" +Write-Host "========================================" +Write-Host "" + +Check-Service "backend" 8000 +Check-Service "frontend" 8080 +Check-Service "celery_worker" +Check-Service "celery_beat" +Write-Host "" + +# Port check +Write-Host "Port Check:" + +Write-Host -NoNewline " 8000 (backend): " +if (Test-ServicePort -Port 8000) { + Write-Host "Open" +} else { + Write-Host "Closed" +} + +Write-Host -NoNewline " 8080 (frontend): " +if (Test-ServicePort -Port 8080) { + Write-Host "Open" +} else { + Write-Host "Closed" +} + +Write-Host "" +exit 0 diff --git a/scripts/check-status.sh b/scripts/check-status.sh new file mode 100644 index 0000000..afc91df --- /dev/null +++ b/scripts/check-status.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# ============================================================ +# Check Service Status +# 使用方法: ./check-status.sh +# ============================================================ + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +PID_DIR="$PROJECT_ROOT/.pids" + +check_service() { + local name=$1 + local pid_file="$PID_DIR/$name.pid" + local port=$2 + + echo -n " $name: " + + if [ -f "$pid_file" ]; then + local pid=$(cat "$pid_file") + if kill -0 "$pid" 2>/dev/null; then + echo "运行中 (PID: $pid)" + return 0 + fi + fi + + # 检查进程名 + local pids=$(pgrep -f "$name" 2>/dev/null | head -1 || true) + if [ -n "$pids" ]; then + echo "运行中 (PID: $pids)" + return 0 + fi + + # 检查端口 + if [ -n "$port" ]; then + if nc -z localhost "$port" 2>/dev/null; then + echo "运行中 (端口: $port)" + return 0 + fi + fi + + echo "未运行" + return 1 +} + +echo "" +check_service "backend" "8000" +check_service "frontend" "8080" +check_service "celery_worker" "" +check_service "celery_beat" "" +echo "" + +# 端口检查 +echo "端口检查:" +echo -n " 8000 (后端): " +nc -z localhost 8000 2>/dev/null && echo "开放" || echo "未开放" + +echo -n " 8080 (前端): " +nc -z localhost 8080 2>/dev/null && echo "开放" || echo "未开放" + +echo "" diff --git a/scripts/start-backend.ps1 b/scripts/start-backend.ps1 new file mode 100644 index 0000000..8aa37ac --- /dev/null +++ b/scripts/start-backend.ps1 @@ -0,0 +1,83 @@ +# ============================================================ +# Start Backend Service (Windows PowerShell) +# Usage: .\start-backend.ps1 [dev|prod] +# +# NOTE: For best compatibility on Windows, consider using Git Bash: +# bash scripts/start-backend.sh +# +# The PowerShell version uses Start-Process which may have issues +# with some Python servers on Windows. +# ============================================================ + +$ErrorActionPreference = "Stop" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +$BackendDir = Join-Path $ProjectRoot "backend" +$PID_DIR = Join-Path $ProjectRoot ".pids" +$LOG_DIR = Join-Path $BackendDir "logs" + +$ENV = if ($args[0]) { $args[0] } else { "dev" } + +# Create directories +if (!(Test-Path $PID_DIR)) { New-Item -ItemType Directory -Path $PID_DIR -Force | Out-Null } +if (!(Test-Path $LOG_DIR)) { New-Item -ItemType Directory -Path $LOG_DIR -Force | Out-Null } + +$PID_FILE = Join-Path $PID_DIR "backend.pid" +$LOG_FILE = Join-Path $LOG_DIR "backend.log" + +# Check if already running +if (Test-Path $PID_FILE) { + $PID = Get-Content $PID_FILE -ErrorAction SilentlyContinue + if ($PID -and (Get-Process -Id $PID -ErrorAction SilentlyContinue)) { + Write-Host "[Backend] Already running (PID: $PID), skipping" + exit 0 + } else { + Write-Host "[Backend] Cleaning stale PID file" + Remove-Item $PID_FILE -Force -ErrorAction SilentlyContinue + } +} + + +# Check dependencies +try { + python -c "import uvicorn" 2>$null + if ($LASTEXITCODE -ne 0) { throw "uvicorn not found" } +} catch { + Write-Host "[Error] uvicorn not installed. Run: cd backend && pip install uvicorn" + exit 1 +} + +# Set environment +$env:DJANGO_SETTINGS_MODULE = "application.settings" + +Write-Host "[Backend] Starting service (ENV=$ENV)..." + +# Select startup method based on environment +if ($ENV -eq "prod") { + Write-Host "[Backend] Using gunicorn (production mode)" + Start-Process -FilePath "python" -ArgumentList "-m gunicorn application.asgi:application -c gunicorn_conf.py --daemon -p $PID_FILE" -WorkingDirectory $BackendDir -RedirectStandardOutput $LOG_FILE -RedirectStandardError $LOG_FILE -WindowStyle Hidden +} else { + Write-Host "[Backend] Using uvicorn (development mode with hot reload)" + $proc = Start-Process -FilePath "python" -ArgumentList "main.py" -WorkingDirectory $BackendDir -PassThru -NoNewWindow + $proc.Id | Set-Content $PID_FILE +} + +# Wait for startup +Start-Sleep -Seconds 3 + +# Check if started successfully +if (Test-Path $PID_FILE) { + $PID = Get-Content $PID_FILE + if (Get-Process -Id $PID -ErrorAction SilentlyContinue) { + Write-Host "[Backend] Started successfully (PID: $PID)" + Write-Host "[Backend] Log file: $LOG_FILE" + } else { + Write-Host "[Backend] Failed to start, check log: $LOG_FILE" + Remove-Item $PID_FILE -Force -ErrorAction SilentlyContinue + } +} else { + Write-Host "[Backend] Failed to start, check log: $LOG_FILE" +} + +exit 0 diff --git a/scripts/start-backend.sh b/scripts/start-backend.sh new file mode 100644 index 0000000..b8036ee --- /dev/null +++ b/scripts/start-backend.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# ============================================================ +# Start Backend Service +# 使用方法: ./start-backend.sh [dev|prod] +# ============================================================ + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +BACKEND_DIR="$PROJECT_ROOT/backend" +PID_DIR="$PROJECT_ROOT/.pids" +LOG_DIR="$BACKEND_DIR/logs" + +ENV=${1:-dev} + +# 创建必要的目录 +mkdir -p "$PID_DIR" +mkdir -p "$LOG_DIR" + +PID_FILE="$PID_DIR/backend.pid" +LOG_FILE="$LOG_DIR/backend.log" + +# 检查是否已运行 +if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + echo "[后端] 已运行 (PID: $PID),跳过启动" + exit 0 + else + echo "[后端] 清理旧的 PID 文件" + rm -f "$PID_FILE" + fi +fi + +cd "$BACKEND_DIR" + +# 检查依赖 +if ! python -c "import uvicorn" 2>/dev/null; then + echo "[错误] 未安装 uvicorn,请先: cd backend && pip install uvicorn" + exit 1 +fi + +# 设置环境变量 +export DJANGO_SETTINGS_MODULE="application.settings" + +echo "[后端] 启动服务 (ENV=$ENV)..." + +# 根据环境选择启动方式 +if [ "$ENV" = "prod" ]; then + # 生产环境使用 gunicorn + echo "[后端] 使用 gunicorn 启动 (生产模式)" + nohup python -m gunicorn application.asgi:application \ + -c gunicorn_conf.py \ + --daemon \ + -p "$PID_FILE" \ + >> "$LOG_FILE" 2>&1 +else + # 开发环境使用 uvicorn (带 reload) + echo "[后端] 使用 uvicorn 启动 (开发模式,带热重载)" + nohup python main.py \ + >> "$LOG_FILE" 2>&1 & + + echo $! > "$PID_FILE" +fi + +# 等待启动 +sleep 3 + +# 检查是否成功启动 +if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + echo "[后端] 启动成功 (PID: $PID)" + echo "[后端] 日志文件: $LOG_FILE" + else + echo "[后端] 启动失败,请检查日志: $LOG_FILE" + rm -f "$PID_FILE" + fi +else + # uvicorn 模式 + sleep 2 + if pgrep -f "uvicorn.*application.asgi" > "$PID_FILE" 2>/dev/null; then + echo "[后端] 启动成功 (PID: $(cat $PID_FILE))" + echo "[后端] 日志文件: $LOG_FILE" + else + echo "[后端] 启动失败,请检查日志: $LOG_FILE" + fi +fi diff --git a/scripts/start-celery.ps1 b/scripts/start-celery.ps1 new file mode 100644 index 0000000..8de48a4 --- /dev/null +++ b/scripts/start-celery.ps1 @@ -0,0 +1,152 @@ +# ============================================================ +# Start Celery Services (Windows PowerShell) +# Usage: .\start-celery.ps1 [dev|prod] +# +# IMPORTANT: Celery on Windows has known issues with PowerShell's +# Start-Process. For reliable operation on Windows, use Git Bash instead: +# +# bash scripts/start-celery.sh +# +# The bash script uses nohup which works correctly with Celery's +# multiprocessing pool (billiard). Start-Process in PowerShell +# causes billiard to fail with "PermissionError" or "OSError: handle invalid". +# ============================================================ + +$ErrorActionPreference = "Stop" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +$BackendDir = Join-Path $ProjectRoot "backend" +$PID_DIR = Join-Path $ProjectRoot ".pids" +$LOG_DIR = Join-Path $BackendDir "logs" + +$ENV = if ($args[0]) { $args[0] } else { "dev" } + +# Create directories +if (!(Test-Path $PID_DIR)) { New-Item -ItemType Directory -Path $PID_DIR -Force | Out-Null } +if (!(Test-Path $LOG_DIR)) { New-Item -ItemType Directory -Path $LOG_DIR -Force | Out-Null } + +$WORKER_PID_FILE = Join-Path $PID_DIR "celery_worker.pid" +$BEAT_PID_FILE = Join-Path $PID_DIR "celery_beat.pid" +$PYTHON_EXE = Join-Path $BackendDir ".venv\Scripts\python.exe" +$CELERY_EXE = Join-Path $BackendDir ".venv\Scripts\celery.exe" + +$WORKER_LOG = Join-Path $LOG_DIR "celery_worker.log" +$BEAT_LOG = Join-Path $LOG_DIR "celery_beat.log" + +# Set Django environment for current process +$env:DJANGO_SETTINGS_MODULE = "application.settings" + +# Helper function to find celery process by port or log +function Find-CeleryProcess { + param([string]$Type) + $allProcs = Get-Process -Name "celery" -ErrorAction SilentlyContinue + return $allProcs +} + +# Check if Worker is already running +$workerRunning = $false +$existingWorker = $null +if (Test-Path $WORKER_PID_FILE) { + $PID = Get-Content $WORKER_PID_FILE -ErrorAction SilentlyContinue + if ($PID) { + $existingWorker = Get-Process -Id $PID -ErrorAction SilentlyContinue + if ($existingWorker) { + $workerRunning = $true + Write-Host "[Celery] Worker already running (PID: $PID), skipping" + } + } +} + +if (-not $workerRunning) { + Write-Host "[Celery] Starting Worker..." + + # Check if celery is installed + try { + & $PYTHON_EXE -c "import celery" 2>$null + if ($LASTEXITCODE -ne 0) { throw "celery not found" } + } catch { + Write-Host "[Error] Celery not installed" + exit 1 + } + + # Get count of existing celery processes + $beforeCount = (Get-Process -Name "celery" -ErrorAction SilentlyContinue).Count + + # Start Celery Worker using cmd /c to run in background session + # Using --pool solo --concurrency 1 to avoid Windows multiprocessing issues with billiard + $cmdArgs = "/c cd /d `"$BackendDir`" && set DJANGO_SETTINGS_MODULE=application.settings && start /b /wait cmd /k `"$CELERY_EXE -A application worker -l info --logfile=$WORKER_LOG --pidfile=$WORKER_PID_FILE --pool solo --concurrency 1`"" + Start-Process -FilePath "cmd.exe" -ArgumentList $cmdArgs -WindowStyle Hidden + + # Wait for process to start + Start-Sleep -Seconds 3 + + # Find the new celery worker process + $afterProcs = Get-Process -Name "celery" -ErrorAction SilentlyContinue + $newProc = $afterProcs | Where-Object { $_.Id -ne (Get-Content $BEAT_PID_FILE -ErrorAction SilentlyContinue) } | Select-Object -First 1 + + if ($newProc) { + $newProc.Id | Set-Content $WORKER_PID_FILE + Write-Host "[Celery] Worker started (PID: $($newProc.Id))" + } else { + Write-Host "[Celery] Worker started (process tracking may be inaccurate on Windows)" + } +} + +# Check Beat +$beatRunning = $false +$existingBeat = $null +if (Test-Path $BEAT_PID_FILE) { + $PID = Get-Content $BEAT_PID_FILE -ErrorAction SilentlyContinue + if ($PID) { + $existingBeat = Get-Process -Id $PID -ErrorAction SilentlyContinue + if ($existingBeat) { + $beatRunning = $true + Write-Host "[Celery Beat] Already running (PID: $PID), skipping" + } + } +} + +if (-not $beatRunning) { + Write-Host "[Celery Beat] Starting scheduler..." + + # Get count before + $beforeCount = (Get-Process -Name "celery" -ErrorAction SilentlyContinue).Count + + # Start Celery Beat + $cmdArgs = "/c cd /d `"$BackendDir`" && set DJANGO_SETTINGS_MODULE=application.settings && start /b /wait cmd /k `"$CELERY_EXE -A application beat -l info --logfile=$BEAT_LOG --pidfile=$BEAT_PID_FILE --scheduler django_celery_beat.schedulers:DatabaseScheduler`"" + Start-Process -FilePath "cmd.exe" -ArgumentList $cmdArgs -WindowStyle Hidden + + # Wait for process to start + Start-Sleep -Seconds 3 + + # Find the new celery beat process + $afterProcs = Get-Process -Name "celery" -ErrorAction SilentlyContinue + $newBeat = $afterProcs | Select-Object -Last 1 + + if ($newBeat) { + $newBeat.Id | Set-Content $BEAT_PID_FILE + Write-Host "[Celery Beat] Started (PID: $($newBeat.Id))" + } else { + Write-Host "[Celery Beat] Started (process tracking may be inaccurate on Windows)" + } +} + +# Wait for startup +Start-Sleep -Seconds 3 + +# Show status +if (Test-Path $WORKER_PID_FILE) { + $wpid = Get-Content $WORKER_PID_FILE + Write-Host "[Celery] Worker PID: $wpid" +} +Write-Host "[Celery] Worker log: $WORKER_LOG" + +if (Test-Path $BEAT_PID_FILE) { + $bpid = Get-Content $BEAT_PID_FILE + Write-Host "[Celery Beat] PID: $bpid" +} +Write-Host "[Celery Beat] log: $BEAT_LOG" + +Write-Host "[Celery] Startup complete" +exit 0 diff --git a/scripts/start-celery.sh b/scripts/start-celery.sh new file mode 100644 index 0000000..3e42ae6 --- /dev/null +++ b/scripts/start-celery.sh @@ -0,0 +1,99 @@ +#!/bin/bash +# ============================================================ +# Start Celery Services +# 使用方法: ./start-celery.sh [dev|prod] +# ============================================================ + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +BACKEND_DIR="$PROJECT_ROOT/backend" +PID_DIR="$PROJECT_ROOT/.pids" +LOG_DIR="$BACKEND_DIR/logs" + +ENV=${1:-dev} + +# 创建必要的目录 +mkdir -p "$PID_DIR" +mkdir -p "$LOG_DIR" + +WORKER_PID_FILE="$PID_DIR/celery_worker.pid" +BEAT_PID_FILE="$PID_DIR/celery_beat.pid" +WORKER_LOG="$LOG_DIR/celery_worker.log" +BEAT_LOG="$LOG_DIR/celery_beat.log" + +cd "$BACKEND_DIR" + +# 设置 Django 环境 +export DJANGO_SETTINGS_MODULE="application.settings" + +# 检查是否已运行 +check_celery() { + if [ -f "$WORKER_PID_FILE" ]; then + PID=$(cat "$WORKER_PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + return 0 + fi + fi + return 1 +} + +if check_celery; then + echo "[Celery] Worker 已运行,跳过启动" +else + echo "[Celery] 启动 Worker..." + + # 检查 celery 是否安装 + if ! python -c "import celery" 2>/dev/null; then + echo "[错误] Celery 未安装" + exit 1 + fi + + # 启动 Celery Worker + nohup celery -A application worker \ + -l info \ + --logfile="$WORKER_LOG" \ + --pidfile="$WORKER_PID_FILE" \ + >> "$WORKER_LOG" 2>&1 & + + echo "[Celery] Worker 启动命令已执行" +fi + +# 检查 Beat +if [ -f "$BEAT_PID_FILE" ]; then + PID=$(cat "$BEAT_PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + echo "[Celery Beat] 已运行 (PID: $PID),跳过启动" + else + rm -f "$BEAT_PID_FILE" + fi +else + echo "[Celery Beat] 启动调度器..." + + # 启动 Celery Beat + nohup celery -A application beat \ + -l info \ + --logfile="$BEAT_LOG" \ + --pidfile="$BEAT_PID_FILE" \ + --scheduler django_celery_beat.schedulers:DatabaseScheduler \ + >> "$BEAT_LOG" 2>&1 & + + echo "[Celery Beat] 启动命令已执行" +fi + +# 等待检查 +sleep 3 + +# 显示状态 +if [ -f "$WORKER_PID_FILE" ]; then + echo "[Celery] Worker PID: $(cat $WORKER_PID_FILE)" + echo "[Celery] Worker 日志: $WORKER_LOG" +fi + +if [ -f "$BEAT_PID_FILE" ]; then + echo "[Celery Beat] PID: $(cat $BEAT_PID_FILE)" + echo "[Celery Beat] 日志: $BEAT_LOG" +fi + +echo "[Celery] 启动完成" diff --git a/scripts/start-frontend.ps1 b/scripts/start-frontend.ps1 new file mode 100644 index 0000000..546c340 --- /dev/null +++ b/scripts/start-frontend.ps1 @@ -0,0 +1,103 @@ +# ============================================================ +# Start Frontend Service (Windows PowerShell) +# Usage: .\start-frontend.ps1 [dev|prod] +# +# NOTE: For best compatibility on Windows, consider using Git Bash: +# bash scripts/start-frontend.sh +# +# The PowerShell version uses Start-Process which may have issues +# with some Node.js development servers. +# ============================================================ + +$ErrorActionPreference = "Stop" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +$FrontendDir = Join-Path $ProjectRoot "web" +$PID_DIR = Join-Path $ProjectRoot ".pids" +$LOG_DIR = Join-Path $ProjectRoot "backend" +$LOG_DIR = Join-Path $LOG_DIR "logs" + +$ENV = if ($args[0]) { $args[0] } else { "dev" } + +# Create directories +if (!(Test-Path $PID_DIR)) { New-Item -ItemType Directory -Path $PID_DIR -Force | Out-Null } +if (!(Test-Path $LOG_DIR)) { New-Item -ItemType Directory -Path $LOG_DIR -Force | Out-Null } + +$PID_FILE = Join-Path $PID_DIR "frontend.pid" +$LOG_FILE = Join-Path $LOG_DIR "frontend.log" + +# Check if already running +if (Test-Path $PID_FILE) { + $PID = Get-Content $PID_FILE -ErrorAction SilentlyContinue + if ($PID -and (Get-Process -Id $PID -ErrorAction SilentlyContinue)) { + Write-Host "[Frontend] Already running (PID: $PID), skipping" + exit 0 + } else { + Write-Host "[Frontend] Cleaning stale PID file" + Remove-Item $PID_FILE -Force -ErrorAction SilentlyContinue + } +} + + +# Check if yarn is available +$yarnCmd = Get-Command yarn -ErrorAction SilentlyContinue +if (!$yarnCmd) { + Write-Host "[Frontend] yarn not found, trying npm..." + $npmCmd = Get-Command npm -ErrorAction SilentlyContinue + if (!$npmCmd) { + Write-Host "[Error] npm not installed" + exit 1 + } + $useNpm = $true +} else { + $useNpm = $false +} + +# Check dependencies +if (!(Test-Path "node_modules")) { + Write-Host "[Frontend] Dependencies not installed, installing..." + if ($useNpm) { + npm install + } else { + yarn install + } +} + +Write-Host "[Frontend] Starting service (ENV=$ENV)..." + +# Select startup method based on environment +if ($ENV -eq "prod") { + Write-Host "[Frontend] Building production version..." + if ($useNpm) { + npm run build + } else { + yarn build + } + Write-Host "[Frontend] Production build complete, use static server" +} else { + if ($useNpm) { + $proc = Start-Process -FilePath "npm" -ArgumentList "run dev" -WorkingDirectory $FrontendDir -PassThru -NoNewWindow + } else { + $proc = Start-Process -FilePath "yarn" -ArgumentList "dev" -WorkingDirectory $FrontendDir -PassThru -NoNewWindow + } + $proc.Id | Set-Content $PID_FILE +} + +# Wait for startup +Start-Sleep -Seconds 5 + +# Check if started successfully +if (Test-Path $PID_FILE) { + $PID = Get-Content $PID_FILE + if (Get-Process -Id $PID -ErrorAction SilentlyContinue) { + Write-Host "[Frontend] Started successfully (PID: $PID)" + Write-Host "[Frontend] Access: http://localhost:8080" + Write-Host "[Frontend] Log file: $LOG_FILE" + } else { + Write-Host "[Frontend] Failed to start, check log: $LOG_FILE" + Remove-Item $PID_FILE -Force -ErrorAction SilentlyContinue + } +} + +exit 0 diff --git a/scripts/start-frontend.sh b/scripts/start-frontend.sh new file mode 100644 index 0000000..fec6ccb --- /dev/null +++ b/scripts/start-frontend.sh @@ -0,0 +1,72 @@ +#!/bin/bash +# ============================================================ +# Start Frontend Service +# 使用方法: ./start-frontend.sh [dev|prod] +# ============================================================ + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +FRONTEND_DIR="$PROJECT_ROOT/web" +PID_DIR="$PROJECT_ROOT/.pids" +LOG_DIR="$PROJECT_ROOT/backend/logs" + +ENV=${1:-dev} + +# 创建必要的目录 +mkdir -p "$PID_DIR" +mkdir -p "$LOG_DIR" + +PID_FILE="$PID_DIR/frontend.pid" +LOG_FILE="$LOG_DIR/frontend.log" + +# 检查是否已运行 +if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + echo "[前端] 已运行 (PID: $PID),跳过启动" + exit 0 + else + echo "[前端] 清理旧的 PID 文件" + rm -f "$PID_FILE" + fi +fi + +cd "$FRONTEND_DIR" + +# 检查依赖 +if [ ! -d "node_modules" ]; then + echo "[前端] 依赖未安装,正在安装..." + yarn install +fi + +echo "[前端] 启动服务 (ENV=$ENV)..." + +# 根据环境选择启动方式 +if [ "$ENV" = "prod" ]; then + echo "[前端] 构建生产版本..." + yarn build + # 生产环境可以用 nginx 或静态服务器 served + echo "[前端] 生产构建完成,请使用静态服务器 serving" +else + # 开发环境 + nohup yarn dev >> "$LOG_FILE" 2>&1 & + echo $! > "$PID_FILE" +fi + +# 等待启动 +sleep 5 + +# 检查是否成功启动 +if [ -f "$PID_FILE" ]; then + PID=$(cat "$PID_FILE") + if kill -0 "$PID" 2>/dev/null; then + echo "[前端] 启动成功 (PID: $PID)" + echo "[前端] 访问地址: http://localhost:8080" + echo "[前端] 日志文件: $LOG_FILE" + else + echo "[前端] 启动失败,请检查日志: $LOG_FILE" + rm -f "$PID_FILE" + fi +fi diff --git a/scripts/stop-all.ps1 b/scripts/stop-all.ps1 new file mode 100644 index 0000000..8505327 --- /dev/null +++ b/scripts/stop-all.ps1 @@ -0,0 +1,76 @@ +# ============================================================ +# Stop All Services (Windows PowerShell) +# ============================================================ + +$ErrorActionPreference = "Continue" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +$PID_DIR = Join-Path $ProjectRoot ".pids" + +function Stop-ServiceByName { + param([string]$Name, [string]$Pattern) + + $pidFile = Join-Path $PID_DIR "$Name.pid" + + if (Test-Path $pidFile) { + $pid = Get-Content $pidFile -ErrorAction SilentlyContinue + if ($pid) { + $proc = Get-Process -Id $pid -ErrorAction SilentlyContinue + if ($proc) { + Write-Host "[$Name] Stopping service (PID: $pid)..." + Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue + Start-Sleep -Milliseconds 500 + $proc = Get-Process -Id $pid -ErrorAction SilentlyContinue + if ($proc) { + Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue + } + Write-Host "[$Name] Stopped" + } + } + Remove-Item $pidFile -Force -ErrorAction SilentlyContinue + } + + # Try to find by process name + $wmiQuery = "SELECT ProcessId, Name, CommandLine FROM Win32_Process WHERE Name LIKE '%$Pattern%' OR CommandLine LIKE '%$Pattern%'" + $procs = Get-WmiObject -Query $wmiQuery -ErrorAction SilentlyContinue + if ($procs) { + foreach ($p in $procs) { + Write-Host "[$Name] Found by pattern PID: $($p.ProcessId), stopping..." + Stop-Process -Id $p.ProcessId -Force -ErrorAction SilentlyContinue + } + } +} + +# Stop each service +Stop-ServiceByName "backend" "uvicorn" +Stop-ServiceByName "frontend" "node" +Stop-ServiceByName "celery_worker" "celery" +Stop-ServiceByName "celery_beat" "celery" + +# Additional cleanup +Write-Host "[Cleanup] Checking for residual processes..." + +# Cleanup uvicorn +$wmiQuery = "SELECT ProcessId, Name FROM Win32_Process WHERE Name LIKE '%uvicorn%'" +Get-WmiObject -Query $wmiQuery -ErrorAction SilentlyContinue | ForEach-Object { + Write-Host "[Cleanup] Stopping uvicorn (PID: $($_.ProcessId))" + Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue +} + +# Cleanup gunicorn +$wmiQuery = "SELECT ProcessId, Name FROM Win32_Process WHERE Name LIKE '%gunicorn%'" +Get-WmiObject -Query $wmiQuery -ErrorAction SilentlyContinue | ForEach-Object { + Write-Host "[Cleanup] Stopping gunicorn (PID: $($_.ProcessId))" + Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue +} + +# Cleanup node/vite +$wmiQuery = "SELECT ProcessId, Name, CommandLine FROM Win32_Process WHERE Name LIKE '%node%' AND (CommandLine LIKE '%vite%' OR CommandLine LIKE '%dev%')" +Get-WmiObject -Query $wmiQuery -ErrorAction SilentlyContinue | ForEach-Object { + Write-Host "[Cleanup] Stopping vite (PID: $($_.ProcessId))" + Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue +} + +Write-Host "[Done] All services stopped" +exit 0 diff --git a/scripts/stop-all.sh b/scripts/stop-all.sh new file mode 100644 index 0000000..7636c6a --- /dev/null +++ b/scripts/stop-all.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# ============================================================ +# Stop All Services +# 使用方法: ./stop-all.sh +# ============================================================ + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +PID_DIR="$PROJECT_ROOT/.pids" + +stop_service() { + local name=$1 + local pid_file="$PID_DIR/$name.pid" + + if [ -f "$pid_file" ]; then + local pid=$(cat "$pid_file") + if kill -0 "$pid" 2>/dev/null; then + echo "[$name] 停止服务 (PID: $pid)..." + kill "$pid" 2>/dev/null || true + sleep 1 + # 强制停止 + if kill -0 "$pid" 2>/dev/null; then + kill -9 "$pid" 2>/dev/null || true + fi + echo "[$name] 已停止" + else + echo "[$name] 未运行" + fi + rm -f "$pid_file" + else + # 尝试通过进程名查找 + local pids=$(pgrep -f "$name" 2>/dev/null || true) + if [ -n "$pids" ]; then + echo "[$name] 通过进程名找到 PID: $pids,停止..." + echo "$pids" | xargs kill 2>/dev/null || true + fi + fi +} + +# 停止各个服务 +stop_service "backend" +stop_service "frontend" +stop_service "celery_worker" +stop_service "celery_beat" + +# 额外清理残留进程 +echo "[清理] 检查残留进程..." + +# 清理 uvicorn +pkill -f "uvicorn.*application.asgi" 2>/dev/null || true +pkill -f "gunicorn.*application.asgi" 2>/dev/null || true + +# 清理 celery +pkill -f "celery.*worker" 2>/dev/null || true +pkill -f "celery.*beat" 2>/dev/null || true + +# 清理 vite +pkill -f "vite" 2>/dev/null || true + +echo "[完成] 所有服务已停止" diff --git a/scripts/stop-celery.ps1 b/scripts/stop-celery.ps1 new file mode 100644 index 0000000..944226b --- /dev/null +++ b/scripts/stop-celery.ps1 @@ -0,0 +1,45 @@ +# ============================================================ +# Stop Celery Services (Windows PowerShell) +# ============================================================ + +$ErrorActionPreference = "Continue" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +$PID_DIR = Join-Path $ProjectRoot ".pids" + +function Stop-CeleryService { + param([string]$Name) + + $pidFile = Join-Path $PID_DIR "$Name.pid" + + if (Test-Path $pidFile) { + $pid = Get-Content $pidFile -ErrorAction SilentlyContinue + if ($pid) { + $proc = Get-Process -Id $pid -ErrorAction SilentlyContinue + if ($proc) { + Write-Host "[$Name] Stopping (PID: $pid)..." + Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue + Start-Sleep -Milliseconds 500 + $proc = Get-Process -Id $pid -ErrorAction SilentlyContinue + if ($proc) { + Stop-Process -Id $pid -Force -ErrorAction SilentlyContinue + } + } + } + Remove-Item $pidFile -Force -ErrorAction SilentlyContinue + } + + # Cleanup residual + $wmiQuery = "SELECT ProcessId, Name FROM Win32_Process WHERE Name LIKE '%celery%'" + Get-WmiObject -Query $wmiQuery -ErrorAction SilentlyContinue | ForEach-Object { + Write-Host "[Cleanup] Stopping celery (PID: $($_.ProcessId))" + Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue + } +} + +Stop-CeleryService "celery_worker" +Stop-CeleryService "celery_beat" + +Write-Host "[Done] Celery stopped" +exit 0 diff --git a/scripts/stop-celery.sh b/scripts/stop-celery.sh new file mode 100644 index 0000000..207ab21 --- /dev/null +++ b/scripts/stop-celery.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# ============================================================ +# Stop Celery Services +# 使用方法: ./stop-celery.sh +# ============================================================ + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +PID_DIR="$PROJECT_ROOT/.pids" + +stop_celery() { + local name=$1 + local pid_file="$PID_DIR/$name.pid" + local pattern="$2" + + if [ -f "$pid_file" ]; then + local pid=$(cat "$pid_file") + if kill -0 "$pid" 2>/dev/null; then + echo "[$name] 停止 (PID: $pid)..." + kill "$pid" 2>/dev/null || true + sleep 1 + if kill -0 "$pid" 2>/dev/null; then + kill -9 "$pid" 2>/dev/null || true + fi + fi + rm -f "$pid_file" + fi + + # 清理残留 + pkill -f "celery.*$pattern" 2>/dev/null || true +} + +stop_celery "celery_worker" "worker" +stop_celery "celery_beat" "beat" + +echo "[完成] Celery 已停止" diff --git a/scripts/view-logs.ps1 b/scripts/view-logs.ps1 new file mode 100644 index 0000000..3542290 --- /dev/null +++ b/scripts/view-logs.ps1 @@ -0,0 +1,85 @@ +# ============================================================ +# View Logs (Windows PowerShell) +# Usage: .\view-logs.ps1 [backend|frontend|celery|all] +# ============================================================ + +$ErrorActionPreference = "Continue" + +$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path +$ProjectRoot = Split-Path -Parent $ScriptDir +$BackendDir = Join-Path $ProjectRoot "backend" +$LOG_DIR = Join-Path $BackendDir "logs" + +$TARGET = if ($args[0]) { $args[0] } else { "all" } + +# Ensure log directory exists +if (!(Test-Path $LOG_DIR)) { + New-Item -ItemType Directory -Path $LOG_DIR -Force | Out-Null +} + +# Create empty log files if they don't exist +$logFiles = @( + (Join-Path $LOG_DIR "backend.log"), + (Join-Path $LOG_DIR "frontend.log"), + (Join-Path $LOG_DIR "celery_worker.log"), + (Join-Path $LOG_DIR "celery_beat.log") +) +foreach ($log in $logFiles) { + if (!(Test-Path $log)) { New-Item -ItemType File -Path $log -Force | Out-Null } +} + +switch ($TARGET) { + "backend" { + Write-Host "Viewing backend logs: $LOG_DIR\backend.log" + Get-Content (Join-Path $LOG_DIR "backend.log") -Wait -Tail 20 + } + "frontend" { + Write-Host "Viewing frontend logs: $LOG_DIR\frontend.log" + Get-Content (Join-Path $LOG_DIR "frontend.log") -Wait -Tail 20 + } + "celery" { + Write-Host "Viewing Celery logs..." + Write-Host "=== Worker ===" + Get-Content (Join-Path $LOG_DIR "celery_worker.log") -Wait -Tail 10 + } + "all" { + Write-Host "Viewing all logs (Ctrl+C to exit)..." + Write-Host "" + Write-Host "=== Backend Logs ===" + if ((Test-Path (Join-Path $LOG_DIR "backend.log")) -and (Get-Content (Join-Path $LOG_DIR "backend.log") -ErrorAction SilentlyContinue)) { + Get-Content (Join-Path $LOG_DIR "backend.log") -Tail 20 + } else { + Write-Host "(empty)" + } + Write-Host "" + Write-Host "=== Frontend Logs ===" + if ((Test-Path (Join-Path $LOG_DIR "frontend.log")) -and (Get-Content (Join-Path $LOG_DIR "frontend.log") -ErrorAction SilentlyContinue)) { + Get-Content (Join-Path $LOG_DIR "frontend.log") -Tail 20 + } else { + Write-Host "(empty)" + } + Write-Host "" + Write-Host "=== Celery Worker Logs ===" + if ((Test-Path (Join-Path $LOG_DIR "celery_worker.log")) -and (Get-Content (Join-Path $LOG_DIR "celery_worker.log") -ErrorAction SilentlyContinue)) { + Get-Content (Join-Path $LOG_DIR "celery_worker.log") -Tail 20 + } else { + Write-Host "(empty)" + } + Write-Host "" + Write-Host "=== Celery Beat Logs ===" + if ((Test-Path (Join-Path $LOG_DIR "celery_beat.log")) -and (Get-Content (Join-Path $LOG_DIR "celery_beat.log") -ErrorAction SilentlyContinue)) { + Get-Content (Join-Path $LOG_DIR "celery_beat.log") -Tail 20 + } else { + Write-Host "(empty)" + } + Write-Host "" + Write-Host "--- Live monitoring all logs (Ctrl+C to exit) ---" + Get-Content $logFiles -Wait + } + default { + Write-Host "Usage: $PSCommandPath [backend|frontend|celery|all]" + exit 1 + } +} + +exit 0 diff --git a/scripts/view-logs.sh b/scripts/view-logs.sh new file mode 100644 index 0000000..86ec940 --- /dev/null +++ b/scripts/view-logs.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# ============================================================ +# View Logs +# 使用方法: ./view-logs.sh [backend|frontend|celery|all] +# ============================================================ + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" +BACKEND_DIR="$PROJECT_ROOT/backend" +LOG_DIR="$BACKEND_DIR/logs" + +TARGET=${1:-all} + +# 确保日志目录存在 +mkdir -p "$LOG_DIR" + +# 创建空的日志文件(如果不存在) +touch "$LOG_DIR/backend.log" 2>/dev/null || true +touch "$LOG_DIR/frontend.log" 2>/dev/null || true +touch "$LOG_DIR/celery_worker.log" 2>/dev/null || true +touch "$LOG_DIR/celery_beat.log" 2>/dev/null || true + +case "$TARGET" in + backend) + echo "查看后端日志: $LOG_DIR/backend.log" + tail -f "$LOG_DIR/backend.log" + ;; + frontend) + echo "查看前端日志: $LOG_DIR/frontend.log" + tail -f "$LOG_DIR/frontend.log" + ;; + celery) + echo "查看 Celery 日志..." + echo "=== Worker ===" + tail -f "$LOG_DIR/celery_worker.log" & + echo "=== Beat ===" + tail -f "$LOG_DIR/celery_beat.log" + ;; + all) + echo "查看所有日志 (Ctrl+C 退出)..." + echo "" + echo "=== 后端日志 ===" + tail -n 20 "$LOG_DIR/backend.log" 2>/dev/null || echo "(空)" + echo "" + echo "=== 前端日志 ===" + tail -n 20 "$LOG_DIR/frontend.log" 2>/dev/null || echo "(空)" + echo "" + echo "=== Celery Worker 日志 ===" + tail -n 20 "$LOG_DIR/celery_worker.log" 2>/dev/null || echo "(空)" + echo "" + echo "=== Celery Beat 日志 ===" + tail -n 20 "$LOG_DIR/celery_beat.log" 2>/dev/null || echo "(空)" + echo "" + echo "--- 实时监控所有日志 (Ctrl+C 退出) ---" + tail -f "$LOG_DIR/backend.log" "$LOG_DIR/frontend.log" "$LOG_DIR/celery_worker.log" "$LOG_DIR/celery_beat.log" + ;; + *) + echo "用法: $0 [backend|frontend|celery|all]" + exit 1 + ;; +esac diff --git a/web/.env.production b/web/.env.production index 2764313..f60a9ca 100644 --- a/web/.env.production +++ b/web/.env.production @@ -2,10 +2,5 @@ ENV = 'production' # 线上环境接口地址 -# 说明:项目内接口多以 /api/... 作为绝对路径(如 /api/captcha/、/api/init/settings/)。 -# 因此 baseURL 不应再额外带 /api,避免拼接成 /api/api/... -# VITE_API_URL = '/' -VITE_API_URL = 'http://192.168.80.90:8000' - -# 是否启用按钮权限 -VITE_PM_ENABLED = true +# 使用 /api 代理,由 nginx 转发请求到后端容器 +VITE_API_URL = '/api' diff --git a/web/.lintstagedrc.json b/web/.lintstagedrc.json new file mode 100644 index 0000000..a89dec5 --- /dev/null +++ b/web/.lintstagedrc.json @@ -0,0 +1,9 @@ +{ + "*.{js,vue,ts,jsx,tsx}": [ + "eslint --fix", + "prettier --write" + ], + "*.{css,scss,vue}": [ + "prettier --write" + ] +} diff --git a/web/Dockerfile b/web/Dockerfile new file mode 100644 index 0000000..6055713 --- /dev/null +++ b/web/Dockerfile @@ -0,0 +1,25 @@ +# 第一阶段:构建 +FROM node:20-alpine as builder + +WORKDIR /web + +# 安装 pnpm +RUN npm install -g pnpm --registry=https://registry.npmmirror.com + +# 先复制 package.json 和 pnpm-lock.yaml(build context 是项目根目录) +COPY web/package.json web/pnpm-lock.yaml* ./ + +# 安装依赖(利用缓存) +RUN pnpm install --registry=https://registry.npmmirror.com --frozen-lockfile + +# 复制源代码 +COPY web/ . + +# 构建 +RUN pnpm build + +# 第二阶段:Nginx 运行时 +FROM docker.1ms.run/nginx:alpine + +# nginx.conf 由 docker-compose volumes 映射,无需复制 +COPY --from=builder /web/dist /usr/share/nginx/html diff --git a/web/Jenkinsfile b/web/Jenkinsfile new file mode 100644 index 0000000..adb7969 --- /dev/null +++ b/web/Jenkinsfile @@ -0,0 +1,60 @@ +pipeline { + agent any + + environment { + HARBOR_URL = '192.168.80.90:8090' + HARBOR_PROJECT = 'pis' + IMAGE_NAME = 'pis-web' + CREDENTIALS_ID = 'harbor-credentials' + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Build Image') { + steps { + script { + def imageTag = "${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:${BUILD_NUMBER}" + env.IMAGE_TAG = imageTag + sh """ + docker build -f web/Dockerfile \ + -t ${imageTag} . + """ + } + } + } + + stage('Push to Harbor') { + steps { + script { + withCredentials([usernamePassword( + credentialsId: CREDENTIALS_ID, + usernameVariable: 'HARBOR_USER', + passwordVariable: 'HARBOR_PASS' + )]) { + sh """ + echo ${HARBOR_PASS} | docker login ${HARBOR_URL} -u ${HARBOR_USER} --password-stdin + docker push ${IMAGE_TAG} || true + docker tag ${IMAGE_TAG} ${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest + docker push ${HARBOR_URL}/${HARBOR_PROJECT}/${IMAGE_NAME}:latest || true + docker logout ${HARBOR_URL} + """ + } + } + } + } + } + + post { + failure { + echo "Frontend Pipeline failed! Check Jenkins logs." + } + success { + echo "Frontend image pushed to Harbor: ${IMAGE_TAG}" + } + } +} diff --git a/web/package.json b/web/package.json index 815e2e0..b34579a 100644 --- a/web/package.json +++ b/web/package.json @@ -9,6 +9,7 @@ "build": "vite build", "build:local": "vite build --mode local_prod", "lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/", + "prepare": "cd .. && husky install", "build:flowH5": "vite build --config flowH5.config.ts" }, "dependencies": { @@ -83,6 +84,8 @@ "baseline-browser-mapping": "^2.9.19", "eslint": "^8.57.1", "eslint-plugin-vue": "^9.27.0", + "husky": "^9.1.7", + "lint-staged": "^16.4.0", "prettier": "^2.8.1", "sass": "^1.56.2", "typescript": "^4.9.4", diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml new file mode 100644 index 0000000..9b82115 --- /dev/null +++ b/web/pnpm-lock.yaml @@ -0,0 +1,8577 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@element-plus/icons-vue': + specifier: ^2.3.1 + version: 2.3.2(vue@3.5.31(typescript@4.9.5)) + '@fast-crud/fast-crud': + specifier: ^1.21.2 + version: 1.27.10(vue@3.5.31(typescript@4.9.5)) + '@fast-crud/fast-extends': + specifier: ^1.21.2 + version: 1.27.10(aws-crt@1.30.0)(vue@3.5.31(typescript@4.9.5)) + '@fast-crud/ui-element': + specifier: ^1.21.2 + version: 1.27.10 + '@fast-crud/ui-interface': + specifier: ^1.21.2 + version: 1.27.10 + '@great-dream/dvadmin3-celery-web': + specifier: ^3.1.3 + version: 3.1.3 + '@iconify/vue': + specifier: ^4.1.2 + version: 4.3.0(vue@3.5.31(typescript@4.9.5)) + '@meetjs/vant4-kit': + specifier: ^1.0.1 + version: 1.0.1(vue@3.5.31(typescript@4.9.5)) + '@types/lodash': + specifier: ^4.17.7 + version: 4.17.24 + '@vitejs/plugin-vue-jsx': + specifier: ^4.0.1 + version: 4.2.0(vite@5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1))(vue@3.5.31(typescript@4.9.5)) + '@wangeditor/editor': + specifier: ^5.1.23 + version: 5.1.23 + '@wangeditor/editor-for-vue': + specifier: ^5.1.12 + version: 5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.31(typescript@4.9.5)) + autoprefixer: + specifier: ^10.4.20 + version: 10.4.27(postcss@8.5.8) + axios: + specifier: ^1.7.4 + version: 1.14.0 + countup.js: + specifier: ^2.8.0 + version: 2.10.0 + cropperjs: + specifier: ^1.6.2 + version: 1.6.2 + date-holidays: + specifier: ^3.24.1 + version: 3.26.12 + e-icon-picker: + specifier: 2.1.1 + version: 2.1.1(vue@3.5.31(typescript@4.9.5)) + echarts: + specifier: ^5.5.1 + version: 5.6.0 + echarts-gl: + specifier: ^2.0.9 + version: 2.0.9(echarts@5.6.0) + echarts-wordcloud: + specifier: ^2.1.0 + version: 2.1.0(echarts@5.6.0) + element-plus: + specifier: ^2.8.0 + version: 2.13.6(typescript@4.9.5)(vue@3.5.31(typescript@4.9.5)) + element-tree-line: + specifier: ^0.2.1 + version: 0.2.1(vue@3.5.31(typescript@4.9.5)) + font-awesome: + specifier: ^4.7.0 + version: 4.7.0 + js-cookie: + specifier: ^3.0.5 + version: 3.0.5 + js-table2excel: + specifier: ^1.1.2 + version: 1.1.2 + jsplumb: + specifier: ^2.15.6 + version: 2.15.6 + less: + specifier: ^4.3.0 + version: 4.6.4 + lodash-es: + specifier: ^4.17.21 + version: 4.17.23 + lunar-javascript: + specifier: ^1.7.1 + version: 1.7.7 + mitt: + specifier: ^3.0.1 + version: 3.0.1 + nprogress: + specifier: ^0.2.0 + version: 0.2.0 + pinia: + specifier: ^2.0.28 + version: 2.3.1(typescript@4.9.5)(vue@3.5.31(typescript@4.9.5)) + pinia-plugin-persist: + specifier: ^1.0.0 + version: 1.0.0(pinia@2.3.1(typescript@4.9.5)(vue@3.5.31(typescript@4.9.5)))(vue@3.5.31(typescript@4.9.5)) + postcss: + specifier: ^8.4.21 + version: 8.5.8 + print-js: + specifier: ^1.6.0 + version: 1.6.0 + qrcodejs2-fixes: + specifier: ^0.0.2 + version: 0.0.2 + qs: + specifier: ^6.11.0 + version: 6.15.0 + rollup-plugin-postcss: + specifier: ^4.0.2 + version: 4.0.2(postcss@8.5.8) + rollup-plugin-terser: + specifier: ^7.0.2 + version: 7.0.2(rollup@4.60.1) + screenfull: + specifier: ^6.0.2 + version: 6.0.2 + sortablejs: + specifier: ^1.15.0 + version: 1.15.7 + splitpanes: + specifier: ^3.1.5 + version: 3.2.0(vue@3.5.31(typescript@4.9.5)) + tailwindcss: + specifier: ^3.2.7 + version: 3.4.19 + ts-md5: + specifier: ^1.3.1 + version: 1.3.1 + upgrade: + specifier: ^1.1.0 + version: 1.1.0 + vant: + specifier: ^4.9.19 + version: 4.9.24(vue@3.5.31(typescript@4.9.5)) + vant4-kit: + specifier: ^1.0.3 + version: 1.0.6(vue@3.5.31(typescript@4.9.5)) + vue: + specifier: ^3.4.38 + version: 3.5.31(typescript@4.9.5) + vue-clipboard3: + specifier: ^2.0.0 + version: 2.0.0 + vue-cropper: + specifier: ^1.0.8 + version: 1.1.4 + vue-draggable-plus: + specifier: ^0.6.0 + version: 0.6.1(@types/sortablejs@1.15.9) + vue-grid-layout: + specifier: ^3.0.0-beta1 + version: 3.0.0-beta1(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@4.9.5) + vue-i18n: + specifier: ^9.14.0 + version: 9.14.5(vue@3.5.31(typescript@4.9.5)) + vue-qr: + specifier: ^4.0.9 + version: 4.0.9 + vue-router: + specifier: ^4.4.3 + version: 4.6.4(vue@3.5.31(typescript@4.9.5)) + vxe-table: + specifier: ^4.6.18 + version: 4.18.10(vue@3.5.31(typescript@4.9.5)) + xe-utils: + specifier: ^3.5.30 + version: 3.9.1 + yarn: + specifier: ^1.22.22 + version: 1.22.22 + devDependencies: + '@types/node': + specifier: ^18.19.42 + version: 18.19.130 + '@types/nprogress': + specifier: ^0.2.3 + version: 0.2.3 + '@types/sortablejs': + specifier: ^1.15.8 + version: 1.15.9 + '@typescript-eslint/eslint-plugin': + specifier: ^5.46.0 + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: ^5.46.0 + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@vitejs/plugin-vue': + specifier: ^5.1.2 + version: 5.2.4(vite@5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1))(vue@3.5.31(typescript@4.9.5)) + '@vue/compiler-sfc': + specifier: ^3.4.38 + version: 3.5.31 + baseline-browser-mapping: + specifier: ^2.9.19 + version: 2.10.13 + eslint: + specifier: ^8.57.1 + version: 8.57.1 + eslint-plugin-vue: + specifier: ^9.27.0 + version: 9.33.0(eslint@8.57.1) + prettier: + specifier: ^2.8.1 + version: 2.8.8 + sass: + specifier: ^1.56.2 + version: 1.98.0 + typescript: + specifier: ^4.9.4 + version: 4.9.5 + vite: + specifier: ^5.4.1 + version: 5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1) + vite-plugin-vue-setup-extend: + specifier: ^0.4.0 + version: 0.4.0(vite@5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1)) + vue-eslint-parser: + specifier: ^9.4.3 + version: 9.4.3(eslint@8.57.1) + +packages: + + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} + + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/crc32c@5.2.0': + resolution: {integrity: sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==} + + '@aws-crypto/sha1-browser@5.2.0': + resolution: {integrity: sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==} + + '@aws-crypto/sha256-browser@5.2.0': + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} + + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/supports-web-crypto@5.2.0': + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} + + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + + '@aws-sdk/client-s3@3.1021.0': + resolution: {integrity: sha512-BCfggq8gYSjlKOZlMSVApix3cgKAQIWGeoJFX/AU5HMvqz1BZBEw83jJFL9LYrqTPCocH8NGl++1Xr70ro+jcg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/core@3.973.26': + resolution: {integrity: sha512-A/E6n2W42ruU+sfWk+mMUOyVXbsSgGrY3MJ9/0Az5qUdG67y8I6HYzzoAa+e/lzxxl1uCYmEL6BTMi9ZiZnplQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/crc64-nvme@3.972.5': + resolution: {integrity: sha512-2VbTstbjKdT+yKi8m7b3a9CiVac+pL/IY2PHJwsaGkkHmuuqkJZIErPck1h6P3T9ghQMLSdMPyW6Qp7Di5swFg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.24': + resolution: {integrity: sha512-FWg8uFmT6vQM7VuzELzwVo5bzExGaKHdubn0StjgrcU5FvuLExUe+k06kn/40uKv59rYzhez8eFNM4yYE/Yb/w==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.26': + resolution: {integrity: sha512-CY4ppZ+qHYqcXqBVi//sdHST1QK3KzOEiLtpLsc9W2k2vfZPKExGaQIsOwcyvjpjUEolotitmd3mUNY56IwDEA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.972.28': + resolution: {integrity: sha512-wXYvq3+uQcZV7k+bE4yDXCTBdzWTU9x/nMiKBfzInmv6yYK1veMK0AKvRfRBd72nGWYKcL6AxwiPg9z/pYlgpw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.28': + resolution: {integrity: sha512-ZSTfO6jqUTCysbdBPtEX5OUR//3rbD0lN7jO3sQeS2Gjr/Y+DT6SbIJ0oT2cemNw3UzKu97sNONd1CwNMthuZQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.29': + resolution: {integrity: sha512-clSzDcvndpFJAggLDnDb36sPdlZYyEs5Zm6zgZjjUhwsJgSWiWKwFIXUVBcbruidNyBdbpOv2tNDL9sX8y3/0g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.24': + resolution: {integrity: sha512-Q2k/XLrFXhEztPHqj4SLCNID3hEPdlhh1CDLBpNnM+1L8fq7P+yON9/9M1IGN/dA5W45v44ylERfXtDAlmMNmw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.972.28': + resolution: {integrity: sha512-IoUlmKMLEITFn1SiCTjPfR6KrE799FBo5baWyk/5Ppar2yXZoUdaRqZzJzK6TcJxx450M8m8DbpddRVYlp5R/A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.28': + resolution: {integrity: sha512-d+6h0SD8GGERzKe27v5rOzNGKOl0D+l0bWJdqrxH8WSQzHzjsQFIAPgIeOTUwBHVsKKwtSxc91K/SWax6XgswQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/crt-loader@3.972.28': + resolution: {integrity: sha512-9kUljr6w63yjnvNPqy1YJs5v2h7sIiFHFBY5iv1vIA102VxRZmI8MjD1F102ZnCEpDO1oxqulsiJpMAbs46MZg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-bucket-endpoint@3.972.8': + resolution: {integrity: sha512-WR525Rr2QJSETa9a050isktyWi/4yIGcmY3BQ1kpHqb0LqUglQHCS8R27dTJxxWNZvQ0RVGtEZjTCbZJpyF3Aw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-expect-continue@3.972.8': + resolution: {integrity: sha512-5DTBTiotEES1e2jOHAq//zyzCjeMB78lEHd35u15qnrid4Nxm7diqIf9fQQ3Ov0ChH1V3Vvt13thOnrACmfGVQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-flexible-checksums@3.974.6': + resolution: {integrity: sha512-YckB8k1ejbyCg/g36gUMFLNzE4W5cERIa4MtsdO+wpTmJEP0+TB7okWIt7d8TDOvnb7SwvxJ21E4TGOBxFpSWQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-host-header@3.972.8': + resolution: {integrity: sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-location-constraint@3.972.8': + resolution: {integrity: sha512-KaUoFuoFPziIa98DSQsTPeke1gvGXlc5ZGMhy+b+nLxZ4A7jmJgLzjEF95l8aOQN2T/qlPP3MrAyELm8ExXucw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-logger@3.972.8': + resolution: {integrity: sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-recursion-detection@3.972.9': + resolution: {integrity: sha512-/Wt5+CT8dpTFQxEJ9iGy/UGrXr7p2wlIOEHvIr/YcHYByzoLjrqkYqXdJjd9UIgWjv7eqV2HnFJen93UTuwfTQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-sdk-s3@3.972.27': + resolution: {integrity: sha512-gomO6DZwx+1D/9mbCpcqO5tPBqYBK7DtdgjTIjZ4yvfh/S7ETwAPS0XbJgP2JD8Ycr5CwVrEkV1sFtu3ShXeOw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-ssec@3.972.8': + resolution: {integrity: sha512-wqlK0yO/TxEC2UsY9wIlqeeutF6jjLe0f96Pbm40XscTo57nImUk9lBcw0dPgsm0sppFtAkSlDrfpK+pC30Wqw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-user-agent@3.972.28': + resolution: {integrity: sha512-cfWZFlVh7Va9lRay4PN2A9ARFzaBYcA097InT5M2CdRS05ECF5yaz86jET8Wsl2WcyKYEvVr/QNmKtYtafUHtQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/nested-clients@3.996.18': + resolution: {integrity: sha512-c7ZSIXrESxHKx2Mcopgd8AlzZgoXMr20fkx5ViPWPOLBvmyhw9VwJx/Govg8Ef/IhEon5R9l53Z8fdYSEmp6VA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/region-config-resolver@3.972.10': + resolution: {integrity: sha512-1dq9ToC6e070QvnVhhbAs3bb5r6cQ10gTVc6cyRV5uvQe7P138TV2uG2i6+Yok4bAkVAcx5AqkTEBUvWEtBlsQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/s3-request-presigner@3.1021.0': + resolution: {integrity: sha512-kkIzsIAc7wnG7vVRkZFIwJ3noOyF3S6ozOQ9t2KxzPde1LsmpmPwYbmiB91DzdfuGySdk4Hpb0JmHh4KhGECXQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-crt@3.1021.0': + resolution: {integrity: sha512-LtRM0atnl4qKxl60vqGmJKUY8e0Gnp2VKWRi22d4BFBiQpO12Z8gpoaDx/pgoWcBmTvGYQZ427dL2eEj/qYNuw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.996.15': + resolution: {integrity: sha512-Ukw2RpqvaL96CjfH/FgfBmy/ZosHBqoHBCFsN61qGg99F33vpntIVii8aNeh65XuOja73arSduskoa4OJea9RQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1021.0': + resolution: {integrity: sha512-TKY6h9spUk3OLs5v1oAgW9mAeBE3LAGNBwJokLy96wwmd4W2v/tYlXseProyed9ValDj2u1jK/4Rg1T+1NXyJA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.973.6': + resolution: {integrity: sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-arn-parser@3.972.3': + resolution: {integrity: sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-endpoints@3.996.5': + resolution: {integrity: sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-format-url@3.972.8': + resolution: {integrity: sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-locate-window@3.965.5': + resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-user-agent-browser@3.972.8': + resolution: {integrity: sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==} + + '@aws-sdk/util-user-agent-node@3.973.14': + resolution: {integrity: sha512-vNSB/DYaPOyujVZBg/zUznH9QC142MaTHVmaFlF7uzzfg3CgT9f/l4C0Yi+vU/tbBhxVcXVB90Oohk5+o+ZbWw==} + engines: {node: '>=20.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + + '@aws-sdk/util-utf8-browser@3.259.0': + resolution: {integrity: sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==} + + '@aws-sdk/xml-builder@3.972.16': + resolution: {integrity: sha512-iu2pyvaqmeatIJLURLqx9D+4jKAdTH20ntzB6BFwjyN7V960r4jK32mx0Zf7YbtOYAbmbtQfDNuL60ONinyw7A==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.2.4': + resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} + engines: {node: '>=18.0.0'} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.28.6': + resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime-corejs2@7.29.2': + resolution: {integrity: sha512-+FqVkbqWaDleqS9fgzFypApKoPvmGFgk5X2lGXbL9wgz6tf88qt2HEUuEn9E3yBeLt7p8pIgODbJ5icVRALKhQ==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@ctrl/tinycolor@4.2.0': + resolution: {integrity: sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==} + engines: {node: '>=14'} + + '@element-plus/icons-vue@2.3.2': + resolution: {integrity: sha512-OzIuTaIfC8QXEPmJvB4Y4kw34rSXdCJzxcD1kFStBvr8bK6X1zQAYDo0CNMjojnfTqRQCJ0I7prlErcoRiET2A==} + peerDependencies: + vue: ^3.2.0 + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@fast-crud/fast-crud@1.27.10': + resolution: {integrity: sha512-msOCxmv0m9uOwqRsBlxrHW88KyHocskRl99ebqLsNSFD0e80GCQErLnUoqF5hOIq6a3uPWoXrfalQzWWyNSfEg==} + + '@fast-crud/fast-extends@1.27.10': + resolution: {integrity: sha512-Ha1h7ciVqOEPYJr0a1rMdihwa57aMwJkU0CEiWGRxdR+UP7Xjg1juQ402YULLs+ALMNOPyoDxvbjIhkRHuWQiQ==} + + '@fast-crud/ui-element@1.27.10': + resolution: {integrity: sha512-w9Gtxo6SaSbBkLvawE60Xpt5LWcTk4RTLdRWmdnnpXTMsTDbycCHvnORucGJqMCHvs9RPHUuxmL8b+EHwoFMLw==} + + '@fast-crud/ui-interface@1.27.10': + resolution: {integrity: sha512-Kz3qMvTFjRDu+dqSQh7LMteHvFzLThm+l8xLYgwgheUzHq+RR2i4z+hoMHF2UUOIhkU+gdqfNXPxkivFHgxNvQ==} + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@great-dream/dvadmin3-celery-web@3.1.3': + resolution: {integrity: sha512-zf1UO6le8rhizN1FjIfHzb1qNoTF23YXczEJhJm0NLoWAbziA+FmobYq/LePvsAEpiVqhsMzrRvbpYj/nWzTQw==} + + '@httptoolkit/websocket-stream@6.0.1': + resolution: {integrity: sha512-A0NOZI+Glp3Xgcz6Na7i7o09+/+xm2m0UCU8gdtM2nIv6/cjLmhMZMqehSpTlgbx9omtLmV8LVqOskPEyWnmZQ==} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/vue@4.3.0': + resolution: {integrity: sha512-Xq0h6zMrHBbrW8jXJ9fISi+x8oDQllg5hTDkDuxnWiskJ63rpJu9CvJshj8VniHVTbsxCg9fVoPAaNp3RQI5OQ==} + peerDependencies: + vue: '>=3' + + '@interactjs/actions@1.10.27': + resolution: {integrity: sha512-FCRg5KwB+stkPcAMx/Cn0fgGP6p4LyMX9S/Upcn/W+hpYme31bPi54PCqmOebzz6myTthN6zFf9jMyLOqtI/gg==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/auto-scroll@1.10.27': + resolution: {integrity: sha512-zPg5TnVsZv+9Hnt4qnbxLvBMf+rIWHkoJVoSETEbLNaj90C8hIyr0pVwukSUySSgDhCgQ7np0f3pg4INLq9beQ==} + peerDependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/auto-start@1.10.27': + resolution: {integrity: sha512-ECLBO/nxmaF1knncJKIE5F7la3KKRgEkn0Cu2JTPOYj9xy/LpfYElo3wkRHsodgOqF651nR70GK2/IzPR2lO9A==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/core@1.10.27': + resolution: {integrity: sha512-SliUr/3ZbLAdED8LokzYzWHWMdCB5Cq+UnpXuRy+BIod1j97m4IUFf/D1iIKUBBjBcucgXbz28z96WnenVCB7Q==} + peerDependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/dev-tools@1.10.27': + resolution: {integrity: sha512-YolmBwRaKH1gWbvyLeV3m5QSwtD38lOZnCBA87PCAlcd9PQAC2gb03fEPeEyD336bE20oLB8f0WZt4Wre+afiw==} + peerDependencies: + '@interactjs/modifiers': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/inertia@1.10.27': + resolution: {integrity: sha512-S/SVj/M0D+wWWPVXHcXN/YUWOK51LFJsEA+CTgVnFhlSU04+1FUvNLwilCZcHgECu1RJxZNKDwZysDATg+r8jQ==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/modifiers': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/interact@1.10.27': + resolution: {integrity: sha512-XdH3A2UUzjEFGGJgFuJlhiz99tE8jB8xNh/DmnoMuL6uOQPxNA+sWRnzEVjG0+zY2P3/dbhEpi4Cn3FLPzydwA==} + + '@interactjs/interactjs@1.10.27': + resolution: {integrity: sha512-UwhfUZMZVXUY72efPABuKSBz1sUY+r+49v8t6Ku9o5Jq76AKg9mwmdGszIlOn3ppnFDDjvtzK/8TL+Sbd0EQEA==} + + '@interactjs/modifiers@1.10.27': + resolution: {integrity: sha512-ei/qfoQ+9/8k6WzNzdNqHI6cWkIV576N4Ap16r5CoqOWwhA6Xzj3OMHf1g0t1O4eSq2HdJsVJn3eLNfw9HsbeQ==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/offset@1.10.27': + resolution: {integrity: sha512-AezsLiuK+Qv4jXdYuRa65HJ2pMFMZPlqiAep6ZRLwhP9HE7O75c0EAm+gfx+dpPrHNHs6J9LaiKSZl+B+A2qAw==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/pointer-events@1.10.27': + resolution: {integrity: sha512-Yo5SS6PhWfC93gHNxnwwW0wvebo5hSYJKGaSnAHO4f9Lh25yibecMnmPBmiEfWVcdMboK/kXrme43mHQaRegVg==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/reflow@1.10.27': + resolution: {integrity: sha512-Msm0QdYFr40oSsPFxyCR3dHN/pQx34k7QSkdN1uIsUn/drrm+YSFvrvVOu99DFOwr7gTThr5vNe06Sz4vubTSA==} + peerDependencies: + '@interactjs/core': 1.10.27 + '@interactjs/utils': 1.10.27 + + '@interactjs/snappers@1.10.27': + resolution: {integrity: sha512-HZLZ0XSi6HI08OmTv/HKG6AltQoaKAALLQ+KDW92utj3XSgw7oren0KsWUKPhaPg3Av7R1jFQd08s+uafqIlLw==} + peerDependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/utils@1.10.27': + resolution: {integrity: sha512-+qfLOio2OxQqg1cXSnRaCl+N8MQDQLDS9w+aOGxH8YLAhIMyt7Asxx/46//sT8orgsi16pmlBPtngPHT9s8zKw==} + + '@intlify/core-base@9.14.5': + resolution: {integrity: sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==} + engines: {node: '>= 16'} + + '@intlify/message-compiler@9.14.5': + resolution: {integrity: sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==} + engines: {node: '>= 16'} + + '@intlify/shared@9.14.5': + resolution: {integrity: sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==} + engines: {node: '>= 16'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@meetjs/vant4-kit@1.0.1': + resolution: {integrity: sha512-94/j0+pjhT4L5B0+cASmhHGeJtLNmmy0GV2o2MpOL9P2eIL9ndUxOWr8S3MQVvgIMXtGZgBoFpGMYD945NESlw==} + peerDependencies: + vue: ^3.4.19 + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + + '@rolldown/pluginutils@1.0.0-rc.12': + resolution: {integrity: sha512-HHMwmarRKvoFsJorqYlFeFRzXZqCt2ETQlEDOb9aqssrnVBB1/+xgTGtuTrIk5vzLNX1MjMtTf7W9z3tsSbrxw==} + + '@rollup/rollup-android-arm-eabi@4.60.1': + resolution: {integrity: sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.1': + resolution: {integrity: sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.1': + resolution: {integrity: sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.1': + resolution: {integrity: sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.1': + resolution: {integrity: sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.1': + resolution: {integrity: sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + resolution: {integrity: sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm-musleabihf@4.60.1': + resolution: {integrity: sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-arm64-gnu@4.60.1': + resolution: {integrity: sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-arm64-musl@4.60.1': + resolution: {integrity: sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-loong64-gnu@4.60.1': + resolution: {integrity: sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==} + cpu: [loong64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-loong64-musl@4.60.1': + resolution: {integrity: sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==} + cpu: [loong64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-ppc64-gnu@4.60.1': + resolution: {integrity: sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-ppc64-musl@4.60.1': + resolution: {integrity: sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-riscv64-gnu@4.60.1': + resolution: {integrity: sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-riscv64-musl@4.60.1': + resolution: {integrity: sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@rollup/rollup-linux-s390x-gnu@4.60.1': + resolution: {integrity: sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-gnu@4.60.1': + resolution: {integrity: sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rollup/rollup-linux-x64-musl@4.60.1': + resolution: {integrity: sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rollup/rollup-openbsd-x64@4.60.1': + resolution: {integrity: sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.1': + resolution: {integrity: sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.1': + resolution: {integrity: sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.1': + resolution: {integrity: sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.1': + resolution: {integrity: sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.1': + resolution: {integrity: sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==} + cpu: [x64] + os: [win32] + + '@smithy/chunked-blob-reader-native@4.2.3': + resolution: {integrity: sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==} + engines: {node: '>=18.0.0'} + + '@smithy/chunked-blob-reader@5.2.2': + resolution: {integrity: sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==} + engines: {node: '>=18.0.0'} + + '@smithy/config-resolver@4.4.13': + resolution: {integrity: sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg==} + engines: {node: '>=18.0.0'} + + '@smithy/core@3.23.13': + resolution: {integrity: sha512-J+2TT9D6oGsUVXVEMvz8h2EmdVnkBiy2auCie4aSJMvKlzUtO5hqjEzXhoCUkIMo7gAYjbQcN0g/MMSXEhDs1Q==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.2.12': + resolution: {integrity: sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-codec@4.2.12': + resolution: {integrity: sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-browser@4.2.12': + resolution: {integrity: sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-config-resolver@4.3.12': + resolution: {integrity: sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-node@4.2.12': + resolution: {integrity: sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-universal@4.2.12': + resolution: {integrity: sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.3.15': + resolution: {integrity: sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A==} + engines: {node: '>=18.0.0'} + + '@smithy/hash-blob-browser@4.2.13': + resolution: {integrity: sha512-YrF4zWKh+ghLuquldj6e/RzE3xZYL8wIPfkt0MqCRphVICjyyjH8OwKD7LLlKpVEbk4FLizFfC1+gwK6XQdR3g==} + engines: {node: '>=18.0.0'} + + '@smithy/hash-node@4.2.12': + resolution: {integrity: sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w==} + engines: {node: '>=18.0.0'} + + '@smithy/hash-stream-node@4.2.12': + resolution: {integrity: sha512-O3YbmGExeafuM/kP7Y8r6+1y0hIh3/zn6GROx0uNlB54K9oihAL75Qtc+jFfLNliTi6pxOAYZrRKD9A7iA6UFw==} + engines: {node: '>=18.0.0'} + + '@smithy/invalid-dependency@4.2.12': + resolution: {integrity: sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g==} + engines: {node: '>=18.0.0'} + + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + + '@smithy/is-array-buffer@4.2.2': + resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} + engines: {node: '>=18.0.0'} + + '@smithy/md5-js@4.2.12': + resolution: {integrity: sha512-W/oIpHCpWU2+iAkfZYyGWE+qkpuf3vEXHLxQQDx9FPNZTTdnul0dZ2d/gUFrtQ5je1G2kp4cjG0/24YueG2LbQ==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-content-length@4.2.12': + resolution: {integrity: sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-endpoint@4.4.28': + resolution: {integrity: sha512-p1gfYpi91CHcs5cBq982UlGlDrxoYUX6XdHSo91cQ2KFuz6QloHosO7Jc60pJiVmkWrKOV8kFYlGFFbQ2WUKKQ==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-retry@4.4.46': + resolution: {integrity: sha512-SpvWNNOPOrKQGUqZbEPO+es+FRXMWvIyzUKUOYdDgdlA6BdZj/R58p4umoQ76c2oJC44PiM7mKizyyex1IJzow==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-serde@4.2.16': + resolution: {integrity: sha512-beqfV+RZ9RSv+sQqor3xroUUYgRFCGRw6niGstPG8zO9LgTl0B0MCucxjmrH/2WwksQN7UUgI7KNANoZv+KALA==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-stack@4.2.12': + resolution: {integrity: sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw==} + engines: {node: '>=18.0.0'} + + '@smithy/node-config-provider@4.3.12': + resolution: {integrity: sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw==} + engines: {node: '>=18.0.0'} + + '@smithy/node-http-handler@4.5.1': + resolution: {integrity: sha512-ejjxdAXjkPIs9lyYyVutOGNOraqUE9v/NjGMKwwFrfOM354wfSD8lmlj8hVwUzQmlLLF4+udhfCX9Exnbmvfzw==} + engines: {node: '>=18.0.0'} + + '@smithy/property-provider@4.2.12': + resolution: {integrity: sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A==} + engines: {node: '>=18.0.0'} + + '@smithy/protocol-http@5.3.12': + resolution: {integrity: sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw==} + engines: {node: '>=18.0.0'} + + '@smithy/querystring-builder@4.2.12': + resolution: {integrity: sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg==} + engines: {node: '>=18.0.0'} + + '@smithy/querystring-parser@4.2.12': + resolution: {integrity: sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw==} + engines: {node: '>=18.0.0'} + + '@smithy/service-error-classification@4.2.12': + resolution: {integrity: sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ==} + engines: {node: '>=18.0.0'} + + '@smithy/shared-ini-file-loader@4.4.7': + resolution: {integrity: sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.3.12': + resolution: {integrity: sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw==} + engines: {node: '>=18.0.0'} + + '@smithy/smithy-client@4.12.8': + resolution: {integrity: sha512-aJaAX7vHe5i66smoSSID7t4rKY08PbD8EBU7DOloixvhOozfYWdcSYE4l6/tjkZ0vBZhGjheWzB2mh31sLgCMA==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.13.1': + resolution: {integrity: sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==} + engines: {node: '>=18.0.0'} + + '@smithy/url-parser@4.2.12': + resolution: {integrity: sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA==} + engines: {node: '>=18.0.0'} + + '@smithy/util-base64@4.3.2': + resolution: {integrity: sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-body-length-browser@4.2.2': + resolution: {integrity: sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-body-length-node@4.2.3': + resolution: {integrity: sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==} + engines: {node: '>=18.0.0'} + + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-buffer-from@4.2.2': + resolution: {integrity: sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==} + engines: {node: '>=18.0.0'} + + '@smithy/util-config-provider@4.2.2': + resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-defaults-mode-browser@4.3.44': + resolution: {integrity: sha512-eZg6XzaCbVr2S5cAErU5eGBDaOVTuTo1I65i4tQcHENRcZ8rMWhQy1DaIYUSLyZjsfXvmCqZrstSMYyGFocvHA==} + engines: {node: '>=18.0.0'} + + '@smithy/util-defaults-mode-node@4.2.48': + resolution: {integrity: sha512-FqOKTlqSaoV3nzO55pMs5NBnZX8EhoI0DGmn9kbYeXWppgHD6dchyuj2HLqp4INJDJbSrj6OFYJkAh/WhSzZPg==} + engines: {node: '>=18.0.0'} + + '@smithy/util-endpoints@3.3.3': + resolution: {integrity: sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig==} + engines: {node: '>=18.0.0'} + + '@smithy/util-hex-encoding@4.2.2': + resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} + engines: {node: '>=18.0.0'} + + '@smithy/util-middleware@4.2.12': + resolution: {integrity: sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-retry@4.2.13': + resolution: {integrity: sha512-qQQsIvL0MGIbUjeSrg0/VlQ3jGNKyM3/2iU3FPNgy01z+Sp4OvcaxbgIoFOTvB61ZoohtutuOvOcgmhbD0katQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-stream@4.5.21': + resolution: {integrity: sha512-KzSg+7KKywLnkoKejRtIBXDmwBfjGvg1U1i/etkC7XSWUyFCoLno1IohV2c74IzQqdhX5y3uE44r/8/wuK+A7Q==} + engines: {node: '>=18.0.0'} + + '@smithy/util-uri-escape@4.2.2': + resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + + '@smithy/util-utf8@4.2.2': + resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-waiter@4.2.14': + resolution: {integrity: sha512-2zqq5o/oizvMaFUlNiTyZ7dbgYv1a893aGut2uaxtbzTx/VYYnRxWzDHuD/ftgcw94ffenua+ZNLrbqwUYE+Bg==} + engines: {node: '>=18.0.0'} + + '@smithy/uuid@1.1.2': + resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} + engines: {node: '>=18.0.0'} + + '@soerenmartius/vue3-clipboard@0.1.2': + resolution: {integrity: sha512-a5er6cFGcFIQ/3qg6kWvU0yFqIz9iWoQGEVs9azjevyRyMAKvj1w3JuLH9y6+u0WhMNby3kn7nuR8nktSnDesg==} + + '@sphinxxxx/color-conversion@2.2.2': + resolution: {integrity: sha512-XExJS3cLqgrmNBIP3bBw6+1oQ1ksGjFh0+oClDKFYpCCqx/hlqwWO5KO/S63fzUo67SxI9dMrF0y5T/Ey7h8Zw==} + + '@sxzz/popperjs-es@2.11.8': + resolution: {integrity: sha512-wOwESXvvED3S8xBmcPWHs2dUuzrE4XiZeFu7e1hROIJkm02a49N120pmOXxY33sBb6hArItm5W5tcg1cBtV+HQ==} + + '@transloadit/prettier-bytes@0.0.7': + resolution: {integrity: sha512-VeJbUb0wEKbcwaSlj5n+LscBl9IPgLPkHVGBkh00cztv6X4L/TJXK58LzFuBKX7/GAfiGhIwH67YTLTlzvIzBA==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/event-emitter@0.3.5': + resolution: {integrity: sha512-zx2/Gg0Eg7gwEiOIIh5w9TrhKKTeQh7CPCOPNc0el4pLSwzebA8SmnHwZs2dWlLONvyulykSwGSQxQHLhjGLvQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.24': + resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + + '@types/node@18.19.130': + resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + + '@types/nprogress@0.2.3': + resolution: {integrity: sha512-k7kRA033QNtC+gLc4VPlfnue58CM1iQLgn1IMAU8VPHGOj7oIHPp9UlhedEnD/Gl8evoCjwkZjlBORtZ3JByUA==} + + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + + '@types/sortablejs@1.15.9': + resolution: {integrity: sha512-7HP+rZGE2p886PKV9c9OJzLBI6BBJu1O7lJGYnPyG3fS4/duUCcngkNCjsLwIMV+WMqANe3tt4irrXHSIe68OQ==} + + '@types/web-bluetooth@0.0.16': + resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==} + + '@types/web-bluetooth@0.0.20': + resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@typescript-eslint/eslint-plugin@5.62.0': + resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@5.62.0': + resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@5.62.0': + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/type-utils@5.62.0': + resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@5.62.0': + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@ungap/structured-clone@1.3.0': + resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + + '@uppy/companion-client@2.2.2': + resolution: {integrity: sha512-5mTp2iq97/mYSisMaBtFRry6PTgZA6SIL7LePteOV5x0/DxKfrZW3DEiQERJmYpHzy7k8johpm2gHnEKto56Og==} + + '@uppy/core@2.3.4': + resolution: {integrity: sha512-iWAqppC8FD8mMVqewavCz+TNaet6HPXitmGXpGGREGrakZ4FeuWytVdrelydzTdXx6vVKkOmI2FLztGg73sENQ==} + + '@uppy/store-default@2.1.1': + resolution: {integrity: sha512-xnpTxvot2SeAwGwbvmJ899ASk5tYXhmZzD/aCFsXePh/v8rNvR2pKlcQUH7cF/y4baUGq3FHO/daKCok/mpKqQ==} + + '@uppy/utils@4.1.3': + resolution: {integrity: sha512-nTuMvwWYobnJcytDO3t+D6IkVq/Qs4Xv3vyoEZ+Iaf8gegZP+rEyoaFT2CK5XLRMienPyqRqNbIfRuFaOWSIFw==} + + '@uppy/xhr-upload@2.1.3': + resolution: {integrity: sha512-YWOQ6myBVPs+mhNjfdWsQyMRWUlrDLMoaG7nvf/G6Y3GKZf8AyjFDjvvJ49XWQ+DaZOftGkHmF1uh/DBeGivJQ==} + peerDependencies: + '@uppy/core': ^2.3.3 + + '@vant/popperjs@1.3.0': + resolution: {integrity: sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==} + + '@vant/use@1.6.0': + resolution: {integrity: sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==} + peerDependencies: + vue: ^3.0.0 + + '@vitejs/plugin-vue-jsx@4.2.0': + resolution: {integrity: sha512-DSTrmrdLp+0LDNF77fqrKfx7X0ErRbOcUAgJL/HbSesqQwoUvUQ4uYQqaex+rovqgGcoPqVk+AwUh3v9CuiYIw==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.0.0 + + '@vitejs/plugin-vue@5.2.4': + resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@vue/babel-helper-vue-transform-on@1.5.0': + resolution: {integrity: sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==} + + '@vue/babel-plugin-jsx@1.5.0': + resolution: {integrity: sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + peerDependenciesMeta: + '@babel/core': + optional: true + + '@vue/babel-plugin-resolve-type@1.5.0': + resolution: {integrity: sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@vue/compiler-core@3.5.31': + resolution: {integrity: sha512-k/ueL14aNIEy5Onf0OVzR8kiqF/WThgLdFhxwa4e/KF/0qe38IwIdofoSWBTvvxQOesaz6riAFAUaYjoF9fLLQ==} + + '@vue/compiler-dom@3.5.31': + resolution: {integrity: sha512-BMY/ozS/xxjYqRFL+tKdRpATJYDTTgWSo0+AJvJNg4ig+Hgb0dOsHPXvloHQ5hmlivUqw1Yt2pPIqp4e0v1GUw==} + + '@vue/compiler-sfc@3.5.31': + resolution: {integrity: sha512-M8wpPgR9UJ8MiRGjppvx9uWJfLV7A/T+/rL8s/y3QG3u0c2/YZgff3d6SuimKRIhcYnWg5fTfDMlz2E6seUW8Q==} + + '@vue/compiler-ssr@3.5.31': + resolution: {integrity: sha512-h0xIMxrt/LHOvJKMri+vdYT92BrK3HFLtDqq9Pr/lVVfE4IyKZKvWf0vJFW10Yr6nX02OR4MkJwI0c1HDa1hog==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/reactivity@3.5.31': + resolution: {integrity: sha512-DtKXxk9E/KuVvt8VxWu+6Luc9I9ETNcqR1T1oW1gf02nXaZ1kuAx58oVu7uX9XxJR0iJCro6fqBLw9oSBELo5g==} + + '@vue/runtime-core@3.5.31': + resolution: {integrity: sha512-AZPmIHXEAyhpkmN7aWlqjSfYynmkWlluDNPHMCZKFHH+lLtxP/30UJmoVhXmbDoP1Ng0jG0fyY2zCj1PnSSA6Q==} + + '@vue/runtime-dom@3.5.31': + resolution: {integrity: sha512-xQJsNRmGPeDCJq/u813tyonNgWBFjzfVkBwDREdEWndBnGdHLHgkwNBQxLtg4zDrzKTEcnikUy1UUNecb3lJ6g==} + + '@vue/server-renderer@3.5.31': + resolution: {integrity: sha512-GJuwRvMcdZX/CriUnyIIOGkx3rMV3H6sOu0JhdKbduaeCji6zb60iOGMY7tFoN24NfsUYoFBhshZtGxGpxO4iA==} + peerDependencies: + vue: 3.5.31 + + '@vue/shared@3.5.31': + resolution: {integrity: sha512-nBxuiuS9Lj5bPkPbWogPUnjxxWpkRniX7e5UBQDWl6Fsf4roq9wwV+cR7ezQ4zXswNvPIlsdj1slcLB7XCsRAw==} + + '@vueuse/core@12.0.0': + resolution: {integrity: sha512-C12RukhXiJCbx4MGhjmd/gH52TjJsc3G0E0kQj/kb19H3Nt6n1CA4DRWuTdWWcaFRdlTe0npWDS942mvacvNBw==} + + '@vueuse/core@9.13.0': + resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==} + + '@vueuse/metadata@12.0.0': + resolution: {integrity: sha512-Yzimd1D3sjxTDOlF05HekU5aSGdKjxhuhRFHA7gDWLn57PRbBIh+SF5NmjhJ0WRgF3my7T8LBucyxdFJjIfRJQ==} + + '@vueuse/metadata@9.13.0': + resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==} + + '@vueuse/shared@12.0.0': + resolution: {integrity: sha512-3i6qtcq2PIio5i/vVYidkkcgvmTjCqrf26u+Fd4LhnbBmIT6FN8y6q/GJERp8lfcB9zVEfjdV0Br0443qZuJpw==} + + '@vueuse/shared@9.13.0': + resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==} + + '@vxe-ui/core@4.4.3': + resolution: {integrity: sha512-IIwi5+h7Yopq3Ps+JtlSmggUQZg3wvzuad2xuWGR9sNzR/r0qlWKfax7qimrM2UNpVhSF1jI+3Z9+3yg+HPYTw==} + peerDependencies: + vue: ^3.2.0 + + '@wangeditor/basic-modules@1.1.7': + resolution: {integrity: sha512-cY9CPkLJaqF05STqfpZKWG4LpxTMeGSIIF1fHvfm/mz+JXatCagjdkbxdikOuKYlxDdeqvOeBmsUBItufDLXZg==} + peerDependencies: + '@wangeditor/core': 1.x + dom7: ^3.0.0 + lodash.throttle: ^4.1.1 + nanoid: ^3.2.0 + slate: ^0.72.0 + snabbdom: ^3.1.0 + + '@wangeditor/code-highlight@1.0.3': + resolution: {integrity: sha512-iazHwO14XpCuIWJNTQTikqUhGKyqj+dUNWJ9288Oym9M2xMVHvnsOmDU2sgUDWVy+pOLojReMPgXCsvvNlOOhw==} + peerDependencies: + '@wangeditor/core': 1.x + dom7: ^3.0.0 + slate: ^0.72.0 + snabbdom: ^3.1.0 + + '@wangeditor/core@1.1.19': + resolution: {integrity: sha512-KevkB47+7GhVszyYF2pKGKtCSj/YzmClsD03C3zTt+9SR2XWT5T0e3yQqg8baZpcMvkjs1D8Dv4fk8ok/UaS2Q==} + peerDependencies: + '@uppy/core': ^2.1.1 + '@uppy/xhr-upload': ^2.0.3 + dom7: ^3.0.0 + is-hotkey: ^0.2.0 + lodash.camelcase: ^4.3.0 + lodash.clonedeep: ^4.5.0 + lodash.debounce: ^4.0.8 + lodash.foreach: ^4.5.0 + lodash.isequal: ^4.5.0 + lodash.throttle: ^4.1.1 + lodash.toarray: ^4.4.0 + nanoid: ^3.2.0 + slate: ^0.72.0 + snabbdom: ^3.1.0 + + '@wangeditor/editor-for-vue@5.1.12': + resolution: {integrity: sha512-0Ds3D8I+xnpNWezAeO7HmPRgTfUxHLMd9JKcIw+QzvSmhC5xUHbpCcLU+KLmeBKTR/zffnS5GQo6qi3GhTMJWQ==} + peerDependencies: + '@wangeditor/editor': '>=5.1.0' + vue: ^3.0.5 + + '@wangeditor/editor@5.1.23': + resolution: {integrity: sha512-0RxfeVTuK1tktUaPROnCoFfaHVJpRAIE2zdS0mpP+vq1axVQpLjM8+fCvKzqYIkH0Pg+C+44hJpe3VVroSkEuQ==} + + '@wangeditor/list-module@1.0.5': + resolution: {integrity: sha512-uDuYTP6DVhcYf7mF1pTlmNn5jOb4QtcVhYwSSAkyg09zqxI1qBqsfUnveeDeDqIuptSJhkh81cyxi+MF8sEPOQ==} + peerDependencies: + '@wangeditor/core': 1.x + dom7: ^3.0.0 + slate: ^0.72.0 + snabbdom: ^3.1.0 + + '@wangeditor/table-module@1.1.4': + resolution: {integrity: sha512-5saanU9xuEocxaemGdNi9t8MCDSucnykEC6jtuiT72kt+/Hhh4nERYx1J20OPsTCCdVr7hIyQenFD1iSRkIQ6w==} + peerDependencies: + '@wangeditor/core': 1.x + dom7: ^3.0.0 + lodash.isequal: ^4.5.0 + lodash.throttle: ^4.1.1 + nanoid: ^3.2.0 + slate: ^0.72.0 + snabbdom: ^3.1.0 + + '@wangeditor/upload-image-module@1.0.2': + resolution: {integrity: sha512-z81lk/v71OwPDYeQDxj6cVr81aDP90aFuywb8nPD6eQeECtOymrqRODjpO6VGvCVxVck8nUxBHtbxKtjgcwyiA==} + peerDependencies: + '@uppy/core': ^2.0.3 + '@uppy/xhr-upload': ^2.0.3 + '@wangeditor/basic-modules': 1.x + '@wangeditor/core': 1.x + dom7: ^3.0.0 + lodash.foreach: ^4.5.0 + slate: ^0.72.0 + snabbdom: ^3.1.0 + + '@wangeditor/video-module@1.1.4': + resolution: {integrity: sha512-ZdodDPqKQrgx3IwWu4ZiQmXI8EXZ3hm2/fM6E3t5dB8tCaIGWQZhmqd6P5knfkRAd3z2+YRSRbxOGfoRSp/rLg==} + peerDependencies: + '@uppy/core': ^2.1.4 + '@uppy/xhr-upload': ^2.0.7 + '@wangeditor/core': 1.x + dom7: ^3.0.0 + nanoid: ^3.2.0 + slate: ^0.72.0 + snabbdom: ^3.1.0 + + ace-builds@1.43.6: + resolution: {integrity: sha512-L1ddibQ7F3vyXR2k2fg+I8TQTPWVA6CKeDQr/h2+8CeyTp3W6EQL8xNFZRTztuP8xNOAqL3IYPqdzs31GCjDvg==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + adler-32@1.3.1: + resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==} + engines: {node: '>=0.8'} + + agentkeepalive@3.5.3: + resolution: {integrity: sha512-yqXL+k5rr8+ZRpOAntkaaRgWgE5o8ESAj5DyRmVTCSoZxXmqemb9Dd7T4i5UzwuERdLAJUy6XzR9zFVuf0kzkw==} + engines: {node: '>= 4.0.0'} + + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + + ali-oss@6.23.0: + resolution: {integrity: sha512-FipRmyd16Pr/tEey/YaaQ/24Pc3HEpLM9S1DRakEuXlSLXNIJnu1oJtHM53eVYpvW3dXapSjrip3xylZUTIZVQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + astronomia@4.2.0: + resolution: {integrity: sha512-mTvpBGyXB80aSsDhAAiuwza5VqAyqmj5yzhjBrFhRy17DcWDzJrb8Vdl4Sm+g276S+mY7bk/5hi6akZ5RQFeHg==} + engines: {node: '>=12.0.0'} + + async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + autoprefixer@10.4.27: + resolution: {integrity: sha512-NP9APE+tO+LuJGn7/9+cohklunJsXWiaWEfV3si4Gi/XHDwVNgkwr1J3RQYFIvPy76GmJ9/bW8vyoU1LcxwKHA==} + engines: {node: ^10 || ^12 || >=14} + hasBin: true + peerDependencies: + postcss: ^8.1.0 + + aws-crt@1.30.0: + resolution: {integrity: sha512-PSbNf2HdLT5orB91SaAR9cARBRTaYznPJIVWDeNlsr//xlcdqYywPAOJQ6L5nBwZnTDArvk7awt6RpL4SIqWsQ==} + + axios@1.14.0: + resolution: {integrity: sha512-3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + baseline-browser-mapping@2.10.13: + resolution: {integrity: sha512-BL2sTuHOdy0YT1lYieUxTw/QMtPBC3pmlJC6xk8BBYVv6vcw3SGdKemQ+Xsx9ik2F/lYDO9tqsFQH1r9PFuHKw==} + engines: {node: '>=6.0.0'} + hasBin: true + + batch-processor@1.0.0: + resolution: {integrity: sha512-xoLQD8gmmR32MeuBHgH0Tzd5PuSZx71ZsbhVxOCRbgktZEPe4SQy7s9Z50uPp0F/f7iw2XmkHN2xkgbMfckMDA==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bowser@1.9.4: + resolution: {integrity: sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==} + + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + + brace-expansion@1.1.13: + resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} + + brace-expansion@2.0.3: + resolution: {integrity: sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + + caldate@2.0.5: + resolution: {integrity: sha512-JndhrUuDuE975KUhFqJaVR1OQkCHZqpOrJur/CFXEIEhWhBMjxO85cRSK8q4FW+B+yyPq6GYua2u4KvNzTcq0w==} + engines: {node: '>=12.0.0'} + + 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.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001782: + resolution: {integrity: sha512-dZcaJLJeDMh4rELYFw1tvSn1bhZWYFOt468FcbHHxx/Z/dFidd1I6ciyFdi3iwfQCyOjqo9upF6lGQYtMiJWxw==} + + cfb@1.2.2: + resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==} + engines: {node: '>=0.8'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + claygl@1.3.0: + resolution: {integrity: sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ==} + + clipboard@2.0.11: + resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==} + + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + + codepage@1.15.0: + resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==} + engines: {node: '>=0.8'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commist@1.1.0: + resolution: {integrity: sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==} + + compute-scroll-into-view@1.0.20: + resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + + concat-with-sourcemaps@1.1.0: + resolution: {integrity: sha512-4gEjHJFT9e+2W/77h/DS5SGUgwDaOwprX8L/gl5+3ixnzkVJJsZWDSelmN3Oilw3LNDZjZV0yqH1hLG3k6nghg==} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + copy-anything@3.0.5: + resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==} + engines: {node: '>=12.13'} + + copy-to@2.0.1: + resolution: {integrity: sha512-3DdaFaU/Zf1AnpLiFDeNCD4TOWe3Zl2RZaTzUvWiIk5ERzcCodOE20Vqq4fzCbNoHURFHT4/us/Lfq+S2zyY4w==} + + core-js@2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cos-js-sdk-v5@1.10.1: + resolution: {integrity: sha512-a4SRfCY5g6Z35C7OWe9te/S1zk77rVQzfpvZ33gmTdJQzKxbNbEG7Aw/v453XwVMsQB352FIf7KRMm5Ya/wlZQ==} + + countup.js@2.10.0: + resolution: {integrity: sha512-QQpZx7oYxsR+OeITlZe46fY/OQjV11oBqjY8wgIXzLU2jIz8GzOrbMhqKLysGY8bWI3T1ZNrYkwGzKb4JNgyzg==} + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + cron-chinese@1.2.0: + resolution: {integrity: sha512-kx8F42h4hNXjo1zvpkNWnnErpu2Crcba7f3sVeA5RB83CVSHIu+dwLXkRoZkPDU3IbHXsXqZV9QmSUHoIXwx/Q==} + + cron-parser@4.9.0: + resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} + engines: {node: '>=12.0.0'} + + cropperjs@1.6.2: + resolution: {integrity: sha512-nhymn9GdnV3CqiEHJVai54TULFAE3VshJTXSqSJKa8yXAKyBKDWdhHarnlIPrshJ0WMFTGuFvG02YjLXfPiuOA==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + css-declaration-sorter@6.4.1: + resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==} + engines: {node: ^10 || ^12 || >=14} + peerDependencies: + postcss: ^8.0.9 + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@5.2.14: + resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + cssnano-utils@3.1.0: + resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + cssnano@5.1.15: + resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + + date-bengali-revised@2.0.2: + resolution: {integrity: sha512-q9iDru4+TSA9k4zfm0CFHJj6nBsxP7AYgWC/qodK/i7oOIlj5K2z5IcQDtESfs/Qwqt/xJYaP86tkazd/vRptg==} + engines: {node: '>=12.0.0'} + + date-chinese@2.1.4: + resolution: {integrity: sha512-WY+6+Qw92ZGWFvGtStmNQHEYpNa87b8IAQ5T8VKt4wqrn24lBXyyBnWI5jAIyy7h/KVwJZ06bD8l/b7yss82Ww==} + engines: {node: '>=12.0.0'} + + date-easter@1.0.3: + resolution: {integrity: sha512-aOViyIgpM4W0OWUiLqivznwTtuMlD/rdUWhc5IatYnplhPiWrLv75cnifaKYhmQwUBLAMWLNG4/9mlLIbXoGBQ==} + engines: {node: '>=12.0.0'} + + date-holidays-parser@3.4.7: + resolution: {integrity: sha512-h09ZEtM6u5cYM6m1bX+1Ny9f+nLO9KVZUKNPEnH7lhbXYTfqZogaGTnhONswGeIJFF91UImIftS3CdM9HLW5oQ==} + engines: {node: '>=12.0.0'} + + date-holidays@3.26.12: + resolution: {integrity: sha512-2OXPk5Nbt4iyKLIaoqiCkiQFt+zxGA3SZ3CWMldy8YXq6Zisv+CguVM8TqrKaGEoiZY2gzGH6qCDCrbFoZFyBA==} + engines: {node: '>=12.0.0'} + hasBin: true + + dateformat@2.2.0: + resolution: {integrity: sha512-GODcnWq3YGoTnygPfi02ygEiRxqUxpJwuRHjdhJYuxpcZmDq4rjBiXYmbCCzStxo176ixfLT6i4NPwQooRySnw==} + + dayjs@1.11.20: + resolution: {integrity: sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ==} + + debounce@1.2.1: + resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-equal@1.1.2: + resolution: {integrity: sha512-5tdhKF6DbU7iIzrIOa1AOUt39ZRm13cmL1cGEh//aqR8x9+tNfbywRf0n5FD/18OKMdo7DNEtrX2t22ZAkI+eg==} + engines: {node: '>= 0.4'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-user-agent@1.0.0: + resolution: {integrity: sha512-bDF7bg6OSNcSwFWPu4zYKpVkJZQYVrAANMYB8bc9Szem1D0yKdm4sa/rOCs2aC9+2GMqQ7KnwtZRvDhmLF0dXw==} + engines: {node: '>= 0.10.0'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegate@3.2.0: + resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + didyoumean@1.2.2: + resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} + + digest-header@1.1.0: + resolution: {integrity: sha512-glXVh42vz40yZb9Cq2oMOt70FIoWiv+vxNvdKdU8CwjLad25qHM3trLxhl9bVjdr6WaslIXhWpn0NO8T/67Qjg==} + engines: {node: '>= 8.0.0'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-zindex@1.0.6: + resolution: {integrity: sha512-FKWIhiU96bi3xpP9ewRMgANsoVmMUBnMnmpCT6dPMZOunVYJQmJhSRruoI0XSPoHeIif3kyEuiHbFrOJwEJaEA==} + + dom7@3.0.0: + resolution: {integrity: sha512-oNlcUdHsC4zb7Msx7JN3K0Nro1dzJ48knvBOnDPKJ2GV9wl1i5vydJZUSyOfrkKFDZEud/jBsTk92S/VGSAe/g==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + e-icon-picker@2.1.1: + resolution: {integrity: sha512-oj+gDuqDEQErbZctBX+DW8IcB0AYvHUJYo7/TcMPpiToITwOPcDRZYbVILb+M+j446YqG71Kkon4y1Y4BkGDww==} + peerDependencies: + vue: ^3.2.0 + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + echarts-gl@2.0.9: + resolution: {integrity: sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==} + peerDependencies: + echarts: ^5.1.2 + + echarts-wordcloud@2.1.0: + resolution: {integrity: sha512-Kt1JmbcROgb+3IMI48KZECK2AP5lG6bSsOEs+AsuwaWJxQom31RTNd6NFYI01E/YaI1PFZeueaupjlmzSQasjQ==} + peerDependencies: + echarts: ^5.0.1 + + echarts@5.6.0: + resolution: {integrity: sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.330: + resolution: {integrity: sha512-jFNydB5kFtYUobh4IkWUnXeyDbjf/r9gcUEXe1xcrcUxIGfTdzPXA+ld6zBRbwvgIGVzDll/LTIiDztEtckSnA==} + + element-plus@2.13.6: + resolution: {integrity: sha512-XHgwXr8Fjz6i+6BaqFhAbae/dJbG7bBAAlHrY3pWL7dpj+JcqcOyKYt4Oy5KP86FQwS1k4uIZDjCx2FyUR5lDg==} + peerDependencies: + vue: ^3.3.0 + + element-resize-detector@1.2.4: + resolution: {integrity: sha512-Fl5Ftk6WwXE0wqCgNoseKWndjzZlDCwuPTcoVZfCP9R3EHQF8qUtr3YUPNETegRBOKqQKPW3n4kiIWngGi8tKg==} + + element-tree-line@0.2.1: + resolution: {integrity: sha512-YWHftDSOFiBuw49drxJV7Yi7pCqPpwBBBeQmySjchcxU3uUOAu72FDLK5RyTGJ5qt4Ci+yoUg7zJqsFP5u7N5A==} + peerDependencies: + vue: ^2.6.11 || ^3.2.0 + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + end-or-error@1.0.1: + resolution: {integrity: sha512-OclLMSug+k2A0JKuf494im25ANRBVW8qsjmwbgX7lQ8P82H21PQ1PWkoYwb9y5yMBS69BPlwtzdIFClo3+7kOQ==} + engines: {node: '>= 0.11.14'} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-plugin-vue@9.33.0: + resolution: {integrity: sha512-174lJKuNsuDIlLpjeXc5E2Tss8P44uIimAfGD0b90k0NoirJqpG7stLuU9Vp/9ioTOrQdWVREc4mRd1BD+CvGw==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + + eventemitter3@2.0.3: + resolution: {integrity: sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.1.2: + resolution: {integrity: sha512-KaJUt+M9t1qaIteSvjc6P3RbMdXsNhK61GRftR6SNxqmhthcd9MGIi4T+o0jD8LUSpSnSKXE20nLtJ3fOHxQig==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-xml-builder@1.1.4: + resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==} + + fast-xml-parser@4.5.0: + resolution: {integrity: sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==} + hasBin: true + + fast-xml-parser@5.5.8: + resolution: {integrity: sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==} + hasBin: true + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-saver@2.0.5: + resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + font-awesome@4.7.0: + resolution: {integrity: sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==} + engines: {node: '>=0.10.3'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + formstream@1.5.2: + resolution: {integrity: sha512-NASf0lgxC1AyKNXQIrXTEYkiX99LhCEXTkiGObXAkpBui86a4u8FjH1o2bGb3PpqI3kafC+yw4zWeK6l6VHTgg==} + + frac@1.1.2: + resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==} + engines: {node: '>=0.8'} + + fraction.js@5.3.4: + resolution: {integrity: sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generic-names@4.0.0: + resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + 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-ready@1.0.0: + resolution: {integrity: sha512-mFXCZPJIlcYcth+N8267+mghfYN9h3EhsDa6JSnbA3Wrhh/XFpuowviFcsDeYZtKspQyWyJqfs4O6P8CHeTwzw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + good-listener@1.2.2: + resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + help-me@3.0.0: + resolution: {integrity: sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==} + + html-void-elements@2.0.1: + resolution: {integrity: sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==} + + humanize-duration@3.33.2: + resolution: {integrity: sha512-K7Ny/ULO1hDm2nnhvAY+SJV1skxFb61fd073SG1IWJl+D44ULrruCuTyjHKjBVVcSuTlnY99DKtgEG39CM5QOQ==} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + i18next@20.6.1: + resolution: {integrity: sha512-yCMYTMEJ9ihCwEQQ3phLo7I/Pwycf8uAx+sRHwwk5U9Aui/IZYgQRyMqXafQOw5QQ7DM1Z+WyEXWIqSuJHhG2A==} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + icss-replace-symbols@1.1.0: + resolution: {integrity: sha512-chIaY3Vh2mh2Q3RGXttaDIzeiPvaVXJ+C4DAh/w3c37SKZ/U6PGMmuicR2EQQp9bKG8zLMCl7I+PtIoOOPp8Gg==} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + image-size@0.5.5: + resolution: {integrity: sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + immer@9.0.21: + resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} + + immutable@5.1.5: + resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} + + import-cwd@3.0.0: + resolution: {integrity: sha512-4pnzH16plW+hgvRECbDWpQl3cqtvSofHWh44met7ESfZ8UZOWWddm8hEyDTqREJ9RbYHY8gi8DqmaelApoOGMg==} + engines: {node: '>=8'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-from@3.0.0: + resolution: {integrity: sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-class-hotfix@0.0.6: + resolution: {integrity: sha512-0n+pzCC6ICtVr/WXnN2f03TK/3BfXY7me4cjCAqT8TYXEl0+JBRoqBo94JJHXcyDSLUeWbNX8Fvy5g5RJdAstQ==} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hotkey@0.2.0: + resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-type-of@1.4.0: + resolution: {integrity: sha512-EddYllaovi5ysMLMEN7yzHEKh8A850cZ7pykrY1aNRQGn/CDjRDE9qEWbIdt7xGEVJmjBXzU/fNnC4ABTm8tEQ==} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jalaali-js@1.2.8: + resolution: {integrity: sha512-Jl/EwY84JwjW2wsWqeU4pNd22VNQ7EkjI36bDuLw31wH98WQW4fPjD0+mG7cdCK+Y8D6s9R3zLiQ3LaKu6bD8A==} + + javascript-natural-sort@0.7.1: + resolution: {integrity: sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==} + + jest-worker@26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + + jiti@1.21.7: + resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} + hasBin: true + + jmespath@0.16.0: + resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==} + engines: {node: '>= 0.6.0'} + + js-base64@2.6.4: + resolution: {integrity: sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==} + + js-binary-schema-parser@2.0.3: + resolution: {integrity: sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg==} + + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + + js-sdsl@4.3.0: + resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==} + + js-table2excel@1.1.2: + resolution: {integrity: sha512-E5QcPLjlF7qcqqF+DgaPxj9b+lQsItMqkwcXKpODtZ8zo5f07huuvem3Ek1WYzOcSOalU7RwEAG/66WQ5PVfWA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-editor-vue3@1.1.1: + resolution: {integrity: sha512-3qslVNZAY+roVfL10ukuaAw1ia9YpWdLO9PnBL+4SuM5a6R3oWCSQU6dLTTPd/dVtqhIefNn4QmthAioYOBHeA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-source-map@0.6.1: + resolution: {integrity: sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsoneditor@9.10.5: + resolution: {integrity: sha512-fVZ0NMt+zm4rqTKBv2x7zPdLeaRyKo1EjJkaR1QjK4gEM1rMwICILYSW1OPxSc1qqyAoDaA/eeNrluKoxOocCA==} + + jsonrepair@3.1.0: + resolution: {integrity: sha512-idqReg23J0PVRAADmZMc5xQM3xeOX5bTB6OTyMnzq33IXJXmn9iJuWIEvGmrN80rQf4d7uLTMEDwpzujNcI0Rg==} + hasBin: true + + jsplumb@2.15.6: + resolution: {integrity: sha512-sIpbpz5eMVM+vV+MQzFCidlaa1RsknrQs6LOTKYDjYUDdTAi2AN2bFi94TxB33TifcIsRNV1jebcaxg0tCoPzg==} + + jstoxml@2.2.9: + resolution: {integrity: sha512-OYWlK0j+roh+eyaMROlNbS5cd5R25Y+IUpdl7cNdB8HNrkgwQzIS7L9MegxOiWNBj9dQhA/yAxiMwCC5mwNoBw==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + less@4.6.4: + resolution: {integrity: sha512-OJmO5+HxZLLw0RLzkqaNHzcgEAQG7C0y3aMbwtCzIUFZsLMNNq/1IdAdHEycQ58CwUO3jPTHmoN+tE5I7FQxNg==} + engines: {node: '>=18'} + hasBin: true + + leven@2.1.0: + resolution: {integrity: sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==} + engines: {node: '>=0.10.0'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + loader-utils@3.3.1: + resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} + engines: {node: '>= 12.13.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.23: + resolution: {integrity: sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==} + + lodash-unified@1.0.3: + resolution: {integrity: sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==} + peerDependencies: + '@types/lodash-es': '*' + lodash: '*' + lodash-es: '*' + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.foreach@4.5.0: + resolution: {integrity: sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ==} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.throttle@4.1.1: + resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==} + + lodash.toarray@4.4.0: + resolution: {integrity: sha512-QyffEA3i5dma5q2490+SgCvDN0pXLmRGSyAANuVi0HQ01Pkfr9fuoKQW8wm1wGBnJITs/mS7wQvS6VshUEBFCw==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + lodash@4.18.0: + resolution: {integrity: sha512-l1mfj2atMqndAHI3ls7XqPxEjV2J9ZkcNyHpoZA3r2T1LLwDB69jgkMWh71YKwhBbK0G2f4WSn05ahmQXVxupA==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lunar-javascript@1.7.7: + resolution: {integrity: sha512-u/KYiwPIBo/0bT+WWfU7qO1d+aqeB90Tuy4ErXenr2Gam0QcWeezUvtiOIyXR7HbVnW2I1DKfU0NBvzMZhbVQw==} + + luxon@3.7.2: + resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} + engines: {node: '>=12'} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + memoize-one@6.0.0: + resolution: {integrity: sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + 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'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-match@1.0.2: + resolution: {integrity: sha512-VXp/ugGDVh3eCLOBCiHZMYWQaTNUHv2IJrut+yXA6+JbLPXHglHwfS/5A5L0ll+jkCY7fIzRJcH6OIunF+c6Cg==} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + mitt@2.1.0: + resolution: {integrity: sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==} + + mitt@3.0.1: + resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mobius1-selectr@2.4.13: + resolution: {integrity: sha512-Mk9qDrvU44UUL0EBhbAA1phfQZ7aMZPjwtL7wkpiBzGh8dETGqfsh50mWoX9EkjDlkONlErWXArHCKfoxVg0Bw==} + + moment-timezone@0.5.48: + resolution: {integrity: sha512-f22b8LV1gbTO2ms2j2z13MuPogNoh5UzxL3nzNAYKGraILnbGc9NEE6dyiiiLv46DGRb8A4kg8UKWLjPthxBHw==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + mqtt-packet@6.10.0: + resolution: {integrity: sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==} + + mqtt@4.3.8: + resolution: {integrity: sha512-2xT75uYa0kiPEF/PE0VPdavmEkoBzMT/UL9moid0rAvlCtV48qBwxD62m7Ld/4j8tSkIO1E/iqRl/S72SEOhOw==} + engines: {node: '>=10.0.0'} + hasBin: true + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + namespace-emitter@2.0.1: + resolution: {integrity: sha512-N/sMKHniSDJBjfrkbS/tpkPj4RAbvW3mr8UAzvlMHyun93XEm83IAvhWtJVHo+RHn/oO8Job5YN4b+wRjSVp5g==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + needle@3.5.0: + resolution: {integrity: sha512-jaQyPKKk2YokHrEg+vFDYxXIHTCBgiZwSHOoVx/8V3GIBS8/VN6NdVRmg8q1ERtPkMvmOvebsgga4sAj5hls/w==} + engines: {node: '>= 4.4.x'} + hasBin: true + + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + + node-hex@1.0.1: + resolution: {integrity: sha512-iwpZdvW6Umz12ICmu9IYPRxg0tOLGmU3Tq2tKetejCj3oZd7b2nUXwP3a7QA5M9glWy8wlPS1G3RwM/CdsUbdQ==} + engines: {node: '>=8.0.0'} + + node-releases@2.0.36: + resolution: {integrity: sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + + normalize-wheel-es@1.2.0: + resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==} + + nprogress@0.2.0: + resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + number-allocator@1.0.14: + resolution: {integrity: sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + os-name@1.0.3: + resolution: {integrity: sha512-f5estLO2KN8vgtTRaILIgEGBoBrMnZ3JQ7W9TMZCnOIGwHe8TRGSpcagnWDo+Dfhd/z08k9Xe75hvciJJ8Qaew==} + engines: {node: '>=0.10.0'} + hasBin: true + + osx-release@1.1.0: + resolution: {integrity: sha512-ixCMMwnVxyHFQLQnINhmIpWqXIfS2YOXchwQrk+OFzmo6nDjQ0E4KXAyyUh0T0MZgV4bUhkRrAbVqlE4yLVq4A==} + engines: {node: '>=0.10.0'} + hasBin: true + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parchment@1.1.4: + resolution: {integrity: sha512-J5FBQt/pM2inLzg4hEWmzQx/8h8D0CiDxaG3vyp9rKrQRSDgBlhjdP5jQGgosEajXPSQouXGHOmVdgo7QmJuOg==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parenthesis@3.1.8: + resolution: {integrity: sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==} + + parse-node-version@1.0.1: + resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} + engines: {node: '>= 0.10'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-expression-matcher@1.2.0: + resolution: {integrity: sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==} + engines: {node: '>=14.0.0'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + picomodal@3.0.0: + resolution: {integrity: sha512-FoR3TDfuLlqUvcEeK5ifpKSVVns6B4BQvc8SDF6THVMuadya6LLtji0QgUDSStw0ZR2J7I6UGi5V2V23rnPWTw==} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pinia-plugin-persist@1.0.0: + resolution: {integrity: sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==} + peerDependencies: + '@vue/composition-api': ^1.0.0 + pinia: ^2.0.0 + vue: ^2.0.0 || >=3.0.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + pinia@2.3.1: + resolution: {integrity: sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==} + peerDependencies: + typescript: '>=4.4.4' + vue: ^2.7.0 || ^3.5.11 + peerDependenciesMeta: + typescript: + optional: true + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + platform@1.3.6: + resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} + + postcss-calc@8.2.4: + resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} + peerDependencies: + postcss: ^8.2.2 + + postcss-colormin@5.3.1: + resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-convert-values@5.1.3: + resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-comments@5.1.2: + resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-duplicates@5.1.0: + resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-empty@5.1.1: + resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-overridden@5.1.0: + resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-import@15.1.0: + resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} + engines: {node: '>=14.0.0'} + peerDependencies: + postcss: ^8.0.0 + + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} + engines: {node: ^12 || ^14 || >= 16} + peerDependencies: + postcss: ^8.4.21 + + postcss-load-config@3.1.4: + resolution: {integrity: sha512-6DiM4E7v4coTE4uzA8U//WhtPwyhiim3eyjEMFCnUpzbrkK9wJHgKDT2mR+HbtSrd/NubVaYTOpSpjUl8NQeRg==} + engines: {node: '>= 10'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss-merge-longhand@5.1.7: + resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-merge-rules@5.1.4: + resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-font-values@5.1.0: + resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-gradients@5.1.1: + resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-params@5.1.4: + resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-selectors@5.2.1: + resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules@4.3.1: + resolution: {integrity: sha512-ItUhSUxBBdNamkT3KzIZwYNNRFKmkJrofvC2nWab3CPKhYBQ1f27XXh1PAPE27Psx58jeelPsxWB/+og+KEH0Q==} + peerDependencies: + postcss: ^8.0.0 + + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} + peerDependencies: + postcss: ^8.2.14 + + postcss-normalize-charset@5.1.0: + resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-display-values@5.1.0: + resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-positions@5.1.1: + resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-repeat-style@5.1.1: + resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-string@5.1.0: + resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-timing-functions@5.1.0: + resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-unicode@5.1.1: + resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-url@5.1.0: + resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-whitespace@5.1.1: + resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-ordered-values@5.1.3: + resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-reduce-initial@5.1.2: + resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-reduce-transforms@5.1.0: + resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-svgo@5.1.0: + resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-unique-selectors@5.1.1: + resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + preact@10.29.0: + resolution: {integrity: sha512-wSAGyk2bYR1c7t3SZ3jHcM6xy0lcBcDel6lODcs9ME6Th++Dx2KU+6D3HD8wMMKGA8Wpw7OMd3/4RGzYRpzwRg==} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prepin@1.0.3: + resolution: {integrity: sha512-0XL2hreherEEvUy0fiaGEfN/ioXFV+JpImqIzQjxk6iBg4jQ2ARKqvC4+BmRD8w/pnpD+lbxvh0Ub+z7yBEjvA==} + hasBin: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + print-js@1.6.0: + resolution: {integrity: sha512-BfnOIzSKbqGRtO4o0rnj/K3681BSd2QUrsIZy/+WdCIugjIswjmx3lDEZpXB2ruGf9d4b3YNINri81+J0FsBWg==} + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + promise.series@0.2.0: + resolution: {integrity: sha512-VWQJyU2bcDTgZw8kpfBpB/ejZASlCrzwz5f2hjb/zlujOEB4oeiAhHygAWq8ubsX2GVkD4kCU5V2dwOTaCY5EQ==} + engines: {node: '>=0.12'} + + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qiniu-js@3.4.1: + resolution: {integrity: sha512-8vxrLqDPlJUk3fUAaTozh3TAT3ww9B5KqGogmGuTiFHnewXDoMxTCSY5z8Ab5UNdrCo6ZxDM07G/o++CICRUFw==} + + qrcodejs2-fixes@0.0.2: + resolution: {integrity: sha512-wMUXYMOixAEJlLnjk5MbLiFaz0gQObWYm/TIFWB5+j7sTY5gPyr09Cx1EpcLYbsgfFdN3wHjrKAhZofTuCBGhg==} + + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + + querystring@0.2.1: + resolution: {integrity: sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==} + engines: {node: '>=0.4.x'} + deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quill-delta@3.6.3: + resolution: {integrity: sha512-wdIGBlcX13tCHOXGMVnnTVFtGRLoP0imqxM696fIPwIf5ODIYUHIvHbZcyvGlZFiFhK5XzDC2lpjbxRhnM05Tg==} + engines: {node: '>=0.10'} + + quill@1.3.7: + resolution: {integrity: sha512-hG/DVzh/TiknWtE6QmWAF/pxoZKYxfe3J/d/+ShUWkDvvkZQVTPeVmUJVu1uE6DDooC4fWTiCLh84ul89oNz5g==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + read-cache@1.0.0: + resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + reinterval@1.1.0: + resolution: {integrity: sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.22.11: + resolution: {integrity: sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==} + engines: {node: '>= 0.4'} + hasBin: true + + 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==} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rollup-plugin-postcss@4.0.2: + resolution: {integrity: sha512-05EaY6zvZdmvPUDi3uCcAQoESDcYnv8ogJJQRp6V5kZ6J6P7uAVJlrTZcaaA20wTH527YTnKfkAoPxWI/jPp4w==} + engines: {node: '>=10'} + peerDependencies: + postcss: 8.x + + rollup-plugin-terser@7.0.2: + resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser + peerDependencies: + rollup: ^2.0.0 + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + rollup@4.60.1: + resolution: {integrity: sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-identifier@0.4.2: + resolution: {integrity: sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sass@1.98.0: + resolution: {integrity: sha512-+4N/u9dZ4PrgzGgPlKnaaRQx64RO0JBKs9sDhQ2pLgN6JQZ25uPQZKQYaBJU48Kd5BxgXoJ4e09Dq7nMcOUW3A==} + engines: {node: '>=14.0.0'} + hasBin: true + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + screenfull@6.0.2: + resolution: {integrity: sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==} + engines: {node: ^14.13.1 || >=16.0.0} + + scroll-into-view-if-needed@2.2.31: + resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==} + + sdk-base@2.0.1: + resolution: {integrity: sha512-eeG26wRwhtwYuKGCDM3LixCaxY27Pa/5lK4rLKhQa7HBjJ3U3Y+f81MMZQRsDw/8SC2Dao/83yJTXJ8aULuN8Q==} + + select@1.1.2: + resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + serialize-javascript@4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slate-history@0.66.0: + resolution: {integrity: sha512-6MWpxGQZiMvSINlCbMW43E2YBSVMCMCIwQfBzGssjWw4kb0qfvj0pIdblWNRQZD0hR6WHP+dHHgGSeVdMWzfng==} + peerDependencies: + slate: '>=0.65.3' + + slate@0.72.8: + resolution: {integrity: sha512-/nJwTswQgnRurpK+bGJFH1oM7naD5qDmHd89JyiKNT2oOKD8marW0QSBtuFnwEbL5aGCS8AmrhXQgNOsn4osAw==} + + snabbdom@3.6.3: + resolution: {integrity: sha512-W2lHLLw2qR2Vv0DcMmcxXqcfdBaIcoN+y/86SmHv8fn4DazEQSH6KN3TjZcWvwujW56OHiiirsbHWZb4vx/0fg==} + engines: {node: '>=12.17.0'} + + sortablejs@1.14.0: + resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==} + + sortablejs@1.15.7: + resolution: {integrity: sha512-Kk8wLQPlS+yi1ZEf48a4+fzHa4yxjC30M/Sr2AnQu+f/MPwvvX9XjZ6OWejiz8crBsLwSq8GHqaxaET7u6ux0A==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + + spark-md5@3.0.2: + resolution: {integrity: sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==} + + split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + + splitpanes@3.2.0: + resolution: {integrity: sha512-K+WKxWdqtKShV33gPjQl769wHxB3glypTOReCvYu/AJd38J+abHlpiF8rK6uBNPMrgw5thHZCI5JkEwsAqa9XA==} + peerDependencies: + vue: ^3.2.0 + + ssf@0.11.2: + resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==} + engines: {node: '>=0.8'} + + ssr-window@3.0.0: + resolution: {integrity: sha512-q+8UfWDg9Itrg0yWK7oe5p/XRCJpJF9OBtXfOPgSJl+u3Xd5KI328RUEvUqSMVM9CiQUEf1QdBzJMkYGErj9QA==} + + stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + stream-http@2.8.2: + resolution: {integrity: sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + stream-wormhole@1.1.0: + resolution: {integrity: sha512-gHFfL3px0Kctd6Po0M8TzEvt3De/xu6cnRrjlfYNhwbhLPLwigI2t1nc6jrzNuaYg5C4YF78PPFuQPzRiqn9ew==} + engines: {node: '>=4.0.0'} + + string-hash@1.1.3: + resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} + + string-split-by@1.0.0: + resolution: {integrity: sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strnum@1.1.2: + resolution: {integrity: sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==} + + strnum@2.2.2: + resolution: {integrity: sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==} + + style-inject@0.3.0: + resolution: {integrity: sha512-IezA2qp+vcdlhJaVm5SOdPPTUu0FCEqfNSli2vRuSIBbu5Nq5UvygTk/VzeCqfLz2Atj3dVII5QBKGZRZ0edzw==} + + stylehacks@5.1.1: + resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + sucrase@3.35.1: + resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svgo@2.8.2: + resolution: {integrity: sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==} + engines: {node: '>=10.13.0'} + hasBin: true + + tailwindcss@3.4.19: + resolution: {integrity: sha512-3ofp+LL8E+pK/JuPLPggVAIaEuhvIz4qNcf3nA1Xn2o/7fb7s/TYpHhwGDv1ZU3PkBluUVaF8PyCHcm48cKLWQ==} + engines: {node: '>=14.0.0'} + hasBin: true + + terser@5.46.1: + resolution: {integrity: sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==} + engines: {node: '>=10'} + hasBin: true + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + tiny-emitter@2.1.0: + resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + to-arraybuffer@1.0.1: + resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-md5@1.3.1: + resolution: {integrity: sha512-DiwiXfwvcTeZ5wCE0z+2A9EseZsztaiZtGrtSaY5JOD7ekPnR/GoIVD5gXZAlK9Na9Kvpo9Waz5rW64WKAWApg==} + engines: {node: '>=12'} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.3.0: + resolution: {integrity: sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type@2.7.3: + resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + unescape@1.0.1: + resolution: {integrity: sha512-O0+af1Gs50lyH1nUu3ZyYS1cRh01Q/kUKatTOkSs7jukXE6/NebucDVxyiDsA9AQ4JC1V1jUH9EO8JX2nMDgGQ==} + engines: {node: '>=0.10.0'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + upgrade@1.1.0: + resolution: {integrity: sha512-NtkVvqVCqsJo5U3mYRum2Tw6uCltOxfIJ/AfTZeTmw6U39IB5X23xF+kRZ9aiPaORqeiQQ7Q209/ibhOvxzwHA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urllib@2.44.0: + resolution: {integrity: sha512-zRCJqdfYllRDA9bXUtx+vccyRqtJPKsw85f44zH7zPD28PIvjMqIgw9VwoTLV7xTBWZsbebUFVHU5ghQcWku2A==} + engines: {node: '>= 0.10.0'} + peerDependencies: + proxy-agent: ^5.0.0 + peerDependenciesMeta: + proxy-agent: + optional: true + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utility@1.18.0: + resolution: {integrity: sha512-PYxZDA+6QtvRvm//++aGdmKG/cI07jNwbROz0Ql+VzFV1+Z0Dy55NI4zZ7RHc9KKpBePNFwoErqIuqQv/cjiTA==} + engines: {node: '>= 0.12.0'} + + vanilla-picker@2.12.3: + resolution: {integrity: sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==} + + vant4-kit@1.0.6: + resolution: {integrity: sha512-xdVFkNTTjvnVY572fpZWrgXVOGkGYWLxvMw4A+K2pnV2ZbETR0n375F0k5eIrwES7oHMSdyM8D/XtSSIZH14Lg==} + peerDependencies: + vue: ^3.4.19 + + vant@4.9.24: + resolution: {integrity: sha512-tP1A7Vjzv1/B1ljb95Jhv9Q9w6acaaZDJvy6wcKrwGgY0gQZlg+FXLZH/AIKZBE3xvYGDUsv/M7AuGcr/Pqd6A==} + peerDependencies: + vue: ^3.0.0 + + vite-plugin-vue-setup-extend@0.4.0: + resolution: {integrity: sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ==} + peerDependencies: + vite: '>=2.0.0' + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vue-clipboard3@2.0.0: + resolution: {integrity: sha512-Q9S7dzWGax7LN5iiSPcu/K1GGm2gcBBlYwmMsUc5/16N6w90cbKow3FnPmPs95sungns4yvd9/+JhbAznECS2A==} + + vue-component-type-helpers@3.2.6: + resolution: {integrity: sha512-O02tnvIfOQVmnvoWwuSydwRoHjZVt8UEBR+2p4rT35p8GAy5VTlWP8o5qXfJR/GWCN0nVZoYWsVUvx2jwgdBmQ==} + + vue-cropper@1.1.4: + resolution: {integrity: sha512-5m98vBsCEI9rbS4JxELxXidtAui3qNyTHLHg67Qbn7g8cg+E6LcnC+hh3SM/p94x6mFh6KRxT1ttnta+wCYqWA==} + + vue-cropperjs@5.0.0: + resolution: {integrity: sha512-RhnC8O33uRZNkn74aiHZwNHnBJOXWlS4P6gsRI0lw4cZlWjKSCywZI9oSI9POlIPI6OYv30jvnHMXGch85tw7w==} + peerDependencies: + vue: '>=3.0.0' + + vue-demi@0.12.5: + resolution: {integrity: sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-demi@0.14.10: + resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==} + engines: {node: '>=12'} + hasBin: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-draggable-plus@0.6.1: + resolution: {integrity: sha512-FbtQ/fuoixiOfTZzG3yoPl4JAo9HJXRHmBQZFB9x2NYCh6pq0TomHf7g5MUmpaDYv+LU2n6BPq2YN9sBO+FbIg==} + peerDependencies: + '@types/sortablejs': ^1.15.0 + '@vue/composition-api': '*' + peerDependenciesMeta: + '@vue/composition-api': + optional: true + + vue-eslint-parser@9.4.3: + resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + + vue-grid-layout@3.0.0-beta1: + resolution: {integrity: sha512-MsW0yfYNtnAO/uDhfZvkP6effxSJxvhAFbIL37x6Rn3vW9xf0WHVefKaSbQMLpSq3mXnR6ut0pg2Cd5lqIIZzg==} + + vue-i18n@9.14.5: + resolution: {integrity: sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==} + engines: {node: '>= 16'} + deprecated: v9 and v10 no longer supported. please migrate to v11. about maintenance status, see https://vue-i18n.intlify.dev/guide/maintenance.html + peerDependencies: + vue: ^3.0.0 + + vue-qr@4.0.9: + resolution: {integrity: sha512-pAISV94T0MNEYA3NGjykUpsXRE2QfaNxlu9ZhEL6CERgqNc21hJYuP3hRVzAWfBQlgO18DPmZTbrFerJC3+Ikw==} + + vue-router@4.6.4: + resolution: {integrity: sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==} + peerDependencies: + vue: ^3.5.0 + + vue@3.5.31: + resolution: {integrity: sha512-iV/sU9SzOlmA/0tygSmjkEN6Jbs3nPoIPFhCMLD2STrjgOU8DX7ZtzMhg4ahVwf5Rp9KoFzcXeB1ZrVbLBp5/Q==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vuedraggable-es@4.1.1: + resolution: {integrity: sha512-F35pjSwC8HS/lnaOd+B59nYR4FZmwuhWAzccK9xftRuWds8SU1TZh5myKVM86j5dFOI7S26O64Kwe7LUHnXjlA==} + peerDependencies: + vue: ^3.2.31 + + vxe-pc-ui@4.13.20: + resolution: {integrity: sha512-AZqFcE5M+KPPIOdPxvQ2Ny+Zf152seKY/o6zqSjHWWzX4EGHYd7dpw3Qrnlp1VT1gVd1Nq599TsSq2MAOR7MaQ==} + + vxe-table@4.18.10: + resolution: {integrity: sha512-8V9WL83pB4PrvgBS6DoDU7dSRxOlJw9ZkVcxDnKBFQkTTnLVvC8HYOJ75uwfRNyo9cALNIpJnSkow2uqaMKbNQ==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wildcard@1.1.2: + resolution: {integrity: sha512-DXukZJxpHA8LuotRwL0pP1+rS6CS7FF2qStDDE1C7DDg2rLud2PXRMuEDYIPhgEezwnlHNL4c+N6MfMTjCGTng==} + + win-release@1.1.1: + resolution: {integrity: sha512-iCRnKVvGxOQdsKhcQId2PXV1vV3J/sDPXKA4Oe9+Eti2nb2ESEsYHRYls/UjoUW3bIc5ZDO8dTH50A/5iVN+bw==} + engines: {node: '>=0.10.0'} + + wmf@1.0.2: + resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==} + engines: {node: '>=0.8'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + word@0.3.0: + resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==} + engines: {node: '>=0.8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xe-utils@3.9.1: + resolution: {integrity: sha512-Ujk5UmoH6Iaqhgz3oGwfCXVcMdUJKlXnfvLABdnMyseMG0eHsX2mcCvLd/8sGlIXtfwsprI9bW7vgcVognLmqQ==} + + xe-utils@4.0.4: + resolution: {integrity: sha512-1IUuTZRHa5w88Y3kEf0O4Y/99O0hIdh5o8EXqmgqyhY3MaT1xWZgS5iuD7pys6v+9JrJOzECb07+6gxRahDsyw==} + + xlsx@0.18.5: + resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==} + engines: {node: '>=0.8'} + hasBin: true + + xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} + engines: {node: '>= 6'} + + yarn@1.22.22: + resolution: {integrity: sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==} + engines: {node: '>=4.0.0'} + hasBin: true + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zrender@5.6.1: + resolution: {integrity: sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==} + +snapshots: + + '@alloc/quick-lru@5.2.0': {} + + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + tslib: 2.8.1 + + '@aws-crypto/crc32c@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + tslib: 2.8.1 + + '@aws-crypto/sha1-browser@5.2.0': + dependencies: + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-locate-window': 3.965.5 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-browser@5.2.0': + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-locate-window': 3.965.5 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + tslib: 2.8.1 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.8.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/client-s3@3.1021.0(aws-crt@1.30.0)': + dependencies: + '@aws-crypto/sha1-browser': 5.2.0 + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.26 + '@aws-sdk/credential-provider-node': 3.972.29(aws-crt@1.30.0) + '@aws-sdk/middleware-bucket-endpoint': 3.972.8 + '@aws-sdk/middleware-expect-continue': 3.972.8 + '@aws-sdk/middleware-flexible-checksums': 3.974.6 + '@aws-sdk/middleware-host-header': 3.972.8 + '@aws-sdk/middleware-location-constraint': 3.972.8 + '@aws-sdk/middleware-logger': 3.972.8 + '@aws-sdk/middleware-recursion-detection': 3.972.9 + '@aws-sdk/middleware-sdk-s3': 3.972.27 + '@aws-sdk/middleware-ssec': 3.972.8 + '@aws-sdk/middleware-user-agent': 3.972.28 + '@aws-sdk/region-config-resolver': 3.972.10 + '@aws-sdk/signature-v4-multi-region': 3.996.15 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@aws-sdk/util-user-agent-browser': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.973.14(aws-crt@1.30.0) + '@smithy/config-resolver': 4.4.13 + '@smithy/core': 3.23.13 + '@smithy/eventstream-serde-browser': 4.2.12 + '@smithy/eventstream-serde-config-resolver': 4.3.12 + '@smithy/eventstream-serde-node': 4.2.12 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/hash-blob-browser': 4.2.13 + '@smithy/hash-node': 4.2.12 + '@smithy/hash-stream-node': 4.2.12 + '@smithy/invalid-dependency': 4.2.12 + '@smithy/md5-js': 4.2.12 + '@smithy/middleware-content-length': 4.2.12 + '@smithy/middleware-endpoint': 4.4.28 + '@smithy/middleware-retry': 4.4.46 + '@smithy/middleware-serde': 4.2.16 + '@smithy/middleware-stack': 4.2.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/node-http-handler': 4.5.1 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.44 + '@smithy/util-defaults-mode-node': 4.2.48 + '@smithy/util-endpoints': 3.3.3 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-retry': 4.2.13 + '@smithy/util-stream': 4.5.21 + '@smithy/util-utf8': 4.2.2 + '@smithy/util-waiter': 4.2.14 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/core@3.973.26': + dependencies: + '@aws-sdk/types': 3.973.6 + '@aws-sdk/xml-builder': 3.972.16 + '@smithy/core': 3.23.13 + '@smithy/node-config-provider': 4.3.12 + '@smithy/property-provider': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/signature-v4': 5.3.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + '@smithy/util-base64': 4.3.2 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@aws-sdk/crc64-nvme@3.972.5': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.24': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.26': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/types': 3.973.6 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/node-http-handler': 4.5.1 + '@smithy/property-provider': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + '@smithy/util-stream': 4.5.21 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.972.28(aws-crt@1.30.0)': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/credential-provider-env': 3.972.24 + '@aws-sdk/credential-provider-http': 3.972.26 + '@aws-sdk/credential-provider-login': 3.972.28(aws-crt@1.30.0) + '@aws-sdk/credential-provider-process': 3.972.24 + '@aws-sdk/credential-provider-sso': 3.972.28(aws-crt@1.30.0) + '@aws-sdk/credential-provider-web-identity': 3.972.28(aws-crt@1.30.0) + '@aws-sdk/nested-clients': 3.996.18(aws-crt@1.30.0) + '@aws-sdk/types': 3.973.6 + '@smithy/credential-provider-imds': 4.2.12 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-login@3.972.28(aws-crt@1.30.0)': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/nested-clients': 3.996.18(aws-crt@1.30.0) + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-node@3.972.29(aws-crt@1.30.0)': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.24 + '@aws-sdk/credential-provider-http': 3.972.26 + '@aws-sdk/credential-provider-ini': 3.972.28(aws-crt@1.30.0) + '@aws-sdk/credential-provider-process': 3.972.24 + '@aws-sdk/credential-provider-sso': 3.972.28(aws-crt@1.30.0) + '@aws-sdk/credential-provider-web-identity': 3.972.28(aws-crt@1.30.0) + '@aws-sdk/types': 3.973.6 + '@smithy/credential-provider-imds': 4.2.12 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-process@3.972.24': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.972.28(aws-crt@1.30.0)': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/nested-clients': 3.996.18(aws-crt@1.30.0) + '@aws-sdk/token-providers': 3.1021.0(aws-crt@1.30.0) + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-web-identity@3.972.28(aws-crt@1.30.0)': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/nested-clients': 3.996.18(aws-crt@1.30.0) + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/crt-loader@3.972.28': + dependencies: + '@aws-sdk/util-user-agent-node': 3.973.14(aws-crt@1.30.0) + aws-crt: 1.30.0 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + '@aws-sdk/middleware-bucket-endpoint@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-arn-parser': 3.972.3 + '@smithy/node-config-provider': 4.3.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-config-provider': 4.2.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-expect-continue@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-flexible-checksums@3.974.6': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@aws-crypto/crc32c': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/core': 3.973.26 + '@aws-sdk/crc64-nvme': 3.972.5 + '@aws-sdk/types': 3.973.6 + '@smithy/is-array-buffer': 4.2.2 + '@smithy/node-config-provider': 4.3.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-stream': 4.5.21 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-host-header@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-location-constraint@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-logger@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-recursion-detection@3.972.9': + dependencies: + '@aws-sdk/types': 3.973.6 + '@aws/lambda-invoke-store': 0.2.4 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-sdk-s3@3.972.27': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-arn-parser': 3.972.3 + '@smithy/core': 3.23.13 + '@smithy/node-config-provider': 4.3.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/signature-v4': 5.3.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-stream': 4.5.21 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-ssec@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-user-agent@3.972.28': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@smithy/core': 3.23.13 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-retry': 4.2.13 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.996.18(aws-crt@1.30.0)': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.26 + '@aws-sdk/middleware-host-header': 3.972.8 + '@aws-sdk/middleware-logger': 3.972.8 + '@aws-sdk/middleware-recursion-detection': 3.972.9 + '@aws-sdk/middleware-user-agent': 3.972.28 + '@aws-sdk/region-config-resolver': 3.972.10 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@aws-sdk/util-user-agent-browser': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.973.14(aws-crt@1.30.0) + '@smithy/config-resolver': 4.4.13 + '@smithy/core': 3.23.13 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/hash-node': 4.2.12 + '@smithy/invalid-dependency': 4.2.12 + '@smithy/middleware-content-length': 4.2.12 + '@smithy/middleware-endpoint': 4.4.28 + '@smithy/middleware-retry': 4.4.46 + '@smithy/middleware-serde': 4.2.16 + '@smithy/middleware-stack': 4.2.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/node-http-handler': 4.5.1 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-body-length-node': 4.2.3 + '@smithy/util-defaults-mode-browser': 4.3.44 + '@smithy/util-defaults-mode-node': 4.2.48 + '@smithy/util-endpoints': 3.3.3 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-retry': 4.2.13 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/region-config-resolver@3.972.10': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/config-resolver': 4.4.13 + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/s3-request-presigner@3.1021.0': + dependencies: + '@aws-sdk/signature-v4-multi-region': 3.996.15 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-format-url': 3.972.8 + '@smithy/middleware-endpoint': 4.4.28 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/signature-v4-crt@3.1021.0': + dependencies: + '@aws-sdk/crt-loader': 3.972.28 + '@aws-sdk/signature-v4-multi-region': 3.996.15 + '@aws-sdk/types': 3.973.6 + '@smithy/querystring-parser': 4.2.12 + '@smithy/signature-v4': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-middleware': 4.2.12 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + '@aws-sdk/signature-v4-multi-region@3.996.15': + dependencies: + '@aws-sdk/middleware-sdk-s3': 3.972.27 + '@aws-sdk/types': 3.973.6 + '@smithy/protocol-http': 5.3.12 + '@smithy/signature-v4': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1021.0(aws-crt@1.30.0)': + dependencies: + '@aws-sdk/core': 3.973.26 + '@aws-sdk/nested-clients': 3.996.18(aws-crt@1.30.0) + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/types@3.973.6': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/util-arn-parser@3.972.3': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/util-endpoints@3.996.5': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-endpoints': 3.3.3 + tslib: 2.8.1 + + '@aws-sdk/util-format-url@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/querystring-builder': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/util-locate-window@3.965.5': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-browser@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-node@3.973.14(aws-crt@1.30.0)': + dependencies: + '@aws-sdk/middleware-user-agent': 3.972.28 + '@aws-sdk/types': 3.973.6 + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-config-provider': 4.2.2 + tslib: 2.8.1 + optionalDependencies: + aws-crt: 1.30.0 + + '@aws-sdk/util-utf8-browser@3.259.0': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.16': + dependencies: + '@smithy/types': 4.13.1 + fast-xml-parser: 5.5.8 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.2.4': {} + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/runtime-corejs2@7.29.2': + dependencies: + core-js: 2.6.12 + + '@babel/runtime@7.29.2': {} + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@ctrl/tinycolor@4.2.0': {} + + '@element-plus/icons-vue@2.3.2(vue@3.5.31(typescript@4.9.5))': + dependencies: + vue: 3.5.31(typescript@4.9.5) + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.14.0 + debug: 4.4.3 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@fast-crud/fast-crud@1.27.10(vue@3.5.31(typescript@4.9.5))': + dependencies: + '@iconify/types': 2.0.0 + file-saver: 2.0.5 + lru-cache: 10.4.3 + vuedraggable-es: 4.1.1(vue@3.5.31(typescript@4.9.5)) + xlsx: 0.18.5 + transitivePeerDependencies: + - vue + + '@fast-crud/fast-extends@1.27.10(aws-crt@1.30.0)(vue@3.5.31(typescript@4.9.5))': + dependencies: + '@aws-sdk/client-s3': 3.1021.0(aws-crt@1.30.0) + '@aws-sdk/s3-request-presigner': 3.1021.0 + '@aws-sdk/signature-v4-crt': 3.1021.0 + '@soerenmartius/vue3-clipboard': 0.1.2 + '@wangeditor/editor': 5.1.23 + '@wangeditor/editor-for-vue': 5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.31(typescript@4.9.5)) + ali-oss: 6.23.0 + cos-js-sdk-v5: 1.10.1 + cropperjs: 1.6.2 + dayjs: 1.11.20 + glob: 10.4.5 + humanize-duration: 3.33.2 + js-yaml: 4.1.1 + jsoneditor: 9.10.5 + lodash-es: 4.17.23 + object-assign: 4.1.1 + qiniu-js: 3.4.1 + quill: 1.3.7 + vue-cropperjs: 5.0.0(vue@3.5.31(typescript@4.9.5)) + transitivePeerDependencies: + - aws-crt + - bufferutil + - debug + - proxy-agent + - supports-color + - utf-8-validate + - vue + + '@fast-crud/ui-element@1.27.10': {} + + '@fast-crud/ui-interface@1.27.10': + dependencies: + lodash-es: 4.17.23 + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/utils@0.2.11': {} + + '@great-dream/dvadmin3-celery-web@3.1.3': + dependencies: + cron-chinese: 1.2.0 + cron-parser: 4.9.0 + json-editor-vue3: 1.1.1 + + '@httptoolkit/websocket-stream@6.0.1': + dependencies: + '@types/ws': 8.18.1 + duplexify: 3.7.1 + inherits: 2.0.4 + isomorphic-ws: 4.0.1(ws@8.20.0) + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + ws: 8.20.0 + xtend: 4.0.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@iconify/types@2.0.0': {} + + '@iconify/vue@4.3.0(vue@3.5.31(typescript@4.9.5))': + dependencies: + '@iconify/types': 2.0.0 + vue: 3.5.31(typescript@4.9.5) + + '@interactjs/actions@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/auto-scroll@1.10.27(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/auto-start@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/core@1.10.27(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/utils': 1.10.27 + + '@interactjs/dev-tools@1.10.27(@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@4.9.5)': + dependencies: + '@interactjs/modifiers': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + vue: 3.5.31(typescript@4.9.5) + transitivePeerDependencies: + - typescript + + '@interactjs/inertia@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/modifiers': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/offset': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/interact@1.10.27': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + + '@interactjs/interactjs@1.10.27(typescript@4.9.5)': + dependencies: + '@interactjs/actions': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/auto-scroll': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/auto-start': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/dev-tools': 1.10.27(@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@4.9.5) + '@interactjs/inertia': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/interact': 1.10.27 + '@interactjs/modifiers': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/offset': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/pointer-events': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/reflow': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + transitivePeerDependencies: + - typescript + + '@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/snappers': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/offset@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/pointer-events@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/reflow@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/core': 1.10.27(@interactjs/utils@1.10.27) + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/snappers@1.10.27(@interactjs/utils@1.10.27)': + dependencies: + '@interactjs/utils': 1.10.27 + optionalDependencies: + '@interactjs/interact': 1.10.27 + + '@interactjs/utils@1.10.27': {} + + '@intlify/core-base@9.14.5': + dependencies: + '@intlify/message-compiler': 9.14.5 + '@intlify/shared': 9.14.5 + + '@intlify/message-compiler@9.14.5': + dependencies: + '@intlify/shared': 9.14.5 + source-map-js: 1.2.1 + + '@intlify/shared@9.14.5': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@meetjs/vant4-kit@1.0.1(vue@3.5.31(typescript@4.9.5))': + dependencies: + vue: 3.5.31(typescript@4.9.5) + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.4 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + optional: true + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@popperjs/core@2.11.8': {} + + '@rolldown/pluginutils@1.0.0-rc.12': {} + + '@rollup/rollup-android-arm-eabi@4.60.1': + optional: true + + '@rollup/rollup-android-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.1': + optional: true + + '@rollup/rollup-darwin-x64@4.60.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.1': + optional: true + + '@smithy/chunked-blob-reader-native@4.2.3': + dependencies: + '@smithy/util-base64': 4.3.2 + tslib: 2.8.1 + + '@smithy/chunked-blob-reader@5.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/config-resolver@4.4.13': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-endpoints': 3.3.3 + '@smithy/util-middleware': 4.2.12 + tslib: 2.8.1 + + '@smithy/core@3.23.13': + dependencies: + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-stream': 4.5.21 + '@smithy/util-utf8': 4.2.2 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.2.12': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/property-provider': 4.2.12 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + tslib: 2.8.1 + + '@smithy/eventstream-codec@4.2.12': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.13.1 + '@smithy/util-hex-encoding': 4.2.2 + tslib: 2.8.1 + + '@smithy/eventstream-serde-browser@4.2.12': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-config-resolver@4.3.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-node@4.2.12': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-universal@4.2.12': + dependencies: + '@smithy/eventstream-codec': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.3.15': + dependencies: + '@smithy/protocol-http': 5.3.12 + '@smithy/querystring-builder': 4.2.12 + '@smithy/types': 4.13.1 + '@smithy/util-base64': 4.3.2 + tslib: 2.8.1 + + '@smithy/hash-blob-browser@4.2.13': + dependencies: + '@smithy/chunked-blob-reader': 5.2.2 + '@smithy/chunked-blob-reader-native': 4.2.3 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/hash-node@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/hash-stream-node@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/invalid-dependency@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/is-array-buffer@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/md5-js@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/middleware-content-length@4.2.12': + dependencies: + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/middleware-endpoint@4.4.28': + dependencies: + '@smithy/core': 3.23.13 + '@smithy/middleware-serde': 4.2.16 + '@smithy/node-config-provider': 4.3.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-middleware': 4.2.12 + tslib: 2.8.1 + + '@smithy/middleware-retry@4.4.46': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/service-error-classification': 4.2.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-retry': 4.2.13 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.2.16': + dependencies: + '@smithy/core': 3.23.13 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/middleware-stack@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/node-config-provider@4.3.12': + dependencies: + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.5.1': + dependencies: + '@smithy/protocol-http': 5.3.12 + '@smithy/querystring-builder': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/property-provider@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/protocol-http@5.3.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/querystring-builder@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + '@smithy/util-uri-escape': 4.2.2 + tslib: 2.8.1 + + '@smithy/querystring-parser@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/service-error-classification@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + + '@smithy/shared-ini-file-loader@4.4.7': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/signature-v4@5.3.12': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-uri-escape': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/smithy-client@4.12.8': + dependencies: + '@smithy/core': 3.23.13 + '@smithy/middleware-endpoint': 4.4.28 + '@smithy/middleware-stack': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-stream': 4.5.21 + tslib: 2.8.1 + + '@smithy/types@4.13.1': + dependencies: + tslib: 2.8.1 + + '@smithy/url-parser@4.2.12': + dependencies: + '@smithy/querystring-parser': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-base64@4.3.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/util-body-length-browser@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-body-length-node@4.2.3': + dependencies: + tslib: 2.8.1 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-buffer-from@4.2.2': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + tslib: 2.8.1 + + '@smithy/util-config-provider@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-defaults-mode-browser@4.3.44': + dependencies: + '@smithy/property-provider': 4.2.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-defaults-mode-node@4.2.48': + dependencies: + '@smithy/config-resolver': 4.4.13 + '@smithy/credential-provider-imds': 4.2.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/property-provider': 4.2.12 + '@smithy/smithy-client': 4.12.8 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-endpoints@3.3.3': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-hex-encoding@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-middleware@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-retry@4.2.13': + dependencies: + '@smithy/service-error-classification': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-stream@4.5.21': + dependencies: + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/node-http-handler': 4.5.1 + '@smithy/types': 4.13.1 + '@smithy/util-base64': 4.3.2 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/util-uri-escape@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-utf8@4.2.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + tslib: 2.8.1 + + '@smithy/util-waiter@4.2.14': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/uuid@1.1.2': + dependencies: + tslib: 2.8.1 + + '@soerenmartius/vue3-clipboard@0.1.2': + dependencies: + clipboard: 2.0.11 + + '@sphinxxxx/color-conversion@2.2.2': {} + + '@sxzz/popperjs-es@2.11.8': {} + + '@transloadit/prettier-bytes@0.0.7': {} + + '@types/estree@1.0.8': {} + + '@types/event-emitter@0.3.5': {} + + '@types/json-schema@7.0.15': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.24 + + '@types/lodash@4.17.24': {} + + '@types/node@18.19.130': + dependencies: + undici-types: 5.26.5 + + '@types/nprogress@0.2.3': {} + + '@types/semver@7.7.1': {} + + '@types/sortablejs@1.15.9': {} + + '@types/web-bluetooth@0.0.16': {} + + '@types/web-bluetooth@0.0.20': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 18.19.130 + + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.4.3 + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.7.4 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + debug: 4.4.3 + eslint: 8.57.1 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.4.3 + eslint: 8.57.1 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.3 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.7.4 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/structured-clone@1.3.0': {} + + '@uppy/companion-client@2.2.2': + dependencies: + '@uppy/utils': 4.1.3 + namespace-emitter: 2.0.1 + + '@uppy/core@2.3.4': + dependencies: + '@transloadit/prettier-bytes': 0.0.7 + '@uppy/store-default': 2.1.1 + '@uppy/utils': 4.1.3 + lodash.throttle: 4.1.1 + mime-match: 1.0.2 + namespace-emitter: 2.0.1 + nanoid: 3.3.11 + preact: 10.29.0 + + '@uppy/store-default@2.1.1': {} + + '@uppy/utils@4.1.3': + dependencies: + lodash.throttle: 4.1.1 + + '@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4)': + dependencies: + '@uppy/companion-client': 2.2.2 + '@uppy/core': 2.3.4 + '@uppy/utils': 4.1.3 + nanoid: 3.3.11 + + '@vant/popperjs@1.3.0': {} + + '@vant/use@1.6.0(vue@3.5.31(typescript@4.9.5))': + dependencies: + vue: 3.5.31(typescript@4.9.5) + + '@vitejs/plugin-vue-jsx@4.2.0(vite@5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1))(vue@3.5.31(typescript@4.9.5))': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + '@rolldown/pluginutils': 1.0.0-rc.12 + '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.29.0) + vite: 5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1) + vue: 3.5.31(typescript@4.9.5) + transitivePeerDependencies: + - supports-color + + '@vitejs/plugin-vue@5.2.4(vite@5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1))(vue@3.5.31(typescript@4.9.5))': + dependencies: + vite: 5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1) + vue: 3.5.31(typescript@4.9.5) + + '@vue/babel-helper-vue-transform-on@1.5.0': {} + + '@vue/babel-plugin-jsx@1.5.0(@babel/core@7.29.0)': + dependencies: + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@vue/babel-helper-vue-transform-on': 1.5.0 + '@vue/babel-plugin-resolve-type': 1.5.0(@babel/core@7.29.0) + '@vue/shared': 3.5.31 + optionalDependencies: + '@babel/core': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@vue/babel-plugin-resolve-type@1.5.0(@babel/core@7.29.0)': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/parser': 7.29.2 + '@vue/compiler-sfc': 3.5.31 + transitivePeerDependencies: + - supports-color + + '@vue/compiler-core@3.5.31': + dependencies: + '@babel/parser': 7.29.2 + '@vue/shared': 3.5.31 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.31': + dependencies: + '@vue/compiler-core': 3.5.31 + '@vue/shared': 3.5.31 + + '@vue/compiler-sfc@3.5.31': + dependencies: + '@babel/parser': 7.29.2 + '@vue/compiler-core': 3.5.31 + '@vue/compiler-dom': 3.5.31 + '@vue/compiler-ssr': 3.5.31 + '@vue/shared': 3.5.31 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.8 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.31': + dependencies: + '@vue/compiler-dom': 3.5.31 + '@vue/shared': 3.5.31 + + '@vue/devtools-api@6.6.4': {} + + '@vue/reactivity@3.5.31': + dependencies: + '@vue/shared': 3.5.31 + + '@vue/runtime-core@3.5.31': + dependencies: + '@vue/reactivity': 3.5.31 + '@vue/shared': 3.5.31 + + '@vue/runtime-dom@3.5.31': + dependencies: + '@vue/reactivity': 3.5.31 + '@vue/runtime-core': 3.5.31 + '@vue/shared': 3.5.31 + csstype: 3.2.3 + + '@vue/server-renderer@3.5.31(vue@3.5.31(typescript@4.9.5))': + dependencies: + '@vue/compiler-ssr': 3.5.31 + '@vue/shared': 3.5.31 + vue: 3.5.31(typescript@4.9.5) + + '@vue/shared@3.5.31': {} + + '@vueuse/core@12.0.0(typescript@4.9.5)': + dependencies: + '@types/web-bluetooth': 0.0.20 + '@vueuse/metadata': 12.0.0 + '@vueuse/shared': 12.0.0(typescript@4.9.5) + vue: 3.5.31(typescript@4.9.5) + transitivePeerDependencies: + - typescript + + '@vueuse/core@9.13.0(vue@3.5.31(typescript@4.9.5))': + dependencies: + '@types/web-bluetooth': 0.0.16 + '@vueuse/metadata': 9.13.0 + '@vueuse/shared': 9.13.0(vue@3.5.31(typescript@4.9.5)) + vue-demi: 0.14.10(vue@3.5.31(typescript@4.9.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vueuse/metadata@12.0.0': {} + + '@vueuse/metadata@9.13.0': {} + + '@vueuse/shared@12.0.0(typescript@4.9.5)': + dependencies: + vue: 3.5.31(typescript@4.9.5) + transitivePeerDependencies: + - typescript + + '@vueuse/shared@9.13.0(vue@3.5.31(typescript@4.9.5))': + dependencies: + vue-demi: 0.14.10(vue@3.5.31(typescript@4.9.5)) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + + '@vxe-ui/core@4.4.3(vue@3.5.31(typescript@4.9.5))': + dependencies: + dom-zindex: 1.0.6 + vue: 3.5.31(typescript@4.9.5) + xe-utils: 4.0.4 + + '@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)': + dependencies: + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + dom7: 3.0.0 + is-url: 1.2.4 + lodash.throttle: 4.1.1 + nanoid: 3.3.11 + slate: 0.72.8 + snabbdom: 3.6.3 + + '@wangeditor/code-highlight@1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3)': + dependencies: + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + dom7: 3.0.0 + prismjs: 1.30.0 + slate: 0.72.8 + snabbdom: 3.6.3 + + '@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)': + dependencies: + '@types/event-emitter': 0.3.5 + '@uppy/core': 2.3.4 + '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) + dom7: 3.0.0 + event-emitter: 0.3.5 + html-void-elements: 2.0.1 + i18next: 20.6.1 + is-hotkey: 0.2.0 + lodash.camelcase: 4.3.0 + lodash.clonedeep: 4.5.0 + lodash.debounce: 4.0.8 + lodash.foreach: 4.5.0 + lodash.isequal: 4.5.0 + lodash.throttle: 4.1.1 + lodash.toarray: 4.4.0 + nanoid: 3.3.11 + scroll-into-view-if-needed: 2.2.31 + slate: 0.72.8 + slate-history: 0.66.0(slate@0.72.8) + snabbdom: 3.6.3 + + '@wangeditor/editor-for-vue@5.1.12(@wangeditor/editor@5.1.23)(vue@3.5.31(typescript@4.9.5))': + dependencies: + '@wangeditor/editor': 5.1.23 + vue: 3.5.31(typescript@4.9.5) + + '@wangeditor/editor@5.1.23': + dependencies: + '@uppy/core': 2.3.4 + '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) + '@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + '@wangeditor/code-highlight': 1.0.3(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + '@wangeditor/list-module': 1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3) + '@wangeditor/table-module': 1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + '@wangeditor/upload-image-module': 1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.3) + '@wangeditor/video-module': 1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + dom7: 3.0.0 + is-hotkey: 0.2.0 + lodash.camelcase: 4.3.0 + lodash.clonedeep: 4.5.0 + lodash.debounce: 4.0.8 + lodash.foreach: 4.5.0 + lodash.isequal: 4.5.0 + lodash.throttle: 4.1.1 + lodash.toarray: 4.4.0 + nanoid: 3.3.11 + slate: 0.72.8 + snabbdom: 3.6.3 + + '@wangeditor/list-module@1.0.5(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(slate@0.72.8)(snabbdom@3.6.3)': + dependencies: + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + dom7: 3.0.0 + slate: 0.72.8 + snabbdom: 3.6.3 + + '@wangeditor/table-module@1.1.4(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)': + dependencies: + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + dom7: 3.0.0 + lodash.isequal: 4.5.0 + lodash.throttle: 4.1.1 + nanoid: 3.3.11 + slate: 0.72.8 + snabbdom: 3.6.3 + + '@wangeditor/upload-image-module@1.0.2(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/basic-modules@1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.foreach@4.5.0)(slate@0.72.8)(snabbdom@3.6.3)': + dependencies: + '@uppy/core': 2.3.4 + '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) + '@wangeditor/basic-modules': 1.1.7(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(lodash.throttle@4.1.1)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + dom7: 3.0.0 + lodash.foreach: 4.5.0 + slate: 0.72.8 + snabbdom: 3.6.3 + + '@wangeditor/video-module@1.1.4(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(@wangeditor/core@1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3))(dom7@3.0.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3)': + dependencies: + '@uppy/core': 2.3.4 + '@uppy/xhr-upload': 2.1.3(@uppy/core@2.3.4) + '@wangeditor/core': 1.1.19(@uppy/core@2.3.4)(@uppy/xhr-upload@2.1.3(@uppy/core@2.3.4))(dom7@3.0.0)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.isequal@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@3.3.11)(slate@0.72.8)(snabbdom@3.6.3) + dom7: 3.0.0 + nanoid: 3.3.11 + slate: 0.72.8 + snabbdom: 3.6.3 + + ace-builds@1.43.6: {} + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + address@1.2.2: {} + + adler-32@1.3.1: {} + + agentkeepalive@3.5.3: + dependencies: + humanize-ms: 1.2.1 + + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ali-oss@6.23.0: + dependencies: + address: 1.2.2 + agentkeepalive: 3.5.3 + bowser: 1.9.4 + copy-to: 2.0.1 + dateformat: 2.2.0 + debug: 4.4.3 + destroy: 1.2.0 + end-or-error: 1.0.1 + get-ready: 1.0.0 + humanize-ms: 1.2.1 + is-type-of: 1.4.0 + js-base64: 2.6.4 + jstoxml: 2.2.9 + lodash: 4.17.21 + merge-descriptors: 1.0.3 + mime: 2.6.0 + platform: 1.3.6 + pump: 3.0.4 + qs: 6.15.0 + sdk-base: 2.0.1 + stream-http: 2.8.2 + stream-wormhole: 1.1.0 + urllib: 2.44.0 + utility: 1.18.0 + xml2js: 0.6.2 + transitivePeerDependencies: + - proxy-agent + - supports-color + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.3: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + arg@5.0.2: {} + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + astronomia@4.2.0: {} + + async-validator@4.2.5: {} + + asynckit@0.4.0: {} + + autoprefixer@10.4.27(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001782 + fraction.js: 5.3.4 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + aws-crt@1.30.0: + dependencies: + '@aws-sdk/util-utf8-browser': 3.259.0 + '@httptoolkit/websocket-stream': 6.0.1 + axios: 1.14.0 + buffer: 6.0.3 + crypto-js: 4.2.0 + mqtt: 4.3.8 + process: 0.11.10 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + axios@1.14.0: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.10.13: {} + + batch-processor@1.0.0: {} + + binary-extensions@2.3.0: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + boolbase@1.0.0: {} + + bowser@1.9.4: {} + + bowser@2.14.1: {} + + brace-expansion@1.1.13: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.3: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.13 + caniuse-lite: 1.0.30001782 + electron-to-chromium: 1.5.330 + node-releases: 2.0.36 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + builtin-status-codes@3.0.0: {} + + caldate@2.0.5: + dependencies: + moment-timezone: 0.5.48 + + 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.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camelcase-css@2.0.1: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001782 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001782: {} + + cfb@1.2.2: + dependencies: + adler-32: 1.3.1 + crc-32: 1.2.2 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + claygl@1.3.0: {} + + clipboard@2.0.11: + dependencies: + good-listener: 1.2.2 + select: 1.1.2 + tiny-emitter: 2.1.0 + + clone@2.1.2: {} + + codepage@1.15.0: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colord@2.9.3: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@7.2.0: {} + + commist@1.1.0: + dependencies: + leven: 2.1.0 + minimist: 1.2.8 + + compute-scroll-into-view@1.0.20: {} + + concat-map@0.0.1: {} + + concat-stream@2.0.0: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + + concat-with-sourcemaps@1.1.0: + dependencies: + source-map: 0.6.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + copy-anything@3.0.5: + dependencies: + is-what: 4.1.16 + + copy-to@2.0.1: {} + + core-js@2.6.12: {} + + core-util-is@1.0.3: {} + + cos-js-sdk-v5@1.10.1: + dependencies: + fast-xml-parser: 4.5.0 + + countup.js@2.10.0: {} + + crc-32@1.2.2: {} + + cron-chinese@1.2.0: {} + + cron-parser@4.9.0: + dependencies: + luxon: 3.7.2 + + cropperjs@1.6.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-js@4.2.0: {} + + css-declaration-sorter@6.4.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-what@6.2.2: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@5.2.14(postcss@8.5.8): + dependencies: + css-declaration-sorter: 6.4.1(postcss@8.5.8) + cssnano-utils: 3.1.0(postcss@8.5.8) + postcss: 8.5.8 + postcss-calc: 8.2.4(postcss@8.5.8) + postcss-colormin: 5.3.1(postcss@8.5.8) + postcss-convert-values: 5.1.3(postcss@8.5.8) + postcss-discard-comments: 5.1.2(postcss@8.5.8) + postcss-discard-duplicates: 5.1.0(postcss@8.5.8) + postcss-discard-empty: 5.1.1(postcss@8.5.8) + postcss-discard-overridden: 5.1.0(postcss@8.5.8) + postcss-merge-longhand: 5.1.7(postcss@8.5.8) + postcss-merge-rules: 5.1.4(postcss@8.5.8) + postcss-minify-font-values: 5.1.0(postcss@8.5.8) + postcss-minify-gradients: 5.1.1(postcss@8.5.8) + postcss-minify-params: 5.1.4(postcss@8.5.8) + postcss-minify-selectors: 5.2.1(postcss@8.5.8) + postcss-normalize-charset: 5.1.0(postcss@8.5.8) + postcss-normalize-display-values: 5.1.0(postcss@8.5.8) + postcss-normalize-positions: 5.1.1(postcss@8.5.8) + postcss-normalize-repeat-style: 5.1.1(postcss@8.5.8) + postcss-normalize-string: 5.1.0(postcss@8.5.8) + postcss-normalize-timing-functions: 5.1.0(postcss@8.5.8) + postcss-normalize-unicode: 5.1.1(postcss@8.5.8) + postcss-normalize-url: 5.1.0(postcss@8.5.8) + postcss-normalize-whitespace: 5.1.1(postcss@8.5.8) + postcss-ordered-values: 5.1.3(postcss@8.5.8) + postcss-reduce-initial: 5.1.2(postcss@8.5.8) + postcss-reduce-transforms: 5.1.0(postcss@8.5.8) + postcss-svgo: 5.1.0(postcss@8.5.8) + postcss-unique-selectors: 5.1.1(postcss@8.5.8) + + cssnano-utils@3.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + cssnano@5.1.15(postcss@8.5.8): + dependencies: + cssnano-preset-default: 5.2.14(postcss@8.5.8) + lilconfig: 2.1.0 + postcss: 8.5.8 + yaml: 1.10.3 + + csso@4.2.0: + dependencies: + css-tree: 1.1.3 + + csstype@3.2.3: {} + + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.3 + + date-bengali-revised@2.0.2: {} + + date-chinese@2.1.4: + dependencies: + astronomia: 4.2.0 + + date-easter@1.0.3: {} + + date-holidays-parser@3.4.7: + dependencies: + astronomia: 4.2.0 + caldate: 2.0.5 + date-bengali-revised: 2.0.2 + date-chinese: 2.1.4 + date-easter: 1.0.3 + deepmerge: 4.3.1 + jalaali-js: 1.2.8 + moment-timezone: 0.5.48 + + date-holidays@3.26.12: + dependencies: + date-holidays-parser: 3.4.7 + js-yaml: 4.1.1 + lodash: 4.18.0 + prepin: 1.0.3 + + dateformat@2.2.0: {} + + dayjs@1.11.20: {} + + debounce@1.2.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-equal@1.1.2: + dependencies: + is-arguments: 1.2.0 + is-date-object: 1.1.0 + is-regex: 1.2.1 + object-is: 1.1.6 + object-keys: 1.1.1 + regexp.prototype.flags: 1.5.4 + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + default-user-agent@1.0.0: + dependencies: + os-name: 1.0.3 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + delegate@3.2.0: {} + + destroy@1.2.0: {} + + detect-libc@2.1.2: + optional: true + + didyoumean@1.2.2: {} + + digest-header@1.1.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dlv@1.1.3: {} + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-zindex@1.0.6: {} + + dom7@3.0.0: + dependencies: + ssr-window: 3.0.0 + + domelementtype@2.3.0: {} + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexify@3.7.1: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.3 + + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + e-icon-picker@2.1.1(vue@3.5.31(typescript@4.9.5)): + dependencies: + '@popperjs/core': 2.11.8 + '@vue/shared': 3.5.31 + '@vueuse/core': 9.13.0(vue@3.5.31(typescript@4.9.5)) + debounce: 1.2.1 + vue: 3.5.31(typescript@4.9.5) + transitivePeerDependencies: + - '@vue/composition-api' + + eastasianwidth@0.2.0: {} + + echarts-gl@2.0.9(echarts@5.6.0): + dependencies: + claygl: 1.3.0 + echarts: 5.6.0 + zrender: 5.6.1 + + echarts-wordcloud@2.1.0(echarts@5.6.0): + dependencies: + echarts: 5.6.0 + + echarts@5.6.0: + dependencies: + tslib: 2.3.0 + zrender: 5.6.1 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.330: {} + + element-plus@2.13.6(typescript@4.9.5)(vue@3.5.31(typescript@4.9.5)): + dependencies: + '@ctrl/tinycolor': 4.2.0 + '@element-plus/icons-vue': 2.3.2(vue@3.5.31(typescript@4.9.5)) + '@floating-ui/dom': 1.7.6 + '@popperjs/core': '@sxzz/popperjs-es@2.11.8' + '@types/lodash': 4.17.24 + '@types/lodash-es': 4.17.12 + '@vueuse/core': 12.0.0(typescript@4.9.5) + async-validator: 4.2.5 + dayjs: 1.11.20 + lodash: 4.18.0 + lodash-es: 4.17.23 + lodash-unified: 1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.23)(lodash@4.18.0) + memoize-one: 6.0.0 + normalize-wheel-es: 1.2.0 + vue: 3.5.31(typescript@4.9.5) + vue-component-type-helpers: 3.2.6 + transitivePeerDependencies: + - typescript + + element-resize-detector@1.2.4: + dependencies: + batch-processor: 1.0.0 + + element-tree-line@0.2.1(vue@3.5.31(typescript@4.9.5)): + dependencies: + vue: 3.5.31(typescript@4.9.5) + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + end-or-error@1.0.1: {} + + entities@2.2.0: {} + + entities@7.0.1: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + optional: true + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + eslint-plugin-vue@9.33.0(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + eslint: 8.57.1 + globals: 13.24.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.1.2 + semver: 7.7.4 + vue-eslint-parser: 9.4.3(eslint@8.57.1) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.2 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.0 + ajv: 6.14.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.3 + + espree@9.6.1: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 3.4.3 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-walker@0.6.1: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + + eventemitter3@2.0.3: {} + + eventemitter3@4.0.7: {} + + ext@1.7.0: + dependencies: + type: 2.7.3 + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.1.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-xml-builder@1.1.4: + dependencies: + path-expression-matcher: 1.2.0 + + fast-xml-parser@4.5.0: + dependencies: + strnum: 1.1.2 + + fast-xml-parser@5.5.8: + dependencies: + fast-xml-builder: 1.1.4 + path-expression-matcher: 1.2.0 + strnum: 2.2.2 + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + file-saver@2.0.5: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + rimraf: 3.0.2 + + flatted@3.4.2: {} + + follow-redirects@1.15.11: {} + + font-awesome@4.7.0: {} + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.5: + 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 + + formstream@1.5.2: + dependencies: + destroy: 1.2.0 + mime: 2.6.0 + node-hex: 1.0.1 + pause-stream: 0.0.11 + + frac@1.1.2: {} + + fraction.js@5.3.4: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + functions-have-names@1.2.3: {} + + generic-names@4.0.0: + dependencies: + loader-utils: 3.3.1 + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-ready@1.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.0 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + good-listener@1.2.2: + dependencies: + delegate: 3.2.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: + optional: true + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + help-me@3.0.0: + dependencies: + glob: 7.2.3 + readable-stream: 3.6.2 + + html-void-elements@2.0.1: {} + + humanize-duration@3.33.2: {} + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + i18next@20.6.1: + dependencies: + '@babel/runtime': 7.29.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + icss-replace-symbols@1.1.0: {} + + icss-utils@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + image-size@0.5.5: + optional: true + + immer@9.0.21: {} + + immutable@5.1.5: {} + + import-cwd@3.0.0: + dependencies: + import-from: 3.0.0 + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-from@3.0.0: + dependencies: + resolve-from: 5.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-class-hotfix@0.0.6: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extendable@0.1.1: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hotkey@0.2.0: {} + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-object@5.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-type-of@1.4.0: + dependencies: + core-util-is: 1.0.3 + is-class-hotfix: 0.0.6 + isstream: 0.1.2 + + is-url@1.2.4: {} + + is-what@4.1.16: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isomorphic-ws@4.0.1(ws@8.20.0): + dependencies: + ws: 8.20.0 + + isstream@0.1.2: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jalaali-js@1.2.8: {} + + javascript-natural-sort@0.7.1: {} + + jest-worker@26.6.2: + dependencies: + '@types/node': 18.19.130 + merge-stream: 2.0.0 + supports-color: 7.2.0 + + jiti@1.21.7: {} + + jmespath@0.16.0: {} + + js-base64@2.6.4: {} + + js-binary-schema-parser@2.0.3: {} + + js-cookie@3.0.5: {} + + js-sdsl@4.3.0: {} + + js-table2excel@1.1.2: {} + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-editor-vue3@1.1.1: + dependencies: + jsoneditor: 9.10.5 + + json-schema-traverse@0.4.1: {} + + json-source-map@0.6.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsoneditor@9.10.5: + dependencies: + ace-builds: 1.43.6 + ajv: 6.14.0 + javascript-natural-sort: 0.7.1 + jmespath: 0.16.0 + json-source-map: 0.6.1 + jsonrepair: 3.1.0 + mobius1-selectr: 2.4.13 + picomodal: 3.0.0 + vanilla-picker: 2.12.3 + + jsonrepair@3.1.0: {} + + jsplumb@2.15.6: {} + + jstoxml@2.2.9: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + less@4.6.4: + dependencies: + copy-anything: 3.0.5 + parse-node-version: 1.0.1 + optionalDependencies: + errno: 0.1.8 + graceful-fs: 4.2.11 + image-size: 0.5.5 + make-dir: 2.1.0 + mime: 1.6.0 + needle: 3.5.0 + source-map: 0.6.1 + + leven@2.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@2.1.0: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + loader-utils@3.3.1: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.23: {} + + lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.23)(lodash@4.18.0): + dependencies: + '@types/lodash-es': 4.17.12 + lodash: 4.18.0 + lodash-es: 4.17.23 + + lodash.camelcase@4.3.0: {} + + lodash.clonedeep@4.5.0: {} + + lodash.debounce@4.0.8: {} + + lodash.foreach@4.5.0: {} + + lodash.isequal@4.5.0: {} + + lodash.memoize@4.1.2: {} + + lodash.merge@4.6.2: {} + + lodash.throttle@4.1.1: {} + + lodash.toarray@4.4.0: {} + + lodash.uniq@4.5.0: {} + + lodash@4.17.21: {} + + lodash@4.18.0: {} + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lunar-javascript@1.7.7: {} + + luxon@3.7.2: {} + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + optional: true + + math-intrinsics@1.1.0: {} + + mdn-data@2.0.14: {} + + memoize-one@6.0.0: {} + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.52.0: {} + + mime-match@1.0.2: + dependencies: + wildcard: 1.1.2 + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: + optional: true + + mime@2.6.0: {} + + mimic-response@3.1.0: {} + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.13 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.0.3 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.0.3 + + minimist@1.2.8: {} + + minipass@7.1.3: {} + + mitt@2.1.0: {} + + mitt@3.0.1: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mobius1-selectr@2.4.13: {} + + moment-timezone@0.5.48: + dependencies: + moment: 2.30.1 + + moment@2.30.1: {} + + mqtt-packet@6.10.0: + dependencies: + bl: 4.1.0 + debug: 4.4.3 + process-nextick-args: 2.0.1 + transitivePeerDependencies: + - supports-color + + mqtt@4.3.8: + dependencies: + commist: 1.1.0 + concat-stream: 2.0.0 + debug: 4.4.3 + duplexify: 4.1.3 + help-me: 3.0.0 + inherits: 2.0.4 + lru-cache: 6.0.0 + minimist: 1.2.8 + mqtt-packet: 6.10.0 + number-allocator: 1.0.14 + pump: 3.0.4 + readable-stream: 3.6.2 + reinterval: 1.1.0 + rfdc: 1.4.1 + split2: 3.2.2 + ws: 7.5.10 + xtend: 4.0.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + namespace-emitter@2.0.1: {} + + nanoid@3.3.11: {} + + natural-compare-lite@1.4.0: {} + + natural-compare@1.4.0: {} + + needle@3.5.0: + dependencies: + iconv-lite: 0.6.3 + sax: 1.6.0 + optional: true + + next-tick@1.1.0: {} + + node-addon-api@7.1.1: + optional: true + + node-hex@1.0.1: {} + + node-releases@2.0.36: {} + + normalize-path@3.0.0: {} + + normalize-url@6.1.0: {} + + normalize-wheel-es@1.2.0: {} + + nprogress@0.2.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + number-allocator@1.0.14: + dependencies: + debug: 4.4.3 + js-sdsl: 4.3.0 + transitivePeerDependencies: + - supports-color + + object-assign@4.1.1: {} + + object-hash@3.0.0: {} + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + os-name@1.0.3: + dependencies: + osx-release: 1.1.0 + win-release: 1.1.1 + + osx-release@1.1.0: + dependencies: + minimist: 1.2.8 + + p-finally@1.0.0: {} + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + package-json-from-dist@1.0.1: {} + + parchment@1.1.4: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parenthesis@3.1.8: {} + + parse-node-version@1.0.1: {} + + path-exists@4.0.0: {} + + path-expression-matcher@1.2.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + path-type@4.0.0: {} + + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + picomodal@3.0.0: {} + + pify@2.3.0: {} + + pify@4.0.1: + optional: true + + pify@5.0.0: {} + + pinia-plugin-persist@1.0.0(pinia@2.3.1(typescript@4.9.5)(vue@3.5.31(typescript@4.9.5)))(vue@3.5.31(typescript@4.9.5)): + dependencies: + pinia: 2.3.1(typescript@4.9.5)(vue@3.5.31(typescript@4.9.5)) + vue: 3.5.31(typescript@4.9.5) + vue-demi: 0.12.5(vue@3.5.31(typescript@4.9.5)) + + pinia@2.3.1(typescript@4.9.5)(vue@3.5.31(typescript@4.9.5)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.31(typescript@4.9.5) + vue-demi: 0.14.10(vue@3.5.31(typescript@4.9.5)) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@vue/composition-api' + + pirates@4.0.7: {} + + platform@1.3.6: {} + + postcss-calc@8.2.4(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-colormin@5.3.1(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-convert-values@5.1.3(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@5.1.2(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-discard-duplicates@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-discard-empty@5.1.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-discard-overridden@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-import@15.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + read-cache: 1.0.0 + resolve: 1.22.11 + + postcss-js@4.1.0(postcss@8.5.8): + dependencies: + camelcase-css: 2.0.1 + postcss: 8.5.8 + + postcss-load-config@3.1.4(postcss@8.5.8): + dependencies: + lilconfig: 2.1.0 + yaml: 1.10.3 + optionalDependencies: + postcss: 8.5.8 + + postcss-load-config@6.0.1(jiti@1.21.7)(postcss@8.5.8): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + jiti: 1.21.7 + postcss: 8.5.8 + + postcss-merge-longhand@5.1.7(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + stylehacks: 5.1.1(postcss@8.5.8) + + postcss-merge-rules@5.1.4(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-utils: 3.1.0(postcss@8.5.8) + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@5.1.1(postcss@8.5.8): + dependencies: + colord: 2.9.3 + cssnano-utils: 3.1.0(postcss@8.5.8) + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-minify-params@5.1.4(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + cssnano-utils: 3.1.0(postcss@8.5.8) + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@5.2.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-modules-extract-imports@3.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.8): + dependencies: + icss-utils: 5.1.0(postcss@8.5.8) + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@3.2.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 7.1.1 + + postcss-modules-values@4.0.0(postcss@8.5.8): + dependencies: + icss-utils: 5.1.0(postcss@8.5.8) + postcss: 8.5.8 + + postcss-modules@4.3.1(postcss@8.5.8): + dependencies: + generic-names: 4.0.0 + icss-replace-symbols: 1.1.0 + lodash.camelcase: 4.3.0 + postcss: 8.5.8 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.8) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.8) + postcss-modules-scope: 3.2.1(postcss@8.5.8) + postcss-modules-values: 4.0.0(postcss@8.5.8) + string-hash: 1.1.3 + + postcss-nested@6.2.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-normalize-charset@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + + postcss-normalize-display-values@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@5.1.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@5.1.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@5.1.1(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@5.1.0(postcss@8.5.8): + dependencies: + normalize-url: 6.1.0 + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@5.1.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@5.1.3(postcss@8.5.8): + dependencies: + cssnano-utils: 3.1.0(postcss@8.5.8) + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@5.1.2(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.8 + + postcss-reduce-transforms@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@5.1.0(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-value-parser: 4.2.0 + svgo: 2.8.2 + + postcss-unique-selectors@5.1.1(postcss@8.5.8): + dependencies: + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + postcss-value-parser@4.2.0: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + preact@10.29.0: {} + + prelude-ls@1.2.1: {} + + prepin@1.0.3: {} + + prettier@2.8.8: {} + + print-js@1.6.0: {} + + prismjs@1.30.0: {} + + process-nextick-args@2.0.1: {} + + process@0.11.10: {} + + promise.series@0.2.0: {} + + proxy-from-env@2.1.0: {} + + prr@1.0.1: + optional: true + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode@2.3.1: {} + + qiniu-js@3.4.1: + dependencies: + '@babel/runtime-corejs2': 7.29.2 + querystring: 0.2.1 + spark-md5: 3.0.2 + + qrcodejs2-fixes@0.0.2: {} + + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + + querystring@0.2.1: {} + + queue-microtask@1.2.3: {} + + quill-delta@3.6.3: + dependencies: + deep-equal: 1.1.2 + extend: 3.0.2 + fast-diff: 1.1.2 + + quill@1.3.7: + dependencies: + clone: 2.1.2 + deep-equal: 1.1.2 + eventemitter3: 2.0.3 + extend: 3.0.2 + parchment: 1.1.4 + quill-delta: 3.6.3 + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + read-cache@1.0.0: + dependencies: + pify: 2.3.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + readdirp@4.1.2: {} + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + reinterval@1.1.0: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve@1.22.11: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rfdc@1.4.1: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rollup-plugin-postcss@4.0.2(postcss@8.5.8): + dependencies: + chalk: 4.1.2 + concat-with-sourcemaps: 1.1.0 + cssnano: 5.1.15(postcss@8.5.8) + import-cwd: 3.0.0 + p-queue: 6.6.2 + pify: 5.0.0 + postcss: 8.5.8 + postcss-load-config: 3.1.4(postcss@8.5.8) + postcss-modules: 4.3.1(postcss@8.5.8) + promise.series: 0.2.0 + resolve: 1.22.11 + rollup-pluginutils: 2.8.2 + safe-identifier: 0.4.2 + style-inject: 0.3.0 + transitivePeerDependencies: + - ts-node + + rollup-plugin-terser@7.0.2(rollup@4.60.1): + dependencies: + '@babel/code-frame': 7.29.0 + jest-worker: 26.6.2 + rollup: 4.60.1 + serialize-javascript: 4.0.0 + terser: 5.46.1 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + rollup@4.60.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.1 + '@rollup/rollup-android-arm64': 4.60.1 + '@rollup/rollup-darwin-arm64': 4.60.1 + '@rollup/rollup-darwin-x64': 4.60.1 + '@rollup/rollup-freebsd-arm64': 4.60.1 + '@rollup/rollup-freebsd-x64': 4.60.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.1 + '@rollup/rollup-linux-arm-musleabihf': 4.60.1 + '@rollup/rollup-linux-arm64-gnu': 4.60.1 + '@rollup/rollup-linux-arm64-musl': 4.60.1 + '@rollup/rollup-linux-loong64-gnu': 4.60.1 + '@rollup/rollup-linux-loong64-musl': 4.60.1 + '@rollup/rollup-linux-ppc64-gnu': 4.60.1 + '@rollup/rollup-linux-ppc64-musl': 4.60.1 + '@rollup/rollup-linux-riscv64-gnu': 4.60.1 + '@rollup/rollup-linux-riscv64-musl': 4.60.1 + '@rollup/rollup-linux-s390x-gnu': 4.60.1 + '@rollup/rollup-linux-x64-gnu': 4.60.1 + '@rollup/rollup-linux-x64-musl': 4.60.1 + '@rollup/rollup-openbsd-x64': 4.60.1 + '@rollup/rollup-openharmony-arm64': 4.60.1 + '@rollup/rollup-win32-arm64-msvc': 4.60.1 + '@rollup/rollup-win32-ia32-msvc': 4.60.1 + '@rollup/rollup-win32-x64-gnu': 4.60.1 + '@rollup/rollup-win32-x64-msvc': 4.60.1 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-identifier@0.4.2: {} + + safer-buffer@2.1.2: {} + + sass@1.98.0: + dependencies: + chokidar: 4.0.3 + immutable: 5.1.5 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + + sax@1.6.0: {} + + screenfull@6.0.2: {} + + scroll-into-view-if-needed@2.2.31: + dependencies: + compute-scroll-into-view: 1.0.20 + + sdk-base@2.0.1: + dependencies: + get-ready: 1.0.0 + + select@1.1.2: {} + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + serialize-javascript@4.0.0: + dependencies: + randombytes: 2.1.0 + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@4.1.0: {} + + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + slash@3.0.0: {} + + slate-history@0.66.0(slate@0.72.8): + dependencies: + is-plain-object: 5.0.0 + slate: 0.72.8 + + slate@0.72.8: + dependencies: + immer: 9.0.21 + is-plain-object: 5.0.0 + tiny-warning: 1.0.3 + + snabbdom@3.6.3: {} + + sortablejs@1.14.0: {} + + sortablejs@1.15.7: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + sourcemap-codec@1.4.8: {} + + spark-md5@3.0.2: {} + + split2@3.2.2: + dependencies: + readable-stream: 3.6.2 + + splitpanes@3.2.0(vue@3.5.31(typescript@4.9.5)): + dependencies: + vue: 3.5.31(typescript@4.9.5) + + ssf@0.11.2: + dependencies: + frac: 1.1.2 + + ssr-window@3.0.0: {} + + stable@0.1.8: {} + + statuses@1.5.0: {} + + stream-http@2.8.2: + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 2.3.8 + to-arraybuffer: 1.0.1 + xtend: 4.0.2 + + stream-shift@1.0.3: {} + + stream-wormhole@1.1.0: {} + + string-hash@1.1.3: {} + + string-split-by@1.0.0: + dependencies: + parenthesis: 3.1.8 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-json-comments@3.1.1: {} + + strnum@1.1.2: {} + + strnum@2.2.2: {} + + style-inject@0.3.0: {} + + stylehacks@5.1.1(postcss@8.5.8): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.8 + postcss-selector-parser: 6.1.2 + + sucrase@3.35.1: + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + commander: 4.1.1 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + tinyglobby: 0.2.15 + ts-interface-checker: 0.1.13 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svgo@2.8.2: + dependencies: + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.1.1 + sax: 1.6.0 + stable: 0.1.8 + + tailwindcss@3.4.19: + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.3 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.7 + lilconfig: 3.1.3 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.5.8 + postcss-import: 15.1.0(postcss@8.5.8) + postcss-js: 4.1.0(postcss@8.5.8) + postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.8) + postcss-nested: 6.2.0(postcss@8.5.8) + postcss-selector-parser: 6.1.2 + resolve: 1.22.11 + sucrase: 3.35.1 + transitivePeerDependencies: + - tsx + - yaml + + terser@5.46.1: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + text-table@0.2.0: {} + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + through@2.3.8: {} + + tiny-emitter@2.1.0: {} + + tiny-warning@1.0.3: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + to-arraybuffer@1.0.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-interface-checker@0.1.13: {} + + ts-md5@1.3.1: {} + + tslib@1.14.1: {} + + tslib@2.3.0: {} + + tslib@2.8.1: {} + + tsutils@3.21.0(typescript@4.9.5): + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-fest@0.20.2: {} + + type@2.7.3: {} + + typedarray@0.0.6: {} + + typescript@4.9.5: {} + + undici-types@5.26.5: {} + + unescape@1.0.1: + dependencies: + extend-shallow: 2.0.1 + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + upgrade@1.1.0: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urllib@2.44.0: + dependencies: + any-promise: 1.3.0 + content-type: 1.0.5 + default-user-agent: 1.0.0 + digest-header: 1.1.0 + ee-first: 1.1.1 + formstream: 1.5.2 + humanize-ms: 1.2.1 + iconv-lite: 0.6.3 + pump: 3.0.4 + qs: 6.15.0 + statuses: 1.5.0 + utility: 1.18.0 + + util-deprecate@1.0.2: {} + + utility@1.18.0: + dependencies: + copy-to: 2.0.1 + escape-html: 1.0.3 + mkdirp: 0.5.6 + mz: 2.7.0 + unescape: 1.0.1 + + vanilla-picker@2.12.3: + dependencies: + '@sphinxxxx/color-conversion': 2.2.2 + + vant4-kit@1.0.6(vue@3.5.31(typescript@4.9.5)): + dependencies: + vue: 3.5.31(typescript@4.9.5) + + vant@4.9.24(vue@3.5.31(typescript@4.9.5)): + dependencies: + '@vant/popperjs': 1.3.0 + '@vant/use': 1.6.0(vue@3.5.31(typescript@4.9.5)) + '@vue/shared': 3.5.31 + vue: 3.5.31(typescript@4.9.5) + + vite-plugin-vue-setup-extend@0.4.0(vite@5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1)): + dependencies: + '@vue/compiler-sfc': 3.5.31 + magic-string: 0.25.9 + vite: 5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1) + + vite@5.4.21(@types/node@18.19.130)(less@4.6.4)(sass@1.98.0)(terser@5.46.1): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.8 + rollup: 4.60.1 + optionalDependencies: + '@types/node': 18.19.130 + fsevents: 2.3.3 + less: 4.6.4 + sass: 1.98.0 + terser: 5.46.1 + + vue-clipboard3@2.0.0: + dependencies: + clipboard: 2.0.11 + + vue-component-type-helpers@3.2.6: {} + + vue-cropper@1.1.4: {} + + vue-cropperjs@5.0.0(vue@3.5.31(typescript@4.9.5)): + dependencies: + cropperjs: 1.6.2 + vue: 3.5.31(typescript@4.9.5) + + vue-demi@0.12.5(vue@3.5.31(typescript@4.9.5)): + dependencies: + vue: 3.5.31(typescript@4.9.5) + + vue-demi@0.14.10(vue@3.5.31(typescript@4.9.5)): + dependencies: + vue: 3.5.31(typescript@4.9.5) + + vue-draggable-plus@0.6.1(@types/sortablejs@1.15.9): + dependencies: + '@types/sortablejs': 1.15.9 + + vue-eslint-parser@9.4.3(eslint@8.57.1): + dependencies: + debug: 4.4.3 + eslint: 8.57.1 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + lodash: 4.17.21 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + + vue-grid-layout@3.0.0-beta1(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@4.9.5): + dependencies: + '@interactjs/actions': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/auto-start': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + '@interactjs/dev-tools': 1.10.27(@interactjs/modifiers@1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27)(typescript@4.9.5) + '@interactjs/interactjs': 1.10.27(typescript@4.9.5) + '@interactjs/modifiers': 1.10.27(@interactjs/core@1.10.27(@interactjs/utils@1.10.27))(@interactjs/utils@1.10.27) + element-resize-detector: 1.2.4 + mitt: 2.1.0 + transitivePeerDependencies: + - '@interactjs/core' + - '@interactjs/utils' + - typescript + + vue-i18n@9.14.5(vue@3.5.31(typescript@4.9.5)): + dependencies: + '@intlify/core-base': 9.14.5 + '@intlify/shared': 9.14.5 + '@vue/devtools-api': 6.6.4 + vue: 3.5.31(typescript@4.9.5) + + vue-qr@4.0.9: + dependencies: + glob: 8.1.0 + js-binary-schema-parser: 2.0.3 + simple-get: 4.0.1 + string-split-by: 1.0.0 + + vue-router@4.6.4(vue@3.5.31(typescript@4.9.5)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.31(typescript@4.9.5) + + vue@3.5.31(typescript@4.9.5): + dependencies: + '@vue/compiler-dom': 3.5.31 + '@vue/compiler-sfc': 3.5.31 + '@vue/runtime-dom': 3.5.31 + '@vue/server-renderer': 3.5.31(vue@3.5.31(typescript@4.9.5)) + '@vue/shared': 3.5.31 + optionalDependencies: + typescript: 4.9.5 + + vuedraggable-es@4.1.1(vue@3.5.31(typescript@4.9.5)): + dependencies: + sortablejs: 1.14.0 + vue: 3.5.31(typescript@4.9.5) + + vxe-pc-ui@4.13.20(vue@3.5.31(typescript@4.9.5)): + dependencies: + '@vxe-ui/core': 4.4.3(vue@3.5.31(typescript@4.9.5)) + transitivePeerDependencies: + - vue + + vxe-table@4.18.10(vue@3.5.31(typescript@4.9.5)): + dependencies: + vxe-pc-ui: 4.13.20(vue@3.5.31(typescript@4.9.5)) + transitivePeerDependencies: + - vue + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wildcard@1.1.2: {} + + win-release@1.1.1: + dependencies: + semver: 5.7.2 + + wmf@1.0.2: {} + + word-wrap@1.2.5: {} + + word@0.3.0: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + ws@7.5.10: {} + + ws@8.20.0: {} + + xe-utils@3.9.1: {} + + xe-utils@4.0.4: {} + + xlsx@0.18.5: + dependencies: + adler-32: 1.3.1 + cfb: 1.2.2 + codepage: 1.15.0 + crc-32: 1.2.2 + ssf: 0.11.2 + wmf: 1.0.2 + word: 0.3.0 + + xml-name-validator@4.0.0: {} + + xml2js@0.6.2: + dependencies: + sax: 1.6.0 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + xtend@4.0.2: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yaml@1.10.3: {} + + yarn@1.22.22: {} + + yocto-queue@0.1.0: {} + + zrender@5.6.1: + dependencies: + tslib: 2.3.0 diff --git a/web/public/favicon.ico b/web/public/favicon.ico index 4bd6fd7..f889dff 100644 Binary files a/web/public/favicon.ico and b/web/public/favicon.ico differ diff --git a/web/src/api/pisadmin/dashboard.ts b/web/src/api/pisadmin/dashboard.ts new file mode 100644 index 0000000..ee80014 --- /dev/null +++ b/web/src/api/pisadmin/dashboard.ts @@ -0,0 +1,10 @@ +import { request } from '/@/utils/service'; + +const apiPrefix = '/api/pisadmin/dashboard/'; + +export function getDashboard() { + return request({ + url: apiPrefix, + method: 'get', + }); +} diff --git a/web/src/assets/supplier-login-bg.jpg b/web/src/assets/supplier-login-bg.jpg new file mode 100644 index 0000000..45f673f Binary files /dev/null and b/web/src/assets/supplier-login-bg.jpg differ diff --git a/web/src/components/pisadmin/dashboard/BuyerTaskList.vue b/web/src/components/pisadmin/dashboard/BuyerTaskList.vue new file mode 100644 index 0000000..5839c7e --- /dev/null +++ b/web/src/components/pisadmin/dashboard/BuyerTaskList.vue @@ -0,0 +1,43 @@ + + + diff --git a/web/src/components/pisadmin/dashboard/KpiCard.vue b/web/src/components/pisadmin/dashboard/KpiCard.vue new file mode 100644 index 0000000..ff42d95 --- /dev/null +++ b/web/src/components/pisadmin/dashboard/KpiCard.vue @@ -0,0 +1,57 @@ + + + + + diff --git a/web/src/components/pisadmin/dashboard/MessageList.vue b/web/src/components/pisadmin/dashboard/MessageList.vue new file mode 100644 index 0000000..b903cfc --- /dev/null +++ b/web/src/components/pisadmin/dashboard/MessageList.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/web/src/components/pisadmin/dashboard/SupplierQuoteList.vue b/web/src/components/pisadmin/dashboard/SupplierQuoteList.vue new file mode 100644 index 0000000..598b89c --- /dev/null +++ b/web/src/components/pisadmin/dashboard/SupplierQuoteList.vue @@ -0,0 +1,38 @@ + + + diff --git a/web/src/components/pisadmin/dashboard/TrendChart.vue b/web/src/components/pisadmin/dashboard/TrendChart.vue new file mode 100644 index 0000000..956500a --- /dev/null +++ b/web/src/components/pisadmin/dashboard/TrendChart.vue @@ -0,0 +1,62 @@ + + + + + diff --git a/web/src/config/brand.ts b/web/src/config/brand.ts index 88cbe3e..9c345d9 100644 --- a/web/src/config/brand.ts +++ b/web/src/config/brand.ts @@ -1,2 +1,2 @@ /** 左上角 Logo、登录页主标题等品牌文案(不受布局配置本地缓存覆盖) */ -export const SITE_BRAND_TITLE = 'PIS'; +export const SITE_BRAND_TITLE = 'Procurement Inquiry System'; diff --git a/web/src/i18n/lang/en.ts b/web/src/i18n/lang/en.ts index 307beb4..01467c9 100644 --- a/web/src/i18n/lang/en.ts +++ b/web/src/i18n/lang/en.ts @@ -28,6 +28,7 @@ export default { limitsBackEnd: 'Backend Control', limitsBackEndEndPage: 'Page Permissions', personal: 'Personal Center', + dashboard: 'Dashboard', }, staticRoutes: { signIn: 'Login', diff --git a/web/src/i18n/lang/zh-cn.ts b/web/src/i18n/lang/zh-cn.ts index 82d7956..3d28ff1 100644 --- a/web/src/i18n/lang/zh-cn.ts +++ b/web/src/i18n/lang/zh-cn.ts @@ -28,6 +28,7 @@ export default { limitsBackEnd: '后端控制', limitsBackEndEndPage: '页面权限', personal: '个人中心', + dashboard: '看板', }, staticRoutes: { signIn: '登录', diff --git a/web/src/i18n/lang/zh-tw.ts b/web/src/i18n/lang/zh-tw.ts index 824a8d7..a19e526 100644 --- a/web/src/i18n/lang/zh-tw.ts +++ b/web/src/i18n/lang/zh-tw.ts @@ -28,6 +28,7 @@ export default { limitsBackEnd: '後端控制', limitsBackEndEndPage: '頁面權限', personal: '個人中心', + dashboard: '看板', }, staticRoutes: { signIn: '登錄', diff --git a/web/src/layout/logo/index.vue b/web/src/layout/logo/index.vue index 216e057..5b2fbe1 100644 --- a/web/src/layout/logo/index.vue +++ b/web/src/layout/logo/index.vue @@ -21,7 +21,7 @@ const storesThemeConfig = useThemeConfig(); const { themeConfig } = storeToRefs(storesThemeConfig); // 与 themeConfig 本地缓存无关,始终使用品牌常量 -const siteBrandTitle = SITE_BRAND_TITLE; +const siteBrandTitle = 'PIS'; // 设置 logo 的显示。classic 经典布局默认显示 logo const setShowLogo = computed(() => { diff --git a/web/src/layout/navBars/breadcrumb/user.vue b/web/src/layout/navBars/breadcrumb/user.vue index 0e3703c..24e4d19 100644 --- a/web/src/layout/navBars/breadcrumb/user.vue +++ b/web/src/layout/navBars/breadcrumb/user.vue @@ -93,7 +93,6 @@ {{ $t('message.user.dropdown1') }} {{ $t('message.user.dropdown2') }} - 更新日志 {{ $t('message.user.dropdown5') }} diff --git a/web/src/layout/navBars/tagsView/tagsView.vue b/web/src/layout/navBars/tagsView/tagsView.vue index b32904b..1e564c0 100644 --- a/web/src/layout/navBars/tagsView/tagsView.vue +++ b/web/src/layout/navBars/tagsView/tagsView.vue @@ -547,6 +547,15 @@ onBeforeMount(() => { }); } }); + // 监听更新 tagsView 名称(如 dashboard 切换角色) + mittBus.on('onUpdateTagsViewName', (data: { path: string; title: string }) => { + const item = state.tagsViewList.find((v: RouteItem) => v.path === data.path); + if (item) { + item.meta.title = data.title; + // 同时更新 Session 缓存 + addBrowserSetSession(state.tagsViewList); + } + }); }); // 页面卸载时 onUnmounted(() => { @@ -556,6 +565,8 @@ onUnmounted(() => { mittBus.off('openOrCloseSortable', () => {}); // 取消监听布局配置开启 TagsView 共用 mittBus.off('openShareTagsView', () => {}); + // 取消监听更新 tagsView 名称 + mittBus.off('onUpdateTagsViewName', () => {}); // 取消窗口 resize 监听 window.removeEventListener('resize', onSortableResize); }); diff --git a/web/src/router/backEnd.ts b/web/src/router/backEnd.ts index dd8a577..e159dea 100644 --- a/web/src/router/backEnd.ts +++ b/web/src/router/backEnd.ts @@ -127,7 +127,10 @@ export async function initBackEndControlRoutes() { // 界面 loading 动画开始执行 if (window.nextLoading === undefined) NextLoading.start(); // 无 token 停止执行下一步 - if (!Session.get('token')) return false; + const token = Session.get('token'); + if (!token) { + return false; + } // 触发初始化用户信息 pinia // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP await useUserInfo().getApiUserInfo(); diff --git a/web/src/router/index.ts b/web/src/router/index.ts index 37708c6..129c0e1 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -109,6 +109,10 @@ const checkToken = ()=>{ } } + +// 防止重复初始化路由的标记 +let isRoutesInitializing = false; + // 路由加载前 router.beforeEach(async (to, from, next) => { // 检查浏览器本地版本与线上版本是否一致,判断是否需要刷新页面进行更新 @@ -117,7 +121,7 @@ router.beforeEach(async (to, from, next) => { NProgress.configure({showSpinner: false}); if (to.meta.title) NProgress.start(); const token = Session.get('token'); - if (to.path === '/login' && !token) { + if ((to.path === '/login' || to.path === '/login/supplier') && !token) { next(); NProgress.done(); } else { @@ -136,17 +140,21 @@ router.beforeEach(async (to, from, next) => { } else { const storesRoutesList = useRoutesList(pinia); const {routesList} = storeToRefs(storesRoutesList); - if (routesList.value.length === 0) { + if (routesList.value.length === 0 && !isRoutesInitializing) { if (isRequestRoutes) { // 后端控制路由:路由数据初始化,防止刷新时丢失 + isRoutesInitializing = true; await initBackEndControlRoutes(); + isRoutesInitializing = false; // 解决刷新时,一直跳 404 页面问题,关联问题 No match found for location with path 'xxx' // to.query 防止页面刷新时,普通路由带参数时,参数丢失。动态路由(xxx/:id/:name")isDynamic 无需处理 next({ path: to.path, query: to.query }); } else { // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP + isRoutesInitializing = true; await initFrontEndControlRoutes(); + isRoutesInitializing = false; next({ path: to.path, query: to.query }); } } else { diff --git a/web/src/router/route.ts b/web/src/router/route.ts index 35df9f6..ed39d77 100644 --- a/web/src/router/route.ts +++ b/web/src/router/route.ts @@ -32,6 +32,14 @@ export const dynamicRoutes: Array = [ }, children: [], }, + { + path: '/home', + name: 'home', + redirect: '/dashboard', + meta: { + isKeepAlive: false, + }, + }, { path: '/personal', name: 'personal', @@ -45,6 +53,20 @@ export const dynamicRoutes: Array = [ isIframe: false, icon: 'iconfont icon-gerenzhongxin', }, + }, + { + path: '/dashboard', + name: 'Dashboard', + component: () => import('/@/views/pisadmin/dashboard/index.vue'), + meta: { + title: 'message.router.dashboard', + isLink: '', + isHide: false, + isKeepAlive: true, + isAffix: false, + isIframe: false, + icon: 'iconfont icon-dashboard', + }, } ]; @@ -88,6 +110,14 @@ export const staticRoutes: Array = [ title: '登录', }, }, + { + path: '/login/supplier', + name: 'supplierLogin', + component: () => import('/@/views/system/login/supplier.vue'), + meta: { + title: '供应商登录', + }, + }, { path: '/demo', name: 'demo', diff --git a/web/src/stores/modules/dashboard.ts b/web/src/stores/modules/dashboard.ts new file mode 100644 index 0000000..d430923 --- /dev/null +++ b/web/src/stores/modules/dashboard.ts @@ -0,0 +1,72 @@ +import { defineStore } from 'pinia'; +import { getDashboard } from '/@/api/pisadmin/dashboard'; + +interface BuyerDashboard { + kpi: { + total_inquiries: number; + pending_inquiries: number; + completed_quotes: number; + total_suppliers: number; + } | null; + tasks: Array<{ + id: number; + title: string; + inquiry_no: string; + status: string; + created_at: string; + }>; + messages: Array<{ + id: number; + title: string; + content: string; + is_read: boolean; + created_at: string; + }>; + trend: Array<{ month: string; count: number }>; +} + +interface SupplierDashboard { + kpi: { + total_quotes: number; + pending_quotes: number; + won_quotes: number; + conversion_rate: number; + } | null; + pending_quotes: Array<{ + id: number; + inquiry_no: string; + item_name: string; + quantity: number; + unit: string; + deadline: string; + }>; + messages: Array<{ + id: number; + title: string; + content: string; + is_read: boolean; + created_at: string; + }>; + trend: Array<{ month: string; quotes: number; won: number }>; +} + +export const useDashboardStore = defineStore('dashboard', { + state: () => ({ + buyer: null as BuyerDashboard | null, + supplier: null as SupplierDashboard | null, + loading: false, + }), + actions: { + async fetchDashboard() { + this.loading = true; + try { + const res: any = await getDashboard(); + // 后端直接返回 {buyer, supplier} 结构 + this.buyer = res?.buyer || null; + this.supplier = res?.supplier || null; + } finally { + this.loading = false; + } + }, + }, +}); diff --git a/web/src/stores/themeConfig.ts b/web/src/stores/themeConfig.ts index 23bc607..3df7ca5 100644 --- a/web/src/stores/themeConfig.ts +++ b/web/src/stores/themeConfig.ts @@ -139,8 +139,8 @@ export const useThemeConfig = defineStore('themeConfig', { */ // 网站主标题(菜单导航、浏览器当前网页标题) globalTitle: SITE_BRAND_TITLE, - // 网站副标题(登录页顶部文字) - globalViceTitle: SITE_BRAND_TITLE, + // 网站副标题(菜单栏标题) + globalViceTitle: 'PIS', // 网站副标题(登录页顶部文字) globalViceTitleMsg: '企业级快速开发平台', // 默认初始语言,可选值"",默认 zh-cn diff --git a/web/src/types/mitt.d.ts b/web/src/types/mitt.d.ts index b68b80d..f5ad068 100644 --- a/web/src/types/mitt.d.ts +++ b/web/src/types/mitt.d.ts @@ -23,6 +23,7 @@ declare type MittType = { openShareTagsView?: string; onTagsViewRefreshRouterView?: T; onCurrentContextmenuClick?: T; + onUpdateTagsViewName?: T; }; // mitt 参数类型定义 diff --git a/web/src/utils/request.ts b/web/src/utils/request.ts index 08e6184..badca30 100644 --- a/web/src/utils/request.ts +++ b/web/src/utils/request.ts @@ -20,7 +20,7 @@ service.interceptors.request.use( (config: AxiosRequestConfig) => { // 在发送请求之前做些什么 token if (Session.get('token')) { - config.headers!['Authorization'] = `${Session.get('token')}`; + config.headers!['Authorization'] = `JWT ${Session.get('token')}`; } return config; }, @@ -44,7 +44,7 @@ service.interceptors.response.use( .then(() => {}) .catch(() => {}); } - return Promise.reject(service.interceptors.response); + return Promise.reject(error); } else { return response.data; } diff --git a/web/src/utils/storage.ts b/web/src/utils/storage.ts index 4aad867..3f3a8ab 100644 --- a/web/src/utils/storage.ts +++ b/web/src/utils/storage.ts @@ -37,23 +37,26 @@ export const Local = { export const Session = { // 设置临时缓存 set(key: string, val: any) { - if (key === 'token') return Cookies.set(key, val); + if (key === 'token') { + // 直接使用 sessionStorage 存储 token,避免 Cookies 的问题 + window.sessionStorage.setItem(key, val); + return; + } window.sessionStorage.setItem(key, JSON.stringify(val)); }, // 获取临时缓存 get(key: string) { - if (key === 'token') return Cookies.get(key); + if (key === 'token') return window.sessionStorage.getItem(key); let json = window.sessionStorage.getItem(key); return JSON.parse(json); }, // 移除临时缓存 remove(key: string) { - if (key === 'token') return Cookies.remove(key); + if (key === 'token') return window.sessionStorage.removeItem(key); window.sessionStorage.removeItem(key); }, // 移除全部临时缓存 clear() { - Cookies.remove('token'); window.sessionStorage.clear(); }, }; diff --git a/web/src/views/pisadmin/dashboard/BuyerDashboard.vue b/web/src/views/pisadmin/dashboard/BuyerDashboard.vue new file mode 100644 index 0000000..ea88f8d --- /dev/null +++ b/web/src/views/pisadmin/dashboard/BuyerDashboard.vue @@ -0,0 +1,739 @@ + + + + + diff --git a/web/src/views/pisadmin/dashboard/SupplierDashboard.vue b/web/src/views/pisadmin/dashboard/SupplierDashboard.vue new file mode 100644 index 0000000..f47fa12 --- /dev/null +++ b/web/src/views/pisadmin/dashboard/SupplierDashboard.vue @@ -0,0 +1,874 @@ + + + + + diff --git a/web/src/views/pisadmin/dashboard/index.vue b/web/src/views/pisadmin/dashboard/index.vue new file mode 100644 index 0000000..d8b8a64 --- /dev/null +++ b/web/src/views/pisadmin/dashboard/index.vue @@ -0,0 +1,92 @@ + + + + + diff --git a/web/src/views/system/login/api.ts b/web/src/views/system/login/api.ts index 4502a75..9c74b6c 100644 --- a/web/src/views/system/login/api.ts +++ b/web/src/views/system/login/api.ts @@ -34,4 +34,12 @@ export function getBackends() { url: '/api/dvadmin3_social_oauth2/backend/get_login_backend/', method: 'get', }); +} + +export function supplierLogin(params: object) { + return request({ + url: '/api/login/supplier/', + method: 'post', + data: params + }); } \ No newline at end of file diff --git a/web/src/views/system/login/component/account.vue b/web/src/views/system/login/component/account.vue index f6d224b..8eed049 100644 --- a/web/src/views/system/login/component/account.vue +++ b/web/src/views/system/login/component/account.vue @@ -144,66 +144,57 @@ export default defineComponent({ }; const loginClick = async () => { if (!formRef.value) return - await formRef.value.validate((valid: any) => { + await formRef.value.validate(async (valid: any) => { if (valid) { - loginApi.login({ ...state.ruleForm, password: Md5.hashStr(state.ruleForm.password) }).then((res: any) => { + try { + // 根据当前 URL 判断使用哪个登录 API + const isSupplierPortal = window.location.href.includes('/login/supplier'); + const loginMethod = isSupplierPortal ? loginApi.supplierLogin : loginApi.login; + const res = await loginMethod({ ...state.ruleForm, password: Md5.hashStr(state.ruleForm.password) }); if (res.code === 2000) { - const {data} = res - Cookies.set('username', res.data.username); - Session.set('token', res.data.access); - useUserInfo().setPwdChangeCount(data.pwd_change_count) - if(data.pwd_change_count==0){ - return router.push('/login'); - } + const { data } = res; + Cookies.set('username', res.data.username); + Session.set('token', res.data.access); + useUserInfo().setPwdChangeCount(data.pwd_change_count); if (!themeConfig.value.isRequestRoutes) { - // 前端控制路由,2、请注意执行顺序 initFrontEndControlRoutes(); - loginSuccess(); + loginSuccess(data.pwd_change_count); } else { - // 模拟后端控制路由,isRequestRoutes 为 true,则开启后端控制路由 - // 添加完动态路由,再进行 router 跳转,否则可能报错 No match found for location with path "/" - initBackEndControlRoutes(); - // 执行完 initBackEndControlRoutes,再执行 signInSuccess - loginSuccess(); + await initBackEndControlRoutes(); + loginSuccess(data.pwd_change_count); } } - }).catch((err: any) => { - // 登录错误之后,刷新验证码 + } catch (err: any) { refreshCaptcha(); - }); + } } else { - errorMessage("请填写登录信息") + errorMessage("请填写登录信息"); } - }) - + }); }; // 登录成功后的跳转 - const loginSuccess = () => { + const loginSuccess = (pwd_change_count: number) => { //获取所有字典 DictionaryStore().getSystemDictionarys(); // 初始化登录成功时间问候语 let currentTimeInfo = currentTime.value; - // 登录成功,跳到转首页 - const pwd_change_count = userInfos.value.pwd_change_count ?? 0 - if(pwd_change_count > 0){ - // 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中 - if (route.query?.redirect) { - router.push({ - path: route.query?.redirect, - query: Object.keys(route.query?.params).length > 0 ? JSON.parse(route.query?.params) : '', - }); - } else { - router.push('/'); - } - // 登录成功提示 - // 关闭 loading - state.loading.signIn = true; - const signInText = t('message.signInText'); - ElMessage.success(`${currentTimeInfo},${signInText}`); - } + // 如果是复制粘贴的路径,非首页/登录页,那么登录成功后重定向到对应的路径中 + if (route.query?.redirect) { + router.push({ + path: route.query?.redirect, + query: Object.keys(route.query?.params).length > 0 ? JSON.parse(route.query?.params) : '', + }); + } else { + router.push('/'); + } + // 登录成功提示 + // 关闭 loading + state.loading.signIn = true; + const signInText = t('message.signInText'); + ElMessage.success(`${currentTimeInfo},${signInText}`); // 添加 loading,防止第一次进入界面时出现短暂空白 NextLoading.start(); }; diff --git a/web/src/views/system/login/index.vue b/web/src/views/system/login/index.vue index 729ace3..eafbaa1 100644 --- a/web/src/views/system/login/index.vue +++ b/web/src/views/system/login/index.vue @@ -14,7 +14,7 @@