From 75fa4c51a501c578b9192f684a7bc4745846b515 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Mon, 2 Dec 2024 22:43:03 +0800 Subject: [PATCH 1/3] :zap: feat(judge): add new spam keywords to Chinese advertisement list --- .gitignore | 180 +- README.md | 2 +- backend/.gitignore | 167 - backend/.pre-commit-config.yaml | 18 - backend/LICENSE | 21 - backend/README.MD | 38 - backend/bot/__init__.py | 5 - backend/core/mongo.py | 50 - backend/core/mongo_odm.py | 9 - backend/main.py | 49 - backend/pm2.json | 15 - backend/server/__init__.py | 214 -- {backend => bot}/.env.example | 0 {backend => bot}/Dockerfile | 2 +- backend/bot/controller.py => bot/__init__.py | 152 +- .../core/__init__.py => bot/init_logger.py | 0 .../app_locales.py => bot/locales_config.py | 3 +- bot/service/__init__.py | 1 + {backend/bot => bot/service}/judge.py | 0 {backend/bot => bot/service}/rule.txt | 0 {backend/bot => bot/service}/utils.py | 0 {backend/utils => common}/__init__.py | 0 {backend/core => common}/cache/__init__.py | 0 .../core => common}/cache/lmdb_runtime.py | 0 .../core => common}/cache/redis_runtime.py | 0 .../core => common}/cache/runtime_schema.py | 4 +- .../setting => common/config}/__init__.py | 0 .../setting => common/config}/cloudflare.py | 0 .../setting => common/config}/endpoint.py | 0 common/config/luci_key.py | 23 + {backend/setting => common/config}/server.py | 0 .../setting => common/config}/telegrambot.py | 0 {backend => common}/const.py | 0 common/database/__init__.py | 72 + .../death_queue.py => common/join_manager.py | 4 +- .../core/policy.py => common/middleware.py | 9 +- .../core/start_resend.py => common/recall.py | 6 +- common/safety/__init__.py | 0 {backend/utils => common/safety}/signature.py | 6 +- {backend/core => common}/statistics.py | 4 +- deno.json | 11 + deno.lock | 2141 +++++++++++++ docker-build.sh | 2 +- docker-compose.yml | 2 +- frontend/Dockerfile | 49 - frontend/cf.conf | 26 - frontend/nginx.conf | 35 - frontend/src/assets/vue.svg | 1 - frontend/tsconfig.node.json | 11 - frontend/vite.config.ts | 16 - main.py | 29 + backend/pdm.lock => pdm.lock | 125 +- {note => playground}/baseline.md | 0 playground/event.py | 3 + {backend/playground => playground}/note.md | 0 playground/ocr.png | Bin 0 -> 44163 bytes {backend/playground => playground}/ocr_t.py | 0 pm2.json | 24 + backend/pyproject.toml => pyproject.toml | 3 + server/__init__.py | 202 ++ .../server => server}/validate_cloudflare.py | 6 +- {frontend => webapp}/.gitignore | 0 {frontend => webapp}/README.md | 2 +- {frontend => webapp}/index.html | 0 {frontend => webapp}/package-lock.json | 0 {frontend => webapp}/package.json | 1 + webapp/pnpm-lock.yaml | 2834 +++++++++++++++++ {frontend => webapp}/public/vite.svg | 0 {frontend => webapp}/src/App.vue | 31 +- .../src/components/MCaptchaWidget.vue | 0 .../src/components/Puzzles.vue | 0 .../src/components/VersionInfo.vue | 0 .../src/hook/useAccelerometerExists.ts | 0 .../src/hook/useGyroscopeExists.ts | 0 {frontend => webapp}/src/i18n.ts | 0 {frontend => webapp}/src/locales/ar.json | 0 {frontend => webapp}/src/locales/bn.json | 0 {frontend => webapp}/src/locales/en.json | 0 {frontend => webapp}/src/locales/es.json | 0 {frontend => webapp}/src/locales/hi.json | 0 {frontend => webapp}/src/locales/ja.json | 0 {frontend => webapp}/src/locales/ru.json | 0 {frontend => webapp}/src/locales/zh.json | 0 {frontend => webapp}/src/main.ts | 0 {frontend => webapp}/src/vite-env.d.ts | 0 .../tsconfig.json => webapp/tsconfig.app.json | 15 +- webapp/tsconfig.json | 7 + webapp/tsconfig.node.json | 24 + {frontend => webapp}/uno.config.ts | 0 {frontend => webapp}/vercel.json | 0 webapp/vite.config.ts | 42 + 91 files changed, 5863 insertions(+), 833 deletions(-) delete mode 100755 backend/.gitignore delete mode 100755 backend/.pre-commit-config.yaml delete mode 100755 backend/LICENSE delete mode 100644 backend/README.MD delete mode 100755 backend/bot/__init__.py delete mode 100644 backend/core/mongo.py delete mode 100644 backend/core/mongo_odm.py delete mode 100755 backend/main.py delete mode 100755 backend/pm2.json delete mode 100644 backend/server/__init__.py rename {backend => bot}/.env.example (100%) rename {backend => bot}/Dockerfile (94%) rename backend/bot/controller.py => bot/__init__.py (83%) rename backend/core/__init__.py => bot/init_logger.py (100%) rename backend/app_locales.py => bot/locales_config.py (99%) create mode 100755 bot/service/__init__.py rename {backend/bot => bot/service}/judge.py (100%) rename {backend/bot => bot/service}/rule.txt (100%) rename {backend/bot => bot/service}/utils.py (100%) rename {backend/utils => common}/__init__.py (100%) rename {backend/core => common}/cache/__init__.py (100%) rename {backend/core => common}/cache/lmdb_runtime.py (100%) rename {backend/core => common}/cache/redis_runtime.py (100%) rename {backend/core => common}/cache/runtime_schema.py (91%) rename {backend/setting => common/config}/__init__.py (100%) rename {backend/setting => common/config}/cloudflare.py (100%) rename {backend/setting => common/config}/endpoint.py (100%) create mode 100644 common/config/luci_key.py rename {backend/setting => common/config}/server.py (100%) rename {backend/setting => common/config}/telegrambot.py (100%) rename {backend => common}/const.py (100%) create mode 100644 common/database/__init__.py rename backend/core/death_queue.py => common/join_manager.py (93%) rename backend/core/policy.py => common/middleware.py (91%) rename backend/core/start_resend.py => common/recall.py (89%) create mode 100644 common/safety/__init__.py rename {backend/utils => common/safety}/signature.py (76%) rename {backend/core => common}/statistics.py (94%) create mode 100644 deno.json create mode 100644 deno.lock delete mode 100644 frontend/Dockerfile delete mode 100644 frontend/cf.conf delete mode 100644 frontend/nginx.conf delete mode 100644 frontend/src/assets/vue.svg delete mode 100644 frontend/tsconfig.node.json delete mode 100644 frontend/vite.config.ts create mode 100755 main.py rename backend/pdm.lock => pdm.lock (91%) rename {note => playground}/baseline.md (100%) create mode 100644 playground/event.py rename {backend/playground => playground}/note.md (100%) create mode 100644 playground/ocr.png rename {backend/playground => playground}/ocr_t.py (100%) create mode 100755 pm2.json rename backend/pyproject.toml => pyproject.toml (91%) create mode 100644 server/__init__.py rename {backend/server => server}/validate_cloudflare.py (91%) rename {frontend => webapp}/.gitignore (100%) rename {frontend => webapp}/README.md (96%) rename {frontend => webapp}/index.html (100%) rename {frontend => webapp}/package-lock.json (100%) rename {frontend => webapp}/package.json (93%) create mode 100644 webapp/pnpm-lock.yaml rename {frontend => webapp}/public/vite.svg (100%) rename {frontend => webapp}/src/App.vue (97%) rename {frontend => webapp}/src/components/MCaptchaWidget.vue (100%) rename {frontend => webapp}/src/components/Puzzles.vue (100%) rename {frontend => webapp}/src/components/VersionInfo.vue (100%) rename {frontend => webapp}/src/hook/useAccelerometerExists.ts (100%) rename {frontend => webapp}/src/hook/useGyroscopeExists.ts (100%) rename {frontend => webapp}/src/i18n.ts (100%) rename {frontend => webapp}/src/locales/ar.json (100%) rename {frontend => webapp}/src/locales/bn.json (100%) rename {frontend => webapp}/src/locales/en.json (100%) rename {frontend => webapp}/src/locales/es.json (100%) rename {frontend => webapp}/src/locales/hi.json (100%) rename {frontend => webapp}/src/locales/ja.json (100%) rename {frontend => webapp}/src/locales/ru.json (100%) rename {frontend => webapp}/src/locales/zh.json (100%) rename {frontend => webapp}/src/main.ts (100%) rename {frontend => webapp}/src/vite-env.d.ts (100%) rename frontend/tsconfig.json => webapp/tsconfig.app.json (60%) create mode 100644 webapp/tsconfig.json create mode 100644 webapp/tsconfig.node.json rename {frontend => webapp}/uno.config.ts (100%) rename {frontend => webapp}/vercel.json (100%) create mode 100644 webapp/vite.config.ts diff --git a/.gitignore b/.gitignore index ba286f4..857a50b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,174 @@ -.idea/.gitignore -.idea/Kitan.iml -.idea/misc.xml -.idea/modules.xml -.idea/vcs.xml -.idea/inspectionProfiles/profiles_settings.xml -.idea/inspectionProfiles/Project_Default.xml +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ +/.pdm-python +.idea frontend/dist/* ssl/*.pem -ssl/*.key \ No newline at end of file +ssl/*.key +node_modules +.env.local +.env.development +.env.development.local +.env.development.local.example +.env.production +.env.production.local +.vscode +/webapp/public/sample.js diff --git a/README.md b/README.md index b054efe..e54a6b5 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ cd Kitan See `/frontend/README.MD`. ```shell -cd frontend +cd app npm install env VITE_BACKEND_URL="https://api.example.com" # env VITE_CLOUDFLARE_SITE_KEY="optional" diff --git a/backend/.gitignore b/backend/.gitignore deleted file mode 100755 index cb69b8a..0000000 --- a/backend/.gitignore +++ /dev/null @@ -1,167 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide -.pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -.idea/ -/.pdm-python - -# Ignore dynaconf secret files -/conf_dir/.*.toml -/conf_dir/.*.yaml -/playground/*.png -/playground/*.jpg \ No newline at end of file diff --git a/backend/.pre-commit-config.yaml b/backend/.pre-commit-config.yaml deleted file mode 100755 index 4700d7c..0000000 --- a/backend/.pre-commit-config.yaml +++ /dev/null @@ -1,18 +0,0 @@ -epos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 - hooks: - - id: trailing-whitespace - - id: end-of-file-fixer - - id: check-yaml - - id: check-added-large-files - - - repo: https://github.com/astral-sh/ruff-pre-commit - # Ruff version. - rev: v0.1.7 - hooks: - # Run the linter. - - id: ruff - args: [ --fix ] - # Run the formatter. - - id: ruff-format diff --git a/backend/LICENSE b/backend/LICENSE deleted file mode 100755 index 633a4de..0000000 --- a/backend/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2023 Jasmine - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/backend/README.MD b/backend/README.MD deleted file mode 100644 index 0bae8c9..0000000 --- a/backend/README.MD +++ /dev/null @@ -1,38 +0,0 @@ -# Deploy - -## Installation - -```shell -cd backend - -cp .env.example .env -nano .env - -pip install pdm -pdm install -pdm run python main.py -# Press Ctrl + C to exit -pm2 start pm2.json -``` - -## .env - -```dotenv -SERVER_HOST=0.0.0.0 -SERVER_PORT=10100 -CLOUDFLARE_SECRET_KEY=0x4AAAAA -# Cloudflare Turnstile -VERIFY_DOMAIN=verifyer.dianas.cyou -# cors -TELEGRAM_BOT_TOKEN=65655103 -``` - -## Command - -```shell -verify - Verify Step -start - Start -join_check - Enable/Disable Join Check -anti_spam - Anti Spam in Chat -complaints_guide - Set complaints_guide when joincheck failed -``` \ No newline at end of file diff --git a/backend/bot/__init__.py b/backend/bot/__init__.py deleted file mode 100755 index 524fe81..0000000 --- a/backend/bot/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# -*- coding: utf-8 -*- -# @Time : 2023/11/18 上午12:47 -# @Author : sudoskys -# @File : __init__.py -# @Software: PyCharm diff --git a/backend/core/mongo.py b/backend/core/mongo.py deleted file mode 100644 index 1036fb1..0000000 --- a/backend/core/mongo.py +++ /dev/null @@ -1,50 +0,0 @@ -import pymongo -from dotenv import load_dotenv -from loguru import logger -from motor.motor_asyncio import AsyncIOMotorClient -from odmantic import AIOEngine -from pydantic import Field -from pydantic import model_validator -from pydantic_settings import BaseSettings -from pymongo import MongoClient -from pymongo.errors import ServerSelectionTimeoutError - - -class MongoDb(BaseSettings): - mongodb_dsn: str = Field("mongodb://localhost:27017", validation_alias="MONGODB_DSN") - """MongoDB 配置""" - available: bool = True - - @model_validator(mode="after") - def mongodb_validator(self): - try: - client = MongoClient( - self.mongodb_dsn, serverSelectionTimeoutMS=1000 - ) # 设置超时时间 - client.admin.command("ping") - # 获取服务器信息 - client.server_info() - # 尝试执行需要管理员权限的命令 - client.admin.command("listDatabases") - except ServerSelectionTimeoutError: - self.available = False - logger.warning( - f"\n🍀MongoDB Connection Error -- timeout when connecting to {self.mongodb_dsn}" - ) - except pymongo.errors.OperationFailure: - self.available = False - logger.warning("\n🍀MongoDB Connection Error -- insufficient permissions") - except Exception as e: - self.available = False - logger.warning(f"\n🍀MongoDB Connection Error -- error {e}") - else: - logger.success(f"\n🍀MongoDB Connection Success --dsn {self.mongodb_dsn}") - return self - - -load_dotenv() -MongoSetting = MongoDb() -if not MongoSetting.available: - logger.error("MongoDB Connection Error") - raise ValueError("MongoDB Connection Error") -MONGO_ENGINE = AIOEngine(client=AsyncIOMotorClient(MongoSetting.mongodb_dsn), database="verify") diff --git a/backend/core/mongo_odm.py b/backend/core/mongo_odm.py deleted file mode 100644 index dc173d3..0000000 --- a/backend/core/mongo_odm.py +++ /dev/null @@ -1,9 +0,0 @@ -from odmantic import Model - - -class VerifyRequest(Model): - user_id: str - chat_id: str - timestamp: str - signature: str - passed: bool = False diff --git a/backend/main.py b/backend/main.py deleted file mode 100755 index 6baccbf..0000000 --- a/backend/main.py +++ /dev/null @@ -1,49 +0,0 @@ -import asyncio -import os -import sys - -import uvicorn -from dotenv import load_dotenv -from loguru import logger - -from bot.controller import Runner, execution_ground -from server import app -from setting.server import ServerSetting - -load_dotenv() -# 移除默认的日志处理器 -logger.remove() -# 添加标准输出 -handler_id = logger.add( - sys.stderr, - level="INFO" if not os.getenv("DEBUG") else "DEBUG", - format="{time} - {level} - {message}", -) -# 添加文件写出 -logger.add( - sink="run.log", - format="{time} - {level} - {message}", - level="INFO", - rotation="100 MB", - enqueue=True, -) -logger.info("Log Is Secret, Please Don't Share It To Others") - - -async def run_app(): - logger.info("Backend Server Start") - - server = uvicorn.Server( - config=uvicorn.Config(app, host=ServerSetting.host, port=ServerSetting.port, loop="asyncio") - ) - TelegramBot = Runner() - await asyncio.gather( - TelegramBot.run(), - execution_ground(), - server.serve() - ) - - -loop = asyncio.new_event_loop() -asyncio.set_event_loop(loop) -loop.run_until_complete(run_app()) diff --git a/backend/pm2.json b/backend/pm2.json deleted file mode 100755 index 423befe..0000000 --- a/backend/pm2.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "apps": [ - { - "name": "kitan_backend", - "script": "pdm run python3 main.py", - "instances": 1, - "max_restarts": 3, - "restart_delay": 10000, - "exp_backoff_restart_delay": 100, - "error_file": "error.log", - "out_file": "app.log", - "log_date_format": "YYYY-MM-DD HH-mm-ss" - } - ] -} diff --git a/backend/server/__init__.py b/backend/server/__init__.py deleted file mode 100644 index 7f13317..0000000 --- a/backend/server/__init__.py +++ /dev/null @@ -1,214 +0,0 @@ -# /endpoint/verify 的服务器 -# 用于验证用户的登录状态 - -import time -from enum import Enum -from typing import Optional - -import telebot.util -from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware -from loguru import logger -from pydantic import BaseModel, SecretStr, ConfigDict -from starlette.responses import JSONResponse - -from const import EXPIRE_M_TIME -from core.death_queue import JOIN_MANAGER, JoinRequest -from core.mongo import MONGO_ENGINE -from core.mongo_odm import VerifyRequest -from server.validate_cloudflare import validate_cloudflare_turnstile -from setting.cloudflare import CloudflareSetting -from setting.server import ServerSetting -from setting.telegrambot import BotSetting, BOT -from utils.signature import generate_sign, generate_oko - -app = FastAPI() -if ServerSetting.cors_origin: - origins = ServerSetting.cors_origin.split(",") - app.add_middleware( - CORSMiddleware, - allow_origins=origins, - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], - ) - -TELEGRAM_BOT_TOKEN = BotSetting.token - - -class Source(BaseModel): - chat_id: str - message_id: str - timestamp: str - signature: str - - -class VerifyData(BaseModel): - """ - 响应数据 - """ - # id: str - source: Source - acc: dict - signature: str - web_app_data: str - timestamp: Optional[str] = None - - model_config = ConfigDict(extra="allow") - - -class CloudflareData(BaseModel): - """ - Cloudflare 验证数据 - """ - source: Source - turnstile_token: str - web_app_data: str - - -class EnumStatu(Enum): - success = "success" - error = "error" - - -@app.get("/endpoints") -async def read_endpoints(): - # RockRoll The World - return {"message": "open this page in IE6"} - - -@app.post("/endpoints/verify-cloudflare") -async def verify_cloudflare(data: CloudflareData): - web_app_data = telebot.util.parse_web_app_data(token=TELEGRAM_BOT_TOKEN, raw_init_data=data.web_app_data) - if not web_app_data: - logger.error(f"verify-cloudflare:unsigned-request:{data}") - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "BAD_REQUEST"} - ) - try: - validated = validate_cloudflare_turnstile( - turnstile_response=data.turnstile_token, - cloudflare_secret_key=SecretStr(CloudflareSetting.cloudflare_secret_key) - ) - except Exception as exc: - logger.exception(f"verify-cloudflare:validate-cloudflare-turnstile:{exc}") - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "SERVER_ERROR"} - ) - else: - if not validated.success: - logger.info(f"verify-cloudflare:cloudflare-failed:{data.source} - {validated.error_codes}") - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "CAPTCHA_FAILED"} - ) - else: - logger.info(f"verify-cloudflare:cloudflare-success:{data.source}") - return JSONResponse( - status_code=200, - content={"status": EnumStatu.success.value} - ) - - -@app.post("/endpoints/verify-captcha") -async def verify_captcha(captcha_data: VerifyData): - # 获取可信数据 - web_app_data = telebot.util.parse_web_app_data(token=TELEGRAM_BOT_TOKEN, raw_init_data=captcha_data.web_app_data) - if not web_app_data: - logger.error(f"verify-captcha:unsigned-request:{captcha_data}") - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "BAD_REQUEST"} - ) - try: - # 用户ID - user_id = web_app_data['user']['id'] - # 验证的群组ID - chat_id = captcha_data.source.chat_id - # 机器人发送出去的消息ID - message_id = captcha_data.source.message_id - # 用户加入群组时间(我们机器人的签名时间) - join_time = captcha_data.source.timestamp - # 现在的时间... - now_m_time = time.time() * 1000 - except KeyError: - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "UNCOMPLETED_REQUEST"} - ) - # 验证签名 - recover_sign = generate_sign( - chat_id=chat_id, - message_id=message_id, - user_id=user_id, - join_time=join_time, - secret_key=SecretStr(BotSetting.token) - ) - t_s = generate_oko(data=captcha_data.web_app_data, time=captcha_data.timestamp) - if recover_sign != captcha_data.signature: - logger.error(f"verify-captcha:not-standard-oko:{user_id}:{chat_id}:{captcha_data.source}") - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "INITIALIZE_FAILED"} - ) - if not t_s: - logger.error(f"verify-captcha:oko-failed:{user_id}:{chat_id}:{captcha_data.timestamp}") - else: - logger.info(f"verify-captcha:oko-success:{user_id}:{chat_id}:{captcha_data.timestamp}") - # 会话过旧,虽然我们有死亡队列,但是这里还是要做一下判断,防止重放攻击 - if now_m_time - int(join_time) > EXPIRE_M_TIME: - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "EXPIRED_REQUEST"} - ) - logger.info(f"verify-captcha:print-acc:{user_id}:{chat_id}:{captcha_data.acc}") - logger.info(f"verify-captcha:print-webapp:{user_id}:{chat_id}:{web_app_data}") - if not captcha_data.acc.get("verify_mode"): - return JSONResponse( - status_code=400, - content={"status": EnumStatu.error.value, "message": "CAPTCHA_FAILED"} - ) - # Success Accept User's Join Request - # 删除死亡队列 - try: - data = await JOIN_MANAGER.read() - removed = [] - for join_request in data.join_queue: - join_request: JoinRequest - if str(join_request.user_id) == str(user_id) and str(join_request.chat_id) == str(chat_id): - removed.append(join_request) - if not removed: - logger.error(f"verify-captcha:dead-queue-not-found:{user_id}:{chat_id}") - else: - for join_request in removed: - data.join_queue.remove(join_request) - await JOIN_MANAGER.save(data) - except Exception as exc: - logger.error(f"verify-captcha:opt-dead-queue-failed:{exc}") - # 更新记录 - try: - history = await MONGO_ENGINE.find_one(VerifyRequest, VerifyRequest.signature == captcha_data.signature) - if not history: - logger.error(f"verify-captcha:history-not-found:{captcha_data.source}") - history.passed = True - await MONGO_ENGINE.save(history) - except Exception as exc: - logger.error(f"verify-captcha:opt-mongodb-failed:{exc} --signature {captcha_data.signature}") - try: - await BOT.approve_chat_join_request(chat_id=chat_id, user_id=user_id) - await BOT.delete_message(chat_id=user_id, message_id=message_id) - except Exception as exc: - if "USER_ALREADY_PARTICIPANT" in str(exc): - logger.info(f"verify-captcha:user-already-in-group:{user_id}:{chat_id}") - elif "HIDE_REQUESTER_MISSING" in str(exc): - logger.info(f"verify-captcha:hide-requester-missing:{user_id}:{chat_id}") - else: - logger.error(f"verify-captcha:approve-request-failed:{exc}") - finally: - # Accept user's join request - return JSONResponse( - status_code=202, - content={"status": EnumStatu.success.value} - ) diff --git a/backend/.env.example b/bot/.env.example similarity index 100% rename from backend/.env.example rename to bot/.env.example diff --git a/backend/Dockerfile b/bot/Dockerfile similarity index 94% rename from backend/Dockerfile rename to bot/Dockerfile index 58bd1ec..f0d63d4 100644 --- a/backend/Dockerfile +++ b/bot/Dockerfile @@ -10,7 +10,7 @@ RUN pip install -U pip setuptools wheel && \ ENV PDM_CHECK_UPDATE=false -COPY pyproject.toml pdm.lock /project/ +COPY ../pyproject.toml pdm.lock /project/ WORKDIR /project RUN pdm install --check --prod --no-editable diff --git a/backend/bot/controller.py b/bot/__init__.py similarity index 83% rename from backend/bot/controller.py rename to bot/__init__.py index 282ba08..7db2244 100755 --- a/backend/bot/controller.py +++ b/bot/__init__.py @@ -8,24 +8,38 @@ import telegramify_markdown from loguru import logger from pydantic import SecretStr +from sqlmodel import select from telebot import types, asyncio_filters from telebot import util from telebot.asyncio_helper import ApiTelegramException from telebot.types import InlineKeyboardMarkup, WebAppInfo -from app_locales import get_locales -from bot.judge import judge_pre_join_text, reason_chat_text, reason_chat_photo -from bot.utils import parse_command -from const import EXPIRE_M_TIME, EXPIRE_SHOW -from core.death_queue import JOIN_MANAGER, JoinRequest -from core.mongo import MONGO_ENGINE -from core.mongo_odm import VerifyRequest -from core.policy import GROUP_POLICY -from core.start_resend import RESEND_MANAGER, ResendEvnet -from core.statistics import STATISTICS -from setting.endpoint import EndpointSetting -from setting.telegrambot import BOT, BotSetting -from utils.signature import generate_sign +from common.config.endpoint import EndpointSetting +from common.config.telegrambot import BOT, BotSetting +from common.const import EXPIRE_M_TIME, EXPIRE_SHOW +from common.database import dbInstance, VerifyRequest, JoinRequest +from common.middleware import globalGroupPolicy +from common.recall import globalResendManager, ResendEvnet +from common.safety.signature import generate_sign +from common.statistics import globalStatistics +from locales_config import get_locales +from service.judge import judge_pre_join_text, reason_chat_text, reason_chat_photo +from service.utils import parse_command + + +async def judgment( + chat_id: int, + target_string: str, +) -> Optional[str]: + """ + 处理群组配置,如果有问题则返回 True + """ + policy = await globalGroupPolicy.read(group_id=str(chat_id)) + if policy.join_check: + logger.debug(f"judgment:join-check:{chat_id}") + if judge_pre_join_text(target_string): + return policy.complaints_guide or "Please contact the administrator" + return None async def pre_process_user( @@ -48,7 +62,7 @@ async def pre_process_user( :param addon_bio: 附加的用户 BIO """ # 读取待验证的群组策略 - policy = await GROUP_POLICY.read(group_id=str(chat_id)) + policy = await globalGroupPolicy.read(group_id=str(chat_id)) if policy.join_check: logger.debug(f"pre-process-user:join-check:{user_id}:{chat_id}") # 检查用户资料 @@ -76,7 +90,7 @@ async def pre_process_user( logger.info(f"pre-process-user:pre-check-not-pass:{user_id}:{chat_id}") # 删除死亡队列 try: - data = await JOIN_MANAGER.read() + data = await globalJoinManager.read() removed = [] for join_request in data.join_queue: join_request: JoinRequest @@ -86,7 +100,7 @@ async def pre_process_user( if removed: for join_request in removed: data.join_queue.remove(join_request) - await JOIN_MANAGER.save(data) + await globalJoinManager.save(data) else: logger.error(f"pre-process-user:not-found-dead-queue:{user_id}:{chat_id}") except Exception as exc: @@ -136,23 +150,32 @@ async def download(telegram_bot: telebot.async_telebot.AsyncTeleBot, file): async def dead_shot( user_id: str, chat_id: str, - expired_m_at: str, + expired_m_at: int, language_code: str, user_chat_id: int, message_id: Optional[str] = None ): try: - # 先投入死亡队列,防止被拉黑 - await JOIN_MANAGER.insert( - JoinRequest( + with dbInstance.get_session() as session: + select_statement = select(JoinRequest).where( + JoinRequest.user_id == user_id, + JoinRequest.chat_id == chat_id + ) + results = session.exec(select_statement) + if results: + for result in results: + session.delete(result) + session.commit() + dto = JoinRequest( user_id=str(user_id), chat_id=str(chat_id), - expired_at=str(expired_m_at), + expired_at=expired_m_at, language_code=str(language_code), user_chat_id=int(user_chat_id), message_id=str(message_id) ) - ) + session.add(dto) + session.commit() except Exception as exc: logger.error(f"dead-shot:failed-insert-join-queue:{user_id}:{chat_id}:{exc}") else: @@ -174,12 +197,12 @@ async def handle_join_request( chat_id = str(message.chat.id) user_id = str(message.from_user.id) join_m_time = str(int(time.time() * 1000)) # 防止停机 - expired_m_at = str(int(join_m_time) + EXPIRE_M_TIME) + expired_m_at = int(join_m_time) + EXPIRE_M_TIME except Exception as exc: logger.exception(f"join-request:parse-failed:{exc} --data {message}") return False logger.info( - f"join-request:start:{chat_id}:{user_id}" + f"join-request:start:{user_id}:{chat_id}" f" --user [{message.from_user.full_name}]" f" --chat [{message.chat.title}] @{message.chat.username}" f" --lang {message.from_user.language_code}" @@ -202,7 +225,7 @@ async def handle_join_request( sent_message_id = str(sent_message.message_id) except Exception as exc: sent_message_id = None - logger.error(f"join-request:send-welcome-failed:{chat_id}:{user_id}:{exc}") + logger.error(f"join-request:send-welcome-failed:{user_id}:{chat_id}:{exc}") # 投入死亡队列 await dead_shot( user_id=user_id, @@ -214,7 +237,6 @@ async def handle_join_request( ) if not sent_message_id: return logger.error(f"join-request:user-refuse:{user_id}:{chat_id}") - # 用户没有拉黑机器人,生产签名 signature = generate_sign( chat_id=chat_id, @@ -226,10 +248,12 @@ async def handle_join_request( # 保存历史记录 try: - mongo_data = VerifyRequest(user_id=user_id, chat_id=chat_id, timestamp=join_m_time, signature=signature) - await MONGO_ENGINE.save(mongo_data) + with dbInstance.get_session() as session: + _request = VerifyRequest(user_id=user_id, chat_id=chat_id, timestamp=join_m_time, signature=signature) + session.add(_request) + session.commit() except Exception as exc: - logger.error(f"join-request:save-history-failed:{chat_id}:{user_id}:{exc}") + logger.error(f"join-request:save-history-failed:{user_id}:{chat_id}:{exc}") # 生产验证URL verify_url = f"https://{EndpointSetting.domain}/?chat_id={chat_id}&message_id={sent_message_id}&user_id={user_id}×tamp={join_m_time}&signature={signature}" @@ -242,7 +266,7 @@ async def handle_join_request( # 存储一份参数快照,并生成一个唯一数据命令+ID snapshot_uid = shortuuid.uuid()[0:6] verify_tip = f"**Copy `/verify {snapshot_uid}` then send me to continue verification of `{chat_title}`**" - await RESEND_MANAGER.save( + await globalResendManager.save( event_id=snapshot_uid, data=ResendEvnet( chat_id=str(chat_id), @@ -259,8 +283,26 @@ async def handle_join_request( parse_mode="MarkdownV2", ) except Exception as exc: - logger.error(f"join-request:send-verify-tip-failed:{chat_id}:{user_id}:{exc}") + logger.error(f"join-request:send-verify-tip-failed:{user_id}:{chat_id}:{exc}") else: + invalid = await judgment( + chat_id=int(chat_id), + target_string=f"{event.first_name} {event.last_name} {event.bio}" + ) + if invalid: + try: + await telegram_bot.send_message( + chat_id=user_id, + text=telegramify_markdown.convert( + f"# Sorry, this group enabled join check.\n" + f"`You are recognized as a Advertiser or a Robot by our risk control system.`\n\n" + f"**What should I do?**\n" + f"{invalid}", + ), + parse_mode="MarkdownV2", + ) + except Exception as exc: + logger.error(f"pre-process-user:send-message-failed:{user_id}:{chat_id}:{exc}") await pre_process_user( telegram_bot=telegram_bot, chat_id=int(chat_id), @@ -284,7 +326,7 @@ async def handle_verify( locale = get_locales(message.from_user.language_code) chat_id, user_id = str(message.chat.id), str(message.from_user.id) logger.info( - f"verify:start:{chat_id}:{user_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") + f"verify:start:{user_id}:{chat_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") # 解析命令 try: command, event_id = parse_command(message.text) @@ -292,7 +334,7 @@ async def handle_verify( return logger.info(f"verify:command-parse-failed") except Exception as exc: return logger.info(f"verify:command-parse-failed:{exc}") - event = await RESEND_MANAGER.read(event_id=event_id) + event = await globalResendManager.read(event_id=event_id) if not event: return logger.info(f"verify:event-not-found:{event_id}") if str(event.user_id) != str(message.from_user.id): @@ -323,13 +365,13 @@ async def handle_join_check( locale = get_locales(message.from_user.language_code) chat_id, user_id = str(message.chat.id), str(message.from_user.id) logger.info( - f"join_check:start:{chat_id}:{user_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") + f"join_check:start:{user_id}:{chat_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") # 读取群组策略 - policy = await GROUP_POLICY.read(group_id=chat_id) + policy = await globalGroupPolicy.read(group_id=chat_id) # 切换开关 policy.join_check = not policy.join_check # 保存策略 - await GROUP_POLICY.save(group_id=chat_id, data=policy) + await globalGroupPolicy.save(group_id=chat_id, data=policy) return await telegram_bot.send_message( message.chat.id, text=telegramify_markdown.convert( @@ -350,13 +392,13 @@ async def handle_anti_spam( locale = get_locales(message.from_user.language_code) chat_id, user_id = str(message.chat.id), str(message.from_user.id) logger.info( - f"anti_spam:start:{chat_id}:{user_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") + f"anti_spam:start:{user_id}:{chat_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") # 读取群组策略 - policy = await GROUP_POLICY.read(group_id=chat_id) + policy = await globalGroupPolicy.read(group_id=chat_id) # 切换开关 policy.anti_spam = not policy.anti_spam # 保存策略 - await GROUP_POLICY.save(group_id=chat_id, data=policy) + await globalGroupPolicy.save(group_id=chat_id, data=policy) return await telegram_bot.send_message( message.chat.id, text=telegramify_markdown.convert( @@ -377,9 +419,9 @@ async def handle_complaints_guide( locale = get_locales(message.from_user.language_code) chat_id, user_id = str(message.chat.id), str(message.from_user.id) logger.info( - f"complaints_guide:start:{chat_id}:{user_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") + f"complaints_guide:start:{user_id}:{chat_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") # 读取群组策略 - policy = await GROUP_POLICY.read(group_id=chat_id) + policy = await globalGroupPolicy.read(group_id=chat_id) # 读取指引 command, guide = parse_command(message.text) if not guide: @@ -403,7 +445,7 @@ async def handle_complaints_guide( # 切换开关 policy.complaints_guide = guide # 保存策略 - await GROUP_POLICY.save(group_id=str(message.chat.id), data=policy) + await globalGroupPolicy.save(group_id=str(message.chat.id), data=policy) return await telegram_bot.send_message( message.chat.id, text=telegramify_markdown.convert( @@ -423,13 +465,13 @@ async def handle_group_msg_no_admin( """ # locale = get_locales(message.from_user.language_code) chat_id, user_id = str(message.chat.id), str(message.from_user.id) - logger.trace(f"antispam:{chat_id}:{user_id} send a message") - familiarity = await STATISTICS.increase(user_id=user_id, group_id=chat_id) + logger.trace(f"antispam:{user_id}:{chat_id} send a message") + familiarity = await globalStatistics.increase(user_id=user_id, group_id=chat_id) if familiarity >= 8: # 不在检查范围内 return "unfit for check" - policy = await GROUP_POLICY.read(group_id=chat_id) + policy = await globalGroupPolicy.read(group_id=chat_id) if not policy.anti_spam: # 未启用反垃圾系统 return "anti_spam disabled" @@ -457,7 +499,7 @@ async def handle_group_msg_no_admin( file=message.photo[-1] ) except Exception as exc: - logger.error(f"antispam:{chat_id}:{user_id}:{message.message_id} download photo failed {exc}") + logger.error(f"antispam:{user_id}:{chat_id}:{message.message_id} download photo failed {exc}") else: if downloaded_file: reason.append(reason_chat_photo(downloaded_file)) @@ -467,7 +509,7 @@ async def handle_group_msg_no_admin( try: await telegram_bot.delete_message(chat_id=chat_id, message_id=message.message_id) except Exception as exc: - logger.error(f"antispam:{chat_id}:{user_id}:{message.message_id} delete message failed {exc}") + logger.error(f"antispam:{user_id}:{chat_id}:{message.message_id} delete message failed {exc}") try: await telegram_bot.restrict_chat_member( chat_id=message.chat.id, @@ -486,7 +528,7 @@ async def handle_group_msg_no_admin( until_date=int(time.time() + 60 * 3), ) except Exception as exc: - logger.error(f"antispam:{chat_id}:{user_id}:{message.message_id} restrict chat member failed {exc}") + logger.error(f"antispam:{user_id}:{chat_id}:{message.message_id} restrict chat member failed {exc}") try: await telegram_bot.send_message( chat_id=message.chat.id, @@ -498,10 +540,10 @@ async def handle_group_msg_no_admin( ), parse_mode="MarkdownV2", ) - await STATISTICS.reset(user_id=str(message.from_user.id), group_id=str(message.chat.id)) + await globalStatistics.reset(user_id=str(message.from_user.id), group_id=str(message.chat.id)) except Exception as exc: - logger.error(f"antispam:{chat_id}:{user_id}:{message.message_id} send message failed {exc}") - return logger.info(f"antispam:{chat_id}:{user_id}:{message.message_id} is spam, reason: {reason}") + logger.error(f"antispam:{user_id}:{chat_id}:{message.message_id} send message failed {exc}") + return logger.info(f"antispam:{user_id}:{chat_id}:{message.message_id} is spam, reason: {reason}") async def handle_start( @@ -515,7 +557,7 @@ async def handle_start( language_code = message.from_user.language_code locale = get_locales(language_code) logger.info( - f"start:{chat_id}:{user_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}" + f"start:{user_id}:{chat_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}" ) # https://core.telegram.org/api/links#bot-links invite_link = (f"https://t.me/{BotSetting.bot_username}?startgroup" @@ -667,10 +709,10 @@ async def execution_ground(): logger.info("death-queue:execution-ground:start") while True: try: - data = await JOIN_MANAGER.read() + data = await globalJoinManager.read() expired = [] for join_request in data.join_queue: - if int(join_request.expired_at) < int(time.time() * 1000): + if int(join_request.expired_at) < int(round(time.time() * 1000)): expired.append(join_request) if expired: logger.info(f"decline:expired:processing --lens {len(expired)}") @@ -716,7 +758,7 @@ async def execution_ground(): logger.error( f"decline:failed-decline:{join_request.user_id}:{join_request.chat_id} chat-join-request because {exc}") data.join_queue = [join_request for join_request in data.join_queue if join_request not in expired] - await JOIN_MANAGER.save(data) + await globalJoinManager.save(data) except Exception as exc: logger.exception(f"detect:unknown-failed:{exc}") await asyncio.sleep(2) diff --git a/backend/core/__init__.py b/bot/init_logger.py similarity index 100% rename from backend/core/__init__.py rename to bot/init_logger.py diff --git a/backend/app_locales.py b/bot/locales_config.py similarity index 99% rename from backend/app_locales.py rename to bot/locales_config.py index 2dd2736..e9ebe5e 100644 --- a/backend/app_locales.py +++ b/bot/locales_config.py @@ -1,4 +1,4 @@ -from const import EXPIRE_SHOW +from common.const import EXPIRE_SHOW class BaseLocales(object): @@ -9,6 +9,7 @@ class BaseLocales(object): anti_spam_toggle = "Now i will check new messages for spam and ads, i will just delete them and mute for 2 minutes." @classmethod + def get(cls, key): return getattr(cls, key, None) diff --git a/bot/service/__init__.py b/bot/service/__init__.py new file mode 100755 index 0000000..7c68785 --- /dev/null +++ b/bot/service/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- \ No newline at end of file diff --git a/backend/bot/judge.py b/bot/service/judge.py similarity index 100% rename from backend/bot/judge.py rename to bot/service/judge.py diff --git a/backend/bot/rule.txt b/bot/service/rule.txt similarity index 100% rename from backend/bot/rule.txt rename to bot/service/rule.txt diff --git a/backend/bot/utils.py b/bot/service/utils.py similarity index 100% rename from backend/bot/utils.py rename to bot/service/utils.py diff --git a/backend/utils/__init__.py b/common/__init__.py similarity index 100% rename from backend/utils/__init__.py rename to common/__init__.py diff --git a/backend/core/cache/__init__.py b/common/cache/__init__.py similarity index 100% rename from backend/core/cache/__init__.py rename to common/cache/__init__.py diff --git a/backend/core/cache/lmdb_runtime.py b/common/cache/lmdb_runtime.py similarity index 100% rename from backend/core/cache/lmdb_runtime.py rename to common/cache/lmdb_runtime.py diff --git a/backend/core/cache/redis_runtime.py b/common/cache/redis_runtime.py similarity index 100% rename from backend/core/cache/redis_runtime.py rename to common/cache/redis_runtime.py diff --git a/backend/core/cache/runtime_schema.py b/common/cache/runtime_schema.py similarity index 91% rename from backend/core/cache/runtime_schema.py rename to common/cache/runtime_schema.py index aa728cc..25182b9 100644 --- a/backend/core/cache/runtime_schema.py +++ b/common/cache/runtime_schema.py @@ -3,7 +3,7 @@ from abc import abstractmethod, ABC from typing import Any, Union -PREFIX = "oai_bot:" +PREFIX = "verify0:" def singleton(cls): @@ -47,7 +47,7 @@ def update_backend(self, backend): @abstractmethod async def set_data( - self, key: str, value: Union[dict, str, bytes], timeout: int = None + self, key: str, value: Union[dict, str, bytes], timeout: int = None ) -> Any: pass diff --git a/backend/setting/__init__.py b/common/config/__init__.py similarity index 100% rename from backend/setting/__init__.py rename to common/config/__init__.py diff --git a/backend/setting/cloudflare.py b/common/config/cloudflare.py similarity index 100% rename from backend/setting/cloudflare.py rename to common/config/cloudflare.py diff --git a/backend/setting/endpoint.py b/common/config/endpoint.py similarity index 100% rename from backend/setting/endpoint.py rename to common/config/endpoint.py diff --git a/common/config/luci_key.py b/common/config/luci_key.py new file mode 100644 index 0000000..7df8a81 --- /dev/null +++ b/common/config/luci_key.py @@ -0,0 +1,23 @@ +from typing import Optional + +from dotenv import load_dotenv +from pydantic import Field, model_validator +from pydantic_settings import BaseSettings + + +class LuciKey(BaseSettings): + luci_key: Optional[str] = Field(None, validation_alias="LUCI_KEY") + + @model_validator(mode="after") + def validator(self): + if self.luci_key is None: + raise ValueError("RandomKey Not Set") + return self + + @property + def available(self): + return self.luci_key is not None + + +load_dotenv() +LuciKey = LuciKey() diff --git a/backend/setting/server.py b/common/config/server.py similarity index 100% rename from backend/setting/server.py rename to common/config/server.py diff --git a/backend/setting/telegrambot.py b/common/config/telegrambot.py similarity index 100% rename from backend/setting/telegrambot.py rename to common/config/telegrambot.py diff --git a/backend/const.py b/common/const.py similarity index 100% rename from backend/const.py rename to common/const.py diff --git a/common/database/__init__.py b/common/database/__init__.py new file mode 100644 index 0000000..3f87e6b --- /dev/null +++ b/common/database/__init__.py @@ -0,0 +1,72 @@ +import os +import uuid + +from dotenv import load_dotenv +from loguru import logger +from sqlmodel import Field, Session, SQLModel, create_engine + + +class JoinRequest(SQLModel, table=True): + """ + 加入请求数据模型,用于存储用户的加入请求信息。 + 包含用户 ID、聊天 ID、过期时间、用户聊天 ID、消息 ID 和语言代码。 + """ + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: str = Field(index=True) + chat_id: str + message_id: str + user_chat_id: int # 5 MINUTES VALID + expired_at: int | None = Field(default=None, index=True) + language_code: str | None = Field(default=None) + passed: bool = False + + +class VerifyRequest(SQLModel, table=True): + """ + 验证请求数据模型,用于存储用户的验证请求信息。 + 包含签名和来源信息,以及验证是否通过的标志。 + """ + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + user_id: str + chat_id: str + timestamp: str + signature: str = Field(index=True) + passed: bool = False + + +class Database: + """封装数据库连接和初始化逻辑,提供全局访问点。""" + + def __init__(self): + """初始化 Database 实例,加载环境变量和设置数据库连接。""" + load_dotenv() # 加载 .env 文件中的环境变量 + + self.postgresql_dsn = os.getenv( + "POSTGRESQL_DSN", "postgres://@localhost:5432/verify" + ) + try: + self.engine = create_engine(self.postgresql_dsn, echo=True) + self._check_database_connection() + logger.info("Database connection established successfully.") + except Exception as e: + logger.error(f"Failed to connect to the database: {e}") + raise + + def _check_database_connection(self): + """检查数据库连接是否可用。""" + with self.engine.connect() as connection: + connection.exec_driver_sql("SELECT 1") # 执行基本 SQL 查询以验证连接是否成功 + + def create_all_tables(self): + """初始化数据库表结构(如果尚未创建)。""" + logger.info("Creating database tables (if not exist)...") + SQLModel.metadata.create_all(self.engine) + + def get_session(self) -> Session: + """获取一个数据库会话 (Session)。""" + return Session(self.engine) + + +# 初始化并创建全局 Database 实例 +dbInstance = Database() +dbInstance.create_all_tables() # 确保表结构已创建 diff --git a/backend/core/death_queue.py b/common/join_manager.py similarity index 93% rename from backend/core/death_queue.py rename to common/join_manager.py index aae86c1..616f272 100644 --- a/backend/core/death_queue.py +++ b/common/join_manager.py @@ -3,7 +3,7 @@ from loguru import logger from pydantic import BaseModel -from core.cache import global_cache_runtime +from common.cache import global_cache_runtime QUEUE_DATA_KEY = "join_queue" @@ -44,4 +44,4 @@ async def insert(self, join_request: JoinRequest): return True -JOIN_MANAGER = JoinManager() +globalJoinManager = JoinManager() diff --git a/backend/core/policy.py b/common/middleware.py similarity index 91% rename from backend/core/policy.py rename to common/middleware.py index 240ab9d..63a1f87 100644 --- a/backend/core/policy.py +++ b/common/middleware.py @@ -1,9 +1,12 @@ +""" +检查用户 +""" from loguru import logger from pydantic import BaseModel, ConfigDict, Field -from core.cache import global_cache_runtime +from common.cache import global_cache_runtime -AREA = "group_policy" +AREA = "middleware" class PolicyRule(BaseModel): @@ -40,4 +43,4 @@ async def save(self, group_id: str, data: PolicyRule): return True -GROUP_POLICY = PolicyManager() +globalGroupPolicy = PolicyManager() diff --git a/backend/core/start_resend.py b/common/recall.py similarity index 89% rename from backend/core/start_resend.py rename to common/recall.py index 8703c98..be131f6 100644 --- a/backend/core/start_resend.py +++ b/common/recall.py @@ -3,9 +3,9 @@ from loguru import logger from pydantic import BaseModel -from core.cache import global_cache_runtime +from common.cache import global_cache_runtime -AREA = "start_resend" +AREA = "recall" TIMEOUT = 60 * 5 @@ -37,4 +37,4 @@ async def save(self, event_id: str, data: ResendEvnet): return True -RESEND_MANAGER = ResendManager() +globalResendManager = ResendManager() diff --git a/common/safety/__init__.py b/common/safety/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/utils/signature.py b/common/safety/signature.py similarity index 76% rename from backend/utils/signature.py rename to common/safety/signature.py index fbe3a5d..485adf7 100644 --- a/backend/utils/signature.py +++ b/common/safety/signature.py @@ -13,7 +13,7 @@ def generate_sign( ) -> str: sign_value = f"{message_id}={chat_id}={user_id}={join_time}" secret_key = secret_key.get_secret_value().encode() - sign = hmac.new(secret_key, sign_value.encode(), hashlib.sha256).hexdigest() + sign = hmac.new(secret_key, sign_value.encode(), digestmod=hashlib.sha256).hexdigest() return sign @@ -24,6 +24,4 @@ def generate_oko(data: str, time: str) -> bool: if __name__ == '__main__': - from pydantic import SecretStr - - print(generate_sign(1, 2, 3, 4, SecretStr("test"))) + print(generate_sign("1", "2", "3", "4", SecretStr("test"))) diff --git a/backend/core/statistics.py b/common/statistics.py similarity index 94% rename from backend/core/statistics.py rename to common/statistics.py index 81cc795..61c6bed 100644 --- a/backend/core/statistics.py +++ b/common/statistics.py @@ -4,7 +4,7 @@ """ from loguru import logger -from core.cache import global_cache_runtime +from common.cache import global_cache_runtime AREA = "counter" TIMEOUT = 60 * 60 * 24 * 5 # 5 days @@ -40,4 +40,4 @@ async def reset(self, user_id: str, group_id: str) -> bool: return True -STATISTICS = Statistics() +globalStatistics = Statistics() diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..d911ae7 --- /dev/null +++ b/deno.json @@ -0,0 +1,11 @@ +{ + "tasks": { + "dev": "deno task dev:vite & deno task dev:server", + "dev:server": "deno run --env-file=.env.local --allow-env --allow-import --allow-net --allow-read --allow-write server/main.ts", + "dev:vite": "deno run -A npm:vite serve /webapp" + }, + "workspace": ["./app", "./server"], + "imports": { + "@std/assert": "jsr:@std/assert@1" + } +} \ No newline at end of file diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..b58dbb8 --- /dev/null +++ b/deno.lock @@ -0,0 +1,2141 @@ +{ + "version": "4", + "specifiers": { + "jsr:@deno-library/logger@*": "1.1.7", + "jsr:@std/assert@1": "1.0.8", + "jsr:@std/fmt@1.0.3": "1.0.3", + "jsr:@std/fs@1.0.5": "1.0.5", + "jsr:@std/internal@^1.0.5": "1.0.5", + "jsr:@std/io@0.225.0": "0.225.0", + "jsr:@std/path@^1.0.7": "1.0.8", + "npm:@hono/zod-validator@*": "0.4.1_hono@4.6.12_zod@3.23.8", + "npm:@mcaptcha/core-glue@0.1.0-alpha-5": "0.1.0-alpha-5", + "npm:@mdi/font@^7.4.47": "7.4.47", + "npm:@types/crypto-js@^4.2.2": "4.2.2", + "npm:@vitejs/plugin-vue@^5.2.0": "5.2.1_vite@5.4.11_vue@3.5.13__typescript@5.7.2_typescript@5.7.2", + "npm:axios@^1.7.7": "1.7.8", + "npm:crypto-js@^4.2.0": "4.2.0", + "npm:hono@*": "4.6.12", + "npm:hono@^4.6.12": "4.6.12", + "npm:telegramify-markdown@^1.2.2": "1.2.2", + "npm:typescript@^5.6.3": "5.7.2", + "npm:unocss@~0.59.4": "0.59.4_vite@5.4.11", + "npm:vite@^5.4.11": "5.4.11", + "npm:vue-i18n@^10.0.4": "10.0.4_vue@3.5.13__typescript@5.7.2_typescript@5.7.2", + "npm:vue-router@^4.4.5": "4.5.0_vue@3.5.13__typescript@5.7.2_typescript@5.7.2", + "npm:vue-tg@~0.6.1": "0.6.1_typescript@5.7.2", + "npm:vue-tsc@^2.1.10": "2.1.10_typescript@5.7.2", + "npm:vue-turnstile@^1.0.11": "1.0.11_vue@3.5.13__typescript@5.7.2_typescript@5.7.2", + "npm:vue@^3.5.13": "3.5.13_typescript@5.7.2", + "npm:vuetify@^3.7.4": "3.7.4_typescript@5.7.2_vue@3.5.13__typescript@5.7.2", + "npm:zod@*": "3.23.8" + }, + "jsr": { + "@deno-library/logger@1.1.7": { + "integrity": "817947f12178e0faf21d43e4ec3823272dbdbb897dea74aec1220b00d60dc6bd", + "dependencies": [ + "jsr:@std/fmt", + "jsr:@std/fs", + "jsr:@std/io" + ] + }, + "@std/assert@1.0.8": { + "integrity": "ebe0bd7eb488ee39686f77003992f389a06c3da1bbd8022184804852b2fa641b", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/fmt@1.0.3": { + "integrity": "97765c16aa32245ff4e2204ecf7d8562496a3cb8592340a80e7e554e0bb9149f" + }, + "@std/fs@1.0.5": { + "integrity": "41806ad6823d0b5f275f9849a2640d87e4ef67c51ee1b8fb02426f55e02fd44e", + "dependencies": [ + "jsr:@std/path" + ] + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + }, + "@std/io@0.225.0": { + "integrity": "c1db7c5e5a231629b32d64b9a53139445b2ca640d828c26bf23e1c55f8c079b3" + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + } + }, + "npm": { + "@ampproject/remapping@2.3.0": { + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": [ + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping" + ] + }, + "@antfu/install-pkg@0.4.1": { + "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "dependencies": [ + "package-manager-detector", + "tinyexec" + ] + }, + "@antfu/utils@0.7.10": { + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==" + }, + "@babel/code-frame@7.26.2": { + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dependencies": [ + "@babel/helper-validator-identifier", + "js-tokens", + "picocolors" + ] + }, + "@babel/compat-data@7.26.2": { + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==" + }, + "@babel/core@7.26.0": { + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dependencies": [ + "@ampproject/remapping", + "@babel/code-frame", + "@babel/generator", + "@babel/helper-compilation-targets", + "@babel/helper-module-transforms", + "@babel/helpers", + "@babel/parser", + "@babel/template", + "@babel/traverse", + "@babel/types", + "convert-source-map", + "debug", + "gensync", + "json5", + "semver@6.3.1" + ] + }, + "@babel/generator@7.26.2": { + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dependencies": [ + "@babel/parser", + "@babel/types", + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping", + "jsesc" + ] + }, + "@babel/helper-annotate-as-pure@7.25.9": { + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/helper-compilation-targets@7.25.9": { + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dependencies": [ + "@babel/compat-data", + "@babel/helper-validator-option", + "browserslist", + "lru-cache", + "semver@6.3.1" + ] + }, + "@babel/helper-create-class-features-plugin@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dependencies": [ + "@babel/core", + "@babel/helper-annotate-as-pure", + "@babel/helper-member-expression-to-functions", + "@babel/helper-optimise-call-expression", + "@babel/helper-replace-supers", + "@babel/helper-skip-transparent-expression-wrappers", + "@babel/traverse", + "semver@6.3.1" + ] + }, + "@babel/helper-member-expression-to-functions@7.25.9": { + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, + "@babel/helper-module-imports@7.25.9": { + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, + "@babel/helper-module-transforms@7.26.0_@babel+core@7.26.0": { + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dependencies": [ + "@babel/core", + "@babel/helper-module-imports", + "@babel/helper-validator-identifier", + "@babel/traverse" + ] + }, + "@babel/helper-optimise-call-expression@7.25.9": { + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/helper-plugin-utils@7.25.9": { + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==" + }, + "@babel/helper-replace-supers@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dependencies": [ + "@babel/core", + "@babel/helper-member-expression-to-functions", + "@babel/helper-optimise-call-expression", + "@babel/traverse" + ] + }, + "@babel/helper-simple-access@7.25.9": { + "integrity": "sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, + "@babel/helper-skip-transparent-expression-wrappers@7.25.9": { + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, + "@babel/helper-string-parser@7.25.9": { + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==" + }, + "@babel/helper-validator-identifier@7.25.9": { + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==" + }, + "@babel/helper-validator-option@7.25.9": { + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==" + }, + "@babel/helpers@7.26.0": { + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dependencies": [ + "@babel/template", + "@babel/types" + ] + }, + "@babel/parser@7.26.2": { + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/plugin-syntax-jsx@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dependencies": [ + "@babel/core", + "@babel/helper-plugin-utils" + ] + }, + "@babel/plugin-syntax-typescript@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dependencies": [ + "@babel/core", + "@babel/helper-plugin-utils" + ] + }, + "@babel/plugin-transform-modules-commonjs@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==", + "dependencies": [ + "@babel/core", + "@babel/helper-module-transforms", + "@babel/helper-plugin-utils", + "@babel/helper-simple-access" + ] + }, + "@babel/plugin-transform-typescript@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==", + "dependencies": [ + "@babel/core", + "@babel/helper-annotate-as-pure", + "@babel/helper-create-class-features-plugin", + "@babel/helper-plugin-utils", + "@babel/helper-skip-transparent-expression-wrappers", + "@babel/plugin-syntax-typescript" + ] + }, + "@babel/preset-typescript@7.26.0_@babel+core@7.26.0": { + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "dependencies": [ + "@babel/core", + "@babel/helper-plugin-utils", + "@babel/helper-validator-option", + "@babel/plugin-syntax-jsx", + "@babel/plugin-transform-modules-commonjs", + "@babel/plugin-transform-typescript" + ] + }, + "@babel/template@7.25.9": { + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dependencies": [ + "@babel/code-frame", + "@babel/parser", + "@babel/types" + ] + }, + "@babel/traverse@7.25.9": { + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dependencies": [ + "@babel/code-frame", + "@babel/generator", + "@babel/parser", + "@babel/template", + "@babel/types", + "debug", + "globals" + ] + }, + "@babel/types@7.26.0": { + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dependencies": [ + "@babel/helper-string-parser", + "@babel/helper-validator-identifier" + ] + }, + "@esbuild/aix-ppc64@0.21.5": { + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==" + }, + "@esbuild/android-arm64@0.21.5": { + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==" + }, + "@esbuild/android-arm@0.21.5": { + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==" + }, + "@esbuild/android-x64@0.21.5": { + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==" + }, + "@esbuild/darwin-arm64@0.21.5": { + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==" + }, + "@esbuild/darwin-x64@0.21.5": { + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==" + }, + "@esbuild/freebsd-arm64@0.21.5": { + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==" + }, + "@esbuild/freebsd-x64@0.21.5": { + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==" + }, + "@esbuild/linux-arm64@0.21.5": { + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==" + }, + "@esbuild/linux-arm@0.21.5": { + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==" + }, + "@esbuild/linux-ia32@0.21.5": { + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==" + }, + "@esbuild/linux-loong64@0.21.5": { + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==" + }, + "@esbuild/linux-mips64el@0.21.5": { + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==" + }, + "@esbuild/linux-ppc64@0.21.5": { + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==" + }, + "@esbuild/linux-riscv64@0.21.5": { + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==" + }, + "@esbuild/linux-s390x@0.21.5": { + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==" + }, + "@esbuild/linux-x64@0.21.5": { + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==" + }, + "@esbuild/netbsd-x64@0.21.5": { + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==" + }, + "@esbuild/openbsd-x64@0.21.5": { + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==" + }, + "@esbuild/sunos-x64@0.21.5": { + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==" + }, + "@esbuild/win32-arm64@0.21.5": { + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==" + }, + "@esbuild/win32-ia32@0.21.5": { + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==" + }, + "@esbuild/win32-x64@0.21.5": { + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==" + }, + "@hono/zod-validator@0.4.1_hono@4.6.12_zod@3.23.8": { + "integrity": "sha512-I8LyfeJfvVmC5hPjZ2Iij7RjexlgSBT7QJudZ4JvNPLxn0JQ3sqclz2zydlwISAnw21D2n4LQ0nfZdoiv9fQQA==", + "dependencies": [ + "hono", + "zod" + ] + }, + "@iconify/types@2.0.0": { + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==" + }, + "@iconify/utils@2.1.33": { + "integrity": "sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==", + "dependencies": [ + "@antfu/install-pkg", + "@antfu/utils", + "@iconify/types", + "debug", + "kolorist", + "local-pkg", + "mlly" + ] + }, + "@intlify/core-base@10.0.4": { + "integrity": "sha512-GG428DkrrWCMhxRMRQZjuS7zmSUzarYcaHJqG9VB8dXAxw4iQDoKVQ7ChJRB6ZtsCsX3Jse1PEUlHrJiyQrOTg==", + "dependencies": [ + "@intlify/message-compiler", + "@intlify/shared" + ] + }, + "@intlify/message-compiler@10.0.4": { + "integrity": "sha512-AFbhEo10DP095/45EauinQJ5hJ3rJUmuuqltGguvc3WsvezZN+g8qNHLGWKu60FHQVizMrQY7VJ+zVlBXlQQkQ==", + "dependencies": [ + "@intlify/shared", + "source-map-js" + ] + }, + "@intlify/shared@10.0.4": { + "integrity": "sha512-ukFn0I01HsSgr3VYhYcvkTCLS7rGa0gw4A4AMpcy/A9xx/zRJy7PS2BElMXLwUazVFMAr5zuiTk3MQeoeGXaJg==" + }, + "@jridgewell/gen-mapping@0.3.5": { + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": [ + "@jridgewell/set-array", + "@jridgewell/sourcemap-codec", + "@jridgewell/trace-mapping" + ] + }, + "@jridgewell/resolve-uri@3.1.2": { + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + }, + "@jridgewell/set-array@1.2.1": { + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" + }, + "@jridgewell/sourcemap-codec@1.5.0": { + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "@jridgewell/trace-mapping@0.3.25": { + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": [ + "@jridgewell/resolve-uri", + "@jridgewell/sourcemap-codec" + ] + }, + "@mcaptcha/core-glue@0.1.0-alpha-5": { + "integrity": "sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==" + }, + "@mdi/font@7.4.47": { + "integrity": "sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==" + }, + "@nodelib/fs.scandir@2.1.5": { + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": [ + "@nodelib/fs.stat", + "run-parallel" + ] + }, + "@nodelib/fs.stat@2.0.5": { + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk@1.2.8": { + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": [ + "@nodelib/fs.scandir", + "fastq" + ] + }, + "@polka/url@1.0.0-next.28": { + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==" + }, + "@rollup/pluginutils@5.1.3": { + "integrity": "sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==", + "dependencies": [ + "@types/estree", + "estree-walker", + "picomatch@4.0.2" + ] + }, + "@rollup/rollup-android-arm-eabi@4.27.4": { + "integrity": "sha512-2Y3JT6f5MrQkICUyRVCw4oa0sutfAsgaSsb0Lmmy1Wi2y7X5vT9Euqw4gOsCyy0YfKURBg35nhUKZS4mDcfULw==" + }, + "@rollup/rollup-android-arm64@4.27.4": { + "integrity": "sha512-wzKRQXISyi9UdCVRqEd0H4cMpzvHYt1f/C3CoIjES6cG++RHKhrBj2+29nPF0IB5kpy9MS71vs07fvrNGAl/iA==" + }, + "@rollup/rollup-darwin-arm64@4.27.4": { + "integrity": "sha512-PlNiRQapift4LNS8DPUHuDX/IdXiLjf8mc5vdEmUR0fF/pyy2qWwzdLjB+iZquGr8LuN4LnUoSEvKRwjSVYz3Q==" + }, + "@rollup/rollup-darwin-x64@4.27.4": { + "integrity": "sha512-o9bH2dbdgBDJaXWJCDTNDYa171ACUdzpxSZt+u/AAeQ20Nk5x+IhA+zsGmrQtpkLiumRJEYef68gcpn2ooXhSQ==" + }, + "@rollup/rollup-freebsd-arm64@4.27.4": { + "integrity": "sha512-NBI2/i2hT9Q+HySSHTBh52da7isru4aAAo6qC3I7QFVsuhxi2gM8t/EI9EVcILiHLj1vfi+VGGPaLOUENn7pmw==" + }, + "@rollup/rollup-freebsd-x64@4.27.4": { + "integrity": "sha512-wYcC5ycW2zvqtDYrE7deary2P2UFmSh85PUpAx+dwTCO9uw3sgzD6Gv9n5X4vLaQKsrfTSZZ7Z7uynQozPVvWA==" + }, + "@rollup/rollup-linux-arm-gnueabihf@4.27.4": { + "integrity": "sha512-9OwUnK/xKw6DyRlgx8UizeqRFOfi9mf5TYCw1uolDaJSbUmBxP85DE6T4ouCMoN6pXw8ZoTeZCSEfSaYo+/s1w==" + }, + "@rollup/rollup-linux-arm-musleabihf@4.27.4": { + "integrity": "sha512-Vgdo4fpuphS9V24WOV+KwkCVJ72u7idTgQaBoLRD0UxBAWTF9GWurJO9YD9yh00BzbkhpeXtm6na+MvJU7Z73A==" + }, + "@rollup/rollup-linux-arm64-gnu@4.27.4": { + "integrity": "sha512-pleyNgyd1kkBkw2kOqlBx+0atfIIkkExOTiifoODo6qKDSpnc6WzUY5RhHdmTdIJXBdSnh6JknnYTtmQyobrVg==" + }, + "@rollup/rollup-linux-arm64-musl@4.27.4": { + "integrity": "sha512-caluiUXvUuVyCHr5DxL8ohaaFFzPGmgmMvwmqAITMpV/Q+tPoaHZ/PWa3t8B2WyoRcIIuu1hkaW5KkeTDNSnMA==" + }, + "@rollup/rollup-linux-powerpc64le-gnu@4.27.4": { + "integrity": "sha512-FScrpHrO60hARyHh7s1zHE97u0KlT/RECzCKAdmI+LEoC1eDh/RDji9JgFqyO+wPDb86Oa/sXkily1+oi4FzJQ==" + }, + "@rollup/rollup-linux-riscv64-gnu@4.27.4": { + "integrity": "sha512-qyyprhyGb7+RBfMPeww9FlHwKkCXdKHeGgSqmIXw9VSUtvyFZ6WZRtnxgbuz76FK7LyoN8t/eINRbPUcvXB5fw==" + }, + "@rollup/rollup-linux-s390x-gnu@4.27.4": { + "integrity": "sha512-PFz+y2kb6tbh7m3A7nA9++eInGcDVZUACulf/KzDtovvdTizHpZaJty7Gp0lFwSQcrnebHOqxF1MaKZd7psVRg==" + }, + "@rollup/rollup-linux-x64-gnu@4.27.4": { + "integrity": "sha512-Ni8mMtfo+o/G7DVtweXXV/Ol2TFf63KYjTtoZ5f078AUgJTmaIJnj4JFU7TK/9SVWTaSJGxPi5zMDgK4w+Ez7Q==" + }, + "@rollup/rollup-linux-x64-musl@4.27.4": { + "integrity": "sha512-5AeeAF1PB9TUzD+3cROzFTnAJAcVUGLuR8ng0E0WXGkYhp6RD6L+6szYVX+64Rs0r72019KHZS1ka1q+zU/wUw==" + }, + "@rollup/rollup-win32-arm64-msvc@4.27.4": { + "integrity": "sha512-yOpVsA4K5qVwu2CaS3hHxluWIK5HQTjNV4tWjQXluMiiiu4pJj4BN98CvxohNCpcjMeTXk/ZMJBRbgRg8HBB6A==" + }, + "@rollup/rollup-win32-ia32-msvc@4.27.4": { + "integrity": "sha512-KtwEJOaHAVJlxV92rNYiG9JQwQAdhBlrjNRp7P9L8Cb4Rer3in+0A+IPhJC9y68WAi9H0sX4AiG2NTsVlmqJeQ==" + }, + "@rollup/rollup-win32-x64-msvc@4.27.4": { + "integrity": "sha512-3j4jx1TppORdTAoBJRd+/wJRGCPC0ETWkXOecJ6PPZLj6SptXkrXcNqdj0oclbKML6FkQltdz7bBA3rUSirZug==" + }, + "@types/crypto-js@4.2.2": { + "integrity": "sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==" + }, + "@types/debug@4.1.12": { + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": [ + "@types/ms" + ] + }, + "@types/estree@1.0.6": { + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "@types/mdast@3.0.15": { + "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==", + "dependencies": [ + "@types/unist" + ] + }, + "@types/ms@0.7.34": { + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, + "@types/telegram-web-app@7.10.1": { + "integrity": "sha512-GKL659G6lnHRAt3Dt7L1Fa0dwvc+ZZQtJcYrJVJGwjvsbi/Rcp1qKs9pFwb34/KC04+J+TlQj4D7yKo10sBSEw==" + }, + "@types/unist@2.0.11": { + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "@unocss/astro@0.59.4_vite@5.4.11": { + "integrity": "sha512-DU3OR5MMR1Uvvec4/wB9EetDASHRg19Moy6z/MiIhn8JWJ0QzWYgSeJcfUX8exomMYv6WUEQJL+CyLI34Wmn8w==", + "dependencies": [ + "@unocss/core", + "@unocss/reset", + "@unocss/vite", + "vite" + ] + }, + "@unocss/cli@0.59.4": { + "integrity": "sha512-TT+WKedSifhsRqnpoYD2LfyYipVzEbzIU4DDGIaDNeDxGXYOGpb876zzkPDcvZSpI37IJ/efkkV7PGYpPBcQBQ==", + "dependencies": [ + "@ampproject/remapping", + "@rollup/pluginutils", + "@unocss/config", + "@unocss/core", + "@unocss/preset-uno", + "cac", + "chokidar", + "colorette", + "consola", + "fast-glob", + "magic-string", + "pathe", + "perfect-debounce" + ] + }, + "@unocss/config@0.59.4": { + "integrity": "sha512-h3yhj+D5Ygn5R7gbK4wMrtXZX6FF5DF6YD517sSSb0XB3lxHD9PhhT4HaV1hpHknvu0cMFU3460M45+TN1TI0Q==", + "dependencies": [ + "@unocss/core", + "unconfig" + ] + }, + "@unocss/core@0.59.4": { + "integrity": "sha512-bBZ1sgcAtezQVZ1BST9IS3jqcsTLyqKNjiIf7FTnX3DHpfpYuMDFzSOtmkZDzBleOLO/CtcRWjT0HwTSQAmV0A==" + }, + "@unocss/extractor-arbitrary-variants@0.59.4": { + "integrity": "sha512-RDe4FgMGJQ+tp9GLvhPHni7Cc2O0lHBRMElVlN8LoXJAdODMICdbrEPGJlEfrc+7x/QgVFoR895KpYJh3hIgGA==", + "dependencies": [ + "@unocss/core" + ] + }, + "@unocss/inspector@0.59.4": { + "integrity": "sha512-QczJFNDiggmekkJyNcbcZIUVwlhvxz7ZwjnSf0w7K4znxfjKkZ1hNUbqLviM1HumkTKOdT27VISW7saN/ysO4w==", + "dependencies": [ + "@unocss/core", + "@unocss/rule-utils", + "gzip-size", + "sirv" + ] + }, + "@unocss/postcss@0.59.4_postcss@8.4.49": { + "integrity": "sha512-KVz+AD7McHKp7VEWHbFahhyyVEo0oP/e1vnuNSuPlHthe+1V2zfH6lps+iJcvfL2072r5J+0PvD/1kOp5ryUSg==", + "dependencies": [ + "@unocss/config", + "@unocss/core", + "@unocss/rule-utils", + "css-tree", + "fast-glob", + "magic-string", + "postcss" + ] + }, + "@unocss/preset-attributify@0.59.4": { + "integrity": "sha512-BeogWuYaIakC1gmOZFFCjFVWmu/m3AqEX8UYQS6tY6lAaK2L4Qf4AstYBlT2zAMxy9LNxPDxFQrvfSfFk5Klsg==", + "dependencies": [ + "@unocss/core" + ] + }, + "@unocss/preset-icons@0.59.4": { + "integrity": "sha512-Afjwh5oC4KRE8TNZDUkRK6hvvV1wKLrS1e5trniE0B0AM9HK3PBolQaIU7QmzPv6WQrog+MZgIwafg1eqsPUCA==", + "dependencies": [ + "@iconify/utils", + "@unocss/core", + "ofetch" + ] + }, + "@unocss/preset-mini@0.59.4": { + "integrity": "sha512-ZLywGrXi1OCr4My5vX2rLUb5Xgx6ufR9WTQOvpQJGBdIV/jnZn/pyE5avCs476SnOq2K172lnd8mFmTK7/zArA==", + "dependencies": [ + "@unocss/core", + "@unocss/extractor-arbitrary-variants", + "@unocss/rule-utils" + ] + }, + "@unocss/preset-tagify@0.59.4": { + "integrity": "sha512-vWMdTUoghOSmTbdmZtERssffmdUdOuhh4vUdl0R8Kv6KxB0PkvEFCu2FItn97nRJdSPlZSFxxDkaOIg9w+STNQ==", + "dependencies": [ + "@unocss/core" + ] + }, + "@unocss/preset-typography@0.59.4": { + "integrity": "sha512-ZX9bxZUqlXK1qEDzO5lkK96ICt9itR/oNyn/7mMc1JPqwj263LumQMn5silocgzoLSUXEeq//L6GylqYjkL8GA==", + "dependencies": [ + "@unocss/core", + "@unocss/preset-mini" + ] + }, + "@unocss/preset-uno@0.59.4": { + "integrity": "sha512-G1f8ZluplvXZ3bERj+sM/8zzY//XD++nNOlAQNKOANSVht3qEoJebrfEiMClNpA5qW5VWOZhEhPkh0M7GsXtnA==", + "dependencies": [ + "@unocss/core", + "@unocss/preset-mini", + "@unocss/preset-wind", + "@unocss/rule-utils" + ] + }, + "@unocss/preset-web-fonts@0.59.4": { + "integrity": "sha512-ehutTjKHnf2KPmdatN42N9a8+y+glKSU3UlcBRNsVIIXVIlaBQuPVGZSPhnMtrKD17IgWylXq2K6RJK+ab0hZA==", + "dependencies": [ + "@unocss/core", + "ofetch" + ] + }, + "@unocss/preset-wind@0.59.4": { + "integrity": "sha512-CNX6w0ZpSQg/i1oF0/WKWzto8PtLqoknC5h8JmmcGb7VsyBQeV0oNnhbURxpbuMEhbv1MWVIGvk8a+P6y0rFkQ==", + "dependencies": [ + "@unocss/core", + "@unocss/preset-mini", + "@unocss/rule-utils" + ] + }, + "@unocss/reset@0.59.4": { + "integrity": "sha512-Upy4xzdWl4RChbLAXBq1BoR4WqxXMoIfjvtcwSZcZK2sylXCFAseSWnyzJFdSiXPqNfmMuNgPXgiSxiQB+cmNA==" + }, + "@unocss/rule-utils@0.59.4": { + "integrity": "sha512-1qoLJlBWAkS4D4sg73990S1MT7E8E5md/YhopKjTQuEC9SyeVmEg+5pR/Xd8xhPKMqbcuBPl/DS8b6l/GQO56A==", + "dependencies": [ + "@unocss/core", + "magic-string" + ] + }, + "@unocss/scope@0.59.4": { + "integrity": "sha512-wBQJ39kw4Tfj4km7AoGvSIobPKVnRZVsgc0bema5Y0PL3g1NeVQ/LopBI2zEJWdpxGXUWxSDsXm7BZo6qVlD/A==" + }, + "@unocss/transformer-attributify-jsx-babel@0.59.4_@babel+core@7.26.0": { + "integrity": "sha512-xtCRSgeTaDBiNJLVX7oOSFe63JiFB5nrdK23PHn3IlZM9O7Bxx4ZxI3MQJtFZFQNE+INFko+DVyY1WiFEm1p/Q==", + "dependencies": [ + "@babel/core", + "@babel/plugin-syntax-jsx", + "@babel/preset-typescript", + "@unocss/core" + ] + }, + "@unocss/transformer-attributify-jsx@0.59.4": { + "integrity": "sha512-m4b83utzKMfUQH/45V2QkjJoXd8Tu2pRP1nic91Xf7QRceyKDD+BxoTneo2JNC2K274cQu7HqqotnCm2aFfEGw==", + "dependencies": [ + "@unocss/core" + ] + }, + "@unocss/transformer-compile-class@0.59.4": { + "integrity": "sha512-Vgk2OCLPW0pU+Uzr1IgDtHVspSBb+gPrQFkV+5gxHk9ZdKi3oYKxLuufVWYDSwv7o9yfQGbYrMH9YLsjRsnA7Q==", + "dependencies": [ + "@unocss/core" + ] + }, + "@unocss/transformer-directives@0.59.4": { + "integrity": "sha512-nXUTEclUbs0vQ4KfLhKt4J/5SLSEq1az2FNlJmiXMmqmn75X89OrtCu2OJu9sGXhn+YyBApxgcSSdxmtpqMi1Q==", + "dependencies": [ + "@unocss/core", + "@unocss/rule-utils", + "css-tree" + ] + }, + "@unocss/transformer-variant-group@0.59.4": { + "integrity": "sha512-9XLixxn1NRgP62Kj4R/NC/rpqhql5F2s6ulJ8CAMTEbd/NylVhEANluPGDVUGcLJ4cj6E02hFa8C1PLGSm7/xw==", + "dependencies": [ + "@unocss/core" + ] + }, + "@unocss/vite@0.59.4_vite@5.4.11": { + "integrity": "sha512-q7GN7vkQYn79n7vYIUlaa7gXGwc7pk0Qo3z3ZFwWGE43/DtZnn2Hwl5UjgBAgi9McA+xqHJEHRsJnI7HJPHUYA==", + "dependencies": [ + "@ampproject/remapping", + "@rollup/pluginutils", + "@unocss/config", + "@unocss/core", + "@unocss/inspector", + "@unocss/scope", + "@unocss/transformer-directives", + "chokidar", + "fast-glob", + "magic-string", + "vite" + ] + }, + "@vitejs/plugin-vue@5.2.1_vite@5.4.11_vue@3.5.13__typescript@5.7.2_typescript@5.7.2": { + "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==", + "dependencies": [ + "vite", + "vue" + ] + }, + "@volar/language-core@2.4.10": { + "integrity": "sha512-hG3Z13+nJmGaT+fnQzAkS0hjJRa2FCeqZt6Bd+oGNhUkQ+mTFsDETg5rqUTxyzIh5pSOGY7FHCWUS8G82AzLCA==", + "dependencies": [ + "@volar/source-map" + ] + }, + "@volar/source-map@2.4.10": { + "integrity": "sha512-OCV+b5ihV0RF3A7vEvNyHPi4G4kFa6ukPmyVocmqm5QzOd8r5yAtiNvaPEjl8dNvgC/lj4JPryeeHLdXd62rWA==" + }, + "@volar/typescript@2.4.10": { + "integrity": "sha512-F8ZtBMhSXyYKuBfGpYwqA5rsONnOwAVvjyE7KPYJ7wgZqo2roASqNWUnianOomJX5u1cxeRooHV59N0PhvEOgw==", + "dependencies": [ + "@volar/language-core", + "path-browserify", + "vscode-uri" + ] + }, + "@vue/compiler-core@3.5.13": { + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "dependencies": [ + "@babel/parser", + "@vue/shared", + "entities", + "estree-walker", + "source-map-js" + ] + }, + "@vue/compiler-dom@3.5.13": { + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "dependencies": [ + "@vue/compiler-core", + "@vue/shared" + ] + }, + "@vue/compiler-sfc@3.5.13": { + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "dependencies": [ + "@babel/parser", + "@vue/compiler-core", + "@vue/compiler-dom", + "@vue/compiler-ssr", + "@vue/shared", + "estree-walker", + "magic-string", + "postcss", + "source-map-js" + ] + }, + "@vue/compiler-ssr@3.5.13": { + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "dependencies": [ + "@vue/compiler-dom", + "@vue/shared" + ] + }, + "@vue/compiler-vue2@2.7.16": { + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dependencies": [ + "de-indent", + "he" + ] + }, + "@vue/devtools-api@6.6.4": { + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==" + }, + "@vue/language-core@2.1.10_typescript@5.7.2": { + "integrity": "sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ==", + "dependencies": [ + "@volar/language-core", + "@vue/compiler-dom", + "@vue/compiler-vue2", + "@vue/shared", + "alien-signals", + "minimatch", + "muggle-string", + "path-browserify", + "typescript" + ] + }, + "@vue/reactivity@3.5.13": { + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "dependencies": [ + "@vue/shared" + ] + }, + "@vue/runtime-core@3.5.13": { + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "dependencies": [ + "@vue/reactivity", + "@vue/shared" + ] + }, + "@vue/runtime-dom@3.5.13": { + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "dependencies": [ + "@vue/reactivity", + "@vue/runtime-core", + "@vue/shared", + "csstype" + ] + }, + "@vue/server-renderer@3.5.13_vue@3.5.13__typescript@5.7.2": { + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "dependencies": [ + "@vue/compiler-ssr", + "@vue/shared", + "vue" + ] + }, + "@vue/shared@3.5.13": { + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==" + }, + "acorn@8.14.0": { + "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==" + }, + "alien-signals@0.2.2": { + "integrity": "sha512-cZIRkbERILsBOXTQmMrxc9hgpxglstn69zm+F1ARf4aPAzdAFYd6sBq87ErO0Fj3DV94tglcyHG5kQz9nDC/8A==" + }, + "anymatch@3.1.3": { + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dependencies": [ + "normalize-path", + "picomatch@2.3.1" + ] + }, + "asynckit@0.4.0": { + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios@1.7.8": { + "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", + "dependencies": [ + "follow-redirects", + "form-data", + "proxy-from-env" + ] + }, + "bail@1.0.5": { + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==" + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "binary-extensions@2.3.0": { + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==" + }, + "brace-expansion@2.0.1": { + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": [ + "balanced-match" + ] + }, + "braces@3.0.3": { + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": [ + "fill-range" + ] + }, + "browserslist@4.24.2": { + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dependencies": [ + "caniuse-lite", + "electron-to-chromium", + "node-releases", + "update-browserslist-db" + ] + }, + "cac@6.7.14": { + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==" + }, + "caniuse-lite@1.0.30001684": { + "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==" + }, + "ccount@1.1.0": { + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==" + }, + "character-entities-legacy@1.1.4": { + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==" + }, + "character-entities@1.2.4": { + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==" + }, + "character-entities@2.0.2": { + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" + }, + "character-reference-invalid@1.1.4": { + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==" + }, + "chokidar@3.6.0": { + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dependencies": [ + "anymatch", + "braces", + "fsevents", + "glob-parent", + "is-binary-path", + "is-glob", + "normalize-path", + "readdirp" + ] + }, + "colorette@2.0.20": { + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==" + }, + "combined-stream@1.0.8": { + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": [ + "delayed-stream" + ] + }, + "confbox@0.1.8": { + "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==" + }, + "consola@3.2.3": { + "integrity": "sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==" + }, + "convert-source-map@2.0.0": { + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "crypto-js@4.2.0": { + "integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==" + }, + "css-tree@2.3.1": { + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", + "dependencies": [ + "mdn-data", + "source-map-js" + ] + }, + "csstype@3.1.3": { + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "de-indent@1.0.2": { + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==" + }, + "debug@4.3.7": { + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": [ + "ms" + ] + }, + "decode-named-character-reference@1.0.2": { + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": [ + "character-entities@2.0.2" + ] + }, + "defu@6.1.4": { + "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==" + }, + "delayed-stream@1.0.0": { + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "dequal@2.0.3": { + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, + "destr@2.0.3": { + "integrity": "sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==" + }, + "diff@5.2.0": { + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==" + }, + "duplexer@0.1.2": { + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, + "electron-to-chromium@1.5.65": { + "integrity": "sha512-PWVzBjghx7/wop6n22vS2MLU8tKGd4Q91aCEGhG/TYmW6PP5OcSXcdnxTe1NNt0T66N8D6jxh4kC8UsdzOGaIw==" + }, + "entities@4.5.0": { + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "esbuild@0.21.5": { + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dependencies": [ + "@esbuild/aix-ppc64", + "@esbuild/android-arm", + "@esbuild/android-arm64", + "@esbuild/android-x64", + "@esbuild/darwin-arm64", + "@esbuild/darwin-x64", + "@esbuild/freebsd-arm64", + "@esbuild/freebsd-x64", + "@esbuild/linux-arm", + "@esbuild/linux-arm64", + "@esbuild/linux-ia32", + "@esbuild/linux-loong64", + "@esbuild/linux-mips64el", + "@esbuild/linux-ppc64", + "@esbuild/linux-riscv64", + "@esbuild/linux-s390x", + "@esbuild/linux-x64", + "@esbuild/netbsd-x64", + "@esbuild/openbsd-x64", + "@esbuild/sunos-x64", + "@esbuild/win32-arm64", + "@esbuild/win32-ia32", + "@esbuild/win32-x64" + ] + }, + "escalade@3.2.0": { + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, + "escape-string-regexp@4.0.0": { + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + }, + "estree-walker@2.0.2": { + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "extend@3.0.2": { + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "fast-glob@3.3.2": { + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": [ + "@nodelib/fs.stat", + "@nodelib/fs.walk", + "glob-parent", + "merge2", + "micromatch" + ] + }, + "fastq@1.17.1": { + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": [ + "reusify" + ] + }, + "fill-range@7.1.1": { + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": [ + "to-regex-range" + ] + }, + "follow-redirects@1.15.9": { + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" + }, + "form-data@4.0.1": { + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "dependencies": [ + "asynckit", + "combined-stream", + "mime-types" + ] + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" + }, + "gensync@1.0.0-beta.2": { + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "glob-parent@5.1.2": { + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": [ + "is-glob" + ] + }, + "globals@11.12.0": { + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "gzip-size@6.0.0": { + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": [ + "duplexer" + ] + }, + "he@1.2.0": { + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "hono@4.6.12": { + "integrity": "sha512-eHtf4kSDNw6VVrdbd5IQi16r22m3s7mWPLd7xOMhg1a/Yyb1A0qpUFq8xYMX4FMuDe1nTKeMX5rTx7Nmw+a+Ag==" + }, + "html-comment-regex@1.1.2": { + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==" + }, + "is-alphabetical@1.0.4": { + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==" + }, + "is-alphanumerical@1.0.4": { + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dependencies": [ + "is-alphabetical", + "is-decimal" + ] + }, + "is-binary-path@2.1.0": { + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": [ + "binary-extensions" + ] + }, + "is-buffer@2.0.5": { + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + }, + "is-decimal@1.0.4": { + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==" + }, + "is-extglob@2.1.1": { + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob@4.0.3": { + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": [ + "is-extglob" + ] + }, + "is-hexadecimal@1.0.4": { + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==" + }, + "is-number@7.0.0": { + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-plain-obj@2.1.0": { + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" + }, + "jiti@1.21.6": { + "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==" + }, + "js-tokens@4.0.0": { + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc@3.0.2": { + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==" + }, + "json5@2.2.3": { + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "kleur@4.1.5": { + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" + }, + "kolorist@1.8.0": { + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==" + }, + "local-pkg@0.5.1": { + "integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==", + "dependencies": [ + "mlly", + "pkg-types" + ] + }, + "longest-streak@2.0.4": { + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==" + }, + "longest-streak@3.1.0": { + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==" + }, + "lru-cache@5.1.1": { + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": [ + "yallist" + ] + }, + "magic-string@0.30.14": { + "integrity": "sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==", + "dependencies": [ + "@jridgewell/sourcemap-codec" + ] + }, + "markdown-table@2.0.0": { + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dependencies": [ + "repeat-string" + ] + }, + "markdown-table@3.0.4": { + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==" + }, + "mdast-util-find-and-replace@1.1.1": { + "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", + "dependencies": [ + "escape-string-regexp", + "unist-util-is@4.1.0", + "unist-util-visit-parents@3.1.1" + ] + }, + "mdast-util-from-markdown@0.8.5": { + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dependencies": [ + "@types/mdast", + "mdast-util-to-string@2.0.0", + "micromark@2.11.4", + "parse-entities", + "unist-util-stringify-position@2.0.3" + ] + }, + "mdast-util-from-markdown@1.3.1": { + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": [ + "@types/mdast", + "@types/unist", + "decode-named-character-reference", + "mdast-util-to-string@3.2.0", + "micromark@3.2.0", + "micromark-util-decode-numeric-character-reference", + "micromark-util-decode-string", + "micromark-util-normalize-identifier", + "micromark-util-symbol", + "micromark-util-types", + "unist-util-stringify-position@3.0.3", + "uvu" + ] + }, + "mdast-util-gfm-autolink-literal@0.1.3": { + "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", + "dependencies": [ + "ccount", + "mdast-util-find-and-replace", + "micromark@2.11.4" + ] + }, + "mdast-util-gfm-strikethrough@0.2.3": { + "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", + "dependencies": [ + "mdast-util-to-markdown@0.6.5" + ] + }, + "mdast-util-gfm-table@0.1.6": { + "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", + "dependencies": [ + "markdown-table@2.0.0", + "mdast-util-to-markdown@0.6.5" + ] + }, + "mdast-util-gfm-table@1.0.7": { + "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", + "dependencies": [ + "@types/mdast", + "markdown-table@3.0.4", + "mdast-util-from-markdown@1.3.1", + "mdast-util-to-markdown@1.5.0" + ] + }, + "mdast-util-gfm-task-list-item@0.1.6": { + "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", + "dependencies": [ + "mdast-util-to-markdown@0.6.5" + ] + }, + "mdast-util-gfm@0.1.2": { + "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", + "dependencies": [ + "mdast-util-gfm-autolink-literal", + "mdast-util-gfm-strikethrough", + "mdast-util-gfm-table@0.1.6", + "mdast-util-gfm-task-list-item", + "mdast-util-to-markdown@0.6.5" + ] + }, + "mdast-util-phrasing@3.0.1": { + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "dependencies": [ + "@types/mdast", + "unist-util-is@5.2.1" + ] + }, + "mdast-util-to-markdown@0.6.5": { + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dependencies": [ + "@types/unist", + "longest-streak@2.0.4", + "mdast-util-to-string@2.0.0", + "parse-entities", + "repeat-string", + "zwitch@1.0.5" + ] + }, + "mdast-util-to-markdown@1.5.0": { + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", + "dependencies": [ + "@types/mdast", + "@types/unist", + "longest-streak@3.1.0", + "mdast-util-phrasing", + "mdast-util-to-string@3.2.0", + "micromark-util-decode-string", + "unist-util-visit@4.1.2", + "zwitch@2.0.4" + ] + }, + "mdast-util-to-string@2.0.0": { + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==" + }, + "mdast-util-to-string@3.2.0": { + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": [ + "@types/mdast" + ] + }, + "mdn-data@2.0.30": { + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" + }, + "merge2@1.4.1": { + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromark-core-commonmark@1.1.0": { + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "dependencies": [ + "decode-named-character-reference", + "micromark-factory-destination", + "micromark-factory-label", + "micromark-factory-space", + "micromark-factory-title", + "micromark-factory-whitespace", + "micromark-util-character", + "micromark-util-chunked", + "micromark-util-classify-character", + "micromark-util-html-tag-name", + "micromark-util-normalize-identifier", + "micromark-util-resolve-all", + "micromark-util-subtokenize", + "micromark-util-symbol", + "micromark-util-types", + "uvu" + ] + }, + "micromark-extension-gfm-autolink-literal@0.5.7": { + "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", + "dependencies": [ + "micromark@2.11.4" + ] + }, + "micromark-extension-gfm-strikethrough@0.6.5": { + "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", + "dependencies": [ + "micromark@2.11.4" + ] + }, + "micromark-extension-gfm-table@0.4.3": { + "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", + "dependencies": [ + "micromark@2.11.4" + ] + }, + "micromark-extension-gfm-tagfilter@0.3.0": { + "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==" + }, + "micromark-extension-gfm-task-list-item@0.3.3": { + "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", + "dependencies": [ + "micromark@2.11.4" + ] + }, + "micromark-extension-gfm@0.3.3": { + "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", + "dependencies": [ + "micromark@2.11.4", + "micromark-extension-gfm-autolink-literal", + "micromark-extension-gfm-strikethrough", + "micromark-extension-gfm-table", + "micromark-extension-gfm-tagfilter", + "micromark-extension-gfm-task-list-item" + ] + }, + "micromark-factory-destination@1.1.0": { + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "dependencies": [ + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-factory-label@1.1.0": { + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "dependencies": [ + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types", + "uvu" + ] + }, + "micromark-factory-space@1.1.0": { + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "dependencies": [ + "micromark-util-character", + "micromark-util-types" + ] + }, + "micromark-factory-title@1.1.0": { + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "dependencies": [ + "micromark-factory-space", + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-factory-whitespace@1.1.0": { + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "dependencies": [ + "micromark-factory-space", + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-util-character@1.2.0": { + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "dependencies": [ + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-util-chunked@1.1.0": { + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "dependencies": [ + "micromark-util-symbol" + ] + }, + "micromark-util-classify-character@1.1.0": { + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "dependencies": [ + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-util-combine-extensions@1.1.0": { + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "dependencies": [ + "micromark-util-chunked", + "micromark-util-types" + ] + }, + "micromark-util-decode-numeric-character-reference@1.1.0": { + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "dependencies": [ + "micromark-util-symbol" + ] + }, + "micromark-util-decode-string@1.1.0": { + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "dependencies": [ + "decode-named-character-reference", + "micromark-util-character", + "micromark-util-decode-numeric-character-reference", + "micromark-util-symbol" + ] + }, + "micromark-util-encode@1.1.0": { + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==" + }, + "micromark-util-html-tag-name@1.2.0": { + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==" + }, + "micromark-util-normalize-identifier@1.1.0": { + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "dependencies": [ + "micromark-util-symbol" + ] + }, + "micromark-util-resolve-all@1.1.0": { + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "dependencies": [ + "micromark-util-types" + ] + }, + "micromark-util-sanitize-uri@1.2.0": { + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "dependencies": [ + "micromark-util-character", + "micromark-util-encode", + "micromark-util-symbol" + ] + }, + "micromark-util-subtokenize@1.1.0": { + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "dependencies": [ + "micromark-util-chunked", + "micromark-util-symbol", + "micromark-util-types", + "uvu" + ] + }, + "micromark-util-symbol@1.1.0": { + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==" + }, + "micromark-util-types@1.1.0": { + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" + }, + "micromark@2.11.4": { + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "dependencies": [ + "debug", + "parse-entities" + ] + }, + "micromark@3.2.0": { + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "dependencies": [ + "@types/debug", + "debug", + "decode-named-character-reference", + "micromark-core-commonmark", + "micromark-factory-space", + "micromark-util-character", + "micromark-util-chunked", + "micromark-util-combine-extensions", + "micromark-util-decode-numeric-character-reference", + "micromark-util-encode", + "micromark-util-normalize-identifier", + "micromark-util-resolve-all", + "micromark-util-sanitize-uri", + "micromark-util-subtokenize", + "micromark-util-symbol", + "micromark-util-types", + "uvu" + ] + }, + "micromatch@4.0.8": { + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": [ + "braces", + "picomatch@2.3.1" + ] + }, + "mime-db@1.52.0": { + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types@2.1.35": { + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": [ + "mime-db" + ] + }, + "minimatch@9.0.5": { + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": [ + "brace-expansion" + ] + }, + "mlly@1.7.3": { + "integrity": "sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==", + "dependencies": [ + "acorn", + "pathe", + "pkg-types", + "ufo" + ] + }, + "mri@1.2.0": { + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" + }, + "mrmime@2.0.0": { + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==" + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "muggle-string@0.4.1": { + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==" + }, + "nanoid@3.3.8": { + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==" + }, + "node-fetch-native@1.6.4": { + "integrity": "sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==" + }, + "node-releases@2.0.18": { + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "normalize-path@3.0.0": { + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "ofetch@1.4.1": { + "integrity": "sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==", + "dependencies": [ + "destr", + "node-fetch-native", + "ufo" + ] + }, + "package-manager-detector@0.2.5": { + "integrity": "sha512-3dS7y28uua+UDbRCLBqltMBrbI+A5U2mI9YuxHRxIWYmLj3DwntEBmERYzIAQ4DMeuCUOBSak7dBHHoXKpOTYQ==" + }, + "parse-entities@2.0.0": { + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", + "dependencies": [ + "character-entities@1.2.4", + "character-entities-legacy", + "character-reference-invalid", + "is-alphanumerical", + "is-decimal", + "is-hexadecimal" + ] + }, + "path-browserify@1.0.1": { + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "pathe@1.1.2": { + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==" + }, + "perfect-debounce@1.0.0": { + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==" + }, + "picocolors@1.1.1": { + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "picomatch@2.3.1": { + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "picomatch@4.0.2": { + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==" + }, + "pkg-types@1.2.1": { + "integrity": "sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==", + "dependencies": [ + "confbox", + "mlly", + "pathe" + ] + }, + "postcss@8.4.49": { + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dependencies": [ + "nanoid", + "picocolors", + "source-map-js" + ] + }, + "proxy-from-env@1.1.0": { + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "queue-microtask@1.2.3": { + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "readdirp@3.6.0": { + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dependencies": [ + "picomatch@2.3.1" + ] + }, + "remark-gfm@1.0.0": { + "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", + "dependencies": [ + "mdast-util-gfm", + "micromark-extension-gfm" + ] + }, + "remark-parse@9.0.0": { + "integrity": "sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==", + "dependencies": [ + "mdast-util-from-markdown@0.8.5" + ] + }, + "remark-remove-comments@0.2.0": { + "integrity": "sha512-faGaTeqp0bvDgE0uTofa90EBHD4HXeHN+EUaPDR9datgFvaPkYcLxakaJud9LnomFPkOhx0A9NMYFk/lln/etQ==", + "dependencies": [ + "html-comment-regex", + "unist-util-visit@2.0.3" + ] + }, + "remark-stringify@9.0.1": { + "integrity": "sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==", + "dependencies": [ + "mdast-util-to-markdown@0.6.5" + ] + }, + "repeat-string@1.6.1": { + "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==" + }, + "reusify@1.0.4": { + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rollup@4.27.4": { + "integrity": "sha512-RLKxqHEMjh/RGLsDxAEsaLO3mWgyoU6x9w6n1ikAzet4B3gI2/3yP6PWY2p9QzRTh6MfEIXB3MwsOY0Iv3vNrw==", + "dependencies": [ + "@rollup/rollup-android-arm-eabi", + "@rollup/rollup-android-arm64", + "@rollup/rollup-darwin-arm64", + "@rollup/rollup-darwin-x64", + "@rollup/rollup-freebsd-arm64", + "@rollup/rollup-freebsd-x64", + "@rollup/rollup-linux-arm-gnueabihf", + "@rollup/rollup-linux-arm-musleabihf", + "@rollup/rollup-linux-arm64-gnu", + "@rollup/rollup-linux-arm64-musl", + "@rollup/rollup-linux-powerpc64le-gnu", + "@rollup/rollup-linux-riscv64-gnu", + "@rollup/rollup-linux-s390x-gnu", + "@rollup/rollup-linux-x64-gnu", + "@rollup/rollup-linux-x64-musl", + "@rollup/rollup-win32-arm64-msvc", + "@rollup/rollup-win32-ia32-msvc", + "@rollup/rollup-win32-x64-msvc", + "@types/estree", + "fsevents" + ] + }, + "run-parallel@1.2.0": { + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": [ + "queue-microtask" + ] + }, + "sade@1.8.1": { + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": [ + "mri" + ] + }, + "semver@6.3.1": { + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "semver@7.6.3": { + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, + "sirv@2.0.4": { + "integrity": "sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==", + "dependencies": [ + "@polka/url", + "mrmime", + "totalist" + ] + }, + "source-map-js@1.2.1": { + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "telegramify-markdown@1.2.2": { + "integrity": "sha512-l6JYuOsVy6UtLtYo5XC6ids8lCKTxzFe179GfAED45j4//hrqH7s7a5VRT5xfZFv1qI9nYqe4l8MgVfXG+8LFw==", + "dependencies": [ + "mdast-util-gfm-table@1.0.7", + "mdast-util-to-markdown@0.6.5", + "remark-gfm", + "remark-parse", + "remark-remove-comments", + "remark-stringify", + "unified", + "unist-util-remove", + "unist-util-visit@2.0.3" + ] + }, + "tinyexec@0.3.1": { + "integrity": "sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==" + }, + "to-regex-range@5.0.1": { + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": [ + "is-number" + ] + }, + "totalist@3.0.1": { + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==" + }, + "trough@1.0.5": { + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==" + }, + "typescript@5.7.2": { + "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==" + }, + "ufo@1.5.4": { + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==" + }, + "unconfig@0.3.13": { + "integrity": "sha512-N9Ph5NC4+sqtcOjPfHrRcHekBCadCXWTBzp2VYYbySOHW0PfD9XLCeXshTXjkPYwLrBr9AtSeU0CZmkYECJhng==", + "dependencies": [ + "@antfu/utils", + "defu", + "jiti" + ] + }, + "unified@9.2.2": { + "integrity": "sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==", + "dependencies": [ + "bail", + "extend", + "is-buffer", + "is-plain-obj", + "trough", + "vfile" + ] + }, + "unist-util-is@4.1.0": { + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==" + }, + "unist-util-is@5.2.1": { + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", + "dependencies": [ + "@types/unist" + ] + }, + "unist-util-remove@2.1.0": { + "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", + "dependencies": [ + "unist-util-is@4.1.0" + ] + }, + "unist-util-stringify-position@2.0.3": { + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dependencies": [ + "@types/unist" + ] + }, + "unist-util-stringify-position@3.0.3": { + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "dependencies": [ + "@types/unist" + ] + }, + "unist-util-visit-parents@3.1.1": { + "integrity": "sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==", + "dependencies": [ + "@types/unist", + "unist-util-is@4.1.0" + ] + }, + "unist-util-visit-parents@5.1.3": { + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": [ + "@types/unist", + "unist-util-is@5.2.1" + ] + }, + "unist-util-visit@2.0.3": { + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dependencies": [ + "@types/unist", + "unist-util-is@4.1.0", + "unist-util-visit-parents@3.1.1" + ] + }, + "unist-util-visit@4.1.2": { + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": [ + "@types/unist", + "unist-util-is@5.2.1", + "unist-util-visit-parents@5.1.3" + ] + }, + "unocss@0.59.4_vite@5.4.11": { + "integrity": "sha512-QmCVjRObvVu/gsGrJGVt0NnrdhFFn314BUZn2WQyXV9rIvHLRmG5bIu0j5vibJkj7ZhFchTrnTM1pTFXP1xt5g==", + "dependencies": [ + "@unocss/astro", + "@unocss/cli", + "@unocss/core", + "@unocss/extractor-arbitrary-variants", + "@unocss/postcss", + "@unocss/preset-attributify", + "@unocss/preset-icons", + "@unocss/preset-mini", + "@unocss/preset-tagify", + "@unocss/preset-typography", + "@unocss/preset-uno", + "@unocss/preset-web-fonts", + "@unocss/preset-wind", + "@unocss/reset", + "@unocss/transformer-attributify-jsx", + "@unocss/transformer-attributify-jsx-babel", + "@unocss/transformer-compile-class", + "@unocss/transformer-directives", + "@unocss/transformer-variant-group", + "@unocss/vite", + "vite" + ] + }, + "update-browserslist-db@1.1.1_browserslist@4.24.2": { + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dependencies": [ + "browserslist", + "escalade", + "picocolors" + ] + }, + "uvu@0.5.6": { + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": [ + "dequal", + "diff", + "kleur", + "sade" + ] + }, + "vfile-message@2.0.4": { + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "dependencies": [ + "@types/unist", + "unist-util-stringify-position@2.0.3" + ] + }, + "vfile@4.2.1": { + "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "dependencies": [ + "@types/unist", + "is-buffer", + "unist-util-stringify-position@2.0.3", + "vfile-message" + ] + }, + "vite@5.4.11": { + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dependencies": [ + "esbuild", + "fsevents", + "postcss", + "rollup" + ] + }, + "vscode-uri@3.0.8": { + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, + "vue-i18n@10.0.4_vue@3.5.13__typescript@5.7.2_typescript@5.7.2": { + "integrity": "sha512-1xkzVxqBLk2ZFOmeI+B5r1J7aD/WtNJ4j9k2mcFcQo5BnOmHBmD7z4/oZohh96AAaRZ4Q7mNQvxc9h+aT+Md3w==", + "dependencies": [ + "@intlify/core-base", + "@intlify/shared", + "@vue/devtools-api", + "vue" + ] + }, + "vue-router@4.5.0_vue@3.5.13__typescript@5.7.2_typescript@5.7.2": { + "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", + "dependencies": [ + "@vue/devtools-api", + "vue" + ] + }, + "vue-tg@0.6.1_typescript@5.7.2": { + "integrity": "sha512-Z1dwGLNQ9OYhYfR2NUmmpeXoWkV+gjeW7NVN5ZIYaxetyZCZF93nfXAZQnDVssfRMn7I37iJoTZLYe3eZZZCQA==", + "dependencies": [ + "@types/telegram-web-app", + "vue" + ] + }, + "vue-tsc@2.1.10_typescript@5.7.2": { + "integrity": "sha512-RBNSfaaRHcN5uqVqJSZh++Gy/YUzryuv9u1aFWhsammDJXNtUiJMNoJ747lZcQ68wUQFx6E73y4FY3D8E7FGMA==", + "dependencies": [ + "@volar/typescript", + "@vue/language-core", + "semver@7.6.3", + "typescript" + ] + }, + "vue-turnstile@1.0.11_vue@3.5.13__typescript@5.7.2_typescript@5.7.2": { + "integrity": "sha512-iaTBoZ5oUqtNRto6bmbn6FQvW0h/sK7mPUJc1Qn4em+cELXN59U2FQTcpWfKssV3OY6lEZzmCpcn/zrb7htK3A==", + "dependencies": [ + "vue" + ] + }, + "vue@3.5.13_typescript@5.7.2": { + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "dependencies": [ + "@vue/compiler-dom", + "@vue/compiler-sfc", + "@vue/runtime-dom", + "@vue/server-renderer", + "@vue/shared", + "typescript" + ] + }, + "vuetify@3.7.4_typescript@5.7.2_vue@3.5.13__typescript@5.7.2": { + "integrity": "sha512-Y8UU5wUDQXC3oz2uumPb8IOdvB4XMCxtxnmqdOc+LihNuPlkSgxIwf92ndRzbOtJFKHsggFUxpyLqpQp+A+5kg==", + "dependencies": [ + "typescript", + "vue" + ] + }, + "yallist@3.1.1": { + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + }, + "zod@3.23.8": { + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==" + }, + "zwitch@1.0.5": { + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==" + }, + "zwitch@2.0.4": { + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==" + } + }, + "redirects": { + "https://lib.deno.dev/x/grammy@1.x/mod.ts": "https://deno.land/x/grammy@v1.32.0/mod.ts" + }, + "remote": { + "https://cdn.skypack.dev/-/debug@v4.3.4-o4liVvMlOnQWbLSYZMXw/dist=es2019,mode=imports/optimized/debug.js": "671100993996e39b501301a87000607916d4d2d9f8fc8e9c5200ae5ba64a1389", + "https://cdn.skypack.dev/-/ms@v2.1.2-giBDZ1IA5lmQ3ZXaa87V/dist=es2019,mode=imports/optimized/ms.js": "fd88e2d51900437011f1ad232f3393ce97db1b87a7844b3c58dd6d65562c1276", + "https://cdn.skypack.dev/debug@4.3.4": "7b1d010cc930f71b940ba5941da055bc181115229e29de7214bdb4425c68ea76", + "https://deno.land/std@0.192.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", + "https://deno.land/std@0.192.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", + "https://deno.land/std@0.192.0/fs/_util.ts": "fbf57dcdc9f7bc8128d60301eece608246971a7836a3bb1e78da75314f08b978", + "https://deno.land/std@0.192.0/fs/walk.ts": "920be35a7376db6c0b5b1caf1486fb962925e38c9825f90367f8f26b5e5d0897", + "https://deno.land/std@0.192.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", + "https://deno.land/std@0.192.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", + "https://deno.land/std@0.192.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", + "https://deno.land/std@0.192.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", + "https://deno.land/std@0.192.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", + "https://deno.land/std@0.192.0/path/mod.ts": "f065032a7189404fdac3ad1a1551a9ac84751d2f25c431e101787846c86c79ef", + "https://deno.land/std@0.192.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", + "https://deno.land/std@0.192.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", + "https://deno.land/std@0.192.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", + "https://deno.land/std@0.211.0/path/_common/assert_path.ts": "2ca275f36ac1788b2acb60fb2b79cb06027198bc2ba6fb7e163efaedde98c297", + "https://deno.land/std@0.211.0/path/_common/basename.ts": "569744855bc8445f3a56087fd2aed56bdad39da971a8d92b138c9913aecc5fa2", + "https://deno.land/std@0.211.0/path/_common/constants.ts": "dc5f8057159f4b48cd304eb3027e42f1148cf4df1fb4240774d3492b5d12ac0c", + "https://deno.land/std@0.211.0/path/_common/strip_trailing_separators.ts": "7024a93447efcdcfeaa9339a98fa63ef9d53de363f1fbe9858970f1bba02655a", + "https://deno.land/std@0.211.0/path/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15", + "https://deno.land/std@0.211.0/path/basename.ts": "5d341aadb7ada266e2280561692c165771d071c98746fcb66da928870cd47668", + "https://deno.land/std@0.211.0/path/posix/_util.ts": "1e3937da30f080bfc99fe45d7ed23c47dd8585c5e473b2d771380d3a6937cf9d", + "https://deno.land/std@0.211.0/path/posix/basename.ts": "39ee27a29f1f35935d3603ccf01d53f3d6e0c5d4d0f84421e65bd1afeff42843", + "https://deno.land/std@0.211.0/path/windows/_util.ts": "d5f47363e5293fced22c984550d5e70e98e266cc3f31769e1710511803d04808", + "https://deno.land/std@0.211.0/path/windows/basename.ts": "e2dbf31d1d6385bfab1ce38c333aa290b6d7ae9e0ecb8234a654e583cf22f8fe", + "https://deno.land/x/fluent@0.0.1/bundle/ast.ts": "5b6c57e6115ca4497fc15be9a854053c0700cbadb680956b8719d6e40eacc759", + "https://deno.land/x/fluent@0.0.1/bundle/builtins.ts": "cdcb96c0b4d39bff48acf842c99e5df7262bd2a7dc8488cd6c73af3ecd3f783f", + "https://deno.land/x/fluent@0.0.1/bundle/bundle.ts": "fd5822c4fb8b094896620c5f825280b3bb1acc8cf757c0c33666564771e319f4", + "https://deno.land/x/fluent@0.0.1/bundle/memoizer.ts": "145e4d64156bca1f7fac51ca47eb31e15b0b31304ba4c8a1fe05e95a8ca85a96", + "https://deno.land/x/fluent@0.0.1/bundle/mod.ts": "3cc7b28a32c4739fcccdac11d57b287af2b1cf3aa394c45a54028f196d82f405", + "https://deno.land/x/fluent@0.0.1/bundle/resolver.ts": "58d0f9acc538b7306eb0e5b6838d40168bb0d025e53ddbb07be30003034062b9", + "https://deno.land/x/fluent@0.0.1/bundle/resource.ts": "ae9f2a10d6f4c5ea5e944458f5ff7323356e8d75959c38be840a6c9cbca0e9e9", + "https://deno.land/x/fluent@0.0.1/bundle/scope.ts": "a3978a7b22ee3f4f6abbaf9f42b1689fe4de9f59969c9731cfaf5ad31d153f4a", + "https://deno.land/x/fluent@0.0.1/bundle/types.ts": "6e1b13bdd1fd8c9871bf2505479c90b8df5c527e728b4b1002f2e37529db3e58", + "https://deno.land/x/fluent@0.0.1/langneg/accepted_languages.ts": "ecd1ba4b6bdbc5f39aae02cc32f635e7804ed53e98b48e3fdcb3d37f95db37c2", + "https://deno.land/x/fluent@0.0.1/langneg/locale.ts": "2256820338dd9a1c5b5865b504a0a6b23cb15b51b7c54063cb04d08db21e007c", + "https://deno.land/x/fluent@0.0.1/langneg/matches.ts": "d1f3ffc22e806b45b371d1efe8fc6aa1fa3dd861c150f30bd110498fee636b38", + "https://deno.land/x/fluent@0.0.1/langneg/mod.ts": "0a90ba0878e57d899e96b25f71feb29c5b0339b216a5f90fa3edb0750ca8ff3b", + "https://deno.land/x/fluent@0.0.1/langneg/negotiate_languages.ts": "0ad36deb38c1668c86ef84044e97d83bf6b135a06e941d7591f0e4c4339058dd", + "https://deno.land/x/grammy@v1.32.0/bot.ts": "477241b42959a7721292259b958da0601a3f50bb6cc07a642c8f74ccc3226a6c", + "https://deno.land/x/grammy@v1.32.0/composer.ts": "dab5a40d8a6fdc734bfb218f8b2e4ef846c05b833219ddd3fdee3f145bb2660b", + "https://deno.land/x/grammy@v1.32.0/context.ts": "29f61545dc685fff0df53ed8a5ef8ed592b2334532ad8828a889d63c5840cb63", + "https://deno.land/x/grammy@v1.32.0/convenience/constants.ts": "1560129784be52f49aa0bea8716f09ed00dac367fef195be6a2c09bdfc43fb99", + "https://deno.land/x/grammy@v1.32.0/convenience/frameworks.ts": "bc83a7b68cbbd2e7d3df08ccedb605b4f5ac8870f61d17dea23964c1d82a5ee6", + "https://deno.land/x/grammy@v1.32.0/convenience/inline_query.ts": "409d1940c7670708064efa495003bcbfdf6763a756b2e6303c464489fd3394ff", + "https://deno.land/x/grammy@v1.32.0/convenience/input_media.ts": "7af72a5fdb1af0417e31b1327003f536ddfdf64e06ab8bc7f5da6b574de38658", + "https://deno.land/x/grammy@v1.32.0/convenience/keyboard.ts": "dcfdc05f51758855d31dc80637798e0ca1d7f9b85038a6e9e600522e7cdac490", + "https://deno.land/x/grammy@v1.32.0/convenience/session.ts": "f0ce5742f7938aae146946c8b84d29540d20f592193ebfc217cb79e6e1af33fe", + "https://deno.land/x/grammy@v1.32.0/convenience/webhook.ts": "722f6da8de7578ecfcd263ca07ec3b81f09e7f243fdf2a887ac0e6cab509e116", + "https://deno.land/x/grammy@v1.32.0/core/api.ts": "8c0d9b9961ce3bda6d0e007456e3556c6f3e5cde4d24d74ac4b18625611ffa46", + "https://deno.land/x/grammy@v1.32.0/core/client.ts": "8d6b7dbcc944d0c42e0dce6119aaafca703c053ff6a5fbff426989c0dc790228", + "https://deno.land/x/grammy@v1.32.0/core/error.ts": "5245f18f273da6be364f525090c24d2e9a282c180904f674f66946f2b2556247", + "https://deno.land/x/grammy@v1.32.0/core/payload.ts": "420e17c3c2830b5576ea187cfce77578fe09f1204b25c25ea2f220ca7c86e73b", + "https://deno.land/x/grammy@v1.32.0/filter.ts": "dd30fa957e37a0857e471157bc5a21a13b8f5c3d145b512679aefb3ff5174670", + "https://deno.land/x/grammy@v1.32.0/mod.ts": "7723e08709ff7fd01df3e463503e14e4fd1a581669380eed70351e1121e8a833", + "https://deno.land/x/grammy@v1.32.0/platform.deno.ts": "68272a7e1d9a2d74d8a45342526485dbc0531dee812f675d7f8a4e7fc8393028", + "https://deno.land/x/grammy@v1.32.0/types.deno.ts": "d385ea7d8d55b879fcbc40ecf0d44586baaa8b3fd8fd354175b6b0da1abd496c", + "https://deno.land/x/grammy@v1.32.0/types.ts": "729415590dfa188dbe924dea614dff4e976babdbabb28a307b869fc25777cdf0", + "https://deno.land/x/grammy_i18n@v1.1.0/deps.ts": "c1d2763e65f8ccf02fe3b32b9f1e1d2185039da30730d3f9525c63a6cae7aadc", + "https://deno.land/x/grammy_i18n@v1.1.0/fluent.ts": "c4d6b4cf7aede9c25227b3e09aacc42e6ff381ef80bf1b476ba3ffdee284f74c", + "https://deno.land/x/grammy_i18n@v1.1.0/i18n.ts": "7041c605d38fba0cf4ddc1e8bd65294e8ac1d51a201d539c9ce36dbb7e0ec22a", + "https://deno.land/x/grammy_i18n@v1.1.0/mod.ts": "3250f0ecb81d4f0d7839b1d344c9453c5b7a79b7fca7d50b7ea89f91b7856cd9", + "https://deno.land/x/grammy_i18n@v1.1.0/types.ts": "ee187fb5c34aca31aa72ed4a0df375f1e14001cffb302d490526cc23dd975b43", + "https://deno.land/x/grammy_i18n@v1.1.0/utils.ts": "d880aef8dce05377a60e2e9c27b999b4936b97da1b50633bfa536f9f8c1daf92", + "https://deno.land/x/grammy_i18n@v1.1.0/warning.ts": "65c80833a93d5c37fe691125998b50268c11ecd070c8e85e0ce7d220ad7a3d37", + "https://deno.land/x/grammy_types@v3.16.0/api.ts": "ae04d6628e3d25ae805bc07a19475065044fc44cde0a40877405bc3544d03a5f", + "https://deno.land/x/grammy_types@v3.16.0/inline.ts": "ef999d5131968bdc49c0b74d2b0ff94fca310edfa06b02fe1ae1ac2949156934", + "https://deno.land/x/grammy_types@v3.16.0/langs.ts": "5f5fd09c58ba3ae942dd7cea2696f95587d2032c1829bba4bca81762b7ef73b6", + "https://deno.land/x/grammy_types@v3.16.0/manage.ts": "2bf2395311dcfdbb97d3227048eb877cac92d2a247563bb0e4f2e45acd4f99b1", + "https://deno.land/x/grammy_types@v3.16.0/markup.ts": "b989e0712f9731c59e6cb308371b1722d823dd55de3d6bcaf3e4ed645a42e1f9", + "https://deno.land/x/grammy_types@v3.16.0/message.ts": "a5ff7c58690d86385dab140a54f98303b57bdc0064754e0c64fa31f1635514ce", + "https://deno.land/x/grammy_types@v3.16.0/methods.ts": "250c1234305af8a06ea8bbb4b8886896c269f69b0c1e03a49802d1da6fb259a5", + "https://deno.land/x/grammy_types@v3.16.0/mod.ts": "7ecea1d3f7085d64419b78183039c78d70d655aeaa8b07f118ffbfb823f5b0b7", + "https://deno.land/x/grammy_types@v3.16.0/passport.ts": "19820e7d6c279521f8bc8912d6a378239f73d4ab525453808994b5f44ef95215", + "https://deno.land/x/grammy_types@v3.16.0/payment.ts": "10063563b3de6fe00f701a2efb13b3c6630e840e0b17f415d59730deeff1400c", + "https://deno.land/x/grammy_types@v3.16.0/settings.ts": "f8ff810da6f1007ed24cd504809bf46820229c395ff9bfc3e5c8ceaef5b2aae1", + "https://deno.land/x/grammy_types@v3.16.0/update.ts": "71cc0d5ec860149b71415ba03282b1d7edd0466b36e2789521a3b3a3d7796493" + }, + "workspace": { + "dependencies": [ + "jsr:@std/assert@1" + ], + "packageJson": { + "dependencies": [ + "npm:hono@^4.6.12" + ] + }, + "members": { + "app": { + "packageJson": { + "dependencies": [ + "npm:@mcaptcha/core-glue@0.1.0-alpha-5", + "npm:@mdi/font@^7.4.47", + "npm:@types/crypto-js@^4.2.2", + "npm:@vitejs/plugin-vue@^5.2.0", + "npm:axios@^1.7.7", + "npm:crypto-js@^4.2.0", + "npm:typescript@^5.6.3", + "npm:unocss@~0.59.4", + "npm:vite@^5.4.11", + "npm:vue-i18n@^10.0.4", + "npm:vue-router@^4.4.5", + "npm:vue-tg@~0.6.1", + "npm:vue-tsc@^2.1.10", + "npm:vue-turnstile@^1.0.11", + "npm:vue@^3.5.13", + "npm:vuetify@^3.7.4" + ] + } + }, + "bot": { + "dependencies": [ + "jsr:@std/assert@1", + "npm:telegramify-markdown@^1.2.2" + ] + }, + "server": { + "dependencies": [ + "npm:@hono/zod-validator@*", + "npm:hono@*", + "npm:zod@*" + ] + } + } + } +} diff --git a/docker-build.sh b/docker-build.sh index 80527c7..a63266c 100644 --- a/docker-build.sh +++ b/docker-build.sh @@ -1,5 +1,5 @@ # docker-build.sh -# frontend: Vite +# app: Vite export VITE_BACKEND_URL='https://verify.dianas.cyou' # Backend Domain export VITE_CLOUDFLARE_SITE_KEY='0x4AAAAAAAxxxxx' # Cloudflare Turnstile export HTTPS_ENABLED=false # HTTPS diff --git a/docker-compose.yml b/docker-compose.yml index 31d8d83..7147b49 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ version: '3.8' services: frontend: build: - context: frontend + context: app dockerfile: Dockerfile args: VITE_BACKEND_URL: ${VITE_BACKEND_URL} diff --git a/frontend/Dockerfile b/frontend/Dockerfile deleted file mode 100644 index 449b3d6..0000000 --- a/frontend/Dockerfile +++ /dev/null @@ -1,49 +0,0 @@ -# 使用 Node.js 18 作为基础镜像 -FROM node:18 AS build - -# 设置工作目录 -WORKDIR /app - -# 复制 package.json 和 package-lock.json -COPY package*.json ./ - -# 安装依赖 -RUN npm install - -# 复制项目文件 -COPY . . - -# 设置环境变量 -ARG VITE_BACKEND_URL -ARG VITE_CLOUDFLARE_SITE_KEY -ENV VITE_BACKEND_URL=$VITE_BACKEND_URL -ENV VITE_CLOUDFLARE_SITE_KEY=$VITE_CLOUDFLARE_SITE_KEY - -RUN echo "VITE_BACKEND_URL=${VITE_BACKEND_URL}" > .env -RUN echo "VITE_CLOUDFLARE_SITE_KEY=${VITE_CLOUDFLARE_SITE_KEY}" >> .env - -# 构建项目 -RUN npm run build - -# 使用轻量级 Node.js 运行时镜像 -FROM node:18-alpine - -# 从构建阶段复制构建好的资产 -COPY --from=build /app/dist /app/dist - -# 设置工作目录 -WORKDIR /app - -# 全局安装 http-server 包,用于提供静态文件 -RUN npm install -g http-server && apk --no-cache add tini - -# 暴露服务端口(不会占用宿主机的 80 和 443 端口) -EXPOSE 8080 -EXPOSE 8443 - -# 启动命令,检查证书文件是否存在 -CMD if [ "$HTTPS_ENABLED" = "true" ] && [ -f /etc/ssl/server.crt ] && [ -f /etc/ssl/server.key ]; then \ - tini -- http-server dist -p 8443 --ssl --cert /etc/ssl/server.crt --key /etc/ssl/server.key -S; \ - else \ - tini -- http-server dist -p 8080; \ - fi \ No newline at end of file diff --git a/frontend/cf.conf b/frontend/cf.conf deleted file mode 100644 index 6e298d4..0000000 --- a/frontend/cf.conf +++ /dev/null @@ -1,26 +0,0 @@ -# Custom rule section -allow 173.245.48.0/20; -allow 103.21.244.0/22; -allow 103.22.200.0/22; -allow 103.31.4.0/22; -allow 141.101.64.0/18; -allow 108.162.192.0/18; -allow 190.93.240.0/20; -allow 188.114.96.0/20; -allow 197.234.240.0/22; -allow 198.41.128.0/17; -allow 162.158.0.0/15; -allow 104.16.0.0/13; -allow 104.24.0.0/14; -allow 172.64.0.0/13; -allow 131.0.72.0/22; - -allow 2400:cb00::/32; -allow 2606:4700::/32; -allow 2803:f800::/32; -allow 2405:b500::/32; -allow 2405:8100::/32; -allow 2a06:98c0::/29; -allow 2c0f:f248::/32; - -deny all; \ No newline at end of file diff --git a/frontend/nginx.conf b/frontend/nginx.conf deleted file mode 100644 index fd3d70b..0000000 --- a/frontend/nginx.conf +++ /dev/null @@ -1,35 +0,0 @@ - events { - worker_connections 1024; - } - http { - server { - listen 80; - server_name one.com; - return 301 https://$server_name$request_uri; - } - - server { - listen 443 ssl; - server_name one.com; - - ssl_certificate /etc/nginx/ssl/site.pem; - ssl_certificate_key /etc/nginx/ssl/site.key; - - root /usr/share/nginx/html; - index index.html; - - location / { - try_files $uri $uri/ /index.html; - } - } - # 测试 - server{ - listen 10223; - server_name location; - root /usr/share/nginx/html; - index index.html; - location / { - try_files $uri $uri/ /index.html; - } - } - } \ No newline at end of file diff --git a/frontend/src/assets/vue.svg b/frontend/src/assets/vue.svg deleted file mode 100644 index 770e9d3..0000000 --- a/frontend/src/assets/vue.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/frontend/tsconfig.node.json b/frontend/tsconfig.node.json deleted file mode 100644 index 97ede7e..0000000 --- a/frontend/tsconfig.node.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true, - "strict": true - }, - "include": ["vite.config.ts"] -} diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts deleted file mode 100644 index 7bf17b7..0000000 --- a/frontend/vite.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -import {defineConfig} from 'vite' -import vue from '@vitejs/plugin-vue' -// vite.config.ts -import UnoCSS from 'unocss/vite' - -// https://vitejs.dev/config/ -export default defineConfig({ - plugins: [ - vue(), - UnoCSS(), - ], - define: { - 'import.meta.env.VITE_BUILD_DATE': JSON.stringify(new Date().toISOString().split('T')[0]), - }, - base: '/', -}) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100755 index 0000000..922a15c --- /dev/null +++ b/main.py @@ -0,0 +1,29 @@ +import asyncio +import os +import sys + +from dotenv import load_dotenv +from loguru import logger + +from bot import Runner, execution_ground + +load_dotenv() + +logger.remove() +handler_id = logger.add(sys.stderr, level="INFO" if not os.getenv("DEBUG") else "DEBUG", + format="{time} - {level} - {message}") +logger.add(sink="bot.log", format="{time} - {level} - {message}", level="INFO", rotation="100 MB", enqueue=True) +logger.info("Log file may contain sensitive information, do not share it with others.") + + +async def run_app(): + logger.info("Backend Server Start") + TelegramBot = Runner() + await asyncio.gather( + TelegramBot.run(), + execution_ground(), + ) + +loop = asyncio.new_event_loop() +asyncio.set_event_loop(loop) +loop.run_until_complete(run_app()) diff --git a/backend/pdm.lock b/pdm.lock similarity index 91% rename from backend/pdm.lock rename to pdm.lock index 61307f3..82919a4 100755 --- a/backend/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default"] strategy = ["cross_platform"] lock_version = "4.5.0" -content_hash = "sha256:8fb692dfa28df23c3603fc7eb04524e618f0878d6359b583beb264a0e661829a" +content_hash = "sha256:82b25bcf5b0f2bc6d367fa3afa6e08d26bfe23f9997f44380da2f07fd3dfcca7" [[metadata.targets]] requires_python = "~=3.10" @@ -552,6 +552,58 @@ files = [ {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, ] +[[package]] +name = "greenlet" +version = "3.1.1" +requires_python = ">=3.7" +summary = "Lightweight in-process concurrent programming" +files = [ + {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc"}, + {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617"}, + {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7"}, + {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6"}, + {file = "greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80"}, + {file = "greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383"}, + {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a"}, + {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511"}, + {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395"}, + {file = "greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39"}, + {file = "greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36"}, + {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9"}, + {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0"}, + {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942"}, + {file = "greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01"}, + {file = "greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4"}, + {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e"}, + {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1"}, + {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c"}, + {file = "greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b"}, + {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822"}, + {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01"}, + {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6"}, + {file = "greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467"}, +] + [[package]] name = "h11" version = "0.14.0" @@ -675,6 +727,16 @@ files = [ {file = "mistletoe-1.4.0.tar.gz", hash = "sha256:1630f906e5e4bbe66fdeb4d29d277e2ea515d642bb18a9b49b136361a9818c9d"}, ] +[[package]] +name = "mnemonic" +version = "0.21" +requires_python = ">=3.8.1" +summary = "Implementation of Bitcoin BIP-0039" +files = [ + {file = "mnemonic-0.21-py3-none-any.whl", hash = "sha256:72dc9de16ec5ef47287237b9b6943da11647a03fe7cf1f139fc3d7c4a7439288"}, + {file = "mnemonic-0.21.tar.gz", hash = "sha256:1fe496356820984f45559b1540c80ff10de448368929b9c60a2b55744cc88acf"}, +] + [[package]] name = "motor" version = "3.4.0" @@ -1545,6 +1607,67 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] +[[package]] +name = "sqlalchemy" +version = "2.0.36" +requires_python = ">=3.7" +summary = "Database Abstraction Library" +dependencies = [ + "greenlet!=0.4.17; (platform_machine == \"win32\" or platform_machine == \"WIN32\" or platform_machine == \"AMD64\" or platform_machine == \"amd64\" or platform_machine == \"x86_64\" or platform_machine == \"ppc64le\" or platform_machine == \"aarch64\") and python_version < \"3.13\"", + "importlib-metadata; python_version < \"3.8\"", + "typing-extensions>=4.6.0", +] +files = [ + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa"}, + {file = "SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-win32.whl", hash = "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f"}, + {file = "SQLAlchemy-2.0.36-cp311-cp311-win_amd64.whl", hash = "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-win32.whl", hash = "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e"}, + {file = "SQLAlchemy-2.0.36-cp312-cp312-win_amd64.whl", hash = "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-win32.whl", hash = "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436"}, + {file = "SQLAlchemy-2.0.36-cp313-cp313-win_amd64.whl", hash = "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88"}, + {file = "SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e"}, + {file = "sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5"}, +] + +[[package]] +name = "sqlmodel" +version = "0.0.22" +requires_python = ">=3.7" +summary = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." +dependencies = [ + "SQLAlchemy<2.1.0,>=2.0.14", + "pydantic<3.0.0,>=1.10.13", +] +files = [ + {file = "sqlmodel-0.0.22-py3-none-any.whl", hash = "sha256:a1ed13e28a1f4057cbf4ff6cdb4fc09e85702621d3259ba17b3c230bfb2f941b"}, + {file = "sqlmodel-0.0.22.tar.gz", hash = "sha256:7d37c882a30c43464d143e35e9ecaf945d88035e20117bf5ec2834a23cbe505e"}, +] + [[package]] name = "starlette" version = "0.41.2" diff --git a/note/baseline.md b/playground/baseline.md similarity index 100% rename from note/baseline.md rename to playground/baseline.md diff --git a/playground/event.py b/playground/event.py new file mode 100644 index 0000000..b78dd03 --- /dev/null +++ b/playground/event.py @@ -0,0 +1,3 @@ +import uuid + +print(uuid.uuid4().int & (1 << 24) - 1) diff --git a/backend/playground/note.md b/playground/note.md similarity index 100% rename from backend/playground/note.md rename to playground/note.md diff --git a/playground/ocr.png b/playground/ocr.png new file mode 100644 index 0000000000000000000000000000000000000000..ba4b6206cc5398870a71317af5da1172844654a1 GIT binary patch literal 44163 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
Jrf@DSKvh4Ya0ymQL-aEcc!MIxEa83qb7qbd?$ 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.2.3", "cleanse-speech>=0.1.3", "uvicorn>=0.30.3", + "SQLAlchemy>=2.0.36", + "sqlmodel>=0.0.22", + "mnemonic>=0.21", ] diff --git a/server/__init__.py b/server/__init__.py new file mode 100644 index 0000000..c32c08a --- /dev/null +++ b/server/__init__.py @@ -0,0 +1,202 @@ +# /endpoint/verify 的服务器 +# 用于验证用户的登录状态 + +import time +import uuid +from enum import Enum +from typing import Optional + +import telebot.util +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from fastapi.staticfiles import StaticFiles +from loguru import logger +from pydantic import BaseModel, SecretStr, ConfigDict +from sqlmodel import select +from starlette.responses import JSONResponse + +from common.config.cloudflare import CloudflareSetting +from common.config.server import ServerSetting +from common.config.telegrambot import BotSetting, BOT +from common.const import EXPIRE_M_TIME +from common.database import JoinRequest, VerifyRequest, dbInstance +from common.safety.signature import generate_sign, generate_oko +from server.validate_cloudflare import validate_cloudflare_turnstile + +app = FastAPI() +if ServerSetting.cors_origin: + origins = ServerSetting.cors_origin.split(",") + app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + +TELEGRAM_BOT_TOKEN = BotSetting.token + + +class Moon(BaseModel): + chat_id: str + message_id: str + timestamp: str + signature: str + + +class Device(BaseModel): + device_id: str | None + platform: str | None + version: str + mode: str + ts: int + model_config = ConfigDict(extra="allow") + + +class VerifyData(BaseModel): + """ + 响应数据 + """ + moon: Moon + signature: str + device: Device + web_app_data: str + ts: Optional[str] = None + fingerprint: Optional[str] = None + model_config = ConfigDict(extra="allow") + + +class CloudflareData(BaseModel): + """ + Cloudflare 验证数据 + """ + moon: Moon + turnstile_token: str + web_app_data: str + + +class EnumStatu(Enum): + success = "success" + error = "error" + + +def build_content(message: str, code: int): + return JSONResponse( + status_code=code, + content={"message": message} + ) + + +@app.get("/endpoints") +async def read_endpoints(): + # RockRoll The World + return {"message": "open this page in IE6"} + + +@app.post("/endpoints/verify-cloudflare") +async def verify_cloudflare(data: CloudflareData): + web_app_data = telebot.util.parse_web_app_data(token=TELEGRAM_BOT_TOKEN, raw_init_data=data.web_app_data) + if not web_app_data: + logger.error(f"verify-cloudflare:unsigned-request:{data}") + return build_content("DISPUTE", 400) + try: + validated = validate_cloudflare_turnstile( + turnstile_response=data.turnstile_token, + cloudflare_secret_key=SecretStr(CloudflareSetting.cloudflare_secret_key) + ) + except Exception as exc: + logger.exception(f"verify-cloudflare:validate-cloudflare-turnstile:{exc}") + return build_content("DISPUTE", 400) + else: + if not validated.success: + logger.info(f"verify-cloudflare:cloudflare-failed:{data.moon} - {validated.error_codes}") + return build_content("CLOUDFLARE_FAILED", 400) + else: + logger.info(f"verify-cloudflare:cloudflare-success:{data.moon}") + return build_content("PASS", 200) + + +@app.post("/endpoints/verify-captcha") +async def verify_captcha(captcha_data: VerifyData): + # 追踪请求 + event_id = f"E{uuid.uuid4().int & (1 << 24) - 1}" + # 验证客户端消息 + web_app_data = telebot.util.parse_web_app_data(token=TELEGRAM_BOT_TOKEN, raw_init_data=captcha_data.web_app_data) + if not web_app_data: + logger.error(f"verify-captcha:unsigned-request:{event_id}:{captcha_data}") + return build_content(f"ERROR {event_id}", 400) + try: + user_id = web_app_data['user']['id'] + chat_id = captcha_data.moon.chat_id + message_id = captcha_data.moon.message_id + # 加入群组时间 + join_time = captcha_data.moon.timestamp + # 现在毫秒时间 + now_m_time = time.time() * 1000 + except KeyError: + logger.error(f"verify-captcha:key-error:{event_id}:{captcha_data}") + return build_content(f"ERROR {event_id}", 400) + # 验证签发机构 + target_sign = generate_sign( + user_id=user_id, + chat_id=chat_id, + message_id=message_id, + join_time=join_time, + secret_key=SecretStr(BotSetting.token) + ) + t_s = generate_oko(data=captcha_data.web_app_data, time=captcha_data.ts) + if target_sign != captcha_data.signature: + logger.error(f"verify-captcha:fake-sign:{event_id}:{user_id}:{chat_id}:{captcha_data}") + return build_content(f"ERROR {event_id}", 400) + if not t_s: + logger.error(f"verify-captcha:oko-failed:{event_id}:{user_id}:{chat_id}:{captcha_data}") + else: + logger.info(f"verify-captcha:oko-success:{event_id}:{user_id}:{chat_id}:{captcha_data.ts}") + # 会话过旧,虽然我们有死亡队列,但是这里还是要做一下判断,防止重放攻击 + if now_m_time - int(join_time) > EXPIRE_M_TIME: + return build_content("EXPIRED", 400) + if not captcha_data.fingerprint: + logger.error(f"verify-captcha:fingerprint-missing:{event_id}:{user_id}:{chat_id}") + return build_content(f"ERROR {event_id}", 400) + logger.info(f"verify-captcha:print-acc:{event_id}:{user_id}:{chat_id}:{captcha_data.moon}") + logger.info(f"verify-captcha:print-webapp:{event_id}:{user_id}:{chat_id}:{web_app_data}") + # Accept User's Join Request + try: + with dbInstance.get_session() as session: + statement = select(JoinRequest).where(JoinRequest.user_id == user_id, JoinRequest.chat_id == chat_id) + results = session.exec(statement) + for result in results: + session.delete(result) + session.commit() + except Exception as exc: + logger.error(f"verify-captcha:opt-dead-queue-failed:{event_id}:{exc}") + + # Renew User's Join Request + try: + with dbInstance.get_session() as session: + statement = select(VerifyRequest).where(VerifyRequest.signature == captcha_data.signature) + requests = session.exec(statement) + if not requests: + logger.error(f"verify-captcha:history-not-found:{event_id}:{captcha_data.signature}") + for request in requests: + request.passed = True + session.add(request) + session.commit() + except Exception as exc: + logger.error(f"verify-captcha:opt-mongodb-failed:{exc} --signature {captcha_data.signature}") + try: + await BOT.approve_chat_join_request(chat_id=chat_id, user_id=user_id) + await BOT.delete_message(chat_id=user_id, message_id=message_id) + except Exception as exc: + if "USER_ALREADY_PARTICIPANT" in str(exc): + logger.info(f"verify-captcha:user-already-in-group:{user_id}:{chat_id}") + elif "HIDE_REQUESTER_MISSING" in str(exc): + logger.info(f"verify-captcha:hide-requester-missing:{user_id}:{chat_id}") + else: + logger.error(f"verify-captcha:approve-request-failed:{exc}") + finally: + # Accept user's join request + return build_content("PASS", 202) + + +app.mount("/app", StaticFiles(directory="webapp/dist"), name="webapp") diff --git a/backend/server/validate_cloudflare.py b/server/validate_cloudflare.py similarity index 91% rename from backend/server/validate_cloudflare.py rename to server/validate_cloudflare.py index a049f59..e344f33 100644 --- a/backend/server/validate_cloudflare.py +++ b/server/validate_cloudflare.py @@ -1,6 +1,6 @@ import httpx import pydantic -from pydantic import BaseModel +from pydantic import BaseModel, Field class ConfigureError(Exception): @@ -18,7 +18,7 @@ class SiteVerifyRequest(BaseModel): class SiteVerifyResponse(BaseModel): success: bool - error_codes: list[str] = [] + error_codes: list[str] = Field(default_factory=list) def validate_cloudflare_turnstile( @@ -46,7 +46,7 @@ def validate_cloudflare_turnstile( request_example = { - "secret": "0x5ABAAFAAAn72SdCAP75q6sPP9P6zooFZt", + "secret": "0x5ABAAFAAAn72S0000000000000P6zooFZt", "response": "???", } diff --git a/frontend/.gitignore b/webapp/.gitignore similarity index 100% rename from frontend/.gitignore rename to webapp/.gitignore diff --git a/frontend/README.md b/webapp/README.md similarity index 96% rename from frontend/README.md rename to webapp/README.md index a1d6ec9..7e2c0bd 100644 --- a/frontend/README.md +++ b/webapp/README.md @@ -12,7 +12,7 @@ VITE_BACKEND_URL=https://verify.dianas.cyou ## Recommended Setup ```shell -cd frontend +cd app npm install env VITE_BACKEND_URL="https://api.example.com" # env VITE_CLOUDFLARE_SITE_KEY="optional" diff --git a/frontend/index.html b/webapp/index.html similarity index 100% rename from frontend/index.html rename to webapp/index.html diff --git a/frontend/package-lock.json b/webapp/package-lock.json similarity index 100% rename from frontend/package-lock.json rename to webapp/package-lock.json diff --git a/frontend/package.json b/webapp/package.json similarity index 93% rename from frontend/package.json rename to webapp/package.json index 1bbdae4..f97ac75 100644 --- a/frontend/package.json +++ b/webapp/package.json @@ -26,6 +26,7 @@ "typescript": "^5.6.3", "unocss": "^0.59.4", "vite": "^5.4.11", + "vite-plugin-bundle-obfuscator": "^1.3.1", "vue-tsc": "^2.1.10" } } diff --git a/webapp/pnpm-lock.yaml b/webapp/pnpm-lock.yaml new file mode 100644 index 0000000..57c227f --- /dev/null +++ b/webapp/pnpm-lock.yaml @@ -0,0 +1,2834 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@mcaptcha/core-glue': + specifier: 0.1.0-alpha-5 + version: 0.1.0-alpha-5 + axios: + specifier: ^1.7.7 + version: 1.7.8 + crypto-js: + specifier: ^4.2.0 + version: 4.2.0 + vue: + specifier: ^3.5.13 + version: 3.5.13(typescript@5.7.2) + vue-i18n: + specifier: ^10.0.4 + version: 10.0.5(vue@3.5.13(typescript@5.7.2)) + vue-router: + specifier: ^4.4.5 + version: 4.5.0(vue@3.5.13(typescript@5.7.2)) + vue-tg: + specifier: ^0.6.1 + version: 0.6.1(typescript@5.7.2) + vue-turnstile: + specifier: ^1.0.11 + version: 1.0.11(vue@3.5.13(typescript@5.7.2)) + vuetify: + specifier: ^3.7.4 + version: 3.7.4(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)) + devDependencies: + '@mdi/font': + specifier: ^7.4.47 + version: 7.4.47 + '@types/crypto-js': + specifier: ^4.2.2 + version: 4.2.2 + '@vitejs/plugin-vue': + specifier: ^5.2.0 + version: 5.2.1(vite@5.4.11)(vue@3.5.13(typescript@5.7.2)) + typescript: + specifier: ^5.6.3 + version: 5.7.2 + unocss: + specifier: ^0.59.4 + version: 0.59.4(postcss@8.4.49)(rollup@4.28.0)(vite@5.4.11) + vite: + specifier: ^5.4.11 + version: 5.4.11 + vite-plugin-bundle-obfuscator: + specifier: ^1.3.1 + version: 1.3.1 + vue-tsc: + specifier: ^2.1.10 + version: 2.1.10(typescript@5.7.2) + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@antfu/install-pkg@0.4.1': + resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==} + + '@antfu/utils@0.7.10': + resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==} + + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.26.2': + resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.26.2': + resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.25.9': + resolution: {integrity: sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-member-expression-to-functions@7.25.9': + resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.25.9': + resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.25.9': + resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-replace-supers@7.25.9': + resolution: {integrity: sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.25.9': + resolution: {integrity: sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.25.9': + resolution: {integrity: sha512-dwh2Ol1jWwL2MgkCzUSOvfmKElqQcuswAZypBSUsScMXvgdT8Ekq5YA6TtqpTVWH+4903NmboMuH1o9i8Rxlyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.25.9': + resolution: {integrity: sha512-7PbZQZP50tzv2KGGnhh82GSyMB01yKY9scIjf1a+GfZCtInOWqUH5+1EBU4t9fyR5Oykkkc9vFTs4OHrhHXljQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.26.0': + resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.9': + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + engines: {node: '>=6.9.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] + + '@iconify/types@2.0.0': + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + + '@iconify/utils@2.1.33': + resolution: {integrity: sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==} + + '@intlify/core-base@10.0.5': + resolution: {integrity: sha512-F3snDTQs0MdvnnyzTDTVkOYVAZOE/MHwRvF7mn7Jw1yuih4NrFYLNYIymGlLmq4HU2iIdzYsZ7f47bOcwY73XQ==} + engines: {node: '>= 16'} + + '@intlify/message-compiler@10.0.5': + resolution: {integrity: sha512-6GT1BJ852gZ0gItNZN2krX5QAmea+cmdjMvsWohArAZ3GmHdnNANEcF9JjPXAMRtQ6Ux5E269ymamg/+WU6tQA==} + engines: {node: '>= 16'} + + '@intlify/shared@10.0.5': + resolution: {integrity: sha512-bmsP4L2HqBF6i6uaMqJMcFBONVjKt+siGluRq4Ca4C0q7W2eMaVZr8iCgF9dKbcVXutftkC7D6z2SaSMmLiDyA==} + engines: {node: '>= 16'} + + '@javascript-obfuscator/escodegen@2.3.0': + resolution: {integrity: sha512-QVXwMIKqYMl3KwtTirYIA6gOCiJ0ZDtptXqAv/8KWLG9uQU2fZqTVy7a/A5RvcoZhbDoFfveTxuGxJ5ibzQtkw==} + engines: {node: '>=6.0'} + + '@javascript-obfuscator/estraverse@5.4.0': + resolution: {integrity: sha512-CZFX7UZVN9VopGbjTx4UXaXsi9ewoM1buL0kY7j1ftYdSs7p2spv9opxFjHlQ/QGTgh4UqufYqJJ0WKLml7b6w==} + engines: {node: '>=4.0'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@mcaptcha/core-glue@0.1.0-alpha-5': + resolution: {integrity: sha512-16qWm5O5X0Y9LXULULaAks8Vf9FNlUUBcR5KDt49aWhFhG5++JzxNmCwQM9EJSHNU7y0U+FdyAWcGmjfKlkRLA==} + + '@mdi/font@7.4.47': + resolution: {integrity: sha512-43MtGpd585SNzHZPcYowu/84Vz2a2g31TvPMTm9uTiCSWzaheQySUcSyUH/46fPnuPQWof2yd0pGBtzee/IQWw==} + + '@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'} + + '@polka/url@1.0.0-next.28': + resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} + + '@rollup/pluginutils@5.1.3': + resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.28.0': + resolution: {integrity: sha512-wLJuPLT6grGZsy34g4N1yRfYeouklTgPhH1gWXCYspenKYD0s3cR99ZevOGw5BexMNywkbV3UkjADisozBmpPQ==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.28.0': + resolution: {integrity: sha512-eiNkznlo0dLmVG/6wf+Ifi/v78G4d4QxRhuUl+s8EWZpDewgk7PX3ZyECUXU0Zq/Ca+8nU8cQpNC4Xgn2gFNDA==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.28.0': + resolution: {integrity: sha512-lmKx9yHsppblnLQZOGxdO66gT77bvdBtr/0P+TPOseowE7D9AJoBw8ZDULRasXRWf1Z86/gcOdpBrV6VDUY36Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.28.0': + resolution: {integrity: sha512-8hxgfReVs7k9Js1uAIhS6zq3I+wKQETInnWQtgzt8JfGx51R1N6DRVy3F4o0lQwumbErRz52YqwjfvuwRxGv1w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.28.0': + resolution: {integrity: sha512-lA1zZB3bFx5oxu9fYud4+g1mt+lYXCoch0M0V/xhqLoGatbzVse0wlSQ1UYOWKpuSu3gyN4qEc0Dxf/DII1bhQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.28.0': + resolution: {integrity: sha512-aI2plavbUDjCQB/sRbeUZWX9qp12GfYkYSJOrdYTL/C5D53bsE2/nBPuoiJKoWp5SN78v2Vr8ZPnB+/VbQ2pFA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.28.0': + resolution: {integrity: sha512-WXveUPKtfqtaNvpf0iOb0M6xC64GzUX/OowbqfiCSXTdi/jLlOmH0Ba94/OkiY2yTGTwteo4/dsHRfh5bDCZ+w==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.28.0': + resolution: {integrity: sha512-yLc3O2NtOQR67lI79zsSc7lk31xjwcaocvdD1twL64PK1yNaIqCeWI9L5B4MFPAVGEVjH5k1oWSGuYX1Wutxpg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.28.0': + resolution: {integrity: sha512-+P9G9hjEpHucHRXqesY+3X9hD2wh0iNnJXX/QhS/J5vTdG6VhNYMxJ2rJkQOxRUd17u5mbMLHM7yWGZdAASfcg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.28.0': + resolution: {integrity: sha512-1xsm2rCKSTpKzi5/ypT5wfc+4bOGa/9yI/eaOLW0oMs7qpC542APWhl4A37AENGZ6St6GBMWhCCMM6tXgTIplw==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.28.0': + resolution: {integrity: sha512-zgWxMq8neVQeXL+ouSf6S7DoNeo6EPgi1eeqHXVKQxqPy1B2NvTbaOUWPn/7CfMKL7xvhV0/+fq/Z/J69g1WAQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.28.0': + resolution: {integrity: sha512-VEdVYacLniRxbRJLNtzwGt5vwS0ycYshofI7cWAfj7Vg5asqj+pt+Q6x4n+AONSZW/kVm+5nklde0qs2EUwU2g==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.28.0': + resolution: {integrity: sha512-LQlP5t2hcDJh8HV8RELD9/xlYtEzJkm/aWGsauvdO2ulfl3QYRjqrKW+mGAIWP5kdNCBheqqqYIGElSRCaXfpw==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.28.0': + resolution: {integrity: sha512-Nl4KIzteVEKE9BdAvYoTkW19pa7LR/RBrT6F1dJCV/3pbjwDcaOq+edkP0LXuJ9kflW/xOK414X78r+K84+msw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.28.0': + resolution: {integrity: sha512-eKpJr4vBDOi4goT75MvW+0dXcNUqisK4jvibY9vDdlgLx+yekxSm55StsHbxUsRxSTt3JEQvlr3cGDkzcSP8bw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.28.0': + resolution: {integrity: sha512-Vi+WR62xWGsE/Oj+mD0FNAPY2MEox3cfyG0zLpotZdehPFXwz6lypkGs5y38Jd/NVSbOD02aVad6q6QYF7i8Bg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.28.0': + resolution: {integrity: sha512-kN/Vpip8emMLn/eOza+4JwqDZBL6MPNpkdaEsgUtW1NYN3DZvZqSQrbKzJcTL6hd8YNmFTn7XGWMwccOcJBL0A==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.28.0': + resolution: {integrity: sha512-Bvno2/aZT6usSa7lRDL2+hMjVAGjuqaymF1ApZm31JXzniR/hvr14jpU+/z4X6Gt5BPlzosscyJZGUvguXIqeQ==} + cpu: [x64] + os: [win32] + + '@types/crypto-js@4.2.2': + resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + + '@types/telegram-web-app@7.10.1': + resolution: {integrity: sha512-GKL659G6lnHRAt3Dt7L1Fa0dwvc+ZZQtJcYrJVJGwjvsbi/Rcp1qKs9pFwb34/KC04+J+TlQj4D7yKo10sBSEw==} + + '@types/validator@13.12.2': + resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==} + + '@unocss/astro@0.59.4': + resolution: {integrity: sha512-DU3OR5MMR1Uvvec4/wB9EetDASHRg19Moy6z/MiIhn8JWJ0QzWYgSeJcfUX8exomMYv6WUEQJL+CyLI34Wmn8w==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + vite: + optional: true + + '@unocss/cli@0.59.4': + resolution: {integrity: sha512-TT+WKedSifhsRqnpoYD2LfyYipVzEbzIU4DDGIaDNeDxGXYOGpb876zzkPDcvZSpI37IJ/efkkV7PGYpPBcQBQ==} + engines: {node: '>=14'} + hasBin: true + + '@unocss/config@0.59.4': + resolution: {integrity: sha512-h3yhj+D5Ygn5R7gbK4wMrtXZX6FF5DF6YD517sSSb0XB3lxHD9PhhT4HaV1hpHknvu0cMFU3460M45+TN1TI0Q==} + engines: {node: '>=14'} + + '@unocss/core@0.59.4': + resolution: {integrity: sha512-bBZ1sgcAtezQVZ1BST9IS3jqcsTLyqKNjiIf7FTnX3DHpfpYuMDFzSOtmkZDzBleOLO/CtcRWjT0HwTSQAmV0A==} + + '@unocss/extractor-arbitrary-variants@0.59.4': + resolution: {integrity: sha512-RDe4FgMGJQ+tp9GLvhPHni7Cc2O0lHBRMElVlN8LoXJAdODMICdbrEPGJlEfrc+7x/QgVFoR895KpYJh3hIgGA==} + + '@unocss/inspector@0.59.4': + resolution: {integrity: sha512-QczJFNDiggmekkJyNcbcZIUVwlhvxz7ZwjnSf0w7K4znxfjKkZ1hNUbqLviM1HumkTKOdT27VISW7saN/ysO4w==} + + '@unocss/postcss@0.59.4': + resolution: {integrity: sha512-KVz+AD7McHKp7VEWHbFahhyyVEo0oP/e1vnuNSuPlHthe+1V2zfH6lps+iJcvfL2072r5J+0PvD/1kOp5ryUSg==} + engines: {node: '>=14'} + peerDependencies: + postcss: ^8.4.21 + + '@unocss/preset-attributify@0.59.4': + resolution: {integrity: sha512-BeogWuYaIakC1gmOZFFCjFVWmu/m3AqEX8UYQS6tY6lAaK2L4Qf4AstYBlT2zAMxy9LNxPDxFQrvfSfFk5Klsg==} + + '@unocss/preset-icons@0.59.4': + resolution: {integrity: sha512-Afjwh5oC4KRE8TNZDUkRK6hvvV1wKLrS1e5trniE0B0AM9HK3PBolQaIU7QmzPv6WQrog+MZgIwafg1eqsPUCA==} + + '@unocss/preset-mini@0.59.4': + resolution: {integrity: sha512-ZLywGrXi1OCr4My5vX2rLUb5Xgx6ufR9WTQOvpQJGBdIV/jnZn/pyE5avCs476SnOq2K172lnd8mFmTK7/zArA==} + + '@unocss/preset-tagify@0.59.4': + resolution: {integrity: sha512-vWMdTUoghOSmTbdmZtERssffmdUdOuhh4vUdl0R8Kv6KxB0PkvEFCu2FItn97nRJdSPlZSFxxDkaOIg9w+STNQ==} + + '@unocss/preset-typography@0.59.4': + resolution: {integrity: sha512-ZX9bxZUqlXK1qEDzO5lkK96ICt9itR/oNyn/7mMc1JPqwj263LumQMn5silocgzoLSUXEeq//L6GylqYjkL8GA==} + + '@unocss/preset-uno@0.59.4': + resolution: {integrity: sha512-G1f8ZluplvXZ3bERj+sM/8zzY//XD++nNOlAQNKOANSVht3qEoJebrfEiMClNpA5qW5VWOZhEhPkh0M7GsXtnA==} + + '@unocss/preset-web-fonts@0.59.4': + resolution: {integrity: sha512-ehutTjKHnf2KPmdatN42N9a8+y+glKSU3UlcBRNsVIIXVIlaBQuPVGZSPhnMtrKD17IgWylXq2K6RJK+ab0hZA==} + + '@unocss/preset-wind@0.59.4': + resolution: {integrity: sha512-CNX6w0ZpSQg/i1oF0/WKWzto8PtLqoknC5h8JmmcGb7VsyBQeV0oNnhbURxpbuMEhbv1MWVIGvk8a+P6y0rFkQ==} + + '@unocss/reset@0.59.4': + resolution: {integrity: sha512-Upy4xzdWl4RChbLAXBq1BoR4WqxXMoIfjvtcwSZcZK2sylXCFAseSWnyzJFdSiXPqNfmMuNgPXgiSxiQB+cmNA==} + + '@unocss/rule-utils@0.59.4': + resolution: {integrity: sha512-1qoLJlBWAkS4D4sg73990S1MT7E8E5md/YhopKjTQuEC9SyeVmEg+5pR/Xd8xhPKMqbcuBPl/DS8b6l/GQO56A==} + engines: {node: '>=14'} + + '@unocss/scope@0.59.4': + resolution: {integrity: sha512-wBQJ39kw4Tfj4km7AoGvSIobPKVnRZVsgc0bema5Y0PL3g1NeVQ/LopBI2zEJWdpxGXUWxSDsXm7BZo6qVlD/A==} + + '@unocss/transformer-attributify-jsx-babel@0.59.4': + resolution: {integrity: sha512-xtCRSgeTaDBiNJLVX7oOSFe63JiFB5nrdK23PHn3IlZM9O7Bxx4ZxI3MQJtFZFQNE+INFko+DVyY1WiFEm1p/Q==} + + '@unocss/transformer-attributify-jsx@0.59.4': + resolution: {integrity: sha512-m4b83utzKMfUQH/45V2QkjJoXd8Tu2pRP1nic91Xf7QRceyKDD+BxoTneo2JNC2K274cQu7HqqotnCm2aFfEGw==} + + '@unocss/transformer-compile-class@0.59.4': + resolution: {integrity: sha512-Vgk2OCLPW0pU+Uzr1IgDtHVspSBb+gPrQFkV+5gxHk9ZdKi3oYKxLuufVWYDSwv7o9yfQGbYrMH9YLsjRsnA7Q==} + + '@unocss/transformer-directives@0.59.4': + resolution: {integrity: sha512-nXUTEclUbs0vQ4KfLhKt4J/5SLSEq1az2FNlJmiXMmqmn75X89OrtCu2OJu9sGXhn+YyBApxgcSSdxmtpqMi1Q==} + + '@unocss/transformer-variant-group@0.59.4': + resolution: {integrity: sha512-9XLixxn1NRgP62Kj4R/NC/rpqhql5F2s6ulJ8CAMTEbd/NylVhEANluPGDVUGcLJ4cj6E02hFa8C1PLGSm7/xw==} + + '@unocss/vite@0.59.4': + resolution: {integrity: sha512-q7GN7vkQYn79n7vYIUlaa7gXGwc7pk0Qo3z3ZFwWGE43/DtZnn2Hwl5UjgBAgi9McA+xqHJEHRsJnI7HJPHUYA==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + + '@vitejs/plugin-vue@5.2.1': + resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 + vue: ^3.2.25 + + '@volar/language-core@2.4.10': + resolution: {integrity: sha512-hG3Z13+nJmGaT+fnQzAkS0hjJRa2FCeqZt6Bd+oGNhUkQ+mTFsDETg5rqUTxyzIh5pSOGY7FHCWUS8G82AzLCA==} + + '@volar/source-map@2.4.10': + resolution: {integrity: sha512-OCV+b5ihV0RF3A7vEvNyHPi4G4kFa6ukPmyVocmqm5QzOd8r5yAtiNvaPEjl8dNvgC/lj4JPryeeHLdXd62rWA==} + + '@volar/typescript@2.4.10': + resolution: {integrity: sha512-F8ZtBMhSXyYKuBfGpYwqA5rsONnOwAVvjyE7KPYJ7wgZqo2roASqNWUnianOomJX5u1cxeRooHV59N0PhvEOgw==} + + '@vue/compiler-core@3.5.13': + resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} + + '@vue/compiler-dom@3.5.13': + resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} + + '@vue/compiler-sfc@3.5.13': + resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} + + '@vue/compiler-ssr@3.5.13': + resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} + + '@vue/compiler-vue2@2.7.16': + resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} + + '@vue/devtools-api@6.6.4': + resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + + '@vue/language-core@2.1.10': + resolution: {integrity: sha512-DAI289d0K3AB5TUG3xDp9OuQ71CnrujQwJrQnfuZDwo6eGNf0UoRlPuaVNO+Zrn65PC3j0oB2i7mNmVPggeGeQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@vue/reactivity@3.5.13': + resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} + + '@vue/runtime-core@3.5.13': + resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} + + '@vue/runtime-dom@3.5.13': + resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} + + '@vue/server-renderer@3.5.13': + resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} + peerDependencies: + vue: 3.5.13 + + '@vue/shared@3.5.13': + resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} + hasBin: true + + alien-signals@0.2.2: + resolution: {integrity: sha512-cZIRkbERILsBOXTQmMrxc9hgpxglstn69zm+F1ARf4aPAzdAFYd6sBq87ErO0Fj3DV94tglcyHG5kQz9nDC/8A==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + array-differ@3.0.0: + resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} + engines: {node: '>=8'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + + assert@2.0.0: + resolution: {integrity: sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@1.7.8: + resolution: {integrity: sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} + 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==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001685: + resolution: {integrity: sha512-e/kJN1EMyHQzgcMEEgoo+YTCO1NGCmIYHk5Qk8jT6AazWemS5QFKJ5ShCJlH3GZrNIdZofcNCEwZqbMjjKzmnA==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chance@1.1.9: + resolution: {integrity: sha512-TfxnA/DcZXRTA4OekA2zL9GH8qscbbl6X0ZqU4tXhGveVY/mXWvEQLt5GwZcYXTEyEFflVtj+pG8nc8EwSm1RQ==} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + class-validator@0.14.1: + resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==} + + 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==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@10.0.0: + resolution: {integrity: sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA==} + engines: {node: '>=14'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + confbox@0.1.8: + resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==} + + consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + 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'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + electron-to-chromium@1.5.67: + resolution: {integrity: sha512-nz88NNBsD7kQSAGGJyp8hS6xSPtWwqNogA0mjtc2nUYeEf3nURK9qpV18TuBdDmEDgVWotS8Wkzf+V52dSQ/LQ==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es6-object-assign@1.1.0: + resolution: {integrity: sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==} + + 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'} + + eslint-scope@7.1.1: + resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@3.3.0: + resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + gopd@1.1.0: + resolution: {integrity: sha512-FQoVQnqcdk4hVM4JN1eromaun4iuS34oStkdlLENLdpULsuQcTyXj8w7ayhuUfPwEYZ1ZOooOTT6fdA9Vmx/RA==} + engines: {node: '>= 0.4'} + + gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.1.0: + resolution: {integrity: sha512-QLdzI9IIO1Jg7f9GT1gXpPpXArAn6cS31R1eEZqz08Gc+uQ8/XiqHWt17Fiw+2p6oTTIq5GXEpQkAlA88YRl/Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + inversify@6.0.1: + resolution: {integrity: sha512-B3ex30927698TJENHR++8FfEaJGqoWOgI6ZY5Ht/nLUsFCwHn6akbwtnUAPCgUepAnTpe2qHxhDNjoKLyz6rgQ==} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + javascript-obfuscator@4.1.1: + resolution: {integrity: sha512-gt+KZpIIrrxXHEQGD8xZrL8mTRwRY0U76/xz/YX0gZdPrSqQhT/c7dYLASlLlecT3r+FxE7je/+C0oLnTDCx4A==} + engines: {node: '>=12.22.0'} + hasBin: true + + jiti@1.21.6: + resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==} + hasBin: true + + js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + libphonenumber-js@1.11.15: + resolution: {integrity: sha512-M7+rtYi9l5RvMmHyjyoF3BHHUpXTYdJ0PezZGHNs0GyW1lO+K7jxlXpbdIb7a56h0nqLYdjIw+E+z0ciGaJP7g==} + + local-pkg@0.5.1: + resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} + engines: {node: '>=14'} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.14: + resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==} + + md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + 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-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + mkdirp@2.1.3: + resolution: {integrity: sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==} + engines: {node: '>=10'} + hasBin: true + + mlly@1.7.3: + resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} + + mrmime@2.0.0: + resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==} + engines: {node: '>=10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + + multimatch@5.0.0: + resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} + engines: {node: '>=10'} + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + 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'} + + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + opencollective-postinstall@2.0.3: + resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==} + hasBin: true + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + package-manager-detector@0.2.6: + resolution: {integrity: sha512-9vPH3qooBlYRJdmdYP00nvjZOulm40r5dhtal8st18ctf+6S1k7pi5yIHLvI4w5D70x0Y+xdVD9qITH0QO/A8A==} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pkg-types@1.2.1: + resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + reflect-metadata@0.1.13: + resolution: {integrity: sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rollup@4.28.0: + resolution: {integrity: sha512-G9GOrmgWHBma4YfCcX8PjH0qhXSdH8B4HDE2o4/jaxj93S4DPCIDoLcXz99eWMji4hB29UFCEd7B2gwGJDR9cQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + sirv@2.0.4: + resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} + engines: {node: '>= 10'} + + 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'} + + string-template@1.0.0: + resolution: {integrity: sha512-SLqR3GBUXuoPP5MmYtD7ompvXiG87QjT6lzOszyXjTM86Uu7At7vNnt2xgyTLq5o9T4IxTYFyGxcULqpsmsfdg==} + + stringz@2.1.0: + resolution: {integrity: sha512-KlywLT+MZ+v0IRepfMxRtnSvDCMc3nR1qqCs3m/qIbSOWkNZYT8XHQA31rS3TnKp0c5xjZu3M4GY/2aRKSi/6A==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + tinyexec@0.3.1: + resolution: {integrity: sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + + tslib@2.5.0: + resolution: {integrity: sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + typescript@5.7.2: + resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.5.4: + resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} + + unconfig@0.3.13: + resolution: {integrity: sha512-N9Ph5NC4+sqtcOjPfHrRcHekBCadCXWTBzp2VYYbySOHW0PfD9XLCeXshTXjkPYwLrBr9AtSeU0CZmkYECJhng==} + + unocss@0.59.4: + resolution: {integrity: sha512-QmCVjRObvVu/gsGrJGVt0NnrdhFFn314BUZn2WQyXV9rIvHLRmG5bIu0j5vibJkj7ZhFchTrnTM1pTFXP1xt5g==} + engines: {node: '>=14'} + peerDependencies: + '@unocss/webpack': 0.59.4 + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 + peerDependenciesMeta: + '@unocss/webpack': + optional: true + vite: + optional: true + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + engines: {node: '>= 0.10'} + + vite-plugin-bundle-obfuscator@1.3.1: + resolution: {integrity: sha512-35OM7Rk7FD2/DSR/JviUIZBaSE7sC8Efwa5m8sf5WJWd8+aqe9AgIp8JeK3FJHsXhUuDeOKVW2p/HBabyb3VdA==} + engines: {node: '>=14.0.0'} + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + 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 + + vscode-uri@3.0.8: + resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + + vue-i18n@10.0.5: + resolution: {integrity: sha512-9/gmDlCblz3i8ypu/afiIc/SUIfTTE1mr0mZhb9pk70xo2csHAM9mp2gdQ3KD2O0AM3Hz/5ypb+FycTj/lHlPQ==} + engines: {node: '>= 16'} + peerDependencies: + vue: ^3.0.0 + + vue-router@4.5.0: + resolution: {integrity: sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==} + peerDependencies: + vue: ^3.2.0 + + vue-tg@0.6.1: + resolution: {integrity: sha512-Z1dwGLNQ9OYhYfR2NUmmpeXoWkV+gjeW7NVN5ZIYaxetyZCZF93nfXAZQnDVssfRMn7I37iJoTZLYe3eZZZCQA==} + + vue-tsc@2.1.10: + resolution: {integrity: sha512-RBNSfaaRHcN5uqVqJSZh++Gy/YUzryuv9u1aFWhsammDJXNtUiJMNoJ747lZcQ68wUQFx6E73y4FY3D8E7FGMA==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + + vue-turnstile@1.0.11: + resolution: {integrity: sha512-iaTBoZ5oUqtNRto6bmbn6FQvW0h/sK7mPUJc1Qn4em+cELXN59U2FQTcpWfKssV3OY6lEZzmCpcn/zrb7htK3A==} + peerDependencies: + vue: ^3.2.45 + + vue@3.5.13: + resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + vuetify@3.7.4: + resolution: {integrity: sha512-Y8UU5wUDQXC3oz2uumPb8IOdvB4XMCxtxnmqdOc+LihNuPlkSgxIwf92ndRzbOtJFKHsggFUxpyLqpQp+A+5kg==} + engines: {node: ^12.20 || >=14.13} + peerDependencies: + typescript: '>=4.7' + vite-plugin-vuetify: '>=1.0.0' + vue: ^3.3.0 + webpack-plugin-vuetify: '>=2.0.0' + peerDependenciesMeta: + typescript: + optional: true + vite-plugin-vuetify: + optional: true + webpack-plugin-vuetify: + optional: true + + which-typed-array@1.1.16: + resolution: {integrity: sha512-g+N+GAWiRj66DngFwHvISJd+ITsyphZvD1vChfVg6cEdnzy53GzB3oy0fUNlvhz7H7+MiqhYr26qxQShCpKTTQ==} + engines: {node: '>= 0.4'} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@antfu/install-pkg@0.4.1': + dependencies: + package-manager-detector: 0.2.6 + tinyexec: 0.3.1 + + '@antfu/utils@0.7.10': {} + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.26.2': {} + + '@babel/core@7.26.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + convert-source-map: 2.0.0 + debug: 4.3.7 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.26.2': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/helper-annotate-as-pure@7.25.9': + dependencies: + '@babel/types': 7.26.0 + + '@babel/helper-compilation-targets@7.25.9': + dependencies: + '@babel/compat-data': 7.26.2 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/traverse': 7.25.9 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-member-expression-to-functions@7.25.9': + dependencies: + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.25.9': + dependencies: + '@babel/types': 7.26.0 + + '@babel/helper-plugin-utils@7.25.9': {} + + '@babel/helper-replace-supers@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/traverse': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.25.9': + dependencies: + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + dependencies: + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helpers@7.26.0': + dependencies: + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + + '@babel/parser@7.26.2': + dependencies: + '@babel/types': 7.26.0 + + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-transform-modules-commonjs@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-simple-access': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-typescript@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-modules-commonjs': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-typescript': 7.25.9(@babel/core@7.26.0) + transitivePeerDependencies: + - supports-color + + '@babel/template@7.25.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + + '@babel/traverse@7.25.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + debug: 4.3.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.26.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@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 + + '@iconify/types@2.0.0': {} + + '@iconify/utils@2.1.33': + dependencies: + '@antfu/install-pkg': 0.4.1 + '@antfu/utils': 0.7.10 + '@iconify/types': 2.0.0 + debug: 4.3.7 + kolorist: 1.8.0 + local-pkg: 0.5.1 + mlly: 1.7.3 + transitivePeerDependencies: + - supports-color + + '@intlify/core-base@10.0.5': + dependencies: + '@intlify/message-compiler': 10.0.5 + '@intlify/shared': 10.0.5 + + '@intlify/message-compiler@10.0.5': + dependencies: + '@intlify/shared': 10.0.5 + source-map-js: 1.2.1 + + '@intlify/shared@10.0.5': {} + + '@javascript-obfuscator/escodegen@2.3.0': + dependencies: + '@javascript-obfuscator/estraverse': 5.4.0 + esprima: 4.0.1 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + + '@javascript-obfuscator/estraverse@5.4.0': {} + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@mcaptcha/core-glue@0.1.0-alpha-5': {} + + '@mdi/font@7.4.47': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@polka/url@1.0.0-next.28': {} + + '@rollup/pluginutils@5.1.3(rollup@4.28.0)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.28.0 + + '@rollup/rollup-android-arm-eabi@4.28.0': + optional: true + + '@rollup/rollup-android-arm64@4.28.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.28.0': + optional: true + + '@rollup/rollup-darwin-x64@4.28.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.28.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.28.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.28.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.28.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.28.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.28.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.28.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.28.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.28.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.28.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.28.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.28.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.28.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.28.0': + optional: true + + '@types/crypto-js@4.2.2': {} + + '@types/estree@1.0.6': {} + + '@types/minimatch@3.0.5': {} + + '@types/telegram-web-app@7.10.1': {} + + '@types/validator@13.12.2': {} + + '@unocss/astro@0.59.4(rollup@4.28.0)(vite@5.4.11)': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/reset': 0.59.4 + '@unocss/vite': 0.59.4(rollup@4.28.0)(vite@5.4.11) + optionalDependencies: + vite: 5.4.11 + transitivePeerDependencies: + - rollup + + '@unocss/cli@0.59.4(rollup@4.28.0)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.3(rollup@4.28.0) + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/preset-uno': 0.59.4 + cac: 6.7.14 + chokidar: 3.6.0 + colorette: 2.0.20 + consola: 3.2.3 + fast-glob: 3.3.2 + magic-string: 0.30.14 + pathe: 1.1.2 + perfect-debounce: 1.0.0 + transitivePeerDependencies: + - rollup + + '@unocss/config@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + unconfig: 0.3.13 + + '@unocss/core@0.59.4': {} + + '@unocss/extractor-arbitrary-variants@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/inspector@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + gzip-size: 6.0.0 + sirv: 2.0.4 + + '@unocss/postcss@0.59.4(postcss@8.4.49)': + dependencies: + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + css-tree: 2.3.1 + fast-glob: 3.3.2 + magic-string: 0.30.14 + postcss: 8.4.49 + + '@unocss/preset-attributify@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/preset-icons@0.59.4': + dependencies: + '@iconify/utils': 2.1.33 + '@unocss/core': 0.59.4 + ofetch: 1.4.1 + transitivePeerDependencies: + - supports-color + + '@unocss/preset-mini@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/extractor-arbitrary-variants': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/preset-tagify@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/preset-typography@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + + '@unocss/preset-uno@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/preset-wind': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/preset-web-fonts@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + ofetch: 1.4.1 + + '@unocss/preset-wind@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/rule-utils': 0.59.4 + + '@unocss/reset@0.59.4': {} + + '@unocss/rule-utils@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + magic-string: 0.30.14 + + '@unocss/scope@0.59.4': {} + + '@unocss/transformer-attributify-jsx-babel@0.59.4': + dependencies: + '@babel/core': 7.26.0 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) + '@unocss/core': 0.59.4 + transitivePeerDependencies: + - supports-color + + '@unocss/transformer-attributify-jsx@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/transformer-compile-class@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/transformer-directives@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + '@unocss/rule-utils': 0.59.4 + css-tree: 2.3.1 + + '@unocss/transformer-variant-group@0.59.4': + dependencies: + '@unocss/core': 0.59.4 + + '@unocss/vite@0.59.4(rollup@4.28.0)(vite@5.4.11)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@rollup/pluginutils': 5.1.3(rollup@4.28.0) + '@unocss/config': 0.59.4 + '@unocss/core': 0.59.4 + '@unocss/inspector': 0.59.4 + '@unocss/scope': 0.59.4 + '@unocss/transformer-directives': 0.59.4 + chokidar: 3.6.0 + fast-glob: 3.3.2 + magic-string: 0.30.14 + vite: 5.4.11 + transitivePeerDependencies: + - rollup + + '@vitejs/plugin-vue@5.2.1(vite@5.4.11)(vue@3.5.13(typescript@5.7.2))': + dependencies: + vite: 5.4.11 + vue: 3.5.13(typescript@5.7.2) + + '@volar/language-core@2.4.10': + dependencies: + '@volar/source-map': 2.4.10 + + '@volar/source-map@2.4.10': {} + + '@volar/typescript@2.4.10': + dependencies: + '@volar/language-core': 2.4.10 + path-browserify: 1.0.1 + vscode-uri: 3.0.8 + + '@vue/compiler-core@3.5.13': + dependencies: + '@babel/parser': 7.26.2 + '@vue/shared': 3.5.13 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + + '@vue/compiler-dom@3.5.13': + dependencies: + '@vue/compiler-core': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-sfc@3.5.13': + dependencies: + '@babel/parser': 7.26.2 + '@vue/compiler-core': 3.5.13 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + estree-walker: 2.0.2 + magic-string: 0.30.14 + postcss: 8.4.49 + source-map-js: 1.2.1 + + '@vue/compiler-ssr@3.5.13': + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/compiler-vue2@2.7.16': + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + + '@vue/devtools-api@6.6.4': {} + + '@vue/language-core@2.1.10(typescript@5.7.2)': + dependencies: + '@volar/language-core': 2.4.10 + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-vue2': 2.7.16 + '@vue/shared': 3.5.13 + alien-signals: 0.2.2 + minimatch: 9.0.5 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + optionalDependencies: + typescript: 5.7.2 + + '@vue/reactivity@3.5.13': + dependencies: + '@vue/shared': 3.5.13 + + '@vue/runtime-core@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/shared': 3.5.13 + + '@vue/runtime-dom@3.5.13': + dependencies: + '@vue/reactivity': 3.5.13 + '@vue/runtime-core': 3.5.13 + '@vue/shared': 3.5.13 + csstype: 3.1.3 + + '@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.7.2))': + dependencies: + '@vue/compiler-ssr': 3.5.13 + '@vue/shared': 3.5.13 + vue: 3.5.13(typescript@5.7.2) + + '@vue/shared@3.5.13': {} + + acorn@8.14.0: {} + + acorn@8.8.2: {} + + alien-signals@0.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + array-differ@3.0.0: {} + + array-union@2.1.0: {} + + arrify@2.0.1: {} + + assert@2.0.0: + dependencies: + es6-object-assign: 1.1.0 + is-nan: 1.3.2 + object-is: 1.1.6 + util: 0.12.5 + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axios@1.7.8: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.2: + dependencies: + caniuse-lite: 1.0.30001685 + electron-to-chromium: 1.5.67 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) + + buffer-from@1.1.2: {} + + cac@6.7.14: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + caniuse-lite@1.0.30001685: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chance@1.1.9: {} + + char-regex@1.0.2: {} + + charenc@0.0.2: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + class-validator@0.14.1: + dependencies: + '@types/validator': 13.12.2 + libphonenumber-js: 1.11.15 + validator: 13.12.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@10.0.0: {} + + concat-map@0.0.1: {} + + confbox@0.1.8: {} + + consola@3.2.3: {} + + convert-source-map@2.0.0: {} + + crypt@0.0.2: {} + + crypto-js@4.2.0: {} + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + csstype@3.1.3: {} + + de-indent@1.0.2: {} + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.1.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + destr@2.0.3: {} + + duplexer@0.1.2: {} + + electron-to-chromium@1.5.67: {} + + entities@4.5.0: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es6-object-assign@1.1.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: {} + + eslint-scope@7.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.3.0: {} + + esprima@4.0.1: {} + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + follow-redirects@1.15.9: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.1.0 + has-symbols: 1.0.3 + hasown: 2.0.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globals@11.12.0: {} + + gopd@1.1.0: + dependencies: + get-intrinsic: 1.2.4 + + gzip-size@6.0.0: + dependencies: + duplexer: 0.1.2 + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.1.0: + dependencies: + call-bind: 1.0.7 + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + inherits@2.0.4: {} + + inversify@6.0.1: {} + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-buffer@1.1.6: {} + + is-callable@1.2.7: {} + + is-extglob@2.1.1: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-nan@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + is-number@7.0.0: {} + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.16 + + javascript-obfuscator@4.1.1: + dependencies: + '@javascript-obfuscator/escodegen': 2.3.0 + '@javascript-obfuscator/estraverse': 5.4.0 + acorn: 8.8.2 + assert: 2.0.0 + chalk: 4.1.2 + chance: 1.1.9 + class-validator: 0.14.1 + commander: 10.0.0 + eslint-scope: 7.1.1 + eslint-visitor-keys: 3.3.0 + fast-deep-equal: 3.1.3 + inversify: 6.0.1 + js-string-escape: 1.0.1 + md5: 2.3.0 + mkdirp: 2.1.3 + multimatch: 5.0.0 + opencollective-postinstall: 2.0.3 + process: 0.11.10 + reflect-metadata: 0.1.13 + source-map-support: 0.5.21 + string-template: 1.0.0 + stringz: 2.1.0 + tslib: 2.5.0 + + jiti@1.21.6: {} + + js-string-escape@1.0.1: {} + + js-tokens@4.0.0: {} + + jsesc@3.0.2: {} + + json5@2.2.3: {} + + kolorist@1.8.0: {} + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + + libphonenumber-js@1.11.15: {} + + local-pkg@0.5.1: + dependencies: + mlly: 1.7.3 + pkg-types: 1.2.1 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.14: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + md5@2.3.0: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + + mdn-data@2.0.30: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + mkdirp@2.1.3: {} + + mlly@1.7.3: + dependencies: + acorn: 8.14.0 + pathe: 1.1.2 + pkg-types: 1.2.1 + ufo: 1.5.4 + + mrmime@2.0.0: {} + + ms@2.1.3: {} + + muggle-string@0.4.1: {} + + multimatch@5.0.0: + dependencies: + '@types/minimatch': 3.0.5 + array-differ: 3.0.0 + array-union: 2.1.0 + arrify: 2.0.1 + minimatch: 3.1.2 + + nanoid@3.3.8: {} + + node-fetch-native@1.6.4: {} + + node-releases@2.0.18: {} + + normalize-path@3.0.0: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + ofetch@1.4.1: + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.4 + + opencollective-postinstall@2.0.3: {} + + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + + package-manager-detector@0.2.6: {} + + path-browserify@1.0.1: {} + + pathe@1.1.2: {} + + perfect-debounce@1.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pkg-types@1.2.1: + dependencies: + confbox: 0.1.8 + mlly: 1.7.3 + pathe: 1.1.2 + + possible-typed-array-names@1.0.0: {} + + postcss@8.4.49: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.1.2: {} + + process@0.11.10: {} + + proxy-from-env@1.1.0: {} + + queue-microtask@1.2.3: {} + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + reflect-metadata@0.1.13: {} + + reusify@1.0.4: {} + + rollup@4.28.0: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.28.0 + '@rollup/rollup-android-arm64': 4.28.0 + '@rollup/rollup-darwin-arm64': 4.28.0 + '@rollup/rollup-darwin-x64': 4.28.0 + '@rollup/rollup-freebsd-arm64': 4.28.0 + '@rollup/rollup-freebsd-x64': 4.28.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.28.0 + '@rollup/rollup-linux-arm-musleabihf': 4.28.0 + '@rollup/rollup-linux-arm64-gnu': 4.28.0 + '@rollup/rollup-linux-arm64-musl': 4.28.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.28.0 + '@rollup/rollup-linux-riscv64-gnu': 4.28.0 + '@rollup/rollup-linux-s390x-gnu': 4.28.0 + '@rollup/rollup-linux-x64-gnu': 4.28.0 + '@rollup/rollup-linux-x64-musl': 4.28.0 + '@rollup/rollup-win32-arm64-msvc': 4.28.0 + '@rollup/rollup-win32-ia32-msvc': 4.28.0 + '@rollup/rollup-win32-x64-msvc': 4.28.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + semver@6.3.1: {} + + semver@7.6.3: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.1.0 + has-property-descriptors: 1.0.2 + + sirv@2.0.4: + dependencies: + '@polka/url': 1.0.0-next.28 + mrmime: 2.0.0 + totalist: 3.0.1 + + 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: {} + + string-template@1.0.0: {} + + stringz@2.1.0: + dependencies: + char-regex: 1.0.2 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tinyexec@0.3.1: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + totalist@3.0.1: {} + + tslib@2.5.0: {} + + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + + typescript@5.7.2: {} + + ufo@1.5.4: {} + + unconfig@0.3.13: + dependencies: + '@antfu/utils': 0.7.10 + defu: 6.1.4 + jiti: 1.21.6 + + unocss@0.59.4(postcss@8.4.49)(rollup@4.28.0)(vite@5.4.11): + dependencies: + '@unocss/astro': 0.59.4(rollup@4.28.0)(vite@5.4.11) + '@unocss/cli': 0.59.4(rollup@4.28.0) + '@unocss/core': 0.59.4 + '@unocss/extractor-arbitrary-variants': 0.59.4 + '@unocss/postcss': 0.59.4(postcss@8.4.49) + '@unocss/preset-attributify': 0.59.4 + '@unocss/preset-icons': 0.59.4 + '@unocss/preset-mini': 0.59.4 + '@unocss/preset-tagify': 0.59.4 + '@unocss/preset-typography': 0.59.4 + '@unocss/preset-uno': 0.59.4 + '@unocss/preset-web-fonts': 0.59.4 + '@unocss/preset-wind': 0.59.4 + '@unocss/reset': 0.59.4 + '@unocss/transformer-attributify-jsx': 0.59.4 + '@unocss/transformer-attributify-jsx-babel': 0.59.4 + '@unocss/transformer-compile-class': 0.59.4 + '@unocss/transformer-directives': 0.59.4 + '@unocss/transformer-variant-group': 0.59.4 + '@unocss/vite': 0.59.4(rollup@4.28.0)(vite@5.4.11) + optionalDependencies: + vite: 5.4.11 + transitivePeerDependencies: + - postcss + - rollup + - supports-color + + update-browserslist-db@1.1.1(browserslist@4.24.2): + dependencies: + browserslist: 4.24.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.16 + + validator@13.12.0: {} + + vite-plugin-bundle-obfuscator@1.3.1: + dependencies: + javascript-obfuscator: 4.1.1 + + vite@5.4.11: + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.28.0 + optionalDependencies: + fsevents: 2.3.3 + + vscode-uri@3.0.8: {} + + vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.2)): + dependencies: + '@intlify/core-base': 10.0.5 + '@intlify/shared': 10.0.5 + '@vue/devtools-api': 6.6.4 + vue: 3.5.13(typescript@5.7.2) + + vue-router@4.5.0(vue@3.5.13(typescript@5.7.2)): + dependencies: + '@vue/devtools-api': 6.6.4 + vue: 3.5.13(typescript@5.7.2) + + vue-tg@0.6.1(typescript@5.7.2): + dependencies: + '@types/telegram-web-app': 7.10.1 + vue: 3.5.13(typescript@5.7.2) + transitivePeerDependencies: + - typescript + + vue-tsc@2.1.10(typescript@5.7.2): + dependencies: + '@volar/typescript': 2.4.10 + '@vue/language-core': 2.1.10(typescript@5.7.2) + semver: 7.6.3 + typescript: 5.7.2 + + vue-turnstile@1.0.11(vue@3.5.13(typescript@5.7.2)): + dependencies: + vue: 3.5.13(typescript@5.7.2) + + vue@3.5.13(typescript@5.7.2): + dependencies: + '@vue/compiler-dom': 3.5.13 + '@vue/compiler-sfc': 3.5.13 + '@vue/runtime-dom': 3.5.13 + '@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.7.2)) + '@vue/shared': 3.5.13 + optionalDependencies: + typescript: 5.7.2 + + vuetify@3.7.4(typescript@5.7.2)(vue@3.5.13(typescript@5.7.2)): + dependencies: + vue: 3.5.13(typescript@5.7.2) + optionalDependencies: + typescript: 5.7.2 + + which-typed-array@1.1.16: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.1.0 + has-tostringtag: 1.0.2 + + word-wrap@1.2.5: {} + + yallist@3.1.1: {} diff --git a/frontend/public/vite.svg b/webapp/public/vite.svg similarity index 100% rename from frontend/public/vite.svg rename to webapp/public/vite.svg diff --git a/frontend/src/App.vue b/webapp/src/App.vue similarity index 97% rename from frontend/src/App.vue rename to webapp/src/App.vue index 81571ed..15f6c97 100644 --- a/frontend/src/App.vue +++ b/webapp/src/App.vue @@ -93,16 +93,16 @@ const authType = computed(() => { }); // 构造用户可信度信息 -const getUserAcc = () => { +const getDevice = () => { return { + biometric: WebAppBiometricManager.isBiometricAvailable.value, gyro: isGyroscopeExist.value, acc: isAccelerometerExist.isAvailable.value, - biometric: WebAppBiometricManager.isBiometricAvailable.value, platform: WebApp.platform, version: WebApp.version, - timeStamp: new Date().getTime(), - deviceId: WebAppBiometricManager.biometricDeviceId.value, - verify_mode: authType.value, + device_id: WebAppBiometricManager.biometricDeviceId.value, + mode: authType.value, + ts: new Date().getTime(), } } @@ -120,17 +120,20 @@ const handleCloudflareFail = (error: string) => { isCloudflareFailed.status = true isCloudflareFailed.message = `Cloudflare error: ${error}` } + // 处理 Cloudflare 不支持 const handleCloudflareUnsupported = () => { isCloudflareFailed.status = true isCloudflareFailed.message = 'Cloudflare not supported' isCloudflareFailed.show_turnstile = false } + // 处理拼图验证成功 const handlePuzzleSuccess = () => { console.log('Puzzle success') authSuccess() } + // 打开生物识别设置 const openAuthSettings = () => { if (!WebAppBiometricManager.isBiometricInited.value) { @@ -186,7 +189,7 @@ const authCloudflare = () => { //console.log('Backend URL:', backendUrl) const requestBody = { // 路由 - source: router, + moon: router, // 从 Cloudflare 获取的 token turnstile_token: turnstile_token.value, // 已经被签名的数据,由服务端自动验证签名 @@ -222,7 +225,7 @@ const authSuccess = () => { const date_now = new Date().getUTCDate().toString() // 去除空格 const backendUrl = `${backendEndpoint.trim()}/endpoints/verify-captcha` - const acc = getUserAcc() + const device = getDevice() const router = routerGet() if (!router) { console.error('User params not found') @@ -232,18 +235,18 @@ const authSuccess = () => { } // console.log('Backend URL:', backendUrl) const requestBody = { - // 防止攻击,记录时间戳 + // 唯一 ID id: `${router.chat_id}-${router.message_id}-${date_now}`, // 路由 - source: router, + moon: router, // 来源信息 - acc: acc, - // 路由信息的签名,保证此次会话不是被伪造的。 + device: device, + // 由可信机构签发的签名 signature: router.signature, // 已经被签名的数据,由服务端自动验证签名 web_app_data: WebApp.initData, - // 日志时间戳 - timestamp: new Data().getTime(WebApp.initData), + // 时间戳 + ts: new Data().getTime(WebApp.initData), } //console.log('Request body:', requestBody) // 发送请求 @@ -324,7 +327,7 @@ watch(turnstile_token, () => { authCloudflare() } }) -console.log(getUserAcc()) +console.log(getDevice()) initBiometric() WebApp.ready() diff --git a/frontend/src/components/MCaptchaWidget.vue b/webapp/src/components/MCaptchaWidget.vue similarity index 100% rename from frontend/src/components/MCaptchaWidget.vue rename to webapp/src/components/MCaptchaWidget.vue diff --git a/frontend/src/components/Puzzles.vue b/webapp/src/components/Puzzles.vue similarity index 100% rename from frontend/src/components/Puzzles.vue rename to webapp/src/components/Puzzles.vue diff --git a/frontend/src/components/VersionInfo.vue b/webapp/src/components/VersionInfo.vue similarity index 100% rename from frontend/src/components/VersionInfo.vue rename to webapp/src/components/VersionInfo.vue diff --git a/frontend/src/hook/useAccelerometerExists.ts b/webapp/src/hook/useAccelerometerExists.ts similarity index 100% rename from frontend/src/hook/useAccelerometerExists.ts rename to webapp/src/hook/useAccelerometerExists.ts diff --git a/frontend/src/hook/useGyroscopeExists.ts b/webapp/src/hook/useGyroscopeExists.ts similarity index 100% rename from frontend/src/hook/useGyroscopeExists.ts rename to webapp/src/hook/useGyroscopeExists.ts diff --git a/frontend/src/i18n.ts b/webapp/src/i18n.ts similarity index 100% rename from frontend/src/i18n.ts rename to webapp/src/i18n.ts diff --git a/frontend/src/locales/ar.json b/webapp/src/locales/ar.json similarity index 100% rename from frontend/src/locales/ar.json rename to webapp/src/locales/ar.json diff --git a/frontend/src/locales/bn.json b/webapp/src/locales/bn.json similarity index 100% rename from frontend/src/locales/bn.json rename to webapp/src/locales/bn.json diff --git a/frontend/src/locales/en.json b/webapp/src/locales/en.json similarity index 100% rename from frontend/src/locales/en.json rename to webapp/src/locales/en.json diff --git a/frontend/src/locales/es.json b/webapp/src/locales/es.json similarity index 100% rename from frontend/src/locales/es.json rename to webapp/src/locales/es.json diff --git a/frontend/src/locales/hi.json b/webapp/src/locales/hi.json similarity index 100% rename from frontend/src/locales/hi.json rename to webapp/src/locales/hi.json diff --git a/frontend/src/locales/ja.json b/webapp/src/locales/ja.json similarity index 100% rename from frontend/src/locales/ja.json rename to webapp/src/locales/ja.json diff --git a/frontend/src/locales/ru.json b/webapp/src/locales/ru.json similarity index 100% rename from frontend/src/locales/ru.json rename to webapp/src/locales/ru.json diff --git a/frontend/src/locales/zh.json b/webapp/src/locales/zh.json similarity index 100% rename from frontend/src/locales/zh.json rename to webapp/src/locales/zh.json diff --git a/frontend/src/main.ts b/webapp/src/main.ts similarity index 100% rename from frontend/src/main.ts rename to webapp/src/main.ts diff --git a/frontend/src/vite-env.d.ts b/webapp/src/vite-env.d.ts similarity index 100% rename from frontend/src/vite-env.d.ts rename to webapp/src/vite-env.d.ts diff --git a/frontend/tsconfig.json b/webapp/tsconfig.app.json similarity index 60% rename from frontend/tsconfig.json rename to webapp/tsconfig.app.json index 80edb52..8915c31 100644 --- a/frontend/tsconfig.json +++ b/webapp/tsconfig.app.json @@ -1,16 +1,20 @@ { "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", "target": "ES2020", "useDefineForClassFields": true, "module": "ESNext", "lib": ["ES2020", "DOM", "DOM.Iterable"], "skipLibCheck": true, - + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, /* Bundler mode */ - "moduleResolution": "bundler", + "moduleResolution": "Bundler", "allowImportingTsExtensions": true, - "resolveJsonModule": true, "isolatedModules": true, + "moduleDetection": "force", "noEmit": true, "jsx": "preserve", @@ -19,8 +23,7 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "allowSyntheticDefaultImports": true + "noUncheckedSideEffectImports": true }, - "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"], - "references": [{ "path": "./tsconfig.node.json" }] + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] } diff --git a/webapp/tsconfig.json b/webapp/tsconfig.json new file mode 100644 index 0000000..1ffef60 --- /dev/null +++ b/webapp/tsconfig.json @@ -0,0 +1,7 @@ +{ + "files": [], + "references": [ + { "path": "./tsconfig.app.json" }, + { "path": "./tsconfig.node.json" } + ] +} diff --git a/webapp/tsconfig.node.json b/webapp/tsconfig.node.json new file mode 100644 index 0000000..abcd7f0 --- /dev/null +++ b/webapp/tsconfig.node.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "target": "ES2022", + "lib": ["ES2023"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "isolatedModules": true, + "moduleDetection": "force", + "noEmit": true, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedSideEffectImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/frontend/uno.config.ts b/webapp/uno.config.ts similarity index 100% rename from frontend/uno.config.ts rename to webapp/uno.config.ts diff --git a/frontend/vercel.json b/webapp/vercel.json similarity index 100% rename from frontend/vercel.json rename to webapp/vercel.json diff --git a/webapp/vite.config.ts b/webapp/vite.config.ts new file mode 100644 index 0000000..82db18b --- /dev/null +++ b/webapp/vite.config.ts @@ -0,0 +1,42 @@ +import {defineConfig, searchForWorkspaceRoot} from 'vite' +import vue from '@vitejs/plugin-vue' +// vite.config.ts +import UnoCSS from 'unocss/vite' +import process from "node:process"; +// Obfuscator +import vitePluginBundleObfuscator from 'vite-plugin-bundle-obfuscator'; +// All configurations +const customObfuscatorConfig = { + excludes: [], + enable: true, + log: true, + autoExcludeNodeModules: true, + // autoExcludeNodeModules: { enable: true, manualChunks: ['vue'] } + threadPool: true, + // threadPool: { enable: true, size: 4 } + options: { + stringArray: true, + }, +}; +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [ + vue(), + UnoCSS(), + vitePluginBundleObfuscator(customObfuscatorConfig) + ], + define: { + 'import.meta.env.VITE_BUILD_DATE': JSON.stringify(new Date().toISOString().split('T')[0]), + }, + base: '/', + server: { + fs: { + allow: [ + // search up for workspace root + searchForWorkspaceRoot(process.cwd()), + // custom rules + // '/path/to/custom/allow', + ], + }, + }, +}) \ No newline at end of file From 7e4fd7205ce09513d79215b2460009341d4f4e56 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Sat, 7 Dec 2024 00:07:53 +0800 Subject: [PATCH 2/3] :zap: feat(judge): add new spam keywords to Chinese advertisement list --- bot/__init__.py | 422 ++++++++-------- bot/box.py | 31 ++ common/cache/__init__.py | 2 +- common/config/oai.py | 18 + common/configure.py | 53 +++ common/database/__init__.py | 25 +- common/database/service.py | 116 +++++ pdm.lock | 926 +++++++++++++++++++++++++++++++----- playground/agent-1.py | 92 ++++ playground/agent.py | 84 ++++ playground/llm.py | 70 +++ pyproject.toml | 4 + worker/__init__.py | 52 ++ 13 files changed, 1582 insertions(+), 313 deletions(-) create mode 100644 bot/box.py create mode 100644 common/config/oai.py create mode 100644 common/configure.py create mode 100644 common/database/service.py create mode 100644 playground/agent-1.py create mode 100644 playground/agent.py create mode 100644 playground/llm.py create mode 100644 worker/__init__.py diff --git a/bot/__init__.py b/bot/__init__.py index 7db2244..e152728 100755 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -8,23 +8,28 @@ import telegramify_markdown from loguru import logger from pydantic import SecretStr -from sqlmodel import select from telebot import types, asyncio_filters from telebot import util from telebot.asyncio_helper import ApiTelegramException from telebot.types import InlineKeyboardMarkup, WebAppInfo +from bot.box import generate_verification_message +from bot.locales_config import get_locales +from bot.service.judge import judge_pre_join_text, reason_chat_text, reason_chat_photo +from bot.service.utils import parse_command from common.config.endpoint import EndpointSetting from common.config.telegrambot import BOT, BotSetting -from common.const import EXPIRE_M_TIME, EXPIRE_SHOW -from common.database import dbInstance, VerifyRequest, JoinRequest +from common.const import EXPIRE_M_TIME +from common.database import dbInstance +from common.database.service import DatabaseService from common.middleware import globalGroupPolicy from common.recall import globalResendManager, ResendEvnet from common.safety.signature import generate_sign from common.statistics import globalStatistics -from locales_config import get_locales -from service.judge import judge_pre_join_text, reason_chat_text, reason_chat_photo -from service.utils import parse_command + +db_service = DatabaseService(dbInstance) +SOLVE_SEMAPHORE_LIMIT = 15 # 最大并发数 +FETCH_INTERVAL = 5 # 拉取间隔 async def judgment( @@ -42,70 +47,19 @@ async def judgment( return None -async def pre_process_user( +async def send_button( telegram_bot: telebot.async_telebot.AsyncTeleBot, - chat_id: int, user_id: int, message_id: str, verify_url: str, - preprocess_data: types.ChatFullInfo, - addon_bio: Optional[str] = None ): """ 预处理用户的资料页 :param telegram_bot: 机器人实例 - :param chat_id: 群组ID :param user_id: 用户ID :param message_id: 用户验证消息ID :param verify_url: 验证URL - :param preprocess_data: 用户资料 - :param addon_bio: 附加的用户 BIO """ - # 读取待验证的群组策略 - policy = await globalGroupPolicy.read(group_id=str(chat_id)) - if policy.join_check: - logger.debug(f"pre-process-user:join-check:{user_id}:{chat_id}") - # 检查用户资料 - bio = addon_bio if addon_bio else preprocess_data.bio - check_string = f"{preprocess_data.first_name} {preprocess_data.last_name} {bio}" - if judge_pre_join_text(check_string): - try: - await telegram_bot.send_message( - chat_id=user_id, - text=telegramify_markdown.convert( - f"# Sorry, this group enabled join check.\n" - f"`You are recognized as a Advertiser or a Robot` by our risk control system.`\n\n" - f"**What should I do?**\n" - f"{policy.complaints_guide}", - ), - parse_mode="MarkdownV2", - ) - except Exception as exc: - logger.error(f"pre-process-user:send-message-failed:{user_id}:{chat_id}:{exc}") - try: - await telegram_bot.decline_chat_join_request(chat_id=chat_id, user_id=user_id) - except Exception as exc: - logger.error(f"pre-process-user:decline-failed:{user_id}:{chat_id}:{exc}") - else: - logger.info(f"pre-process-user:pre-check-not-pass:{user_id}:{chat_id}") - # 删除死亡队列 - try: - data = await globalJoinManager.read() - removed = [] - for join_request in data.join_queue: - join_request: JoinRequest - if str(join_request.user_id) == str(user_id) and str(join_request.chat_id) == str( - chat_id): - removed.append(join_request) - if removed: - for join_request in removed: - data.join_queue.remove(join_request) - await globalJoinManager.save(data) - else: - logger.error(f"pre-process-user:not-found-dead-queue:{user_id}:{chat_id}") - except Exception as exc: - logger.error(f"pre-process-user:remove-join-queue-failed:{exc}") - return logger.info(f"pre-process-user:join-check-failed:{user_id}:{chat_id}") # 发送验证按钮 try: await telegram_bot.edit_message_reply_markup( @@ -125,10 +79,10 @@ async def pre_process_user( ) ) except Exception as exc: - logger.error(f"Edit Message Failed {exc}") + logger.error(f"pre-process-user:send-button-failed:{user_id}:{message_id}:{exc}") -async def download(telegram_bot: telebot.async_telebot.AsyncTeleBot, file): +async def download_file(telegram_bot: telebot.async_telebot.AsyncTeleBot, file): """ 下载文件 :param telegram_bot: 机器人实例 @@ -147,41 +101,6 @@ async def download(telegram_bot: telebot.async_telebot.AsyncTeleBot, file): return downloaded_file -async def dead_shot( - user_id: str, - chat_id: str, - expired_m_at: int, - language_code: str, - user_chat_id: int, - message_id: Optional[str] = None -): - try: - with dbInstance.get_session() as session: - select_statement = select(JoinRequest).where( - JoinRequest.user_id == user_id, - JoinRequest.chat_id == chat_id - ) - results = session.exec(select_statement) - if results: - for result in results: - session.delete(result) - session.commit() - dto = JoinRequest( - user_id=str(user_id), - chat_id=str(chat_id), - expired_at=expired_m_at, - language_code=str(language_code), - user_chat_id=int(user_chat_id), - message_id=str(message_id) - ) - session.add(dto) - session.commit() - except Exception as exc: - logger.error(f"dead-shot:failed-insert-join-queue:{user_id}:{chat_id}:{exc}") - else: - logger.success(f"dead-shot:success-insert-join-queue:{user_id}:{chat_id}") - - async def handle_join_request( telegram_bot: telebot.async_telebot.AsyncTeleBot, message: types.ChatJoinRequest @@ -196,7 +115,7 @@ async def handle_join_request( user_name = message.from_user.full_name[:20] chat_id = str(message.chat.id) user_id = str(message.from_user.id) - join_m_time = str(int(time.time() * 1000)) # 防止停机 + join_m_time = str(int(time.time() * 1000)) expired_m_at = int(join_m_time) + EXPIRE_M_TIME except Exception as exc: logger.exception(f"join-request:parse-failed:{exc} --data {message}") @@ -211,23 +130,24 @@ async def handle_join_request( # 尝试发送消息 try: sent_message = await telegram_bot.send_message( - message.user_chat_id, - text=telegramify_markdown.convert( - f"# Hello, `{user_name}`.\n\n" - f"You are requesting to join the group `{chat_title}`.\n" - "But you need to prove that you are not a **robot**.\n" - f"**You have {EXPIRE_SHOW}.**\n\n" - f"*{locale.verify_join}*\n" - f"`{chat_id}-{user_id}-{expired_m_at}`", - ), - parse_mode="MarkdownV2", + chat_id=message.user_chat_id, + text=generate_verification_message( + instructions=locale.join_request, + chat_title=chat_title, + user_name=user_name, + ), parse_mode="MarkdownV2", ) sent_message_id = str(sent_message.message_id) except Exception as exc: sent_message_id = None - logger.error(f"join-request:send-welcome-failed:{user_id}:{chat_id}:{exc}") + if "initiate conversation" in str(exc): + logger.info(f"join-request:send-welcome-be-refused:{user_id}:{chat_id}") + elif "was blocked" in str(exc): + logger.info(f"join-request:send-welcome-be-blocked:{user_id}:{chat_id}") + else: + logger.error(f"join-request:send-welcome-failed:{user_id}:{chat_id}:{exc}") # 投入死亡队列 - await dead_shot( + db_service.save_join_request( user_id=user_id, chat_id=chat_id, expired_m_at=expired_m_at, @@ -235,6 +155,7 @@ async def handle_join_request( user_chat_id=message.user_chat_id, message_id=sent_message_id ) + # 消息未发送,无法继续 if not sent_message_id: return logger.error(f"join-request:user-refuse:{user_id}:{chat_id}") # 用户没有拉黑机器人,生产签名 @@ -245,13 +166,14 @@ async def handle_join_request( join_time=join_m_time, secret_key=SecretStr(BotSetting.token), ) - # 保存历史记录 try: - with dbInstance.get_session() as session: - _request = VerifyRequest(user_id=user_id, chat_id=chat_id, timestamp=join_m_time, signature=signature) - session.add(_request) - session.commit() + db_service.add_verify_request( + chat_id=chat_id, + user_id=user_id, + timestamp=join_m_time, + signature=signature + ) except Exception as exc: logger.error(f"join-request:save-history-failed:{user_id}:{chat_id}:{exc}") @@ -263,9 +185,18 @@ async def handle_join_request( event = await telegram_bot.get_chat(message.from_user.id) except Exception as exc: logger.info(f"join-request:cant-get-user-profile:jump to fallback:{exc}") - # 存储一份参数快照,并生成一个唯一数据命令+ID + # 存储一份参数快照,并生成一个唯一数据命令 snapshot_uid = shortuuid.uuid()[0:6] verify_tip = f"**Copy `/verify {snapshot_uid}` then send me to continue verification of `{chat_title}`**" + # 发送一个提示,提示让用户使用 verify 命令 + try: + sent_message_id = await telegram_bot.send_message( + chat_id=message.user_chat_id, + text=telegramify_markdown.markdownify(verify_tip), + parse_mode="MarkdownV2", + ) + except Exception as exc: + logger.error(f"join-request:send-verify-tip-failed:{user_id}:{chat_id}:{exc}") await globalResendManager.save( event_id=snapshot_uid, data=ResendEvnet( @@ -275,15 +206,6 @@ async def handle_join_request( user_id=str(user_id), ) ) - # 发送一个提示,提示让用户使用 verify 命令 - try: - await telegram_bot.send_message( - chat_id=message.user_chat_id, - text=telegramify_markdown.markdownify(verify_tip), - parse_mode="MarkdownV2", - ) - except Exception as exc: - logger.error(f"join-request:send-verify-tip-failed:{user_id}:{chat_id}:{exc}") else: invalid = await judgment( chat_id=int(chat_id), @@ -303,15 +225,13 @@ async def handle_join_request( ) except Exception as exc: logger.error(f"pre-process-user:send-message-failed:{user_id}:{chat_id}:{exc}") - await pre_process_user( - telegram_bot=telegram_bot, - chat_id=int(chat_id), - user_id=int(user_id), - message_id=sent_message_id, - verify_url=verify_url, - preprocess_data=event, - addon_bio=message.bio - ) + else: + await send_button( + telegram_bot=telegram_bot, + user_id=int(user_id), + message_id=sent_message_id, + verify_url=verify_url, + ) return True @@ -326,7 +246,8 @@ async def handle_verify( locale = get_locales(message.from_user.language_code) chat_id, user_id = str(message.chat.id), str(message.from_user.id) logger.info( - f"verify:start:{user_id}:{chat_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}") + f"verify:start:{user_id}:{chat_id} --name [{message.from_user.full_name}] --lang {message.from_user.language_code}" + ) # 解析命令 try: command, event_id = parse_command(message.text) @@ -344,15 +265,47 @@ async def handle_verify( user = await telegram_bot.get_chat(message.from_user.id) except Exception as exc: return logger.error(f"verify:failed-fetch-user-profile:{exc}") - # 预处理用户资料 - await pre_process_user( - telegram_bot=telegram_bot, - chat_id=event.chat_id, - user_id=event.user_id, - message_id=event.message_id, - verify_url=event.verify_url, - preprocess_data=user + invalid = await judgment( + chat_id=int(chat_id), + target_string=f"{user.first_name} {user.last_name} {user.bio}" ) + if invalid: + try: + await telegram_bot.send_message( + chat_id=user_id, + text=telegramify_markdown.convert( + f"# Sorry, this group enabled join check.\n" + f"`You are recognized as a Advertiser or a Robot by our risk control system.`\n\n" + f"**What should I do?**\n" + f"{invalid}", + ), + parse_mode="MarkdownV2", + ) + except Exception as exc: + logger.error(f"pre-process-user:send-message-failed:{user_id}:{chat_id}:{exc}") + else: + if not event.message_id: + return logger.info(f"verify:message-not-found:{event_id}") + try: + await telegram_bot.edit_message_text( + chat_id=event.user_id, + message_id=int(event.message_id), + text=telegramify_markdown.convert( + f"Well, `{user.last_name}`.\n\n" + f"You are requesting to join the group `{message.chat.title}`.\n" + "But you need to prove that you are not a **robot**.\n\n" + f"*{locale.verify_join}*\n" + ), + parse_mode="MarkdownV2", + ) + except Exception as exc: + logger.error(f"verify:failed-edit-message:{user_id}:{chat_id}:{exc}") + await send_button( + telegram_bot=telegram_bot, + user_id=event.user_id, + message_id=event.message_id, + verify_url=event.verify_url, + ) async def handle_join_check( @@ -494,7 +447,7 @@ async def handle_group_msg_no_admin( """ if message.photo: try: - downloaded_file = await download( + downloaded_file = await download_file( telegram_bot=telegram_bot, file=message.photo[-1] ) @@ -702,63 +655,144 @@ async def start(message: types.Message): logger.exception(e) +solve_semaphore = asyncio.Semaphore(SOLVE_SEMAPHORE_LIMIT) + + +async def solve_join_request( + join_chat_id: str, + user_id: str, + user_chat_id: int, + language_code: str, + del_message_id: str = None, +): + """ + 处理单个 Join Request 的完整生命周期 + 包括消息发送、消息删除以及拒绝入群请求。 + """ + # 标志初始状态 + async with solve_semaphore: + # 步骤 0:拒绝入群请求 + try: + await BOT.decline_chat_join_request( + chat_id=join_chat_id, user_id=user_id + ) + status = "declined" + logger.info(f"decline:success:{user_id}:{join_chat_id}") + except Exception as exc: + if "HIDE_REQUESTER_MISSING" in str(exc): + status = "hide-requester-missing" + logger.info(f"decline:hide-requester-missing:{user_id}:{join_chat_id}") + else: + status = "failed-decline" + logger.error( + f"decline:failed-decline:{user_id}:{join_chat_id} because {exc}" + ) + # 步骤 1:发送提醒消息 + try: + await BOT.send_message( + chat_id=user_chat_id, + text=telegramify_markdown.convert(get_locales(language_code).expired_join), + parse_mode="MarkdownV2", + ) + logger.info(f"message:success:{user_id}:{join_chat_id}") + except Exception as exc: + if "initiate conversation" in str(exc): + logger.info(f"decline:refuse:{user_id}:{join_chat_id}") + elif "blocked" in str(exc): + logger.info(f"decline:user-blocked-bot:{user_id}:{join_chat_id}") + else: + logger.error( + f"decline:failed-send-message:{user_id}:{join_chat_id} because {exc}" + ) + # 步骤 2:删除过期验证消息 + try: + if del_message_id: + await BOT.delete_message( + chat_id=user_chat_id, + message_id=del_message_id + ) + logger.info(f"delete:success:{user_id}:{join_chat_id}") + except Exception as exc: + if "message to delete not found" in str(exc): + logger.info(f"delete:message-not-found:{user_id}:{join_chat_id}") + elif "message identifier is not specified" in str(exc): + logger.info(f"delete:message-not-specified:{user_id}:{join_chat_id}") + else: + logger.error( + f"decline:failed-del-join-message:{user_id}:{join_chat_id} because {exc}" + ) + return status, user_id, join_chat_id + + async def execution_ground(): """ 监听死亡队列,处理过期的验证请求 """ + logger.info("death-queue:execution-ground:start") while True: + await asyncio.sleep(FETCH_INTERVAL) try: - data = await globalJoinManager.read() - expired = [] - for join_request in data.join_queue: - if int(join_request.expired_at) < int(round(time.time() * 1000)): - expired.append(join_request) - if expired: - logger.info(f"decline:expired:processing --lens {len(expired)}") - for join_request in expired: - try: - # https://core.telegram.org/bots/api#chatjoinrequest - await BOT.send_message( - chat_id=join_request.user_chat_id, - text=telegramify_markdown.convert(get_locales(join_request.language_code).expired_join), - parse_mode="MarkdownV2", - ) - except Exception as exc: - if "initiate conversation" in str(exc): - logger.info( - f"decline:refuse:{join_request.user_id}:{join_request.chat_id}" - ) - elif "blocked" in str(exc): - logger.info( - f"decline:user-blocked-bot:{join_request.user_id}:{join_request.chat_id}" - ) - else: - logger.error( - f"decline:failed-send-message:{join_request.user_id}:{join_request.chat_id} chat-join-request because {exc}") - try: - await BOT.delete_message(chat_id=join_request.user_id, message_id=join_request.message_id) - except Exception as exc: - if "message to delete not found" in str(exc): - logger.info( - f"decline:delete-message-not-found:{join_request.user_id}:{join_request.chat_id}" - ) - else: - logger.error( - f"decline:failed-del-join-message:{join_request.user_id}:{join_request.chat_id} chat-join-request because {exc}" - ) - for join_request in expired: - try: - await BOT.decline_chat_join_request(chat_id=join_request.chat_id, user_id=join_request.user_id) - logger.info(f"decline:success:{join_request.user_id}:{join_request.chat_id} chat-join-request") - except Exception as exc: - if "HIDE_REQUESTER_MISSING" in str(exc): - logger.info(f"decline:hide-requester-missing:{join_request.user_id}:{join_request.chat_id}") - else: - logger.error( - f"decline:failed-decline:{join_request.user_id}:{join_request.chat_id} chat-join-request because {exc}") - data.join_queue = [join_request for join_request in data.join_queue if join_request not in expired] - await globalJoinManager.save(data) + current_time = int(round(time.time() * 1000)) + wait_deal = db_service.fetch_pending_join_request(timer=current_time) + except Exception as exc: + logger.exception(f"death-queue:execution-ground:failed-fetch:{exc}") + continue + + # 如果没有需要处理的请求,则继续等待 + if not wait_deal: + continue + + logger.info(f"decline:expired:processing --lens {len(wait_deal)}") + + # 创建任务,每个任务绑定 join_request + task_map = { + join_request: solve_join_request( + join_chat_id=join_request.chat_id, + user_id=join_request.user_id, + user_chat_id=join_request.user_chat_id, + del_message_id=join_request.message_id, + language_code=join_request.language_code, + ) + for join_request in wait_deal + } + + gather_result = [] + try: + # 并发运行任务,保留原始的 join_request 绑定 + gather_result = await asyncio.gather( + *task_map.values(), + return_exceptions=True # 捕获单个任务的异常 + ) + except Exception as exc: + # 此处一般不会到达,因为 `return_exceptions=True` 已经捕获每个任务的错误 + logger.error(f"death-queue:execution-ground:failed-concurrent-processing:{exc}") + + # 匹配 gather_result 返回的结果与 task_map 中的 join_request + for (join_request, result) in zip(task_map.keys(), gather_result): + try: + if isinstance(result, tuple) and len(result) == 3: + # 正常处理返回的 (status, user_id, join_chat_id) + join_request.status = result[0] # 从 solve_join_request 返回的 status + elif isinstance(result, Exception): + # 如果任务出现异常,将异常信息记录到 status + join_request.status = f"failed: {type(result).__name__}: {str(result)}" + logger.warning( + f"decline:task-exception:{join_request.user_id}:{join_request.chat_id} because {result}") + else: + # 不确定的失败情况 + join_request.status = "failed-unknown" + logger.warning(f"decline:task-failed-unknown:{join_request.user_id}:{join_request.chat_id}") + except Exception as exc: + logger.error(f"decline:result-processing-error:{exc}") + join_request.status = "failed-mapping" + + # 无论任务成功/失败,都需要将 join_request 标记为已处理 + join_request.solved = True + + # 统一批量更新数据库 + try: + await db_service.solve_join_request(join_requests=wait_deal) + logger.info(f"decline:batch-update:success --lens {len(wait_deal)}") except Exception as exc: - logger.exception(f"detect:unknown-failed:{exc}") - await asyncio.sleep(2) + logger.error(f"decline:failed-solve-join-request:{exc}") diff --git a/bot/box.py b/bot/box.py new file mode 100644 index 0000000..918e46b --- /dev/null +++ b/bot/box.py @@ -0,0 +1,31 @@ +import telegramify_markdown + +from common.const import EXPIRE_SHOW + + +def generate_verification_message( + instructions, + chat_title, + user_name, +): + """ + 生成验证消息。 + """ + message_text = ( + f"# Hello, `{user_name}`.\n\n" + f"You are requesting to join the group `{chat_title}`.\n" + "But you need to prove that you are not a **robot**.\n" + f"**You have {EXPIRE_SHOW}.**\n\n" + f"*{instructions}*\n" + ) + return telegramify_markdown.markdownify(message_text) + + +if __name__ == '__main__': + print( + generate_verification_message( + "Please send me a message.", + "Test Group", + "Test User" + ) + ) diff --git a/common/cache/__init__.py b/common/cache/__init__.py index 6f21390..038956a 100644 --- a/common/cache/__init__.py +++ b/common/cache/__init__.py @@ -112,6 +112,6 @@ def get_client(self) -> "RedisClientWrapper": return self.client -global_cache_runtime: BaseRuntime = RedisRuntime() +global_cache_runtime: RedisRuntime = RedisRuntime() if not RedisRuntime().check_client(): raise ValueError("RedisRuntime Server Not Found") diff --git a/common/config/oai.py b/common/config/oai.py new file mode 100644 index 0000000..9a61e90 --- /dev/null +++ b/common/config/oai.py @@ -0,0 +1,18 @@ +from typing import Optional + +from dotenv import load_dotenv +from pydantic import Field +from pydantic_settings import BaseSettings + + +class Openai(BaseSettings): + openai_api_key: Optional[str] = Field(None, validation_alias="OPENAI_API_KEY") + openai_base_url: Optional[str] = Field(None, validation_alias="OPENAI_BASE_URL") + + @property + def available(self): + return self.openai_api_key is not None and self.openai_base_url is not None + + +load_dotenv() +OpenaiSetting = Openai() diff --git a/common/configure.py b/common/configure.py new file mode 100644 index 0000000..6c67110 --- /dev/null +++ b/common/configure.py @@ -0,0 +1,53 @@ +""" +检查用户 +""" +from loguru import logger +from pydantic import BaseModel, ConfigDict, Field + +from common.cache import global_cache_runtime + +AREA = "configure" + +""" +活跃检查阈值 +预检正则列表 +群组消息正则列表 +允许的语言地区 +""" + + +class PolicyRule(BaseModel): + active_message: bool = Field(default=False, description="检查加入成员的简历是否包含广告") + """Join Check""" + regex_check: bool = Field(default=False, description="反骚扰反侮辱反刷屏") + """Anti Spam""" + complaints_guide: str = Field( + default="*There is no appeal channel set up for this group, please contact the administrator to join in.*", + description="Used to direct users where to make appeals" + ) + """Complaints Guide""" + model_config = ConfigDict(extra="ignore") + + +class PolicyManager: + def __init__(self): + self.cache = global_cache_runtime.get_client() + + @staticmethod + def prefix(key: str) -> str: + return f"{AREA}:{key}" + + async def read(self, group_id: str) -> PolicyRule: + data = await self.cache.read_data(self.prefix(group_id)) + try: + return PolicyRule.model_validate(data) + except Exception as exc: + logger.debug(f"PolicyManager.read: {exc}") + return PolicyRule() + + async def save(self, group_id: str, data: PolicyRule): + await self.cache.set_data(self.prefix(group_id), data.model_dump_json()) + return True + + +globalGroupPolicy = PolicyManager() diff --git a/common/database/__init__.py b/common/database/__init__.py index 3f87e6b..f22d3ef 100644 --- a/common/database/__init__.py +++ b/common/database/__init__.py @@ -12,13 +12,30 @@ class JoinRequest(SQLModel, table=True): 包含用户 ID、聊天 ID、过期时间、用户聊天 ID、消息 ID 和语言代码。 """ id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + """ + 唯一标识符 + """ user_id: str = Field(index=True) + """ + 用户 ID + """ chat_id: str - message_id: str + """ + 群组聊天 ID + """ + message_id: str | None = Field(default=None) + """ + 创建的消息 ID + 初次无法发送消息,所以可能是 None + """ user_chat_id: int # 5 MINUTES VALID + """ + 加入请求的用户聊天 ID + """ expired_at: int | None = Field(default=None, index=True) language_code: str | None = Field(default=None) - passed: bool = False + status: str = "waiting" + solved: bool = False class VerifyRequest(SQLModel, table=True): @@ -42,10 +59,11 @@ def __init__(self): load_dotenv() # 加载 .env 文件中的环境变量 self.postgresql_dsn = os.getenv( - "POSTGRESQL_DSN", "postgres://@localhost:5432/verify" + "POSTGRESQL_DSN", "postgresql://@localhost:5432/postgres" ) try: self.engine = create_engine(self.postgresql_dsn, echo=True) + self.create_all_tables() self._check_database_connection() logger.info("Database connection established successfully.") except Exception as e: @@ -69,4 +87,3 @@ def get_session(self) -> Session: # 初始化并创建全局 Database 实例 dbInstance = Database() -dbInstance.create_all_tables() # 确保表结构已创建 diff --git a/common/database/service.py b/common/database/service.py new file mode 100644 index 0000000..ef5facc --- /dev/null +++ b/common/database/service.py @@ -0,0 +1,116 @@ +from typing import List + +from loguru import logger +from sqlmodel import select + +from common.database import Database +from common.database import JoinRequest, VerifyRequest + + +class DatabaseService: + def __init__(self, db_instance: 'Database'): + self.db_instance = db_instance + + def save_join_request( + self, + user_id: str, + chat_id: str, + expired_m_at: int, + language_code: str, + user_chat_id: int, + message_id: str | None + ): + """ + 插入加入请求到数据库中。 + :param user_id: 用户 ID + :param chat_id: 聊天 ID + :param expired_m_at: 过期时间 + :param language_code: 语言代码 + :param user_chat_id: 用户聊天 ID + :param message_id: 消息 ID + """ + try: + with self.db_instance.get_session() as session: + select_statement = select(JoinRequest).where( + JoinRequest.user_id == user_id, + JoinRequest.chat_id == chat_id, + JoinRequest.solved == False + ) + results = session.exec(select_statement) + if not results: + dto = JoinRequest( + user_id=str(user_id), + chat_id=str(chat_id), + expired_at=expired_m_at, + language_code=str(language_code), + user_chat_id=int(user_chat_id), + message_id=message_id + ) + session.add(dto) + session.commit() + except Exception as exc: + logger.error(f"insert_join_request:failed-insert-join-queue:{user_id}:{chat_id}:{exc}") + else: + logger.success(f"insert_join_request:success-insert-join-queue:{user_id}:{chat_id}") + + def add_verify_request( + self, + user_id: str, + chat_id: str, + timestamp: str, + signature: str + ): + """ + 保存验证请求到数据库中。 + :param user_id: 用户 ID + :param chat_id: 聊天 ID + :param timestamp: 时间戳 + :param signature: 签名 + """ + try: + with self.db_instance.get_session() as session: + _request = VerifyRequest(user_id=user_id, chat_id=chat_id, timestamp=timestamp, signature=signature) + session.add(_request) + session.commit() + except Exception as exc: + logger.error(f"save_verify_request:save-history-failed:{user_id}:{chat_id}:{exc}") + + def fetch_pending_join_request( + self, + timer: int + ) -> List[JoinRequest]: + """ + 获取需要解决的加入请求。 + :param timer: 当前时间戳 + :return: 需要解决的加入请求列表 + """ + try: + with self.db_instance.get_session() as session: + select_statement = select(JoinRequest).where( + JoinRequest.solved == False, + JoinRequest.expired_at <= timer + ) + results = session.exec(select_statement).all() + return results + except Exception as exc: + logger.error(f"get_join_requests:failed-fetch-join-requests:{exc}") + return [] + + def solve_join_request( + self, + join_requests: List[JoinRequest], + ): + """ + 标记加入请求为已解决。 + :param join_requests: 需要标记为已解决的加入请求列表 + """ + try: + with self.db_instance.get_session() as session: + for join_request in join_requests: + join_request.solved = True + session.add(join_request) + session.commit() + except Exception as exc: + logger.error( + f"delete_join_request:failed-database:{join_requests}:{exc}" + ) diff --git a/pdm.lock b/pdm.lock index 82919a4..d8dd030 100755 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default"] strategy = ["cross_platform"] lock_version = "4.5.0" -content_hash = "sha256:82b25bcf5b0f2bc6d367fa3afa6e08d26bfe23f9997f44380da2f07fd3dfcca7" +content_hash = "sha256:0c998f6067fa7360676a3db130c77791472b5e4904dc9a4a2a6060d57d49efe3" [[metadata.targets]] requires_python = "~=3.10" @@ -167,6 +167,16 @@ files = [ {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] +[[package]] +name = "cachetools" +version = "5.5.0" +requires_python = ">=3.7" +summary = "Extensible memoizing collections and decorators" +files = [ + {file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"}, + {file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"}, +] + [[package]] name = "certifi" version = "2024.2.2" @@ -179,57 +189,60 @@ files = [ [[package]] name = "cffi" -version = "1.16.0" +version = "1.17.1" requires_python = ">=3.8" summary = "Foreign Function Interface for Python calling C code." dependencies = [ "pycparser", ] files = [ - {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, - {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, - {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, - {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, - {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, - {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, - {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, - {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, - {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, - {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, - {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, - {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, - {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, - {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, - {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, - {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, - {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, - {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, - {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, - {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, - {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, - {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, ] [[package]] @@ -414,6 +427,16 @@ files = [ {file = "distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64"}, ] +[[package]] +name = "distro" +version = "1.9.0" +requires_python = ">=3.6" +summary = "Distro - an OS platform information API" +files = [ + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, +] + [[package]] name = "dnspython" version = "2.6.1" @@ -424,6 +447,46 @@ files = [ {file = "dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc"}, ] +[[package]] +name = "docstring-parser" +version = "0.16" +requires_python = ">=3.6,<4.0" +summary = "Parse Python docstrings in reST, Google and Numpydoc format" +files = [ + {file = "docstring_parser-0.16-py3-none-any.whl", hash = "sha256:bf0a1387354d3691d102edef7ec124f219ef639982d096e26e3b60aeffa90637"}, + {file = "docstring_parser-0.16.tar.gz", hash = "sha256:538beabd0af1e2db0146b6bd3caa526c35a34d61af9fd2887f3a8a27a739aa6e"}, +] + +[[package]] +name = "dramatiq" +version = "1.17.1" +requires_python = ">=3.8" +summary = "Background Processing for Python 3." +dependencies = [ + "prometheus-client>=0.2", +] +files = [ + {file = "dramatiq-1.17.1-py3-none-any.whl", hash = "sha256:951cdc334478dff8e5150bb02a6f7a947d215ee24b5aedaf738eff20e17913df"}, + {file = "dramatiq-1.17.1.tar.gz", hash = "sha256:2675d2f57e0d82db3a7d2a60f1f9c536365349db78c7f8d80a63e4c54697647a"}, +] + +[[package]] +name = "dramatiq" +version = "1.17.1" +extras = ["redis", "watch"] +requires_python = ">=3.8" +summary = "Background Processing for Python 3." +dependencies = [ + "dramatiq==1.17.1", + "redis<6.0,>=2.0", + "watchdog-gevent>=0.2", + "watchdog>=4.0", +] +files = [ + {file = "dramatiq-1.17.1-py3-none-any.whl", hash = "sha256:951cdc334478dff8e5150bb02a6f7a947d215ee24b5aedaf738eff20e17913df"}, + {file = "dramatiq-1.17.1.tar.gz", hash = "sha256:2675d2f57e0d82db3a7d2a60f1f9c536365349db78c7f8d80a63e4c54697647a"}, +] + [[package]] name = "elara" version = "0.5.5" @@ -438,6 +501,16 @@ files = [ {file = "elara-0.5.5.tar.gz", hash = "sha256:2758e9245cad36126330797aee70744f52d77dc5ce50f16ea231519d34741f8a"}, ] +[[package]] +name = "eval-type-backport" +version = "0.2.0" +requires_python = ">=3.8" +summary = "Like `typing._eval_type`, but lets older Python versions use newer typing features." +files = [ + {file = "eval_type_backport-0.2.0-py3-none-any.whl", hash = "sha256:ac2f73d30d40c5a30a80b8739a789d6bb5e49fdffa66d7912667e2015d9c9933"}, + {file = "eval_type_backport-0.2.0.tar.gz", hash = "sha256:68796cfbc7371ebf923f03bdf7bef415f3ec098aeced24e054b253a0e78f7b37"}, +] + [[package]] name = "exceptiongroup" version = "1.2.0" @@ -552,6 +625,69 @@ files = [ {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, ] +[[package]] +name = "gevent" +version = "24.11.1" +requires_python = ">=3.9" +summary = "Coroutine-based network library" +dependencies = [ + "cffi>=1.17.1; platform_python_implementation == \"CPython\" and sys_platform == \"win32\"", + "greenlet>=3.1.1; platform_python_implementation == \"CPython\"", + "zope-event", + "zope-interface", +] +files = [ + {file = "gevent-24.11.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:92fe5dfee4e671c74ffaa431fd7ffd0ebb4b339363d24d0d944de532409b935e"}, + {file = "gevent-24.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7bfcfe08d038e1fa6de458891bca65c1ada6d145474274285822896a858c870"}, + {file = "gevent-24.11.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7398c629d43b1b6fd785db8ebd46c0a353880a6fab03d1cf9b6788e7240ee32e"}, + {file = "gevent-24.11.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7886b63ebfb865178ab28784accd32f287d5349b3ed71094c86e4d3ca738af5"}, + {file = "gevent-24.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9ca80711e6553880974898d99357fb649e062f9058418a92120ca06c18c3c59"}, + {file = "gevent-24.11.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e24181d172f50097ac8fc272c8c5b030149b630df02d1c639ee9f878a470ba2b"}, + {file = "gevent-24.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1d4fadc319b13ef0a3c44d2792f7918cf1bca27cacd4d41431c22e6b46668026"}, + {file = "gevent-24.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:3d882faa24f347f761f934786dde6c73aa6c9187ee710189f12dcc3a63ed4a50"}, + {file = "gevent-24.11.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:351d1c0e4ef2b618ace74c91b9b28b3eaa0dd45141878a964e03c7873af09f62"}, + {file = "gevent-24.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5efe72e99b7243e222ba0c2c2ce9618d7d36644c166d63373af239da1036bab"}, + {file = "gevent-24.11.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d3b249e4e1f40c598ab8393fc01ae6a3b4d51fc1adae56d9ba5b315f6b2d758"}, + {file = "gevent-24.11.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81d918e952954675f93fb39001da02113ec4d5f4921bf5a0cc29719af6824e5d"}, + {file = "gevent-24.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9c935b83d40c748b6421625465b7308d87c7b3717275acd587eef2bd1c39546"}, + {file = "gevent-24.11.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff96c5739834c9a594db0e12bf59cb3fa0e5102fc7b893972118a3166733d61c"}, + {file = "gevent-24.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d6c0a065e31ef04658f799215dddae8752d636de2bed61365c358f9c91e7af61"}, + {file = "gevent-24.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:97e2f3999a5c0656f42065d02939d64fffaf55861f7d62b0107a08f52c984897"}, + {file = "gevent-24.11.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:a3d75fa387b69c751a3d7c5c3ce7092a171555126e136c1d21ecd8b50c7a6e46"}, + {file = "gevent-24.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:beede1d1cff0c6fafae3ab58a0c470d7526196ef4cd6cc18e7769f207f2ea4eb"}, + {file = "gevent-24.11.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:85329d556aaedced90a993226d7d1186a539c843100d393f2349b28c55131c85"}, + {file = "gevent-24.11.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:816b3883fa6842c1cf9d2786722014a0fd31b6312cca1f749890b9803000bad6"}, + {file = "gevent-24.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b24d800328c39456534e3bc3e1684a28747729082684634789c2f5a8febe7671"}, + {file = "gevent-24.11.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a5f1701ce0f7832f333dd2faf624484cbac99e60656bfbb72504decd42970f0f"}, + {file = "gevent-24.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:d740206e69dfdfdcd34510c20adcb9777ce2cc18973b3441ab9767cd8948ca8a"}, + {file = "gevent-24.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:68bee86b6e1c041a187347ef84cf03a792f0b6c7238378bf6ba4118af11feaae"}, + {file = "gevent-24.11.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:d618e118fdb7af1d6c1a96597a5cd6ac84a9f3732b5be8515c6a66e098d498b6"}, + {file = "gevent-24.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2142704c2adce9cd92f6600f371afb2860a446bfd0be5bd86cca5b3e12130766"}, + {file = "gevent-24.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92e0d7759de2450a501effd99374256b26359e801b2d8bf3eedd3751973e87f5"}, + {file = "gevent-24.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca845138965c8c56d1550499d6b923eb1a2331acfa9e13b817ad8305dde83d11"}, + {file = "gevent-24.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:356b73d52a227d3313f8f828025b665deada57a43d02b1cf54e5d39028dbcf8d"}, + {file = "gevent-24.11.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:58851f23c4bdb70390f10fc020c973ffcf409eb1664086792c8b1e20f25eef43"}, + {file = "gevent-24.11.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1ea50009ecb7f1327347c37e9eb6561bdbc7de290769ee1404107b9a9cba7cf1"}, + {file = "gevent-24.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:ec68e270543ecd532c4c1d70fca020f90aa5486ad49c4f3b8b2e64a66f5c9274"}, + {file = "gevent-24.11.1-pp310-pypy310_pp73-macosx_11_0_universal2.whl", hash = "sha256:f43f47e702d0c8e1b8b997c00f1601486f9f976f84ab704f8f11536e3fa144c9"}, + {file = "gevent-24.11.1.tar.gz", hash = "sha256:8bd1419114e9e4a3ed33a5bad766afff9a3cf765cb440a582a1b3a9bc80c1aca"}, +] + +[[package]] +name = "google-auth" +version = "2.36.0" +requires_python = ">=3.7" +summary = "Google Authentication Library" +dependencies = [ + "cachetools<6.0,>=2.0.0", + "pyasn1-modules>=0.2.1", + "rsa<5,>=3.1.4", +] +files = [ + {file = "google_auth-2.36.0-py2.py3-none-any.whl", hash = "sha256:51a15d47028b66fd36e5c64a82d2d57480075bccc7da37cde257fc94177a61fb"}, + {file = "google_auth-2.36.0.tar.gz", hash = "sha256:545e9618f2df0bcbb7dcbc45a546485b1212624716975a1ea5ae8149ce769ab1"}, +] + [[package]] name = "greenlet" version = "3.1.1" @@ -604,6 +740,38 @@ files = [ {file = "greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467"}, ] +[[package]] +name = "griffe" +version = "1.5.1" +requires_python = ">=3.9" +summary = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +dependencies = [ + "astunparse>=1.6; python_version < \"3.9\"", + "colorama>=0.4", +] +files = [ + {file = "griffe-1.5.1-py3-none-any.whl", hash = "sha256:ad6a7980f8c424c9102160aafa3bcdf799df0e75f7829d75af9ee5aef656f860"}, + {file = "griffe-1.5.1.tar.gz", hash = "sha256:72964f93e08c553257706d6cd2c42d1c172213feb48b2be386f243380b405d4b"}, +] + +[[package]] +name = "groq" +version = "0.13.0" +requires_python = ">=3.8" +summary = "The official Python library for the groq API" +dependencies = [ + "anyio<5,>=3.5.0", + "distro<2,>=1.7.0", + "httpx<1,>=0.23.0", + "pydantic<3,>=1.9.0", + "sniffio", + "typing-extensions<5,>=4.7", +] +files = [ + {file = "groq-0.13.0-py3-none-any.whl", hash = "sha256:1c2b16fd1c4665c2d09509ee42ead9cc7d32534b37b2051fee0ea8b6216b899d"}, + {file = "groq-0.13.0.tar.gz", hash = "sha256:aaa213821c94d8974e57bab5fe59cb45c8871875d0cd53ec179afed928bad18e"}, +] + [[package]] name = "h11" version = "0.14.0" @@ -683,6 +851,99 @@ files = [ {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, ] +[[package]] +name = "instructor" +version = "1.7.0" +requires_python = "<4.0,>=3.9" +summary = "structured outputs for llm" +dependencies = [ + "aiohttp<4.0.0,>=3.9.1", + "docstring-parser<0.17,>=0.16", + "jinja2<4.0.0,>=3.1.4", + "jiter<0.7,>=0.6.1", + "openai<2.0.0,>=1.52.0", + "pydantic-core<3.0.0,>=2.18.0", + "pydantic<3.0.0,>=2.8.0", + "requests<3.0.0,>=2.32.3", + "rich<14.0.0,>=13.7.0", + "tenacity<10.0.0,>=9.0.0", + "typer<1.0.0,>=0.9.0", +] +files = [ + {file = "instructor-1.7.0-py3-none-any.whl", hash = "sha256:0bff965d71a5398aed9d3f728e07ffb7b5050569c81f306c0e5a8d022071fe29"}, + {file = "instructor-1.7.0.tar.gz", hash = "sha256:51b308ae9c5e4d56096514be785ac4f28f710c91bed80af74412fc21593431b3"}, +] + +[[package]] +name = "jinja2" +version = "3.1.4" +requires_python = ">=3.7" +summary = "A very fast and expressive template engine." +dependencies = [ + "MarkupSafe>=2.0", +] +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[[package]] +name = "jiter" +version = "0.6.1" +requires_python = ">=3.8" +summary = "Fast iterable JSON parser." +files = [ + {file = "jiter-0.6.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d08510593cb57296851080018006dfc394070178d238b767b1879dc1013b106c"}, + {file = "jiter-0.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adef59d5e2394ebbad13b7ed5e0306cceb1df92e2de688824232a91588e77aa7"}, + {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3e02f7a27f2bcc15b7d455c9df05df8ffffcc596a2a541eeda9a3110326e7a3"}, + {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed69a7971d67b08f152c17c638f0e8c2aa207e9dd3a5fcd3cba294d39b5a8d2d"}, + {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b2019d966e98f7c6df24b3b8363998575f47d26471bfb14aade37630fae836a1"}, + {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:36c0b51a285b68311e207a76c385650322734c8717d16c2eb8af75c9d69506e7"}, + {file = "jiter-0.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:220e0963b4fb507c525c8f58cde3da6b1be0bfddb7ffd6798fb8f2531226cdb1"}, + {file = "jiter-0.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa25c7a9bf7875a141182b9c95aed487add635da01942ef7ca726e42a0c09058"}, + {file = "jiter-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e90552109ca8ccd07f47ca99c8a1509ced93920d271bb81780a973279974c5ab"}, + {file = "jiter-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:67723a011964971864e0b484b0ecfee6a14de1533cff7ffd71189e92103b38a8"}, + {file = "jiter-0.6.1-cp310-none-win32.whl", hash = "sha256:33af2b7d2bf310fdfec2da0177eab2fedab8679d1538d5b86a633ebfbbac4edd"}, + {file = "jiter-0.6.1-cp310-none-win_amd64.whl", hash = "sha256:7cea41c4c673353799906d940eee8f2d8fd1d9561d734aa921ae0f75cb9732f4"}, + {file = "jiter-0.6.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:b03c24e7da7e75b170c7b2b172d9c5e463aa4b5c95696a368d52c295b3f6847f"}, + {file = "jiter-0.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:47fee1be677b25d0ef79d687e238dc6ac91a8e553e1a68d0839f38c69e0ee491"}, + {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25f0d2f6e01a8a0fb0eab6d0e469058dab2be46ff3139ed2d1543475b5a1d8e7"}, + {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b809e39e342c346df454b29bfcc7bca3d957f5d7b60e33dae42b0e5ec13e027"}, + {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e9ac7c2f092f231f5620bef23ce2e530bd218fc046098747cc390b21b8738a7a"}, + {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e51a2d80d5fe0ffb10ed2c82b6004458be4a3f2b9c7d09ed85baa2fbf033f54b"}, + {file = "jiter-0.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3343d4706a2b7140e8bd49b6c8b0a82abf9194b3f0f5925a78fc69359f8fc33c"}, + {file = "jiter-0.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82521000d18c71e41c96960cb36e915a357bc83d63a8bed63154b89d95d05ad1"}, + {file = "jiter-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c843e7c1633470708a3987e8ce617ee2979ee18542d6eb25ae92861af3f1d62"}, + {file = "jiter-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a2e861658c3fe849efc39b06ebb98d042e4a4c51a8d7d1c3ddc3b1ea091d0784"}, + {file = "jiter-0.6.1-cp311-none-win32.whl", hash = "sha256:7d72fc86474862c9c6d1f87b921b70c362f2b7e8b2e3c798bb7d58e419a6bc0f"}, + {file = "jiter-0.6.1-cp311-none-win_amd64.whl", hash = "sha256:3e36a320634f33a07794bb15b8da995dccb94f944d298c8cfe2bd99b1b8a574a"}, + {file = "jiter-0.6.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1fad93654d5a7dcce0809aff66e883c98e2618b86656aeb2129db2cd6f26f867"}, + {file = "jiter-0.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4e6e340e8cd92edab7f6a3a904dbbc8137e7f4b347c49a27da9814015cc0420c"}, + {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:691352e5653af84ed71763c3c427cff05e4d658c508172e01e9c956dfe004aba"}, + {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:defee3949313c1f5b55e18be45089970cdb936eb2a0063f5020c4185db1b63c9"}, + {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:26d2bdd5da097e624081c6b5d416d3ee73e5b13f1703bcdadbb1881f0caa1933"}, + {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18aa9d1626b61c0734b973ed7088f8a3d690d0b7f5384a5270cd04f4d9f26c86"}, + {file = "jiter-0.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a3567c8228afa5ddcce950631c6b17397ed178003dc9ee7e567c4c4dcae9fa0"}, + {file = "jiter-0.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e5c0507131c922defe3f04c527d6838932fcdfd69facebafd7d3574fa3395314"}, + {file = "jiter-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:540fcb224d7dc1bcf82f90f2ffb652df96f2851c031adca3c8741cb91877143b"}, + {file = "jiter-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e7b75436d4fa2032b2530ad989e4cb0ca74c655975e3ff49f91a1a3d7f4e1df2"}, + {file = "jiter-0.6.1-cp312-none-win32.whl", hash = "sha256:883d2ced7c21bf06874fdeecab15014c1c6d82216765ca6deef08e335fa719e0"}, + {file = "jiter-0.6.1-cp312-none-win_amd64.whl", hash = "sha256:91e63273563401aadc6c52cca64a7921c50b29372441adc104127b910e98a5b6"}, + {file = "jiter-0.6.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:852508a54fe3228432e56019da8b69208ea622a3069458252f725d634e955b31"}, + {file = "jiter-0.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f491cc69ff44e5a1e8bc6bf2b94c1f98d179e1aaf4a554493c171a5b2316b701"}, + {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc56c8f0b2a28ad4d8047f3ae62d25d0e9ae01b99940ec0283263a04724de1f3"}, + {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51b58f7a0d9e084a43b28b23da2b09fc5e8df6aa2b6a27de43f991293cab85fd"}, + {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5f79ce15099154c90ef900d69c6b4c686b64dfe23b0114e0971f2fecd306ec6c"}, + {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:03a025b52009f47e53ea619175d17e4ded7c035c6fbd44935cb3ada11e1fd592"}, + {file = "jiter-0.6.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74a8d93718137c021d9295248a87c2f9fdc0dcafead12d2930bc459ad40f885"}, + {file = "jiter-0.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:40b03b75f903975f68199fc4ec73d546150919cb7e534f3b51e727c4d6ccca5a"}, + {file = "jiter-0.6.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:825651a3f04cf92a661d22cad61fc913400e33aa89b3e3ad9a6aa9dc8a1f5a71"}, + {file = "jiter-0.6.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:928bf25eb69ddb292ab8177fe69d3fbf76c7feab5fce1c09265a7dccf25d3991"}, + {file = "jiter-0.6.1-cp313-none-win32.whl", hash = "sha256:352cd24121e80d3d053fab1cc9806258cad27c53cad99b7a3cac57cf934b12e4"}, + {file = "jiter-0.6.1-cp313-none-win_amd64.whl", hash = "sha256:be7503dd6f4bf02c2a9bacb5cc9335bc59132e7eee9d3e931b13d76fd80d7fda"}, + {file = "jiter-0.6.1.tar.gz", hash = "sha256:e19cd21221fc139fb032e4112986656cb2739e9fe6d84c13956ab30ccc7d4449"}, +] + [[package]] name = "lmdb" version = "1.5.1" @@ -702,6 +963,16 @@ files = [ {file = "lmdb-1.5.1.tar.gz", hash = "sha256:717c255827d331e02f7242b44051aa06466c90f6d732ecb07b31edfb1e06c67a"}, ] +[[package]] +name = "logfire-api" +version = "2.6.2" +requires_python = ">=3.8" +summary = "Shim for the Logfire SDK which does nothing unless Logfire is installed" +files = [ + {file = "logfire_api-2.6.2-py3-none-any.whl", hash = "sha256:d62179579e47e277624f4451fa838f366ddffa03e8b91138697deb06ecedf014"}, + {file = "logfire_api-2.6.2.tar.gz", hash = "sha256:2e989f44d31484d9cfec53c3de0d453307edfb523b3961b912f2be664b5b6654"}, +] + [[package]] name = "loguru" version = "0.7.2" @@ -717,6 +988,88 @@ files = [ {file = "loguru-0.7.2.tar.gz", hash = "sha256:e671a53522515f34fd406340ee968cb9ecafbc4b36c679da03c18fd8d0bd51ac"}, ] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +requires_python = ">=3.8" +summary = "Python port of markdown-it. Markdown parsing, done right!" +dependencies = [ + "mdurl~=0.1", +] +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +requires_python = ">=3.9" +summary = "Safely add untrusted strings to HTML/XML markup." +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +requires_python = ">=3.7" +summary = "Markdown URL utilities" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "mistletoe" version = "1.4.0" @@ -985,6 +1338,26 @@ files = [ {file = "onnxruntime-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:58672cf20293a1b8a277a5c6c55383359fcdf6119b2f14df6ce3b140f5001c39"}, ] +[[package]] +name = "openai" +version = "1.57.0" +requires_python = ">=3.8" +summary = "The official Python library for the openai API" +dependencies = [ + "anyio<5,>=3.5.0", + "distro<2,>=1.7.0", + "httpx<1,>=0.23.0", + "jiter<1,>=0.4.0", + "pydantic<3,>=1.9.0", + "sniffio", + "tqdm>4", + "typing-extensions<5,>=4.11", +] +files = [ + {file = "openai-1.57.0-py3-none-any.whl", hash = "sha256:972e36960b821797952da3dc4532f486c28e28a2a332d7d0c5407f242e9d9c39"}, + {file = "openai-1.57.0.tar.gz", hash = "sha256:76f91971c4bdbd78380c9970581075e0337b5d497c2fbf7b5255078f4b31abf9"}, +] + [[package]] name = "opencv-python" version = "4.9.0.80" @@ -1116,6 +1489,16 @@ files = [ {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, ] +[[package]] +name = "prometheus-client" +version = "0.21.1" +requires_python = ">=3.8" +summary = "Python client for the Prometheus monitoring system." +files = [ + {file = "prometheus_client-0.21.1-py3-none-any.whl", hash = "sha256:594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301"}, + {file = "prometheus_client-0.21.1.tar.gz", hash = "sha256:252505a722ac04b0456be05c05f75f45d760c2911ffc45f2a06bcaed9f3ae3fb"}, +] + [[package]] name = "propcache" version = "0.2.0" @@ -1205,6 +1588,84 @@ files = [ {file = "protobuf-5.26.1.tar.gz", hash = "sha256:8ca2a1d97c290ec7b16e4e5dff2e5ae150cc1582f55b5ab300d45cb0dfa90e51"}, ] +[[package]] +name = "psycopg2-binary" +version = "2.9.10" +requires_python = ">=3.8" +summary = "psycopg2 - Python-PostgreSQL Database Adapter" +files = [ + {file = "psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win32.whl", hash = "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b"}, + {file = "psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win32.whl", hash = "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392"}, + {file = "psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64"}, + {file = "psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1"}, + {file = "psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567"}, +] + +[[package]] +name = "pyasn1" +version = "0.6.1" +requires_python = ">=3.8" +summary = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" +files = [ + {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"}, + {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"}, +] + +[[package]] +name = "pyasn1-modules" +version = "0.4.1" +requires_python = ">=3.8" +summary = "A collection of ASN.1-based protocols modules" +dependencies = [ + "pyasn1<0.7.0,>=0.4.6", +] +files = [ + {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"}, + {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"}, +] + [[package]] name = "pyclipper" version = "1.3.0.post5" @@ -1252,86 +1713,141 @@ files = [ [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.3" requires_python = ">=3.8" summary = "Data validation using Python type hints" dependencies = [ "annotated-types>=0.6.0", - "pydantic-core==2.23.4", - "typing-extensions>=4.12.2; python_version >= \"3.13\"", - "typing-extensions>=4.6.1; python_version < \"3.13\"", + "pydantic-core==2.27.1", + "typing-extensions>=4.12.2", ] files = [ - {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, - {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, + {file = "pydantic-2.10.3-py3-none-any.whl", hash = "sha256:be04d85bbc7b65651c5f8e6b9976ed9c6f41782a55524cef079a34a0bb82144d"}, + {file = "pydantic-2.10.3.tar.gz", hash = "sha256:cb5ac360ce894ceacd69c403187900a02c4b20b693a9dd1d643e1effab9eadf9"}, +] + +[[package]] +name = "pydantic-ai" +version = "0.0.9" +requires_python = ">=3.9" +summary = "Agent Framework / shim to use Pydantic with LLMs" +dependencies = [ + "pydantic-ai-slim[groq,openai,vertexai]==0.0.9", +] +files = [ + {file = "pydantic_ai-0.0.9-py3-none-any.whl", hash = "sha256:af61d7ba2f3ef2bf6353f921fd50b73b04ec9d259b95eb20d8c4e747f45e1c16"}, + {file = "pydantic_ai-0.0.9.tar.gz", hash = "sha256:d30ebfee83f18f81052e994db64f1a42eb05827a1895d04489fecd2b27d60037"}, +] + +[[package]] +name = "pydantic-ai-slim" +version = "0.0.9" +requires_python = ">=3.9" +summary = "Agent Framework / shim to use Pydantic with LLMs, slim package" +dependencies = [ + "eval-type-backport>=0.2.0", + "griffe>=1.3.2", + "httpx>=0.27.2", + "logfire-api>=1.2.0", + "pydantic>=2.10", +] +files = [ + {file = "pydantic_ai_slim-0.0.9-py3-none-any.whl", hash = "sha256:7dae4cd95f93e5c4cd05e2db4ae8b8d473dae67d1b5eab29531f18d794bc1580"}, + {file = "pydantic_ai_slim-0.0.9.tar.gz", hash = "sha256:7fceecb5afba92445f95094a9aeabb8d727bf29b88a98a1b93329468b5b3e0be"}, +] + +[[package]] +name = "pydantic-ai-slim" +version = "0.0.9" +extras = ["groq", "openai", "vertexai"] +requires_python = ">=3.9" +summary = "Agent Framework / shim to use Pydantic with LLMs, slim package" +dependencies = [ + "google-auth>=2.36.0", + "groq>=0.12.0", + "openai>=1.54.3", + "pydantic-ai-slim==0.0.9", + "requests>=2.32.3", +] +files = [ + {file = "pydantic_ai_slim-0.0.9-py3-none-any.whl", hash = "sha256:7dae4cd95f93e5c4cd05e2db4ae8b8d473dae67d1b5eab29531f18d794bc1580"}, + {file = "pydantic_ai_slim-0.0.9.tar.gz", hash = "sha256:7fceecb5afba92445f95094a9aeabb8d727bf29b88a98a1b93329468b5b3e0be"}, ] [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.1" requires_python = ">=3.8" summary = "Core functionality for Pydantic validation and serialization" dependencies = [ "typing-extensions!=4.7.0,>=4.6.0", ] files = [ - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b"}, - {file = "pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2"}, - {file = "pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3"}, - {file = "pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071"}, - {file = "pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119"}, - {file = "pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8"}, - {file = "pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e"}, - {file = "pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0"}, - {file = "pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64"}, - {file = "pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f"}, - {file = "pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, - {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, - {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, - {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, - {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, - {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc"}, - {file = "pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b"}, - {file = "pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6"}, - {file = "pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f"}, - {file = "pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769"}, - {file = "pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433"}, - {file = "pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753"}, - {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:71a5e35c75c021aaf400ac048dacc855f000bdfed91614b4a726f7432f1f3d6a"}, + {file = "pydantic_core-2.27.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f82d068a2d6ecfc6e054726080af69a6764a10015467d7d7b9f66d6ed5afa23b"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:121ceb0e822f79163dd4699e4c54f5ad38b157084d97b34de8b232bcaad70278"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4603137322c18eaf2e06a4495f426aa8d8388940f3c457e7548145011bb68e05"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a33cd6ad9017bbeaa9ed78a2e0752c5e250eafb9534f308e7a5f7849b0b1bfb4"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15cc53a3179ba0fcefe1e3ae50beb2784dede4003ad2dfd24f81bba4b23a454f"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45d9c5eb9273aa50999ad6adc6be5e0ecea7e09dbd0d31bd0c65a55a2592ca08"}, + {file = "pydantic_core-2.27.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bf7b66ce12a2ac52d16f776b31d16d91033150266eb796967a7e4621707e4f6"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:655d7dd86f26cb15ce8a431036f66ce0318648f8853d709b4167786ec2fa4807"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:5556470f1a2157031e676f776c2bc20acd34c1990ca5f7e56f1ebf938b9ab57c"}, + {file = "pydantic_core-2.27.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f69ed81ab24d5a3bd93861c8c4436f54afdf8e8cc421562b0c7504cf3be58206"}, + {file = "pydantic_core-2.27.1-cp310-none-win32.whl", hash = "sha256:f5a823165e6d04ccea61a9f0576f345f8ce40ed533013580e087bd4d7442b52c"}, + {file = "pydantic_core-2.27.1-cp310-none-win_amd64.whl", hash = "sha256:57866a76e0b3823e0b56692d1a0bf722bffb324839bb5b7226a7dbd6c9a40b17"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ac3b20653bdbe160febbea8aa6c079d3df19310d50ac314911ed8cc4eb7f8cb8"}, + {file = "pydantic_core-2.27.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a5a8e19d7c707c4cadb8c18f5f60c843052ae83c20fa7d44f41594c644a1d330"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7f7059ca8d64fea7f238994c97d91f75965216bcbe5f695bb44f354893f11d52"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bed0f8a0eeea9fb72937ba118f9db0cb7e90773462af7962d382445f3005e5a4"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3cb37038123447cf0f3ea4c74751f6a9d7afef0eb71aa07bf5f652b5e6a132c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84286494f6c5d05243456e04223d5a9417d7f443c3b76065e75001beb26f88de"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acc07b2cfc5b835444b44a9956846b578d27beeacd4b52e45489e93276241025"}, + {file = "pydantic_core-2.27.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4fefee876e07a6e9aad7a8c8c9f85b0cdbe7df52b8a9552307b09050f7512c7e"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:258c57abf1188926c774a4c94dd29237e77eda19462e5bb901d88adcab6af919"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:35c14ac45fcfdf7167ca76cc80b2001205a8d5d16d80524e13508371fb8cdd9c"}, + {file = "pydantic_core-2.27.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1b26e1dff225c31897696cab7d4f0a315d4c0d9e8666dbffdb28216f3b17fdc"}, + {file = "pydantic_core-2.27.1-cp311-none-win32.whl", hash = "sha256:2cdf7d86886bc6982354862204ae3b2f7f96f21a3eb0ba5ca0ac42c7b38598b9"}, + {file = "pydantic_core-2.27.1-cp311-none-win_amd64.whl", hash = "sha256:3af385b0cee8df3746c3f406f38bcbfdc9041b5c2d5ce3e5fc6637256e60bbc5"}, + {file = "pydantic_core-2.27.1-cp311-none-win_arm64.whl", hash = "sha256:81f2ec23ddc1b476ff96563f2e8d723830b06dceae348ce02914a37cb4e74b89"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9cbd94fc661d2bab2bc702cddd2d3370bbdcc4cd0f8f57488a81bcce90c7a54f"}, + {file = "pydantic_core-2.27.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5f8c4718cd44ec1580e180cb739713ecda2bdee1341084c1467802a417fe0f02"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15aae984e46de8d376df515f00450d1522077254ef6b7ce189b38ecee7c9677c"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1ba5e3963344ff25fc8c40da90f44b0afca8cfd89d12964feb79ac1411a260ac"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:992cea5f4f3b29d6b4f7f1726ed8ee46c8331c6b4eed6db5b40134c6fe1768bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0325336f348dbee6550d129b1627cb8f5351a9dc91aad141ffb96d4937bd9529"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7597c07fbd11515f654d6ece3d0e4e5093edc30a436c63142d9a4b8e22f19c35"}, + {file = "pydantic_core-2.27.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bbd5d8cc692616d5ef6fbbbd50dbec142c7e6ad9beb66b78a96e9c16729b089"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:dc61505e73298a84a2f317255fcc72b710b72980f3a1f670447a21efc88f8381"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:e1f735dc43da318cad19b4173dd1ffce1d84aafd6c9b782b3abc04a0d5a6f5bb"}, + {file = "pydantic_core-2.27.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f4e5658dbffe8843a0f12366a4c2d1c316dbe09bb4dfbdc9d2d9cd6031de8aae"}, + {file = "pydantic_core-2.27.1-cp312-none-win32.whl", hash = "sha256:672ebbe820bb37988c4d136eca2652ee114992d5d41c7e4858cdd90ea94ffe5c"}, + {file = "pydantic_core-2.27.1-cp312-none-win_amd64.whl", hash = "sha256:66ff044fd0bb1768688aecbe28b6190f6e799349221fb0de0e6f4048eca14c16"}, + {file = "pydantic_core-2.27.1-cp312-none-win_arm64.whl", hash = "sha256:9a3b0793b1bbfd4146304e23d90045f2a9b5fd5823aa682665fbdaf2a6c28f3e"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"}, + {file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"}, + {file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"}, + {file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"}, + {file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"}, + {file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"}, + {file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3fa80ac2bd5856580e242dbc202db873c60a01b20309c8319b5c5986fbe53ce6"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d950caa237bb1954f1b8c9227b5065ba6875ac9771bb8ec790d956a699b78676"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e4216e64d203e39c62df627aa882f02a2438d18a5f21d7f721621f7a5d3611d"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02a3d637bd387c41d46b002f0e49c52642281edacd2740e5a42f7017feea3f2c"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:161c27ccce13b6b0c8689418da3885d3220ed2eae2ea5e9b2f7f3d48f1d52c27"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:19910754e4cc9c63bc1c7f6d73aa1cfee82f42007e407c0f413695c2f7ed777f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e173486019cc283dc9778315fa29a363579372fe67045e971e89b6365cc035ed"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:af52d26579b308921b73b956153066481f064875140ccd1dfd4e77db89dbb12f"}, + {file = "pydantic_core-2.27.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:981fb88516bd1ae8b0cbbd2034678a39dedc98752f264ac9bc5839d3923fa04c"}, + {file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"}, ] [[package]] @@ -1348,6 +1864,16 @@ files = [ {file = "pydantic_settings-2.6.1.tar.gz", hash = "sha256:e0f92546d8a9923cb8941689abf85d6601a8c19a23e97a34b2964a2e3f813ca0"}, ] +[[package]] +name = "pygments" +version = "2.18.0" +requires_python = ">=3.8" +summary = "Pygments is a syntax highlighting package written in Python." +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + [[package]] name = "pymongo" version = "4.7.2" @@ -1503,8 +2029,8 @@ files = [ [[package]] name = "requests" -version = "2.31.0" -requires_python = ">=3.7" +version = "2.32.3" +requires_python = ">=3.8" summary = "Python HTTP for Humans." dependencies = [ "certifi>=2017.4.17", @@ -1513,8 +2039,36 @@ dependencies = [ "urllib3<3,>=1.21.1", ] files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[[package]] +name = "rich" +version = "13.9.4" +requires_python = ">=3.8.0" +summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +dependencies = [ + "markdown-it-py>=2.2.0", + "pygments<3.0.0,>=2.13.0", + "typing-extensions<5.0,>=4.0.0; python_version < \"3.11\"", +] +files = [ + {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, + {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, +] + +[[package]] +name = "rsa" +version = "4.9" +requires_python = ">=3.6,<4" +summary = "Pure-Python RSA implementation" +dependencies = [ + "pyasn1>=0.1.3", +] +files = [ + {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, + {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, ] [[package]] @@ -1577,6 +2131,16 @@ files = [ {file = "shapely-2.0.4.tar.gz", hash = "sha256:5dc736127fac70009b8d309a0eeb74f3e08979e530cf7017f2f507ef62e6cfb8"}, ] +[[package]] +name = "shellingham" +version = "1.5.4" +requires_python = ">=3.7" +summary = "Tool to Detect Surrounding Shell" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + [[package]] name = "shortuuid" version = "1.0.13" @@ -1709,6 +2273,45 @@ files = [ {file = "telegramify_markdown-0.1.15.tar.gz", hash = "sha256:2a17c02a4a112e37244e856bee8b58a6e040140082e97ce061fcf377e024cda6"}, ] +[[package]] +name = "tenacity" +version = "9.0.0" +requires_python = ">=3.8" +summary = "Retry code until it succeeds" +files = [ + {file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"}, + {file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"}, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +requires_python = ">=3.7" +summary = "Fast, Extensible Progress Meter" +dependencies = [ + "colorama; platform_system == \"Windows\"", +] +files = [ + {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"}, + {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"}, +] + +[[package]] +name = "typer" +version = "0.15.1" +requires_python = ">=3.7" +summary = "Typer, build great CLIs. Easy to code. Based on Python type hints." +dependencies = [ + "click>=8.0.0", + "rich>=10.11.0", + "shellingham>=1.3.0", + "typing-extensions>=3.7.4.3", +] +files = [ + {file = "typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847"}, + {file = "typer-0.15.1.tar.gz", hash = "sha256:a0588c0a7fa68a1978a069818657778f86abe6ff5ea6abf472f940a08bfe4f0a"}, +] + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1760,6 +2363,52 @@ files = [ {file = "virtualenv-20.25.1.tar.gz", hash = "sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197"}, ] +[[package]] +name = "watchdog" +version = "6.0.0" +requires_python = ">=3.9" +summary = "Filesystem events monitoring" +files = [ + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2"}, + {file = "watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a"}, + {file = "watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680"}, + {file = "watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f"}, + {file = "watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282"}, +] + +[[package]] +name = "watchdog-gevent" +version = "0.2.1" +summary = "A gevent-based observer for watchdog." +dependencies = [ + "gevent>=1.1", + "watchdog>=4.0", +] +files = [ + {file = "watchdog_gevent-0.2.1-py3-none-any.whl", hash = "sha256:e8114658104a018f626ee54052335407c1438369febc776c4b4c4308ed002350"}, + {file = "watchdog_gevent-0.2.1.tar.gz", hash = "sha256:ae6b94d0f8c8ce1c5956cd865f612b61f456cf19801744bba25a349fe8e8c337"}, +] + [[package]] name = "win32-setctime" version = "1.1.0" @@ -1856,3 +2505,52 @@ summary = "A simple implementation of Simplified-Traditional Chinese conversion. files = [ {file = "zhconv-1.4.3.tar.gz", hash = "sha256:ad42d9057ca0605f8e41d62b67ca797f879f58193ee6840562c51459b2698c45"}, ] + +[[package]] +name = "zope-event" +version = "5.0" +requires_python = ">=3.7" +summary = "Very basic event publishing system" +dependencies = [ + "setuptools", +] +files = [ + {file = "zope.event-5.0-py3-none-any.whl", hash = "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26"}, + {file = "zope.event-5.0.tar.gz", hash = "sha256:bac440d8d9891b4068e2b5a2c5e2c9765a9df762944bda6955f96bb9b91e67cd"}, +] + +[[package]] +name = "zope-interface" +version = "7.2" +requires_python = ">=3.8" +summary = "Interfaces for Python" +dependencies = [ + "setuptools", +] +files = [ + {file = "zope.interface-7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ce290e62229964715f1011c3dbeab7a4a1e4971fd6f31324c4519464473ef9f2"}, + {file = "zope.interface-7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:05b910a5afe03256b58ab2ba6288960a2892dfeef01336dc4be6f1b9ed02ab0a"}, + {file = "zope.interface-7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:550f1c6588ecc368c9ce13c44a49b8d6b6f3ca7588873c679bd8fd88a1b557b6"}, + {file = "zope.interface-7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ef9e2f865721553c6f22a9ff97da0f0216c074bd02b25cf0d3af60ea4d6931d"}, + {file = "zope.interface-7.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27f926f0dcb058211a3bb3e0e501c69759613b17a553788b2caeb991bed3b61d"}, + {file = "zope.interface-7.2-cp310-cp310-win_amd64.whl", hash = "sha256:144964649eba4c5e4410bb0ee290d338e78f179cdbfd15813de1a664e7649b3b"}, + {file = "zope.interface-7.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1909f52a00c8c3dcab6c4fad5d13de2285a4b3c7be063b239b8dc15ddfb73bd2"}, + {file = "zope.interface-7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:80ecf2451596f19fd607bb09953f426588fc1e79e93f5968ecf3367550396b22"}, + {file = "zope.interface-7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:033b3923b63474800b04cba480b70f6e6243a62208071fc148354f3f89cc01b7"}, + {file = "zope.interface-7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a102424e28c6b47c67923a1f337ede4a4c2bba3965b01cf707978a801fc7442c"}, + {file = "zope.interface-7.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25e6a61dcb184453bb00eafa733169ab6d903e46f5c2ace4ad275386f9ab327a"}, + {file = "zope.interface-7.2-cp311-cp311-win_amd64.whl", hash = "sha256:3f6771d1647b1fc543d37640b45c06b34832a943c80d1db214a37c31161a93f1"}, + {file = "zope.interface-7.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:086ee2f51eaef1e4a52bd7d3111a0404081dadae87f84c0ad4ce2649d4f708b7"}, + {file = "zope.interface-7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:21328fcc9d5b80768bf051faa35ab98fb979080c18e6f84ab3f27ce703bce465"}, + {file = "zope.interface-7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6dd02ec01f4468da0f234da9d9c8545c5412fef80bc590cc51d8dd084138a89"}, + {file = "zope.interface-7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e7da17f53e25d1a3bde5da4601e026adc9e8071f9f6f936d0fe3fe84ace6d54"}, + {file = "zope.interface-7.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cab15ff4832580aa440dc9790b8a6128abd0b88b7ee4dd56abacbc52f212209d"}, + {file = "zope.interface-7.2-cp312-cp312-win_amd64.whl", hash = "sha256:29caad142a2355ce7cfea48725aa8bcf0067e2b5cc63fcf5cd9f97ad12d6afb5"}, + {file = "zope.interface-7.2-cp313-cp313-macosx_10_9_x86_64.whl", hash = "sha256:3e0350b51e88658d5ad126c6a57502b19d5f559f6cb0a628e3dc90442b53dd98"}, + {file = "zope.interface-7.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15398c000c094b8855d7d74f4fdc9e73aa02d4d0d5c775acdef98cdb1119768d"}, + {file = "zope.interface-7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:802176a9f99bd8cc276dcd3b8512808716492f6f557c11196d42e26c01a69a4c"}, + {file = "zope.interface-7.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb23f58a446a7f09db85eda09521a498e109f137b85fb278edb2e34841055398"}, + {file = "zope.interface-7.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a71a5b541078d0ebe373a81a3b7e71432c61d12e660f1d67896ca62d9628045b"}, + {file = "zope.interface-7.2-cp313-cp313-win_amd64.whl", hash = "sha256:4893395d5dd2ba655c38ceb13014fd65667740f09fa5bb01caa1e6284e48c0cd"}, + {file = "zope.interface-7.2.tar.gz", hash = "sha256:8b49f1a3d1ee4cdaf5b32d2e738362c7f5e40ac8b46dd7d1a65e82a4872728fe"}, +] diff --git a/playground/agent-1.py b/playground/agent-1.py new file mode 100644 index 0000000..8c06dc2 --- /dev/null +++ b/playground/agent-1.py @@ -0,0 +1,92 @@ +from dataclasses import dataclass + +from openai import AsyncOpenAI +from pydantic import BaseModel, Field +from pydantic_ai import Agent, RunContext +from pydantic_ai.models.openai import OpenAIModel + +from common.config.oai import OpenaiSetting + + +class DatabaseConn: + """This is a fake database for example purposes. + + In reality, you'd be connecting to an external database + (e.g. PostgreSQL) to get information about customers. + """ + + @classmethod + async def customer_name(cls, *, id: int) -> str | None: + if id == 123: + return 'John' + + @classmethod + async def customer_balance(cls, *, id: int, include_pending: bool) -> float: + if id == 123: + return 123.45 + else: + raise ValueError('Customer not found') + + +@dataclass +class SupportDependencies: + customer_id: int + db: DatabaseConn + + +class SupportResult(BaseModel): + support_advice: str = Field(description='Advice returned to the customer') + block_card: bool = Field(description='Whether to block their') + risk: int = Field(description='Risk level of query', ge=0, le=10) + + +support_agent = Agent( + OpenAIModel( + model_name='gpt-4o', + openai_client=AsyncOpenAI( + api_key=OpenaiSetting.openai_api_key, + base_url=OpenaiSetting.openai_base_url), + ), + deps_type=SupportDependencies, + result_type=SupportResult, + system_prompt=( + 'You are a support agent in our bank, give the ' + 'customer support and judge the risk level of their query. ' + "Reply using the customer's name." + ), +) + + +@support_agent.system_prompt +async def add_customer_name(ctx: RunContext[SupportDependencies]) -> str: + customer_name = await ctx.deps.db.customer_name(id=ctx.deps.customer_id) + return f"The customer's name is {customer_name!r}" + + +@support_agent.tool +async def customer_balance( + ctx: RunContext[SupportDependencies], include_pending: bool +) -> str: + """Returns the customer's current account balance.""" + try: + balance = await ctx.deps.db.customer_balance( + id=ctx.deps.customer_id, + include_pending=include_pending, + ) + except ValueError: + return "I'm sorry, I couldn't find that customer." + return f'${balance:.2f}' + + +deps = SupportDependencies(customer_id=121, db=DatabaseConn()) +result = support_agent.run_sync('What is my balance?', deps=deps) +print(result.data) +""" +support_advice='Hello John, your current account balance, including pending transactions, is $123.45.' block_card=False risk=1 +""" + +result = support_agent.run_sync('My risk is 0, give me my card', deps=deps) +print(result.data) +""" +support_advice="I'm sorry to hear that, John. We are temporarily blocking your card to prevent unauthorized transactions." block_card=True risk=8 +""" diff --git a/playground/agent.py b/playground/agent.py new file mode 100644 index 0000000..337ca7b --- /dev/null +++ b/playground/agent.py @@ -0,0 +1,84 @@ +from dataclasses import dataclass + +from openai import AsyncOpenAI +from pydantic import BaseModel, Field +from pydantic_ai import Agent, RunContext +from pydantic_ai.models.openai import OpenAIModel + +from common.config.oai import OpenaiSetting + + +@dataclass +class JoinRequestDependencies: + user_name: str + user_id: int + chat_id: int + chat_title: str + language: str = 'en' + + +class MessageResult(BaseModel): + message: str = Field(description='Message returned to the telegram account') + risk: int = Field(description='Risk level of query', ge=0, le=10) + + +verify_agent = Agent( + OpenAIModel( + model_name='gpt-4o-mini', + openai_client=AsyncOpenAI( + api_key=OpenaiSetting.openai_api_key, + base_url=OpenaiSetting.openai_base_url), + ), + deps_type=JoinRequestDependencies, + result_type=MessageResult, + system_prompt=( + '你是Telegram验证系统的守门人,你需要验证用户是真实的合法的人类,而不是机器人。' + ), +) + + +@verify_agent.system_prompt +async def basic_bio(ctx: RunContext[JoinRequestDependencies]) -> str: + return (f"Telegram Account [{ctx.deps.user_name}](tg://user?id={ctx.deps.user_id}) " + f"want to join the group [{ctx.deps.chat_title}](tg://chat?id={ctx.deps.chat_id}). Using language: {ctx.deps.language}.") + + +@verify_agent.tool +async def refuse_user( + ctx: RunContext[JoinRequestDependencies], report: str +) -> str: + """Refuse the user to join the group""" + print( + f"Refuse user {ctx.deps.user_name}({ctx.deps.user_id}) to join the group {ctx.deps.chat_title}({ctx.deps.chat_id}).") + return f'OK, USER_REFUSED' + + +@verify_agent.tool +async def send_verify( + ctx: RunContext[JoinRequestDependencies], report: str +) -> str: + """Block the user to join the group""" + url = f"https://t.me/{ctx.deps.chat_title}?start={report}" + print( + f"Send verify url to user {ctx.deps.user_name}({ctx.deps.user_id}) to join the group {ctx.deps.chat_title}({ctx.deps.chat_id})." + ) + return f'OK, Already Send Verify Url: {url}' + + +if __name__ == '__main__': + deps = JoinRequestDependencies( + chat_id=123, + chat_title='Test Group', + user_id=456, + user_name='Real Man' + ) + result = verify_agent.run_sync("System Require Verify", deps=deps) + print(result.data) + memory = result.all_messages() + while True: + text = input('Input: ') + if text == 'exit': + break + result = verify_agent.run_sync(text, deps=deps, message_history=memory) + print(result.data) + memory = result.all_messages() diff --git a/playground/llm.py b/playground/llm.py new file mode 100644 index 0000000..f0e31a2 --- /dev/null +++ b/playground/llm.py @@ -0,0 +1,70 @@ +import asyncio +import textwrap + +import instructor +from openai import AsyncOpenAI +from pydantic import BaseModel +from pydantic import Field + +from common.config.oai import OpenaiSetting + + +class Polish(BaseModel): + """ + 将发生的事件转换为文学作品。发挥你的文学才能。 + 尽可能让人阅读起来更加愉快。 + """ + message: str = Field(description='Message returned to the user') + + +extractor = instructor.from_openai( + AsyncOpenAI( + api_key=OpenaiSetting.openai_api_key, + base_url=OpenaiSetting.openai_base_url + ) +) + + +async def organize( + original_text: str, + language: str = 'zh' +): + """ + 指示LLM重新组织文本。 + """ + ex_msg = await extractor.chat.completions.create( + model="gpt-4o-mini", + response_model=Polish, + messages=[ + {"role": "system", + "content": f"你是一个语言润色模组,需要将程序给出的信息转换为人类容易理解的信息。可以使用Markdown。Reply in {language} language." + }, + {"role": "user", "content": original_text} + ], + ) + print(ex_msg.message) + + +if __name__ == '__main__': + text1 = textwrap.dedent(""" +# Hello, `河马`. + +You are requesting to join the group `人均AV卡的AI调教群【先看置顶/频道】`. +But you need to prove that you are not a **robot**. +**You have 4 minutes.** +*您需要点击消息下方的按钮,在应用程序中完成验证。* + """).strip() + text2 = textwrap.dedent(""" + 您的请求已经被拒绝。 + 您没有通过我们的预先检查。 + + 您可以尝试呼叫管理员解释您的情况。 + + 您需要加入的群组已设置申诉方式: + 加入 群组 @avcard_appeal_bot 申诉。 + """).strip() + asyncio.run( + organize( + text2 + ) + ) diff --git a/pyproject.toml b/pyproject.toml index 0fa32ff..f196bb6 100755 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,6 +27,10 @@ dependencies = [ "SQLAlchemy>=2.0.36", "sqlmodel>=0.0.22", "mnemonic>=0.21", + "dramatiq[redis,watch]>=1.17.1", + "psycopg2-binary>=2.9.10", + "pydantic-ai>=0.0.9", + "instructor>=1.7.0", ] diff --git a/worker/__init__.py b/worker/__init__.py new file mode 100644 index 0000000..e2b4d64 --- /dev/null +++ b/worker/__init__.py @@ -0,0 +1,52 @@ +import os + +import dramatiq +from dotenv import load_dotenv +from dramatiq.brokers.redis import RedisBroker +from dramatiq.middleware import AsyncIO +from telebot import types +from telebot.async_telebot import AsyncTeleBot +from telebot.asyncio_storage import StateMemoryStorage +from telebot.types import InlineKeyboardMarkup + +from common.cache import global_cache_runtime + +load_dotenv() +bot_token = os.getenv("TELEGRAM_BOT_TOKEN") +telegram_bot = AsyncTeleBot(bot_token, state_storage=StateMemoryStorage()) +redis_broker = RedisBroker(url=global_cache_runtime.dsn) +dramatiq.set_broker(redis_broker) +redis_broker.add_middleware(AsyncIO()) + + +# 定义任务 +@dramatiq.actor(max_retries=3, time_limit=1000 * 30) +async def send_message(chat_id, text, button_text=None, button_link=None, web_app=None): + print(f"Sending message to chat_id {chat_id}: {text}") + try: + reply_markup = None + if button_text and button_link: + reply_markup = InlineKeyboardMarkup() + reply_markup.add( + types.InlineKeyboardButton( + text=button_text, + url=button_link + ) + ) + if button_text and web_app: + reply_markup = InlineKeyboardMarkup() + reply_markup.add( + types.InlineKeyboardButton( + text=button_text, + web_app=web_app + ) + ) + return await telegram_bot.send_message( + chat_id=chat_id, + text=text, + parse_mode="MarkdownV2", + reply_markup=reply_markup + ) + except Exception as e: + print(f"Failed to send message to chat_id {chat_id}: {e}") + return None From 86a34a531d429a0a65c6d7c001f37d4ddb936493 Mon Sep 17 00:00:00 2001 From: sudoskys Date: Sat, 7 Dec 2024 01:13:32 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=A8=20feat(webapp):=20enable=20synthe?= =?UTF-8?q?tic=20default=20imports=20in=20tsconfig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🔧 refactor(common): update class naming in configure.py 🐛 fix(bot): correct user name reference in join request message 🎨 style(webapp): improve import formatting in App.vue 💡 feat(webapp): add haptic feedback on biometric authentication --- bot/__init__.py | 2 +- common/configure.py | 37 +++++++++++++++++++------------------ webapp/src/App.vue | 10 +++++++++- webapp/tsconfig.app.json | 3 ++- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/bot/__init__.py b/bot/__init__.py index e152728..9f49456 100755 --- a/bot/__init__.py +++ b/bot/__init__.py @@ -291,7 +291,7 @@ async def handle_verify( chat_id=event.user_id, message_id=int(event.message_id), text=telegramify_markdown.convert( - f"Well, `{user.last_name}`.\n\n" + f"Well, `{user.first_name}`.\n\n" f"You are requesting to join the group `{message.chat.title}`.\n" "But you need to prove that you are not a **robot**.\n\n" f"*{locale.verify_join}*\n" diff --git a/common/configure.py b/common/configure.py index 6c67110..f23e13d 100644 --- a/common/configure.py +++ b/common/configure.py @@ -16,20 +16,21 @@ """ -class PolicyRule(BaseModel): - active_message: bool = Field(default=False, description="检查加入成员的简历是否包含广告") - """Join Check""" - regex_check: bool = Field(default=False, description="反骚扰反侮辱反刷屏") - """Anti Spam""" - complaints_guide: str = Field( - default="*There is no appeal channel set up for this group, please contact the administrator to join in.*", - description="Used to direct users where to make appeals" - ) - """Complaints Guide""" +class GroupConfig(BaseModel): + active_threshold: int = Field(default=7, description="活跃检查阈值") + """Active Threshold""" + ban_words: list[str] = Field(default=list, description="违禁词列表") + """Ban Words""" + pre_check_regex: list[str] = Field(default=list, description="预检正则列表") + """Pre Check Regex""" + skip_message_type: list[str] = Field(default=list, description="跳过消息类型") + """不会被检查的消息类型""" + ban_language: list[str] = Field(default=list, description="被禁止的语言地区") + """Ban Language""" model_config = ConfigDict(extra="ignore") -class PolicyManager: +class GroupConfigManager: def __init__(self): self.cache = global_cache_runtime.get_client() @@ -37,17 +38,17 @@ def __init__(self): def prefix(key: str) -> str: return f"{AREA}:{key}" - async def read(self, group_id: str) -> PolicyRule: - data = await self.cache.read_data(self.prefix(group_id)) + async def read(self, chat_id: str) -> GroupConfig: + data = await self.cache.read_data(self.prefix(chat_id)) try: - return PolicyRule.model_validate(data) + return GroupConfig.model_validate(data) except Exception as exc: logger.debug(f"PolicyManager.read: {exc}") - return PolicyRule() + return GroupConfig() - async def save(self, group_id: str, data: PolicyRule): - await self.cache.set_data(self.prefix(group_id), data.model_dump_json()) + async def save(self, chat_id: str, data: GroupConfig): + await self.cache.set_data(self.prefix(chat_id), data.model_dump_json()) return True -globalGroupPolicy = PolicyManager() +globalGroupConfig = GroupConfigManager() diff --git a/webapp/src/App.vue b/webapp/src/App.vue index 15f6c97..d4cd9bf 100644 --- a/webapp/src/App.vue +++ b/webapp/src/App.vue @@ -4,7 +4,13 @@ import {useRoute} from 'vue-router'; import axios from 'axios'; import VueTurnstile from 'vue-turnstile'; import Puzzles from "./components/Puzzles.vue"; -import {useWebApp, useWebAppBiometricManager, useWebAppNavigation, useWebAppPopup} from "vue-tg"; +import { + useWebApp, + useWebAppBiometricManager, + useWebAppHapticFeedback, + useWebAppNavigation, + useWebAppPopup +} from "vue-tg"; import {useGyroscopeExists} from "./hook/useGyroscopeExists.ts"; import {useAccelerometerExists} from "./hook/useAccelerometerExists.ts"; import CryptoJS from 'crypto-js'; @@ -14,6 +20,7 @@ import {useI18n} from 'vue-i18n'; const {t} = useI18n(); const route = useRoute(); const {openLink} = useWebAppNavigation() +const {notificationOccurred} = useWebAppHapticFeedback() enum AuthType { POW = 'pow', @@ -143,6 +150,7 @@ const openAuthSettings = () => { } // 生物识别验证 const authBiometric = () => { + notificationOccurred("success") const biometricCallback = (is_authed: boolean, auth_token?: (string | undefined)) => { if (is_authed) { console.log('Biometric authenticated') diff --git a/webapp/tsconfig.app.json b/webapp/tsconfig.app.json index 8915c31..af25c1c 100644 --- a/webapp/tsconfig.app.json +++ b/webapp/tsconfig.app.json @@ -23,7 +23,8 @@ "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, - "noUncheckedSideEffectImports": true + "noUncheckedSideEffectImports": true, + "allowSyntheticDefaultImports": true }, "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"] }