diff --git a/.github/workflows/build.py b/.github/workflows/build.py
new file mode 100644
index 0000000..c3a9b19
--- /dev/null
+++ b/.github/workflows/build.py
@@ -0,0 +1,17 @@
+import yapf_third_party
+
+params = [
+ "--windowed",
+ "--onefile",
+ "--add-data",
+ "static:static",
+ "--add-data",
+ f'{yapf_third_party.__file__.replace("__init__.py", "")}:yapf_third_party',
+ "--clean",
+ "--noconfirm",
+ "client.py",
+]
+
+from PyInstaller import __main__ as pyi
+
+pyi.run(params)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index fa641ba..70f38c8 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -41,13 +41,12 @@ jobs:
- name: Install dependencies
run: |
pip install -r requirements.txt
- pip install pywebview
pip install pyinstaller
pip install pillow
- name: Build executable
run: |
- python build.py
+ python .github/workflows/build.py
- name: Upload executables
uses: actions/upload-release-asset@v1
@@ -77,13 +76,12 @@ jobs:
- name: Install dependencies
run: |
pip install -r requirements.txt
- pip install pywebview
pip install pyinstaller
pip install pillow
- name: Build executable
run: |
- pyinstaller -w -F --add-data static:static client.py
+ python .github/workflows/build.py
if [[ "${{ matrix.os }}" == "macos-latest" ]]; then
zip -r -X client-macos.zip ./dist/client.app
fi
diff --git a/.github/workflows/update_readme.py b/.github/workflows/update_readme.py
index f3de8aa..2941530 100644
--- a/.github/workflows/update_readme.py
+++ b/.github/workflows/update_readme.py
@@ -7,50 +7,56 @@
def update_readme():
# 获取环境变量
- repo = os.environ.get('REPO_NAME')
- readme_path = os.environ.get('README_PATH')
+ repo = os.environ.get("REPO_NAME")
+ readme_path = os.environ.get("README_PATH")
# 获取贡献者信息和头像 URL
- response = requests.get(f'https://api.github.com/repos/{repo}/contributors')
+ response = requests.get(f"https://api.github.com/repos/{repo}/contributors")
contributors_data = response.json()
- contributors_md = ''
+ contributors_md = ""
for contributor in contributors_data:
- if contributor['type'] != "User":
+ if contributor["type"] != "User":
continue
- login = contributor['login']
- avatar_url = contributor['avatar_url']
- html_url = contributor['html_url']
- contributions = contributor['contributions']
- contributor_md = f'
' \
- f'
' \
- f'
{login}
Contributions: {contributions}
'
+ login = contributor["login"]
+ avatar_url = contributor["avatar_url"]
+ html_url = contributor["html_url"]
+ contributions = contributor["contributions"]
+ contributor_md = (
+ f''
+ f'
'
+ f"
{login}
Contributions: {contributions}
"
+ )
contributors_md += contributor_md
# 更新 README 文件
- with open(readme_path, 'r') as f:
+ with open(readme_path, "r") as f:
readme_content = f.read()
# 定义要进行匹配和替换的正则表达式模式,使用括号分组
- pattern = re.compile(r'.*', re.DOTALL)
+ pattern = re.compile(
+ r".*", re.DOTALL
+ )
# 定义要替换的字符串
- replacement = f'' \
- f'\n{contributors_md}\n
' \
- f''
+ replacement = (
+ f""
+ f'\n{contributors_md}\n
'
+ f""
+ )
# 使用正则表达式进行匹配和替换
new_readme_content = pattern.sub(replacement, readme_content)
# 提交更改
if new_readme_content != readme_content:
- with open(readme_path, 'w') as f:
+ with open(readme_path, "w") as f:
f.write(new_readme_content)
- commit_message = f'CI: Update README (contributors: {len(contributors_data)})'
- subprocess.run(['git', 'add', readme_path])
- subprocess.run(['git', 'commit', '-m', commit_message])
- subprocess.run(['git', 'push'])
+ commit_message = f"CI: Update README (contributors: {len(contributors_data)})"
+ subprocess.run(["git", "add", readme_path])
+ subprocess.run(["git", "commit", "-m", commit_message])
+ subprocess.run(["git", "push"])
else:
print("no change")
diff --git a/README.md b/README.md
index dad4a66..1c567a6 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,7 @@
3. [fastapi-crudrouter](https://fastapi-crudrouter.awtkns.com/) 内部通过add_router方式注册路由,虽然代码减少了,但是灵活性变低了
4. 或该更多的使用表之间[逻辑关联](https://www.zhihu.com/question/20006142)
-# 上图
-![home](image/home.png)
-![conf](image/conf.png)
-![model_code](image/model_code.png)
-![router_code](image/router_code.png)
-![db_code](image/db_code.png)
+
# 使用项目
> 桌面端请在Release处下载
diff --git a/build.py b/build.py
deleted file mode 100644
index ded5694..0000000
--- a/build.py
+++ /dev/null
@@ -1,28 +0,0 @@
-import platform
-
-import yapf_third_party
-
-params = [
- '--windowed',
- '--onefile',
- '--add-data', 'static:static',
- '--add-data', f'{yapf_third_party.__file__.replace("__init__.py", "")}:yapf_third_party',
- '--clean',
- '--noconfirm',
- 'client.py',
-]
-
-current_os = platform.system()
-
-from PyInstaller import __main__ as pyi
-
-params.append("--icon"),
-if current_os == "Windows":
- params.append("static/logo.icns")
- path = "./dist/client.exe"
-else:
- params.append("static/logo.icon")
- path = "./dist/client"
-
-pyi.run(params)
-print(path)
\ No newline at end of file
diff --git a/client.py b/client.py
deleted file mode 100644
index 721adf0..0000000
--- a/client.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import threading
-
-import uvicorn
-import webview
-
-import socket
-import random
-
-from main import app
-
-
-def get_unused_port():
- """获取未被使用的端口"""
- while True:
- port = random.randint(1024, 65535) # 端口范围一般为1024-65535
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- try:
- sock.bind(("localhost", port))
- sock.close()
- return port
- except OSError:
- pass
-
-
-def desktop_client():
- port = get_unused_port()
- t = threading.Thread(target=uvicorn.run, args=(app,), kwargs={"port": port})
- t.daemon = True
- t.start()
- webview.create_window("DFS代码生成", url=f"http://127.0.0.1:{port}")
- webview.start(debug=True)
-
-
-if __name__ == "__main__":
- desktop_client()
diff --git a/entity.py b/entity.py
deleted file mode 100644
index 5fe7286..0000000
--- a/entity.py
+++ /dev/null
@@ -1,107 +0,0 @@
-import uuid
-from typing import Generic, List, Optional, TypeVar
-
-from yapf.yapflib.yapf_api import FormatCode
-import isort
-from pydantic import BaseModel, ConfigDict, field_serializer
-from pydantic.alias_generators import to_camel
-from sqlmodel import Field, MetaData, Session, SQLModel, create_engine, select
-
-db_uri = "sqlite:///main.sqlite"
-engine = create_engine(db_uri)
-
-
-def get_metadata_by_db_uri(uri: str):
- db_engine = create_engine(uri)
- db_metadata = MetaData()
- db_metadata.reflect(bind=db_engine)
- return db_metadata
-
-
-class Conf(SQLModel, table=True):
- __tablename__ = "dfs_conf"
- id: int = Field(None, primary_key=True)
- db_uri: str = Field(..., description="数据库连接")
-
- @classmethod
- def get_db_uri_last_new(cls):
- """获取最新的db_url"""
- with Session(engine) as session:
- query = select(cls).order_by(cls.id.desc())
- latest_conf = session.exec(query).first()
- if latest_conf:
- return latest_conf.db_uri
- else:
- return None
-
- @classmethod
- def create(cls, uri) -> "Conf":
- with Session(engine) as session:
- obj = cls(db_uri=uri)
- session.add(obj)
- session.commit()
- session.refresh(obj)
- return obj
-
- @classmethod
- def get_last_uri_with_metadata(cls):
- uri = cls.get_db_uri_last_new()
- return uri, get_metadata_by_db_uri(uri)
-
-
-SQLModel.metadata.create_all(engine)
-
-
-T = TypeVar("T")
-
-
-class R(BaseModel, Generic[T]):
- code: int = 20000
- msg: str = "ok"
- data: Optional[T] = None
-
- @classmethod
- def success(cls, **kwargs):
- return cls(**kwargs)
-
- @classmethod
- def error(cls, msg):
- return cls(code=40000, msg=msg)
-
-
-class RList(R[T]):
- data: List[T] = Field(default_factory=list)
-
-
-class BaseVo(SQLModel):
- key: uuid.UUID = Field(default_factory=uuid.uuid4)
- model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
-
-
-class Table(BaseVo):
- table_name: str
- table_comment: Optional[str] = None
-
-
-class DBConf(SQLModel):
- user: str
- password: str
- port: int
- host: str
- db: str
-
- def get_db_uri(self):
- return f"mysql+pymysql://{self.user}:{self.password}@{self.host}:{self.port}/{self.db}"
-
- def get_metadata(self):
- return get_metadata_by_db_uri(self.get_db_uri())
-
-
-class CodeGen(BaseVo):
- name: str
- code: str
-
- @field_serializer("code")
- def serialize_code(self, code: str, _info):
- _code = FormatCode(code, style_config="pep8")[0]
- return isort.code(_code)
diff --git a/generate/__init__.py b/generate/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/generate/main.py b/generate/main.py
deleted file mode 100644
index 077ea3b..0000000
--- a/generate/main.py
+++ /dev/null
@@ -1,100 +0,0 @@
-from generate.model import GenerateEntity, Table, to_pascal
-
-main_template = """
-from fastapi import FastAPI
-from fastapi.openapi.docs import get_swagger_ui_html
-
-from router import {table_name}_router
-
-app = FastAPI()
-
-
-@app.get("/docs", include_in_schema=False)
-def docs():
- return get_swagger_ui_html(
- swagger_js_url="https://cdn.bootcdn.net/ajax/libs/swagger-ui/5.6.2/swagger-ui-bundle.min.js",
- swagger_css_url="https://cdn.bootcdn.net/ajax/libs/swagger-ui/5.6.2/swagger-ui.min.css"
- )
-
-
-app.include_router({table_name}_router)
-
-if __name__ == '__main__':
- import uvicorn
- uvicorn.run("main:app", reload=True, port=5000)
-
-"""
-
-
-def render_main(table_name):
- return main_template.format(table_name=table_name)
-
-
-db_template = """
-from sqlmodel import create_engine
-
-db_uri = "{db_uri}"
-
-engine = create_engine(db_uri)
-"""
-
-
-def render_db(db_uri):
- """数据库链接- sqlalchemy"""
- return db_template.format(db_uri=db_uri)
-
-
-router_template = """
-from fastapi import APIRouter, Depends
-from sqlmodel import Session
-from model import {pascal_name}DTO, {pascal_name}, Result, PageResult, {pascal_name}Query
-from db import engine
-
-{table_name}_router = APIRouter(prefix="/{table_name}", tags=["{table_name}"])
-
-@{table_name}_router.get("/{id}", summary="通过ID查询详情")
-def query_{table_name}_by_id(id: int) -> Result[{pascal_name}]:
- with Session(engine) as session:
- return Result.ok({pascal_name}.query_by_id(session, id))
-
-@{table_name}_router.get("", summary="分页条件查询")
-def query_{table_name}_all_by_limit(query: {pascal_name}Query = Depends()) -> PageResult[{pascal_name}]:
- with Session(engine) as session:
- total = {pascal_name}.count(session, **query.count_kwargs(exclude_none=True))
- data = {pascal_name}.query_all_by_limit(session, **query.model_dump(exclude_none=True))
- return PageResult.ok(data=data, total=total)
-
-
-@{table_name}_router.post("", summary="新增数据")
-def create_{table_name}(instance: {pascal_name}DTO) -> Result[{pascal_name}]:
- with Session(engine) as session:
- return Result.ok({pascal_name}.create(session, instance))
-
-
-@{table_name}_router.patch("/{id}", summary="更新数据")
-def update_{table_name}_by_id(id: int, instance: {pascal_name}DTO) -> Result[{pascal_name}]:
- with Session(engine) as session:
- return Result.ok({pascal_name}.update(session, id, instance))
-
-
-@{table_name}_router.delete("/{id}", summary="删除数据")
-def delete_{table_name}_by_id(id: int) -> Result[{pascal_name}]:
- with Session(engine) as session:
- return Result.ok({pascal_name}.delete_by_id(session, id))
-"""
-
-
-def render_router(table_name):
- router_code = router_template.format(
- table_name=table_name, pascal_name=to_pascal(table_name), id="{id}"
- )
- return router_code
-
-
-def generate_code(table: Table, uri: str):
- return [
- {"name": "model.py", "code": GenerateEntity(table).render()},
- {"name": "router.py", "code": render_router(table.name)},
- {"name": "main.py", "code": render_main(table.name)},
- {"name": "db.py", "code": render_db(uri)},
- ]
diff --git a/generate/model.py b/generate/model.py
deleted file mode 100644
index 800a20b..0000000
--- a/generate/model.py
+++ /dev/null
@@ -1,274 +0,0 @@
-from typing import Any, Dict, Sequence
-
-from pydantic.alias_generators import to_pascal
-from sqlmodel import DATETIME, Column, Table
-
-
-class GenerateEntity:
- template = """
-{imports}
-from typing import Generic, TypeVar, List, Optional
-from sqlmodel import Session, SQLModel,select, func, Field
-from pydantic import BaseModel
-from pydantic.alias_generators import to_camel
-T = TypeVar('T')
-class Result(BaseModel, Generic[T]):
- success: bool = Field(..., description="是否成功")
- message: str = Field(..., description="额外消息")
- data: Optional[T] = Field(None, description="响应数据")
-
- @classmethod
- def ok(cls, data: T, message: str="成功"):
- return cls(data=data, message=message, success=True)
-
- @classmethod
- def error(cls, message: str = "失败"):
- return cls(data=None, message=message, success=False)
-
-class PageResult(Result[T]):
- total: int = Field(0, description="数据总数")
- data: List[T] = Field(default_factory=list, description="响应数据")
-
- @classmethod
- def ok(cls, data: List[T], total: int, message: str = "成功"):
- return cls(data=data, total=total, message=message, success=True)
-
-class {table_name}DTO(SQLModel):
-{dto_fields}
-class {table_name}Query({table_name}DTO):
- page_number: int = Field(1, description="页码")
- page_size: int = Field(10, description="页量")
-{query_fields}
-
- def count_kwargs(self, **kwargs):
- default_exclude = {default_exclude}
- if v := kwargs.get("exclude"):
- default_exclude.union(v)
- data = self.model_dump(exclude=default_exclude, **kwargs)
- return data
-
-class {table_name}({table_name}DTO, table=True):\n{do_fields}\n
- @classmethod
- def create(cls, session: Session, obj_in: {table_name}DTO) -> "{table_name}":
- obj = cls(**obj_in.dict())
- session.add(obj)
- session.commit()
- session.refresh(obj)
- return obj
-
- @classmethod
- def query_by_id(cls, session: Session, id: int) -> Optional["{table_name}"]:
- return session.get(cls, id)
-
- @classmethod
- def update(cls, session: Session, id: int, obj_in: {table_name}DTO) -> Optional["{table_name}"]:
- obj = cls.query_by_id(session, id)
- if obj:
- for field, value in obj_in.dict(exclude_unset=True).items():
- setattr(obj, field, value)
- session.add(obj)
- session.commit()
- session.refresh(obj)
- return obj
-
- @classmethod
- def delete_by_id(cls, session: Session, id: int) -> Optional["{table_name}"]:
- obj = session.get(cls, id)
- if obj:
- session.delete(obj)
- session.commit()
- return obj
-
- @classmethod
- def count(cls, session: Session, **kwargs) -> int:
- return session.scalar(
- select(func.count()).
- select_from({table_name}).filter_by(**kwargs)
-)
-
- @classmethod
- def query_all_by_limit(cls, session: Session, page_number: int, page_size: int, **kwargs) -> List["{table_name}"]:
- stmt = select(cls).filter_by(**kwargs).offset((page_number - 1) * page_size).limit(page_size)
- return session.exec(stmt).all()
- """
-
- def __init__(self, table: Table):
- self.table = table
- self.do_fields = []
- self.dto_fields = []
- self.query_fields = []
- self.imports = set()
- self.indent = " " * 4
-
- def _column_type_parse(self, column: Column):
- """
- 解析column type
- """
- python_type = column.type.python_type
- module_name = python_type.__module__
- class_name = python_type.__name__
- if module_name not in ["__builtin__", "builtins"]:
- self.imports.add(f"from {module_name} import {class_name}")
-
- c_type = column.type.__dict__
- kwargs = {}
- if v := c_type.get("length"):
- kwargs["max_length"] = v
- if v := c_type.get("precision"):
- kwargs["max_digits"] = v
- if v := c_type.get("scale"):
- kwargs["decimal_places"] = v
- if class_name == "dict":
- self.imports.add("from sqlmodel import JSON")
- kwargs["sa_type"] = "JSON"
- return kwargs
-
- def _column_default_datetime(self, text: str):
- """https://github.com/tiangolo/sqlmodel/issues/594"""
- _current = "CURRENT_TIMESTAMP"
- if _current in text and "ON UPDATE" in text:
- self.imports.add("from sqlmodel import func, DateTime, Column")
- return {"sa_column": "Column(DateTime(), onupdate=func.now())"}
- if _current in text:
- return {"default_factory": "datetime.utcnow"}
- return {"default": text}
-
- def _column_default_parse(self, column: Column):
- """解析 column 默认值"""
- if column.server_default:
- text = column.server_default.arg.text
- if isinstance(column.type, DATETIME):
- return self._column_default_datetime(text)
- elif column.type.python_type.__name__ == "int":
- return {"default": text.replace("'", "")}
- else:
- return {"default": text}
-
- def field_all_attrs(self, column: Column) -> dict:
- kwargs = {"default": None, **self._column_type_parse(column)}
-
- # 是否可以为空
- if v := column.nullable:
- kwargs["nullable"] = v
- else:
- kwargs["default"] = "..."
-
- # 默认值
- if v := self._column_default_parse(column):
- kwargs.update(v)
- # 主键
- if column.primary_key:
- kwargs["primary_key"] = True
- kwargs["default"] = None
-
- # 索引
- if column.index:
- kwargs["index"] = True
-
- # 唯一
- if column.unique:
- kwargs["unique"] = True
-
- # 描述
- if desc := column.comment:
- kwargs["description"] = '"' + desc + '"'
-
- if "default_factory" in kwargs:
- kwargs.pop("default")
-
- if "sa_column" in kwargs:
- kwargs.pop("nullable")
- return kwargs
-
- def get_field_repr(
- self, field_name: str, field_type: str, field_attrs: Dict[str, Any]
- ) -> str:
- """字段信息
- https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/?h=optional#optional-fields-nullable-columns
- :param field_name: 字段名称
- :param field_type: 字段类型
- :param field_attrs: 字段其他属性
- return name: str = Field(..., max_length=22)
- """
- if (
- "func.now" not in field_attrs.get("sa_column", "")
- and field_attrs.get("default", "") is None
- ):
- field_type = f"Optional[{field_type}]"
-
- head = f"{field_name}:{field_type}=Field("
- tail = ",".join(f"{k}={v}" for k, v in field_attrs.items()) + ")"
- return head + tail
-
- def get_optional_field_repr(
- self, field_name: str, field_type: str, field_attrs: Dict[str, Any]
- ) -> str:
- if field_attrs.get("default") is None:
- field_type = f"Optional[{field_type}]"
-
- head = f"{field_name}:{field_type}=Field("
- tail = ",".join(f"{k}={v}" for k, v in field_attrs.items()) + ")"
- return head + tail
-
- def _add_query_field(
- self, filed_name: str, field_type: str, kwargs: Dict[str, Any]
- ):
- _qf_kwargs = {"default": None}
- for k, v in kwargs.items():
- if k in ["max_length", "max_digits", "decimal_places", "description"]:
- _qf_kwargs[k] = v
- self.query_fields.append(
- self.get_optional_field_repr(filed_name, field_type, _qf_kwargs)
- )
-
- def add_field_by_column(self, column: Column):
- field_name = column.name
- field_type = column.type.python_type.__name__
- field_attrs = self.field_all_attrs(column)
- field_repr = self.get_field_repr(field_name, field_type, field_attrs)
- if column.primary_key:
- self.do_fields.append(field_repr)
- else:
- self.dto_fields.append(field_repr)
- if (
- not column.nullable
- or "datetime.utcnow" in field_repr
- or "func.now" in field_repr
- ):
- self._add_query_field(field_name, field_type, field_attrs)
-
- def add_dto_head_field(self):
- do_annotation = f'"""{self.table.comment or self.table.description}"""'
- do_metadata = f'__tablename__ = "{self.table.name}"'
- self.do_fields.append(do_annotation)
- self.do_fields.append(do_metadata)
-
- def add_do_tail_field(self):
- self.imports.add("from pydantic.alias_generators import to_camel")
- self.imports.add("from sqlmodel import SQLModel, Field")
- self.dto_fields.append(
- 'model_config = {"alias_generator": to_camel, "populate_by_name": True}'
- )
-
- def render_fields_str(self, fields: Sequence[str], use_indent=True) -> str:
- if use_indent:
- return "\n".join(self.indent + field for field in fields)
- else:
- return "\n".join(field for field in fields)
-
- def render(self) -> str:
- """生成model code"""
- self.add_dto_head_field()
- for column in self.table.columns:
- self.add_field_by_column(column)
- self.add_do_tail_field()
- kwargs = {
- "table_name": to_pascal(self.table.name),
- "imports": self.render_fields_str(self.imports, use_indent=False),
- "dto_fields": self.render_fields_str(self.dto_fields),
- "do_fields": self.render_fields_str(self.do_fields),
- "query_fields": self.render_fields_str(self.query_fields),
- "default_exclude": "{'page_number', 'page_size'}",
- }
-
- return self.template.format(**kwargs)
diff --git a/image/conf.png b/image/conf.png
deleted file mode 100644
index 0bcfcb7..0000000
Binary files a/image/conf.png and /dev/null differ
diff --git a/image/db_code.png b/image/db_code.png
deleted file mode 100644
index da79598..0000000
Binary files a/image/db_code.png and /dev/null differ
diff --git a/image/home.png b/image/home.png
deleted file mode 100644
index ff353d8..0000000
Binary files a/image/home.png and /dev/null differ
diff --git a/image/main_code.png b/image/main_code.png
deleted file mode 100644
index 20a044e..0000000
Binary files a/image/main_code.png and /dev/null differ
diff --git a/image/model_code.png b/image/model_code.png
deleted file mode 100644
index bcf5c76..0000000
Binary files a/image/model_code.png and /dev/null differ
diff --git a/image/router_code.png b/image/router_code.png
deleted file mode 100644
index ac0ac8a..0000000
Binary files a/image/router_code.png and /dev/null differ
diff --git a/main.py b/main.py
index b51dc85..ec5ccd8 100644
--- a/main.py
+++ b/main.py
@@ -1,28 +1,333 @@
import os
+import uuid
+from typing import Any, Dict, Generic, List, Optional, Sequence, TypeVar
+import isort
from fastapi import FastAPI, Query
from fastapi.requests import Request
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
-import pkg_resources
+from jinja2 import Environment, FileSystemLoader
+from pydantic import BaseModel, ConfigDict, field_serializer
+from pydantic.alias_generators import to_camel, to_pascal, to_snake
+from sqlmodel import (DATETIME, Column, Field, MetaData, Session, SQLModel,
+ Table, create_engine, select)
+from yapf.yapflib.yapf_api import FormatCode
-from entity import CodeGen, Conf, DBConf, R, RList, Table
-from generate.main import generate_code
+class Analysis:
-app = FastAPI(title="dfs-generate", description="FastAPI SQLModel 逆向生成代码")
+ def __init__(self, table: Table):
+ self.table = table
+ self.do_fields = []
+ self.dto_fields = []
+ self.query_fields = []
+ self.imports = set()
+ def _column_type_parse(self, column: Column):
+ """
+ 解析column type
+ """
+ python_type = column.type.python_type
+ module_name = python_type.__module__
+ class_name = python_type.__name__
+ if module_name not in ["__builtin__", "builtins"]:
+ self.imports.add(f"from {module_name} import {class_name}")
-# 解决打包桌面程序static找不到
-static_path = pkg_resources.resource_filename(__name__, "static")
+ c_type = column.type.__dict__
+ kwargs = {}
+ if v := c_type.get("length"):
+ kwargs["max_length"] = v
+ if v := c_type.get("precision"):
+ kwargs["max_digits"] = v
+ if v := c_type.get("scale"):
+ kwargs["decimal_places"] = v
+ if class_name == "dict":
+ self.imports.add("from sqlmodel import JSON")
+ kwargs["sa_type"] = "JSON"
+ return kwargs
+
+ def _column_default_datetime(self, text: str):
+ """https://github.com/tiangolo/sqlmodel/issues/594"""
+ _current = "CURRENT_TIMESTAMP"
+ if _current in text and "ON UPDATE" in text:
+ self.imports.add("from sqlmodel import func, DateTime, Column")
+ return {"sa_column": "Column(DateTime(), onupdate=func.now())"}
+ if _current in text:
+ return {"default_factory": "datetime.utcnow"}
+ return {"default": text}
+
+ def _column_default_parse(self, column: Column):
+ """解析 column 默认值"""
+ if column.server_default:
+ text = column.server_default.arg.text
+ if isinstance(column.type, DATETIME):
+ return self._column_default_datetime(text)
+ elif column.type.python_type.__name__ == "int":
+ return {"default": text.replace("'", "")}
+ else:
+ return {"default": text}
+
+ def field_all_attrs(self, column: Column) -> dict:
+ kwargs = {"default": None, **self._column_type_parse(column)}
+
+ # 是否可以为空
+ if v := column.nullable:
+ kwargs["nullable"] = v
+ else:
+ kwargs["default"] = "..."
+
+ # 默认值
+ if v := self._column_default_parse(column):
+ kwargs.update(v)
+ # 主键
+ if column.primary_key:
+ kwargs["primary_key"] = True
+ kwargs["default"] = None
+
+ # 索引
+ if column.index:
+ kwargs["index"] = True
+
+ # 唯一
+ if column.unique:
+ kwargs["unique"] = True
+
+ # 描述
+ if desc := column.comment:
+ kwargs["description"] = '"' + desc + '"'
+
+ if "default_factory" in kwargs:
+ kwargs.pop("default")
+
+ if "sa_column" in kwargs:
+ kwargs.pop("nullable")
+ return kwargs
+
+ def get_field_repr(
+ self, field_name: str, field_type: str, field_attrs: Dict[str, Any]
+ ) -> str:
+ """字段信息
+ https://sqlmodel.tiangolo.com/tutorial/create-db-and-table/?h=optional#optional-fields-nullable-columns
+ :param field_name: 字段名称
+ :param field_type: 字段类型
+ :param field_attrs: 字段其他属性
+ return name: str = Field(..., max_length=22)
+ """
+ if (
+ "func.now" not in field_attrs.get("sa_column", "")
+ and field_attrs.get("default", "") is None
+ ):
+ field_type = f"Optional[{field_type}]"
+
+ head = f"{field_name}:{field_type}=Field("
+ tail = ",".join(f"{k}={v}" for k, v in field_attrs.items()) + ")"
+ return head + tail
+
+ def get_optional_field_repr(
+ self, field_name: str, field_type: str, field_attrs: Dict[str, Any]
+ ) -> str:
+ if field_attrs.get("default") is None:
+ field_type = f"Optional[{field_type}]"
+
+ head = f"{field_name}:{field_type}=Field("
+ tail = ",".join(f"{k}={v}" for k, v in field_attrs.items()) + ")"
+ return head + tail
+
+ def _add_query_field(
+ self, filed_name: str, field_type: str, kwargs: Dict[str, Any]
+ ):
+ _qf_kwargs = {"default": None}
+ for k, v in kwargs.items():
+ if k in ["max_length", "max_digits", "decimal_places", "description"]:
+ _qf_kwargs[k] = v
+ self.query_fields.append(
+ self.get_optional_field_repr(filed_name, field_type, _qf_kwargs)
+ )
+
+ def add_field_by_column(self, column: Column):
+ field_name = column.name
+ field_type = column.type.python_type.__name__
+ field_attrs = self.field_all_attrs(column)
+ field_repr = self.get_field_repr(field_name, field_type, field_attrs)
+ if column.primary_key:
+ self.do_fields.append(field_repr)
+ else:
+ self.dto_fields.append(field_repr)
+ if (
+ not column.nullable
+ or "datetime.utcnow" in field_repr
+ or "func.now" in field_repr
+ ):
+ self._add_query_field(field_name, field_type, field_attrs)
+
+ def add_dto_head_field(self):
+ do_annotation = f'"""{self.table.comment or self.table.description}"""'
+ do_metadata = f'__tablename__ = "{self.table.name}"'
+ self.do_fields.append(do_annotation)
+ self.do_fields.append(do_metadata)
+
+ def add_do_tail_field(self):
+ self.imports.add("from pydantic.alias_generators import to_camel")
+ self.imports.add("from sqlmodel import SQLModel, Field")
+ self.dto_fields.append(
+ 'model_config = {"alias_generator": to_camel, "populate_by_name": True}'
+ )
+
+ def render_fields_str(self, fields: Sequence[str], use_indent=True) -> str:
+ if use_indent:
+ return "\n".join(self.indent + field for field in fields)
+ else:
+ return "\n".join(field for field in fields)
+
+ def render(self):
+ """生成model code"""
+ self.add_dto_head_field()
+ for column in self.table.columns:
+ self.add_field_by_column(column)
+ self.add_do_tail_field()
+ return {
+ "table_name": self.table.name,
+ "imports": self.imports,
+ "dto_fields": self.dto_fields,
+ "do_fields": self.do_fields,
+ "query_fields": self.query_fields,
+ "default_exclude": "{'page_number', 'page_size'}",
+ }
+
+
+env = Environment(loader=FileSystemLoader("templates"))
+env.filters["to_snake"] = to_snake
+env.filters["to_pascal"] = to_pascal
+
+
+def generate_code(table: Table, uri: str):
+ name = {"table": table.name}
+ main = env.get_template("main.j2").render(name)
+ router = env.get_template("router.j2").render(name)
+ db = env.get_template("db.j2").render({"uri": uri})
+ model = env.get_template("model.j2").render(Analysis(table).render())
+
+ return [
+ {"name": "model.py", "code": model},
+ {"name": "router.py", "code": router},
+ {"name": "main.py", "code": main},
+ {"name": "db.py", "code": db},
+ ]
+
+
+db_uri = "sqlite:///main.sqlite"
+engine = create_engine(db_uri)
+
+
+def get_metadata_by_db_uri(uri: str):
+ db_engine = create_engine(uri)
+ db_metadata = MetaData()
+ db_metadata.reflect(bind=db_engine)
+ return db_metadata
+
+
+class Conf(SQLModel, table=True):
+ __tablename__ = "dfs_conf"
+ id: int = Field(None, primary_key=True)
+ db_uri: str = Field(..., description="数据库连接")
+
+ @classmethod
+ def get_db_uri_last_new(cls):
+ """获取最新的db_url"""
+ with Session(engine) as session:
+ query = select(cls).order_by(cls.id.desc())
+ latest_conf = session.exec(query).first()
+ if latest_conf:
+ return latest_conf.db_uri
+ else:
+ return None
+
+ @classmethod
+ def create(cls, uri) -> "Conf":
+ with Session(engine) as session:
+ obj = cls(db_uri=uri)
+ session.add(obj)
+ session.commit()
+ session.refresh(obj)
+ return obj
+
+ @classmethod
+ def get_last_uri_with_metadata(cls):
+ uri = cls.get_db_uri_last_new()
+ return uri, get_metadata_by_db_uri(uri)
-app.mount("/static", StaticFiles(directory=static_path), name="static")
+SQLModel.metadata.create_all(engine)
+
+T = TypeVar("T")
+
+
+class R(BaseModel, Generic[T]):
+ code: int = 20000
+ msg: str = "ok"
+ data: Optional[T] = None
+
+ @classmethod
+ def success(cls, **kwargs):
+ return cls(**kwargs)
+
+ @classmethod
+ def error(cls, msg):
+ return cls(code=40000, msg=msg)
+
+
+class RList(R[T]):
+ data: List[T] = Field(default_factory=list)
+
+
+class BaseVo(SQLModel):
+ key: uuid.UUID = Field(default_factory=uuid.uuid4)
+ model_config = ConfigDict(alias_generator=to_camel, populate_by_name=True)
+
+
+class Table(BaseVo):
+ table_name: str
+ table_comment: Optional[str] = None
+
+
+class DBConf(SQLModel):
+ user: str
+ password: str
+ port: int
+ host: str
+ db: str
+
+ def get_db_uri(self):
+ return f"mysql+pymysql://{self.user}:{self.password}@{self.host}:{self.port}/{self.db}"
+
+ def get_metadata(self):
+ return get_metadata_by_db_uri(self.get_db_uri())
+
+
+class CodeGen(BaseVo):
+ name: str
+ code: str
+
+ @field_serializer("code")
+ def serialize_code(self, code: str, _info):
+ _code = FormatCode(code, style_config="pep8")[0]
+ return isort.code(_code)
+
+
+### API
+
+app = FastAPI(title="dfs-generate", description="FastAPI SQLModel 逆向生成代码")
+
+# 解决打包桌面程序static找不到
+static_file_abspath = os.path.join(os.path.dirname(__file__), "static")
+
+app.mount("/static", StaticFiles(directory=static_file_abspath), name="static")
@app.get("/", include_in_schema=False)
def index():
- return FileResponse(os.path.join(static_path, "index.html"))
+ return FileResponse(f"{static_file_abspath}/index.html")
@app.get("/tables", response_model=RList[Table])
@@ -68,3 +373,39 @@ def change_db(conf: DBConf):
except Exception as e:
print(e)
return R.error(msg="请确认信息是否填写正确")
+
+
+import random
+import socket
+import threading
+
+import uvicorn
+import webview
+
+# client
+
+
+def get_unused_port():
+ """获取未被使用的端口"""
+ while True:
+ port = random.randint(1024, 65535) # 端口范围一般为1024-65535
+ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ sock.bind(("localhost", port))
+ sock.close()
+ return port
+ except OSError:
+ pass
+
+
+def desktop_client():
+ port = get_unused_port()
+ t = threading.Thread(target=uvicorn.run, args=(app,), kwargs={"port": port})
+ t.daemon = True
+ t.start()
+ webview.create_window("DFS代码生成", url=f"http://127.0.0.1:{port}")
+ webview.start()
+
+
+if __name__ == "__main__":
+ desktop_client()
diff --git a/main.sqlite b/main.sqlite
new file mode 100644
index 0000000..20ccce0
Binary files /dev/null and b/main.sqlite differ
diff --git a/requirements.txt b/requirements.txt
index 6f9cf4d..9e17d83 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -4,3 +4,5 @@ PyMySQL==1.1.0
isort==5.13.2
uvicorn==0.24.0.post1
yapf==0.40.2
+pywebview==5.0.5
+Jinja2==3.1.3
diff --git a/templates/db.j2 b/templates/db.j2
new file mode 100644
index 0000000..fc0174d
--- /dev/null
+++ b/templates/db.j2
@@ -0,0 +1,5 @@
+from sqlmodel import create_engine
+
+db_uri = "{{uri}}"
+
+engine = create_engine(db_uri)
\ No newline at end of file
diff --git a/templates/main.j2 b/templates/main.j2
new file mode 100644
index 0000000..3708500
--- /dev/null
+++ b/templates/main.j2
@@ -0,0 +1,12 @@
+from fastapi import FastAPI
+
+from router import {{table | to_snake}}_router
+
+app = FastAPI()
+
+
+app.include_router({{table | to_snake}}_router)
+
+if __name__ == '__main__':
+ import uvicorn
+ uvicorn.run("main:app", reload=True, port=5000)
\ No newline at end of file
diff --git a/templates/model.j2 b/templates/model.j2
new file mode 100644
index 0000000..558bbcf
--- /dev/null
+++ b/templates/model.j2
@@ -0,0 +1,96 @@
+{# 模型类 、请求输入 输出模型#}
+{% for import in imports %}
+{{import}}
+{% endfor %}
+from typing import Generic, TypeVar, List, Optional
+from sqlmodel import Session, SQLModel,select, func, Field
+from pydantic import BaseModel
+from pydantic.alias_generators import to_camel
+T = TypeVar('T')
+class Result(BaseModel, Generic[T]):
+ success: bool = Field(..., description="是否成功")
+ message: str = Field(..., description="额外消息")
+ data: Optional[T] = Field(None, description="响应数据")
+
+ @classmethod
+ def ok(cls, data: T, message: str="成功"):
+ return cls(data=data, message=message, success=True)
+
+ @classmethod
+ def error(cls, message: str = "失败"):
+ return cls(data=None, message=message, success=False)
+
+class PageResult(Result[T]):
+ total: int = Field(0, description="数据总数")
+ data: List[T] = Field(default_factory=list, description="响应数据")
+
+ @classmethod
+ def ok(cls, data: List[T], total: int, message: str = "成功"):
+ return cls(data=data, total=total, message=message, success=True)
+
+class {{table_name | to_pascal}}DTO(SQLModel):
+ {% for field in dto_fields %}
+ {{field}}
+ {% endfor%}
+
+class {{table_name | to_pascal}}Query({{table_name | to_pascal}}DTO):
+ page_number: int = Field(1, description="页码")
+ page_size: int = Field(10, description="页量")
+ {% for field in query_fields %}
+ {{field}}
+ {% endfor%}
+
+ def count_kwargs(self, **kwargs):
+ default_exclude = {{default_exclude}}
+ if v := kwargs.get("exclude"):
+ default_exclude.union(v)
+ data = self.model_dump(exclude=default_exclude, **kwargs)
+ return data
+
+class {{table_name|to_pascal}}({{table_name|to_pascal}}DTO, table=True):
+ {% for field in do_fields %}
+ {{field}}
+ {% endfor%}
+
+ @classmethod
+ def create(cls, session: Session, obj_in: {{table_name|to_pascal}}DTO) -> "{{table_name|to_pascal}}":
+ obj = cls(**obj_in.dict())
+ session.add(obj)
+ session.commit()
+ session.refresh(obj)
+ return obj
+
+ @classmethod
+ def query_by_id(cls, session: Session, id: int) -> Optional["{{table_name|to_pascal}}"]:
+ return session.get(cls, id)
+
+ @classmethod
+ def update(cls, session: Session, id: int, obj_in: {{table_name|to_pascal}}DTO) -> Optional["{{table_name|to_pascal}}"]:
+ obj = cls.query_by_id(session, id)
+ if obj:
+ for field, value in obj_in.dict(exclude_unset=True).items():
+ setattr(obj, field, value)
+ session.add(obj)
+ session.commit()
+ session.refresh(obj)
+ return obj
+
+ @classmethod
+ def delete_by_id(cls, session: Session, id: int) -> Optional["{{table_name|to_pascal}}"]:
+ obj = session.get(cls, id)
+ if obj:
+ session.delete(obj)
+ session.commit()
+ return obj
+
+ @classmethod
+ def count(cls, session: Session, **kwargs) -> int:
+ return session.scalar(
+ select(func.count()).
+ select_from({table_name}).filter_by(**kwargs)
+)
+
+ @classmethod
+ def query_all_by_limit(cls, session: Session, page_number: int, page_size: int, **kwargs) -> List["{{table_name|to_pascal}}"]:
+ stmt = select(cls).filter_by(**kwargs).offset((page_number - 1) * page_size).limit(page_size)
+ return session.exec(stmt).all()
\ No newline at end of file
diff --git a/templates/router.j2 b/templates/router.j2
new file mode 100644
index 0000000..3a37356
--- /dev/null
+++ b/templates/router.j2
@@ -0,0 +1,37 @@
+{# table #}
+from fastapi import APIRouter, Depends
+from sqlmodel import Session
+from model import {{table | to_pascal}}DTO, {{table | to_pascal}}, Result, PageResult, {{table | to_pascal}}Query
+from db import engine
+
+{{table | to_snake}}_router = APIRouter(prefix="/{{table | to_pascal}}", tags=["{{table | to_pascal}}"])
+
+@{{table | to_snake}}_router.get("/{id}", summary="通过ID查询详情")
+def query_{{table | to_snake}}_by_id(id: int) -> Result[{{table | to_pascal}}]:
+ with Session(engine) as session:
+ return Result.ok({{table | to_pascal}}.query_by_id(session, id))
+
+@{{table | to_snake}}_router.get("", summary="分页条件查询")
+def query_{{table | to_snake}}_all_by_limit(query: {{table | to_pascal}}Query = Depends()) -> PageResult[{{table | to_pascal}}]:
+ with Session(engine) as session:
+ total = {{table | to_pascal}}.count(session, **query.count_kwargs(exclude_none=True))
+ data = {{table | to_pascal}}.query_all_by_limit(session, **query.model_dump(exclude_none=True))
+ return PageResult.ok(data=data, total=total)
+
+
+@{{table | to_snake}}_router.post("", summary="新增数据")
+def create_{{table | to_snake}}(instance: {{table | to_pascal}}DTO) -> Result[{{table | to_pascal}}]:
+ with Session(engine) as session:
+ return Result.ok({{table | to_pascal}}.create(session, instance))
+
+
+@{{table | to_snake}}_router.patch("/{id}", summary="更新数据")
+def update_{{table | to_snake}}_by_id(id: int, instance: {{table | to_pascal}}DTO) -> Result[{{table | to_pascal}}]:
+ with Session(engine) as session:
+ return Result.ok({{table | to_pascal}}.update(session, id, instance))
+
+
+@{{table | to_snake}}_router.delete("/{id}", summary="删除数据")
+def delete_{{table | to_snake}}_by_id(id: int) -> Result[{{table | to_pascal}}]:
+ with Session(engine) as session:
+ return Result.ok({{table | to_pascal}}.delete_by_id(session, id))
\ No newline at end of file
diff --git a/web/.gitignore b/web/.gitignore
new file mode 100644
index 0000000..a547bf3
--- /dev/null
+++ b/web/.gitignore
@@ -0,0 +1,24 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/web/index.html b/web/index.html
new file mode 100644
index 0000000..ae140ee
--- /dev/null
+++ b/web/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+ dfs-generate
+
+
+
+
+
+
diff --git a/web/package-lock.json b/web/package-lock.json
new file mode 100644
index 0000000..05178db
--- /dev/null
+++ b/web/package-lock.json
@@ -0,0 +1,2433 @@
+{
+ "name": "fs-generate-web",
+ "version": "0.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "fs-generate-web",
+ "version": "0.0.0",
+ "dependencies": {
+ "@monaco-editor/react": "^4.6.0",
+ "antd": "^5.12.5",
+ "monaco-editor": "^0.45.0",
+ "react": "^18.2.0",
+ "react-ace": "^10.1.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.24",
+ "@types/react-dom": "^18.0.8",
+ "@vitejs/plugin-react": "^2.2.0",
+ "vite": "^3.2.3"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.2.1.tgz",
+ "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.0",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@ant-design/colors": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/@ant-design/colors/-/colors-7.0.0.tgz",
+ "integrity": "sha512-iVm/9PfGCbC0dSMBrz7oiEXZaaGH7ceU40OJEfKmyuzR9R5CRimJYPlRiFtMQGQcbNMea/ePcoIebi4ASGYXtg==",
+ "dependencies": {
+ "@ctrl/tinycolor": "^3.4.0"
+ }
+ },
+ "node_modules/@ant-design/cssinjs": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmmirror.com/@ant-design/cssinjs/-/cssinjs-1.18.1.tgz",
+ "integrity": "sha512-1JURAPrsjK1GwpqByTq3bJ7nF7lbMKDZpehqeR2n8/IR5O58/W1U4VcOeaw5ZyTHri3tEMcom7dyP2tvxpW54g==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "@emotion/hash": "^0.8.0",
+ "@emotion/unitless": "^0.7.5",
+ "classnames": "^2.3.1",
+ "csstype": "3.1.2",
+ "rc-util": "^5.35.0",
+ "stylis": "^4.0.13"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/@ant-design/cssinjs/node_modules/csstype": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz",
+ "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
+ },
+ "node_modules/@ant-design/icons": {
+ "version": "5.2.6",
+ "resolved": "https://registry.npmmirror.com/@ant-design/icons/-/icons-5.2.6.tgz",
+ "integrity": "sha512-4wn0WShF43TrggskBJPRqCD0fcHbzTYjnaoskdiJrVHg86yxoZ8ZUqsXvyn4WUqehRiFKnaclOhqk9w4Ui2KVw==",
+ "dependencies": {
+ "@ant-design/colors": "^7.0.0",
+ "@ant-design/icons-svg": "^4.3.0",
+ "@babel/runtime": "^7.11.2",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.31.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/@ant-design/icons-svg": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmmirror.com/@ant-design/icons-svg/-/icons-svg-4.3.1.tgz",
+ "integrity": "sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g=="
+ },
+ "node_modules/@ant-design/react-slick": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/@ant-design/react-slick/-/react-slick-1.0.2.tgz",
+ "integrity": "sha512-Wj8onxL/T8KQLFFiCA4t8eIRGpRR+UPgOdac2sYzonv+i0n3kXHmvHLLiOYL655DQx2Umii9Y9nNgL7ssu5haQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.4",
+ "classnames": "^2.2.5",
+ "json2mq": "^0.2.0",
+ "resize-observer-polyfill": "^1.5.1",
+ "throttle-debounce": "^5.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.23.5.tgz",
+ "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.23.6.tgz",
+ "integrity": "sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==",
+ "dev": true,
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-compilation-targets": "^7.23.6",
+ "@babel/helper-module-transforms": "^7.23.3",
+ "@babel/helpers": "^7.23.6",
+ "@babel/parser": "^7.23.6",
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.6",
+ "@babel/types": "^7.23.6",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.23.6.tgz",
+ "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.23.6",
+ "@jridgewell/gen-mapping": "^0.3.2",
+ "@jridgewell/trace-mapping": "^0.3.17",
+ "jsesc": "^2.5.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-annotate-as-pure": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
+ "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz",
+ "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/compat-data": "^7.23.5",
+ "@babel/helper-validator-option": "^7.23.5",
+ "browserslist": "^4.22.2",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-environment-visitor": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+ "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-function-name": {
+ "version": "7.23.0",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+ "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/types": "^7.23.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-hoist-variables": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+ "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz",
+ "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
+ "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-simple-access": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/helper-validator-identifier": "^7.22.20"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
+ "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-simple-access": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
+ "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-split-export-declaration": {
+ "version": "7.22.6",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
+ "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/types": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
+ "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz",
+ "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.23.6.tgz",
+ "integrity": "sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/template": "^7.22.15",
+ "@babel/traverse": "^7.23.6",
+ "@babel/types": "^7.23.6"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmmirror.com/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.23.6.tgz",
+ "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz",
+ "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz",
+ "integrity": "sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-annotate-as-pure": "^7.22.5",
+ "@babel/helper-module-imports": "^7.22.15",
+ "@babel/helper-plugin-utils": "^7.22.5",
+ "@babel/plugin-syntax-jsx": "^7.23.3",
+ "@babel/types": "^7.23.4"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-development": {
+ "version": "7.22.5",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz",
+ "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/plugin-transform-react-jsx": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-self": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz",
+ "integrity": "sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-transform-react-jsx-source": {
+ "version": "7.23.3",
+ "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz",
+ "integrity": "sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.22.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.6.tgz",
+ "integrity": "sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==",
+ "dependencies": {
+ "regenerator-runtime": "^0.14.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.22.15",
+ "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.22.15.tgz",
+ "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "@babel/parser": "^7.22.15",
+ "@babel/types": "^7.22.15"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.23.6.tgz",
+ "integrity": "sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.23.5",
+ "@babel/generator": "^7.23.6",
+ "@babel/helper-environment-visitor": "^7.22.20",
+ "@babel/helper-function-name": "^7.23.0",
+ "@babel/helper-hoist-variables": "^7.22.5",
+ "@babel/helper-split-export-declaration": "^7.22.6",
+ "@babel/parser": "^7.23.6",
+ "@babel/types": "^7.23.6",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.23.6",
+ "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.23.6.tgz",
+ "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.23.4",
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "to-fast-properties": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@ctrl/tinycolor": {
+ "version": "3.6.1",
+ "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz",
+ "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@emotion/hash": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz",
+ "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
+ },
+ "node_modules/@emotion/unitless": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.7.5.tgz",
+ "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg=="
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
+ "integrity": "sha512-5GT+kcs2WVGjVs7+boataCkO5Fg0y4kCjzkB5bAip7H4jfnOS3dA6KPiww9W1OEKTKeAcUVhdZGvgI65OXmUnw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz",
+ "integrity": "sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
+ "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/set-array": "^1.0.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.9"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
+ "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.1.2.tgz",
+ "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.4.15",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
+ "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "dev": true
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.20",
+ "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
+ "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
+ "dev": true,
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@monaco-editor/loader": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/@monaco-editor/loader/-/loader-1.4.0.tgz",
+ "integrity": "sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg==",
+ "dependencies": {
+ "state-local": "^1.0.6"
+ },
+ "peerDependencies": {
+ "monaco-editor": ">= 0.21.0 < 1"
+ }
+ },
+ "node_modules/@monaco-editor/react": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmmirror.com/@monaco-editor/react/-/react-4.6.0.tgz",
+ "integrity": "sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw==",
+ "dependencies": {
+ "@monaco-editor/loader": "^1.4.0"
+ },
+ "peerDependencies": {
+ "monaco-editor": ">= 0.25.0 < 1",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/@rc-component/color-picker": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmmirror.com/@rc-component/color-picker/-/color-picker-1.4.1.tgz",
+ "integrity": "sha512-vh5EWqnsayZa/JwUznqDaPJz39jznx/YDbyBuVJntv735tKXKwEUZZb2jYEldOg+NKWZwtALjGMrNeGBmqFoEw==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@ctrl/tinycolor": "^3.6.0",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.30.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/context": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/@rc-component/context/-/context-1.4.0.tgz",
+ "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "rc-util": "^5.27.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/mini-decimal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz",
+ "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ }
+ },
+ "node_modules/@rc-component/mutate-observer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz",
+ "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.0",
+ "classnames": "^2.3.2",
+ "rc-util": "^5.24.4"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/portal": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/@rc-component/portal/-/portal-1.1.2.tgz",
+ "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.0",
+ "classnames": "^2.3.2",
+ "rc-util": "^5.24.4"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/tour": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmmirror.com/@rc-component/tour/-/tour-1.11.1.tgz",
+ "integrity": "sha512-c9Lw3/oVinj5D64Rsp8aDLOXcgdViE+hq7bj0Qoo8fTuQEh9sSpUw5OZcum943JkjeIE4hLcc5FD4a5ANtMJ4w==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.0",
+ "@rc-component/portal": "^1.0.0-9",
+ "@rc-component/trigger": "^1.3.6",
+ "classnames": "^2.3.2",
+ "rc-util": "^5.24.4"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@rc-component/trigger": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmmirror.com/@rc-component/trigger/-/trigger-1.18.2.tgz",
+ "integrity": "sha512-jRLYgFgjLEPq3MvS87fIhcfuywFSRDaDrYw1FLku7Cm4esszvzTbA0JBsyacAyLrK9rF3TiHFcvoEDMzoD3CTA==",
+ "dependencies": {
+ "@babel/runtime": "^7.23.2",
+ "@rc-component/portal": "^1.1.0",
+ "classnames": "^2.3.2",
+ "rc-motion": "^2.0.0",
+ "rc-resize-observer": "^1.3.1",
+ "rc-util": "^5.38.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/@types/prop-types": {
+ "version": "15.7.11",
+ "resolved": "https://registry.npmmirror.com/@types/prop-types/-/prop-types-15.7.11.tgz",
+ "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==",
+ "dev": true
+ },
+ "node_modules/@types/react": {
+ "version": "18.2.45",
+ "resolved": "https://registry.npmmirror.com/@types/react/-/react-18.2.45.tgz",
+ "integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==",
+ "dev": true,
+ "dependencies": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@types/react-dom": {
+ "version": "18.2.18",
+ "resolved": "https://registry.npmmirror.com/@types/react-dom/-/react-dom-18.2.18.tgz",
+ "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==",
+ "dev": true,
+ "dependencies": {
+ "@types/react": "*"
+ }
+ },
+ "node_modules/@types/scheduler": {
+ "version": "0.16.8",
+ "resolved": "https://registry.npmmirror.com/@types/scheduler/-/scheduler-0.16.8.tgz",
+ "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==",
+ "dev": true
+ },
+ "node_modules/@vitejs/plugin-react": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/@vitejs/plugin-react/-/plugin-react-2.2.0.tgz",
+ "integrity": "sha512-FFpefhvExd1toVRlokZgxgy2JtnBOdp4ZDsq7ldCWaqGSGn9UhWMAVm/1lxPL14JfNS5yGz+s9yFrQY6shoStA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.19.6",
+ "@babel/plugin-transform-react-jsx": "^7.19.0",
+ "@babel/plugin-transform-react-jsx-development": "^7.18.6",
+ "@babel/plugin-transform-react-jsx-self": "^7.18.6",
+ "@babel/plugin-transform-react-jsx-source": "^7.19.6",
+ "magic-string": "^0.26.7",
+ "react-refresh": "^0.14.0"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^3.0.0"
+ }
+ },
+ "node_modules/ace-builds": {
+ "version": "1.32.2",
+ "resolved": "https://registry.npmmirror.com/ace-builds/-/ace-builds-1.32.2.tgz",
+ "integrity": "sha512-mnJAc803p+7eeDt07r6XI7ufV7VdkpPq4gJZT8Jb3QsowkaBTVy4tdBgPrVT0WbXLm0toyEQXURKSVNj/7dfJQ=="
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/antd": {
+ "version": "5.12.5",
+ "resolved": "https://registry.npmmirror.com/antd/-/antd-5.12.5.tgz",
+ "integrity": "sha512-m9r9VhTmANS4kdBwHcxI4QWIGoZh3LspXNb2SxoezRSUZ9RUFpf+gO0AjPx8EPeO/nLKsHAoCSLza9r041bAgw==",
+ "dependencies": {
+ "@ant-design/colors": "^7.0.0",
+ "@ant-design/cssinjs": "^1.18.1",
+ "@ant-design/icons": "^5.2.6",
+ "@ant-design/react-slick": "~1.0.2",
+ "@babel/runtime": "^7.23.4",
+ "@ctrl/tinycolor": "^3.6.1",
+ "@rc-component/color-picker": "~1.4.1",
+ "@rc-component/mutate-observer": "^1.1.0",
+ "@rc-component/tour": "~1.11.1",
+ "@rc-component/trigger": "^1.18.2",
+ "classnames": "^2.3.2",
+ "copy-to-clipboard": "^3.3.3",
+ "dayjs": "^1.11.1",
+ "qrcode.react": "^3.1.0",
+ "rc-cascader": "~3.20.0",
+ "rc-checkbox": "~3.1.0",
+ "rc-collapse": "~3.7.2",
+ "rc-dialog": "~9.3.4",
+ "rc-drawer": "~6.5.2",
+ "rc-dropdown": "~4.1.0",
+ "rc-field-form": "~1.41.0",
+ "rc-image": "~7.5.1",
+ "rc-input": "~1.3.11",
+ "rc-input-number": "~8.4.0",
+ "rc-mentions": "~2.9.1",
+ "rc-menu": "~9.12.4",
+ "rc-motion": "^2.9.0",
+ "rc-notification": "~5.3.0",
+ "rc-pagination": "~4.0.3",
+ "rc-picker": "~3.14.6",
+ "rc-progress": "~3.5.1",
+ "rc-rate": "~2.12.0",
+ "rc-resize-observer": "^1.4.0",
+ "rc-segmented": "~2.2.2",
+ "rc-select": "~14.10.0",
+ "rc-slider": "~10.5.0",
+ "rc-steps": "~6.0.1",
+ "rc-switch": "~4.1.0",
+ "rc-table": "~7.36.1",
+ "rc-tabs": "~12.14.1",
+ "rc-textarea": "~1.5.3",
+ "rc-tooltip": "~6.1.3",
+ "rc-tree": "~5.8.2",
+ "rc-tree-select": "~5.15.0",
+ "rc-upload": "~4.3.5",
+ "rc-util": "^5.38.1",
+ "scroll-into-view-if-needed": "^3.1.0",
+ "throttle-debounce": "^5.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/array-tree-filter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
+ "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw=="
+ },
+ "node_modules/async-validator": {
+ "version": "4.2.5",
+ "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz",
+ "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg=="
+ },
+ "node_modules/browserslist": {
+ "version": "4.22.2",
+ "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.22.2.tgz",
+ "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==",
+ "dev": true,
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001565",
+ "electron-to-chromium": "^1.4.601",
+ "node-releases": "^2.0.14",
+ "update-browserslist-db": "^1.0.13"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001571",
+ "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001571.tgz",
+ "integrity": "sha512-tYq/6MoXhdezDLFZuCO/TKboTzuQ/xR5cFdgXPfDtM7/kchBO3b4VWghE/OAi/DV7tTdhmLjZiZBZi1fA/GheQ==",
+ "dev": true
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/classnames": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmmirror.com/classnames/-/classnames-2.3.2.tgz",
+ "integrity": "sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw=="
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/compute-scroll-into-view": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz",
+ "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg=="
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true
+ },
+ "node_modules/copy-to-clipboard": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmmirror.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
+ "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
+ "dependencies": {
+ "toggle-selection": "^1.0.6"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "dev": true
+ },
+ "node_modules/dayjs": {
+ "version": "1.11.10",
+ "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.10.tgz",
+ "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/diff-match-patch": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/diff-match-patch/-/diff-match-patch-1.0.5.tgz",
+ "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw=="
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.4.616",
+ "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.616.tgz",
+ "integrity": "sha512-1n7zWYh8eS0L9Uy+GskE0lkBUNK83cXTVJI0pU3mGprFsbfSdAc15VTFbo+A+Bq4pwstmL30AVcEU3Fo463lNg==",
+ "dev": true
+ },
+ "node_modules/esbuild": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.15.18.tgz",
+ "integrity": "sha512-x/R72SmW3sSFRm5zrrIjAhCeQSAWoni3CmHEqfQrZIQTM3lVCdehdwuIqaOtfC2slvpdlLa62GYoN8SxT23m6Q==",
+ "dev": true,
+ "hasInstallScript": true,
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "optionalDependencies": {
+ "@esbuild/android-arm": "0.15.18",
+ "@esbuild/linux-loong64": "0.15.18",
+ "esbuild-android-64": "0.15.18",
+ "esbuild-android-arm64": "0.15.18",
+ "esbuild-darwin-64": "0.15.18",
+ "esbuild-darwin-arm64": "0.15.18",
+ "esbuild-freebsd-64": "0.15.18",
+ "esbuild-freebsd-arm64": "0.15.18",
+ "esbuild-linux-32": "0.15.18",
+ "esbuild-linux-64": "0.15.18",
+ "esbuild-linux-arm": "0.15.18",
+ "esbuild-linux-arm64": "0.15.18",
+ "esbuild-linux-mips64le": "0.15.18",
+ "esbuild-linux-ppc64le": "0.15.18",
+ "esbuild-linux-riscv64": "0.15.18",
+ "esbuild-linux-s390x": "0.15.18",
+ "esbuild-netbsd-64": "0.15.18",
+ "esbuild-openbsd-64": "0.15.18",
+ "esbuild-sunos-64": "0.15.18",
+ "esbuild-windows-32": "0.15.18",
+ "esbuild-windows-64": "0.15.18",
+ "esbuild-windows-arm64": "0.15.18"
+ }
+ },
+ "node_modules/esbuild-android-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-android-64/-/esbuild-android-64-0.15.18.tgz",
+ "integrity": "sha512-wnpt3OXRhcjfIDSZu9bnzT4/TNTDsOUvip0foZOUBG7QbSt//w3QV4FInVJxNhKc/ErhUxc5z4QjHtMi7/TbgA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-android-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-android-arm64/-/esbuild-android-arm64-0.15.18.tgz",
+ "integrity": "sha512-G4xu89B8FCzav9XU8EjsXacCKSG2FT7wW9J6hOc18soEHJdtWu03L3TQDGf0geNxfLTtxENKBzMSq9LlbjS8OQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-darwin-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-darwin-64/-/esbuild-darwin-64-0.15.18.tgz",
+ "integrity": "sha512-2WAvs95uPnVJPuYKP0Eqx+Dl/jaYseZEUUT1sjg97TJa4oBtbAKnPnl3b5M9l51/nbx7+QAEtuummJZW0sBEmg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-darwin-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.15.18.tgz",
+ "integrity": "sha512-tKPSxcTJ5OmNb1btVikATJ8NftlyNlc8BVNtyT/UAr62JFOhwHlnoPrhYWz09akBLHI9nElFVfWSTSRsrZiDUA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-freebsd-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.15.18.tgz",
+ "integrity": "sha512-TT3uBUxkteAjR1QbsmvSsjpKjOX6UkCstr8nMr+q7zi3NuZ1oIpa8U41Y8I8dJH2fJgdC3Dj3CXO5biLQpfdZA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-freebsd-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.15.18.tgz",
+ "integrity": "sha512-R/oVr+X3Tkh+S0+tL41wRMbdWtpWB8hEAMsOXDumSSa6qJR89U0S/PpLXrGF7Wk/JykfpWNokERUpCeHDl47wA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-32": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-32/-/esbuild-linux-32-0.15.18.tgz",
+ "integrity": "sha512-lphF3HiCSYtaa9p1DtXndiQEeQDKPl9eN/XNoBf2amEghugNuqXNZA/ZovthNE2aa4EN43WroO0B85xVSjYkbg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-64/-/esbuild-linux-64-0.15.18.tgz",
+ "integrity": "sha512-hNSeP97IviD7oxLKFuii5sDPJ+QHeiFTFLoLm7NZQligur8poNOWGIgpQ7Qf8Balb69hptMZzyOBIPtY09GZYw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-arm": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-arm/-/esbuild-linux-arm-0.15.18.tgz",
+ "integrity": "sha512-UH779gstRblS4aoS2qpMl3wjg7U0j+ygu3GjIeTonCcN79ZvpPee12Qun3vcdxX+37O5LFxz39XeW2I9bybMVA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.15.18.tgz",
+ "integrity": "sha512-54qr8kg/6ilcxd+0V3h9rjT4qmjc0CccMVWrjOEM/pEcUzt8X62HfBSeZfT2ECpM7104mk4yfQXkosY8Quptug==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-mips64le": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.15.18.tgz",
+ "integrity": "sha512-Mk6Ppwzzz3YbMl/ZZL2P0q1tnYqh/trYZ1VfNP47C31yT0K8t9s7Z077QrDA/guU60tGNp2GOwCQnp+DYv7bxQ==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-ppc64le": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.15.18.tgz",
+ "integrity": "sha512-b0XkN4pL9WUulPTa/VKHx2wLCgvIAbgwABGnKMY19WhKZPT+8BxhZdqz6EgkqCLld7X5qiCY2F/bfpUUlnFZ9w==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-riscv64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.15.18.tgz",
+ "integrity": "sha512-ba2COaoF5wL6VLZWn04k+ACZjZ6NYniMSQStodFKH/Pu6RxzQqzsmjR1t9QC89VYJxBeyVPTaHuBMCejl3O/xg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-linux-s390x": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.15.18.tgz",
+ "integrity": "sha512-VbpGuXEl5FCs1wDVp93O8UIzl3ZrglgnSQ+Hu79g7hZu6te6/YHgVJxCM2SqfIila0J3k0csfnf8VD2W7u2kzQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-netbsd-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.15.18.tgz",
+ "integrity": "sha512-98ukeCdvdX7wr1vUYQzKo4kQ0N2p27H7I11maINv73fVEXt2kyh4K4m9f35U1K43Xc2QGXlzAw0K9yoU7JUjOg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-openbsd-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.15.18.tgz",
+ "integrity": "sha512-yK5NCcH31Uae076AyQAXeJzt/vxIo9+omZRKj1pauhk3ITuADzuOx5N2fdHrAKPxN+zH3w96uFKlY7yIn490xQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-sunos-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-sunos-64/-/esbuild-sunos-64-0.15.18.tgz",
+ "integrity": "sha512-On22LLFlBeLNj/YF3FT+cXcyKPEI263nflYlAhz5crxtp3yRG1Ugfr7ITyxmCmjm4vbN/dGrb/B7w7U8yJR9yw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-32": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-windows-32/-/esbuild-windows-32-0.15.18.tgz",
+ "integrity": "sha512-o+eyLu2MjVny/nt+E0uPnBxYuJHBvho8vWsC2lV61A7wwTWC3jkN2w36jtA+yv1UgYkHRihPuQsL23hsCYGcOQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-windows-64/-/esbuild-windows-64-0.15.18.tgz",
+ "integrity": "sha512-qinug1iTTaIIrCorAUjR0fcBk24fjzEedFYhhispP8Oc7SFvs+XeW3YpAKiKp8dRpizl4YYAhxMjlftAMJiaUw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/esbuild-windows-arm64": {
+ "version": "0.15.18",
+ "resolved": "https://registry.npmmirror.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.15.18.tgz",
+ "integrity": "sha512-q9bsYzegpZcLziq0zgUi5KqGVtfhjxGbnksaBFYmWLxeV/S1fK4OLdq2DFYnXcLMjlZw2L0jLsk1eGoB522WXQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.0.tgz",
+ "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.13.1.tgz",
+ "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+ "dev": true,
+ "dependencies": {
+ "hasown": "^2.0.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+ },
+ "node_modules/jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true,
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/json2mq": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmmirror.com/json2mq/-/json2mq-0.2.0.tgz",
+ "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==",
+ "dependencies": {
+ "string-convert": "^0.2.0"
+ }
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmmirror.com/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ=="
+ },
+ "node_modules/lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmmirror.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ=="
+ },
+ "node_modules/loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dependencies": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ },
+ "bin": {
+ "loose-envify": "cli.js"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/magic-string": {
+ "version": "0.26.7",
+ "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.26.7.tgz",
+ "integrity": "sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==",
+ "dev": true,
+ "dependencies": {
+ "sourcemap-codec": "^1.4.8"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/monaco-editor": {
+ "version": "0.45.0",
+ "resolved": "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.45.0.tgz",
+ "integrity": "sha512-mjv1G1ZzfEE3k9HZN0dQ2olMdwIfaeAAjFiwNprLfYNRSz7ctv9XuCT7gPtBGrMUeV1/iZzYKj17Khu1hxoHOA=="
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.7",
+ "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.7.tgz",
+ "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "dev": true,
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.14",
+ "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.14.tgz",
+ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "dev": true
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmmirror.com/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true
+ },
+ "node_modules/picocolors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz",
+ "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+ "dev": true
+ },
+ "node_modules/postcss": {
+ "version": "8.4.32",
+ "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.32.tgz",
+ "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
+ "dev": true,
+ "dependencies": {
+ "nanoid": "^3.3.7",
+ "picocolors": "^1.0.0",
+ "source-map-js": "^1.0.2"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prop-types": {
+ "version": "15.8.1",
+ "resolved": "https://registry.npmmirror.com/prop-types/-/prop-types-15.8.1.tgz",
+ "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
+ "dependencies": {
+ "loose-envify": "^1.4.0",
+ "object-assign": "^4.1.1",
+ "react-is": "^16.13.1"
+ }
+ },
+ "node_modules/prop-types/node_modules/react-is": {
+ "version": "16.13.1",
+ "resolved": "https://registry.npmmirror.com/react-is/-/react-is-16.13.1.tgz",
+ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
+ },
+ "node_modules/qrcode.react": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/qrcode.react/-/qrcode.react-3.1.0.tgz",
+ "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/rc-cascader": {
+ "version": "3.20.0",
+ "resolved": "https://registry.npmmirror.com/rc-cascader/-/rc-cascader-3.20.0.tgz",
+ "integrity": "sha512-lkT9EEwOcYdjZ/jvhLoXGzprK1sijT3/Tp4BLxQQcHDZkkOzzwYQC9HgmKoJz0K7CukMfgvO9KqHeBdgE+pELw==",
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "array-tree-filter": "^2.1.0",
+ "classnames": "^2.3.1",
+ "rc-select": "~14.10.0",
+ "rc-tree": "~5.8.1",
+ "rc-util": "^5.37.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-checkbox": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/rc-checkbox/-/rc-checkbox-3.1.0.tgz",
+ "integrity": "sha512-PAwpJFnBa3Ei+5pyqMMXdcKYKNBMS+TvSDiLdDnARnMJHC8ESxwPfm4Ao1gJiKtWLdmGfigascnCpwrHFgoOBQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.3.2",
+ "rc-util": "^5.25.2"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-collapse": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmmirror.com/rc-collapse/-/rc-collapse-3.7.2.tgz",
+ "integrity": "sha512-ZRw6ipDyOnfLFySxAiCMdbHtb5ePAsB9mT17PA6y1mRD/W6KHRaZeb5qK/X9xDV1CqgyxMpzw0VdS74PCcUk4A==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.3.4",
+ "rc-util": "^5.27.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-dialog": {
+ "version": "9.3.4",
+ "resolved": "https://registry.npmmirror.com/rc-dialog/-/rc-dialog-9.3.4.tgz",
+ "integrity": "sha512-975X3018GhR+EjZFbxA2Z57SX5rnu0G0/OxFgMMvZK4/hQWEm3MHaNvP4wXpxYDoJsp+xUvVW+GB9CMMCm81jA==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/portal": "^1.0.0-8",
+ "classnames": "^2.2.6",
+ "rc-motion": "^2.3.0",
+ "rc-util": "^5.21.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-drawer": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmmirror.com/rc-drawer/-/rc-drawer-6.5.2.tgz",
+ "integrity": "sha512-QckxAnQNdhh4vtmKN0ZwDf3iakO83W9eZcSKWYYTDv4qcD2fHhRAZJJ/OE6v2ZlQ2kSqCJX5gYssF4HJFvsEPQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/portal": "^1.1.1",
+ "classnames": "^2.2.6",
+ "rc-motion": "^2.6.1",
+ "rc-util": "^5.36.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-dropdown": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/rc-dropdown/-/rc-dropdown-4.1.0.tgz",
+ "integrity": "sha512-VZjMunpBdlVzYpEdJSaV7WM7O0jf8uyDjirxXLZRNZ+tAC+NzD3PXPEtliFwGzVwBBdCmGuSqiS9DWcOLxQ9tw==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "@rc-component/trigger": "^1.7.0",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.17.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.11.0",
+ "react-dom": ">=16.11.0"
+ }
+ },
+ "node_modules/rc-field-form": {
+ "version": "1.41.0",
+ "resolved": "https://registry.npmmirror.com/rc-field-form/-/rc-field-form-1.41.0.tgz",
+ "integrity": "sha512-k9AS0wmxfJfusWDP/YXWTpteDNaQ4isJx9UKxx4/e8Dub4spFeZ54/EuN2sYrMRID/+hUznPgVZeg+Gf7XSYCw==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.0",
+ "async-validator": "^4.1.0",
+ "rc-util": "^5.32.2"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-image": {
+ "version": "7.5.1",
+ "resolved": "https://registry.npmmirror.com/rc-image/-/rc-image-7.5.1.tgz",
+ "integrity": "sha512-Z9loECh92SQp0nSipc0MBuf5+yVC05H/pzC+Nf8xw1BKDFUJzUeehYBjaWlxly8VGBZJcTHYri61Fz9ng1G3Ag==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "@rc-component/portal": "^1.0.2",
+ "classnames": "^2.2.6",
+ "rc-dialog": "~9.3.4",
+ "rc-motion": "^2.6.2",
+ "rc-util": "^5.34.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-input": {
+ "version": "1.3.11",
+ "resolved": "https://registry.npmmirror.com/rc-input/-/rc-input-1.3.11.tgz",
+ "integrity": "sha512-jhH7QP5rILanSHCGSUkdoFE5DEtpv8FIseYhuYkOZzUBeiVAiwM3q26YqZ6xBB0QFEZ/yUAgms4xW4iuub3xFQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.18.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/rc-input-number": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmmirror.com/rc-input-number/-/rc-input-number-8.4.0.tgz",
+ "integrity": "sha512-B6rziPOLRmeP7kcS5qbdC5hXvvDHYKV4vUxmahevYx2E6crS2bRi0xLDjhJ0E1HtOWo8rTmaE2EBJAkTCZOLdA==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/mini-decimal": "^1.0.1",
+ "classnames": "^2.2.5",
+ "rc-input": "~1.3.5",
+ "rc-util": "^5.28.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-mentions": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmmirror.com/rc-mentions/-/rc-mentions-2.9.1.tgz",
+ "integrity": "sha512-cZuElWr/5Ws0PXx1uxobxfYh4mqUw2FitfabR62YnWgm+WAfDyXZXqZg5DxXW+M1cgVvntrQgDDd9LrihrXzew==",
+ "dependencies": {
+ "@babel/runtime": "^7.22.5",
+ "@rc-component/trigger": "^1.5.0",
+ "classnames": "^2.2.6",
+ "rc-input": "~1.3.5",
+ "rc-menu": "~9.12.0",
+ "rc-textarea": "~1.5.0",
+ "rc-util": "^5.34.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-menu": {
+ "version": "9.12.4",
+ "resolved": "https://registry.npmmirror.com/rc-menu/-/rc-menu-9.12.4.tgz",
+ "integrity": "sha512-t2NcvPLV1mFJzw4F21ojOoRVofK2rWhpKPx69q2raUsiHPDP6DDevsBILEYdsIegqBeSXoWs2bf6CueBKg3BFg==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/trigger": "^1.17.0",
+ "classnames": "2.x",
+ "rc-motion": "^2.4.3",
+ "rc-overflow": "^1.3.1",
+ "rc-util": "^5.27.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-motion": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmmirror.com/rc-motion/-/rc-motion-2.9.0.tgz",
+ "integrity": "sha512-XIU2+xLkdIr1/h6ohPZXyPBMvOmuyFZQ/T0xnawz+Rh+gh4FINcnZmMT5UTIj6hgI0VLDjTaPeRd+smJeSPqiQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.21.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-notification": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmmirror.com/rc-notification/-/rc-notification-5.3.0.tgz",
+ "integrity": "sha512-WCf0uCOkZ3HGfF0p1H4Sgt7aWfipxORWTPp7o6prA3vxwtWhtug3GfpYls1pnBp4WA+j8vGIi5c2/hQRpGzPcQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.9.0",
+ "rc-util": "^5.20.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-overflow": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmmirror.com/rc-overflow/-/rc-overflow-1.3.2.tgz",
+ "integrity": "sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.37.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-pagination": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/rc-pagination/-/rc-pagination-4.0.3.tgz",
+ "integrity": "sha512-s1MNwyU83AgycikYckRdpmkN+4ZZuul0E0YdDp7dMgcjg/d2fak767ZIbLP4Q5YPPla7NDorfVFTvGQAPj6jXA==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.3.2",
+ "rc-util": "^5.38.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-picker": {
+ "version": "3.14.6",
+ "resolved": "https://registry.npmmirror.com/rc-picker/-/rc-picker-3.14.6.tgz",
+ "integrity": "sha512-AdKKW0AqMwZsKvIpwUWDUnpuGKZVrbxVTZTNjcO+pViGkjC1EBcjMgxVe8tomOEaIHJL5Gd13vS8Rr3zzxWmag==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/trigger": "^1.5.0",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.30.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "date-fns": ">= 2.x",
+ "dayjs": ">= 1.x",
+ "luxon": ">= 3.x",
+ "moment": ">= 2.x",
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ },
+ "peerDependenciesMeta": {
+ "date-fns": {
+ "optional": true
+ },
+ "dayjs": {
+ "optional": true
+ },
+ "luxon": {
+ "optional": true
+ },
+ "moment": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/rc-progress": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmmirror.com/rc-progress/-/rc-progress-3.5.1.tgz",
+ "integrity": "sha512-V6Amx6SbLRwPin/oD+k1vbPrO8+9Qf8zW1T8A7o83HdNafEVvAxPV5YsgtKFP+Ud5HghLj33zKOcEHrcrUGkfw==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.16.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-rate": {
+ "version": "2.12.0",
+ "resolved": "https://registry.npmmirror.com/rc-rate/-/rc-rate-2.12.0.tgz",
+ "integrity": "sha512-g092v5iZCdVzbjdn28FzvWebK2IutoVoiTeqoLTj9WM7SjA/gOJIw5/JFZMRyJYYVe1jLAU2UhAfstIpCNRozg==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-resize-observer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz",
+ "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.7",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.38.0",
+ "resize-observer-polyfill": "^1.5.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-segmented": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmmirror.com/rc-segmented/-/rc-segmented-2.2.2.tgz",
+ "integrity": "sha512-Mq52M96QdHMsNdE/042ibT5vkcGcD5jxKp7HgPC2SRofpia99P5fkfHy1pEaajLMF/kj0+2Lkq1UZRvqzo9mSA==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-motion": "^2.4.4",
+ "rc-util": "^5.17.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/rc-select": {
+ "version": "14.10.0",
+ "resolved": "https://registry.npmmirror.com/rc-select/-/rc-select-14.10.0.tgz",
+ "integrity": "sha512-TsIJTYafTTapCA32LLNpx/AD6ntepR1TG8jEVx35NiAAWCPymhUfuca8kRcUNd3WIGVMDcMKn9kkphoxEz+6Ag==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/trigger": "^1.5.0",
+ "classnames": "2.x",
+ "rc-motion": "^2.0.1",
+ "rc-overflow": "^1.3.1",
+ "rc-util": "^5.16.1",
+ "rc-virtual-list": "^3.5.2"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/rc-slider": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmmirror.com/rc-slider/-/rc-slider-10.5.0.tgz",
+ "integrity": "sha512-xiYght50cvoODZYI43v3Ylsqiw14+D7ELsgzR40boDZaya1HFa1Etnv9MDkQE8X/UrXAffwv2AcNAhslgYuDTw==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.27.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-steps": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/rc-steps/-/rc-steps-6.0.1.tgz",
+ "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==",
+ "dependencies": {
+ "@babel/runtime": "^7.16.7",
+ "classnames": "^2.2.3",
+ "rc-util": "^5.16.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-switch": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmmirror.com/rc-switch/-/rc-switch-4.1.0.tgz",
+ "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==",
+ "dependencies": {
+ "@babel/runtime": "^7.21.0",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.30.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-table": {
+ "version": "7.36.1",
+ "resolved": "https://registry.npmmirror.com/rc-table/-/rc-table-7.36.1.tgz",
+ "integrity": "sha512-9qMxEm/3Y8ukdW8I8ZvmhX0QImfNKzH0JEUlSbyaUlsYTB+/tQEbfaB8YkG4sHVZ1io4pxqK/BXoZYqebi/TIQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "@rc-component/context": "^1.4.0",
+ "classnames": "^2.2.5",
+ "rc-resize-observer": "^1.1.0",
+ "rc-util": "^5.37.0",
+ "rc-virtual-list": "^3.11.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-tabs": {
+ "version": "12.14.1",
+ "resolved": "https://registry.npmmirror.com/rc-tabs/-/rc-tabs-12.14.1.tgz",
+ "integrity": "sha512-1xlE7JQNYxD5RwBsM7jf2xSdUrkmTSDFLFEm2gqAgnsRlOGydEzXXNAVTOT6QcgM1G/gCm+AgG+FYPUGb4Hs4g==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "classnames": "2.x",
+ "rc-dropdown": "~4.1.0",
+ "rc-menu": "~9.12.0",
+ "rc-motion": "^2.6.2",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.34.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-textarea": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmmirror.com/rc-textarea/-/rc-textarea-1.5.3.tgz",
+ "integrity": "sha512-oH682ghHx++stFNYrosPRBfwsypywrTXpaD0/5Z8MPkUOnyOQUaY9ueL9tMu6BP1LfsuYQ1VLpg5OtshViLNgA==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "rc-input": "~1.3.5",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.27.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-tooltip": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmmirror.com/rc-tooltip/-/rc-tooltip-6.1.3.tgz",
+ "integrity": "sha512-HMSbSs5oieZ7XddtINUddBLSVgsnlaSb3bZrzzGWjXa7/B7nNedmsuz72s7EWFEro9mNa7RyF3gOXKYqvJiTcQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "@rc-component/trigger": "^1.18.0",
+ "classnames": "^2.3.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-tree": {
+ "version": "5.8.2",
+ "resolved": "https://registry.npmmirror.com/rc-tree/-/rc-tree-5.8.2.tgz",
+ "integrity": "sha512-xH/fcgLHWTLmrSuNphU8XAqV7CdaOQgm4KywlLGNoTMhDAcNR3GVNP6cZzb0GrKmIZ9yae+QLot/cAgUdPRMzg==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.0.1",
+ "rc-util": "^5.16.1",
+ "rc-virtual-list": "^3.5.1"
+ },
+ "engines": {
+ "node": ">=10.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/rc-tree-select": {
+ "version": "5.15.0",
+ "resolved": "https://registry.npmmirror.com/rc-tree-select/-/rc-tree-select-5.15.0.tgz",
+ "integrity": "sha512-YJHfdO6azFnR0/JuNBZLDptGE4/RGfVeHAafUIYcm2T3RBkL1O8aVqiHvwIyLzdK59ry0NLrByd+3TkfpRM+9Q==",
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-select": "~14.10.0",
+ "rc-tree": "~5.8.1",
+ "rc-util": "^5.16.1"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/rc-upload": {
+ "version": "4.3.6",
+ "resolved": "https://registry.npmmirror.com/rc-upload/-/rc-upload-4.3.6.tgz",
+ "integrity": "sha512-Bt7ESeG5tT3IY82fZcP+s0tQU2xmo1W6P3S8NboUUliquJLQYLkUcsaExi3IlBVr43GQMCjo30RA2o0i70+NjA==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.2.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-util": {
+ "version": "5.38.1",
+ "resolved": "https://registry.npmmirror.com/rc-util/-/rc-util-5.38.1.tgz",
+ "integrity": "sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng==",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "react-is": "^18.2.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/rc-virtual-list": {
+ "version": "3.11.3",
+ "resolved": "https://registry.npmmirror.com/rc-virtual-list/-/rc-virtual-list-3.11.3.tgz",
+ "integrity": "sha512-tu5UtrMk/AXonHwHxUogdXAWynaXsrx1i6dsgg+lOo/KJSF8oBAcprh1z5J3xgnPJD5hXxTL58F8s8onokdt0Q==",
+ "dependencies": {
+ "@babel/runtime": "^7.20.0",
+ "classnames": "^2.2.6",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.36.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/react": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmmirror.com/react/-/react-18.2.0.tgz",
+ "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/react-ace": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmmirror.com/react-ace/-/react-ace-10.1.0.tgz",
+ "integrity": "sha512-VkvUjZNhdYTuKOKQpMIZi7uzZZVgzCjM7cLYu6F64V0mejY8a2XTyPUIMszC6A4trbeMIHbK5fYFcT/wkP/8VA==",
+ "dependencies": {
+ "ace-builds": "^1.4.14",
+ "diff-match-patch": "^1.0.5",
+ "lodash.get": "^4.4.2",
+ "lodash.isequal": "^4.5.0",
+ "prop-types": "^15.7.2"
+ },
+ "peerDependencies": {
+ "react": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^0.13.0 || ^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
+ "node_modules/react-dom": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-18.2.0.tgz",
+ "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
+ "dependencies": {
+ "loose-envify": "^1.1.0",
+ "scheduler": "^0.23.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.2.0",
+ "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz",
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
+ },
+ "node_modules/react-refresh": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmmirror.com/react-refresh/-/react-refresh-0.14.0.tgz",
+ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regenerator-runtime": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
+ "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
+ },
+ "node_modules/resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ }
+ },
+ "node_modules/rollup": {
+ "version": "2.79.1",
+ "resolved": "https://registry.npmmirror.com/rollup/-/rollup-2.79.1.tgz",
+ "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "dev": true,
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/scheduler": {
+ "version": "0.23.0",
+ "resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
+ "dependencies": {
+ "loose-envify": "^1.1.0"
+ }
+ },
+ "node_modules/scroll-into-view-if-needed": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmmirror.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz",
+ "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==",
+ "dependencies": {
+ "compute-scroll-into-view": "^3.0.2"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz",
+ "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sourcemap-codec": {
+ "version": "1.4.8",
+ "resolved": "https://registry.npmmirror.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
+ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
+ "deprecated": "Please use @jridgewell/sourcemap-codec instead",
+ "dev": true
+ },
+ "node_modules/state-local": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/state-local/-/state-local-1.0.7.tgz",
+ "integrity": "sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w=="
+ },
+ "node_modules/string-convert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmmirror.com/string-convert/-/string-convert-0.2.1.tgz",
+ "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A=="
+ },
+ "node_modules/stylis": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.3.0.tgz",
+ "integrity": "sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ=="
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/throttle-debounce": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/throttle-debounce/-/throttle-debounce-5.0.0.tgz",
+ "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==",
+ "engines": {
+ "node": ">=12.22"
+ }
+ },
+ "node_modules/to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/toggle-selection": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/toggle-selection/-/toggle-selection-1.0.6.tgz",
+ "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
+ "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+ "dev": true,
+ "dependencies": {
+ "escalade": "^3.1.1",
+ "picocolors": "^1.0.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "3.2.7",
+ "resolved": "https://registry.npmmirror.com/vite/-/vite-3.2.7.tgz",
+ "integrity": "sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==",
+ "dev": true,
+ "dependencies": {
+ "esbuild": "^0.15.9",
+ "postcss": "^8.4.18",
+ "resolve": "^1.22.1",
+ "rollup": "^2.79.1"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^14.18.0 || >=16.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ },
+ "peerDependencies": {
+ "@types/node": ">= 14",
+ "less": "*",
+ "sass": "*",
+ "stylus": "*",
+ "sugarss": "*",
+ "terser": "^5.4.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true
+ }
+ }
+}
diff --git a/web/package.json b/web/package.json
new file mode 100644
index 0000000..4dd5c8a
--- /dev/null
+++ b/web/package.json
@@ -0,0 +1,23 @@
+{
+ "name": "dfs-generate-web",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "antd": "^5.12.5",
+ "react": "^18.2.0",
+ "react-ace": "^10.1.0",
+ "react-dom": "^18.2.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.24",
+ "@types/react-dom": "^18.0.8",
+ "@vitejs/plugin-react": "^2.2.0",
+ "vite": "^3.2.3"
+ }
+}
\ No newline at end of file
diff --git a/web/public/logo.icon b/web/public/logo.icon
new file mode 100644
index 0000000..c9a99d4
Binary files /dev/null and b/web/public/logo.icon differ
diff --git a/web/public/vite.svg b/web/public/vite.svg
new file mode 100644
index 0000000..e7b8dfb
--- /dev/null
+++ b/web/public/vite.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/web/src/App.css b/web/src/App.css
new file mode 100644
index 0000000..5d9424c
--- /dev/null
+++ b/web/src/App.css
@@ -0,0 +1,26 @@
+#root,
+html,
+body {
+ width: 100vw;
+ height: 100vh;
+}
+
+#app {
+ padding: 20px;
+}
+
+.project {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.logo {
+ height: 100px;
+ width: auto;
+}
+.left {
+ margin: 0px 20px;
+ font-size: 30px;
+ cursor: pointer;
+}
diff --git a/web/src/App.jsx b/web/src/App.jsx
new file mode 100644
index 0000000..fc1185b
--- /dev/null
+++ b/web/src/App.jsx
@@ -0,0 +1,27 @@
+import "./App.css";
+import { GithubOutlined } from "@ant-design/icons";
+import Logo from "./assets/logo.png";
+
+import DFSContent from "./compoents/content";
+
+const visitGithub = () => {
+ window.open("https://github.com/zy7y/dfs-generate");
+};
+
+function App() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default App;
diff --git a/web/src/assets/logo.icon b/web/src/assets/logo.icon
new file mode 100644
index 0000000..c9a99d4
Binary files /dev/null and b/web/src/assets/logo.icon differ
diff --git a/image/logo.png b/web/src/assets/logo.png
similarity index 100%
rename from image/logo.png
rename to web/src/assets/logo.png
diff --git a/web/src/assets/react.svg b/web/src/assets/react.svg
new file mode 100644
index 0000000..6c87de9
--- /dev/null
+++ b/web/src/assets/react.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/web/src/compoents/codegen.jsx b/web/src/compoents/codegen.jsx
new file mode 100644
index 0000000..3809e29
--- /dev/null
+++ b/web/src/compoents/codegen.jsx
@@ -0,0 +1,65 @@
+import { Tabs, message } from "antd";
+
+import PythonEditor from "./python";
+import { TableOutlined } from "@ant-design/icons";
+import { useEffect, useState } from "react";
+import useWindowSize from "../hooks/useWindowSize";
+import { host } from "../conf";
+
+// 单张表
+const TableItem = ({ codes }) => {
+ return (
+ {
+ return {
+ label: item.name,
+ key: item.key,
+ children: ,
+ };
+ })}
+ />
+ );
+};
+
+const CodeGenerate = ({ tables }) => {
+ const [selectTable, setSelectTable] = useState(tables[0]);
+ const [generateCodes, setGenerateCodes] = useState([]);
+
+ const { windowWidth, windowHeight } = useWindowSize();
+
+ const changeTableGetCode = async () => {
+ // await
+ const res = await fetch(`${host}/codegen?tableName=${selectTable}`);
+ const resData = await res.json();
+ console.log(resData);
+ if (resData?.code == 40000) {
+ message.error(resData.msg);
+ } else {
+ setGenerateCodes(resData.data);
+ }
+ };
+ useEffect(() => {
+ changeTableGetCode();
+ }, [selectTable]);
+
+ return (
+ setSelectTable(value)}
+ // tabBarStyle={{ width: 200, overflowX: "auto" }}
+ // indicatorSize={(v) => v - 200}
+ items={tables?.map((item) => {
+ return {
+ label: item,
+ icon: ,
+ key: item,
+ children: ,
+ };
+ })}
+ />
+ );
+};
+export default CodeGenerate;
diff --git a/web/src/compoents/content.jsx b/web/src/compoents/content.jsx
new file mode 100644
index 0000000..4451caf
--- /dev/null
+++ b/web/src/compoents/content.jsx
@@ -0,0 +1,187 @@
+import {
+ Modal,
+ Table,
+ Form,
+ Drawer,
+ Button,
+ Input,
+ InputNumber,
+ message,
+ Affix,
+} from "antd";
+import { useEffect, useState } from "react";
+import { CodepenOutlined, SettingOutlined } from "@ant-design/icons";
+import CodeGenerate from "../compoents/codegen";
+import { host } from "../conf";
+
+const changDBFormRules = [{ required: true, message: "该项必须填写" }];
+
+// 修改配置组件
+const ChangeDB = ({ onDbFinsh }) => {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+const columns = [
+ {
+ title: "表名",
+ dataIndex: "tableName",
+ },
+ {
+ title: "描述",
+ dataIndex: "tableComment",
+ },
+];
+
+const DFSContent = () => {
+ const [tableData, setTableData] = useState([]);
+ const [selectTable, setSelectTable] = useState([]);
+
+ const getTables = async (data = "") => {
+ const res = await fetch(`${host}/tables?tableName=${data}`);
+ const resData = await res.json();
+ if (resData.code === 40000) {
+ message.error(resData.msg);
+ return;
+ }
+ setTableData(resData.data);
+ };
+
+ useEffect(() => {
+ getTables();
+ }, []);
+
+ // 搜索
+ const onSearch = async (values) => {
+ await getTables(values?.tableName);
+ };
+
+ // 选中表
+ const rowSelection = {
+ onChange: (selectedRowKeys, selectedRows) => {
+ console.log(
+ `selectedRowKeys: ${selectedRowKeys}`,
+ "selectedRows: ",
+ selectedRows
+ );
+ setSelectTable(selectedRows.map((e) => e.tableName));
+ },
+ };
+
+ // 修改连接
+
+ const [modalOpen, setModalOpen] = useState(false);
+
+ const onDbFinsh = async (values) => {
+ const res = await fetch(`${host}/conf`, {
+ method: "post",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ body: JSON.stringify(values),
+ });
+ const resBody = await res.json();
+ if (resBody.code === 40000) {
+ message.error(resBody.msg);
+ } else {
+ message.success(resBody.msg);
+ setModalOpen(false);
+ await getTables();
+ }
+ };
+
+ // 生成代码
+ const [openDrawer, setOpenDrawer] = useState(false);
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
setModalOpen(false)}
+ >
+
+
+
+
setOpenDrawer(false)}
+ open={openDrawer}
+ destroyOnClose={true}
+ keyboard={false}
+ >
+
+
+
+ );
+};
+
+export default DFSContent;
diff --git a/web/src/compoents/index.css b/web/src/compoents/index.css
new file mode 100644
index 0000000..b20b655
--- /dev/null
+++ b/web/src/compoents/index.css
@@ -0,0 +1,18 @@
+.editor-wrapper {
+ /* 相对定位 */
+ position: relative;
+}
+
+.copy-icon {
+ /* 绝对定位对于editor-wrapper */
+ position: absolute;
+ top: 10px;
+ right: 20px;
+ z-index: 1;
+ color: #1677ff;
+ font-size: 26px;
+}
+
+.ant-tabs-tab {
+ margin-top: 0px !important;
+}
diff --git a/web/src/compoents/python.jsx b/web/src/compoents/python.jsx
new file mode 100644
index 0000000..7eb9e1b
--- /dev/null
+++ b/web/src/compoents/python.jsx
@@ -0,0 +1,41 @@
+import AceEditor from "react-ace";
+import copy from "copy-to-clipboard";
+import "ace-builds/src-noconflict/mode-python";
+import "ace-builds/src-noconflict/theme-monokai";
+import { message } from "antd";
+import { CopyOutlined } from "@ant-design/icons";
+import "./index.css";
+import useWindowSize from "../hooks/useWindowSize";
+
+const PythonEditor = ({ code }) => {
+ const { windowWidth, windowHeight } = useWindowSize();
+ console.log(windowHeight, windowWidth);
+
+ const handleCopyClick = () => {
+ copy(code);
+ message.success("已复制到剪贴板");
+ };
+
+ return (
+
+ );
+};
+
+export default PythonEditor;
diff --git a/web/src/conf.js b/web/src/conf.js
new file mode 100644
index 0000000..31fa4c0
--- /dev/null
+++ b/web/src/conf.js
@@ -0,0 +1,5 @@
+// 服务地址
+// const host = "http://127.0.0.1:8002";
+const host = "";
+
+export { host };
diff --git a/web/src/hooks/useWindowSize.jsx b/web/src/hooks/useWindowSize.jsx
new file mode 100644
index 0000000..867ba98
--- /dev/null
+++ b/web/src/hooks/useWindowSize.jsx
@@ -0,0 +1,23 @@
+import { useState, useEffect } from "react";
+
+const useWindowSize = () => {
+ const [windowWidth, setWindowWidth] = useState(window.innerWidth);
+ const [windowHeight, setWindowHeight] = useState(window.innerHeight);
+
+ useEffect(() => {
+ const handleResize = () => {
+ setWindowWidth(window.innerWidth);
+ setWindowHeight(window.innerHeight);
+ };
+
+ window.addEventListener("resize", handleResize);
+
+ return () => {
+ window.removeEventListener("resize", handleResize);
+ };
+ }, []);
+
+ return { windowWidth, windowHeight };
+};
+
+export default useWindowSize;
diff --git a/web/src/main.jsx b/web/src/main.jsx
new file mode 100644
index 0000000..d0d585c
--- /dev/null
+++ b/web/src/main.jsx
@@ -0,0 +1,5 @@
+import React from "react";
+import ReactDOM from "react-dom/client";
+import App from "./App";
+
+ReactDOM.createRoot(document.getElementById("root")).render();
diff --git a/web/vite.config.js b/web/vite.config.js
new file mode 100644
index 0000000..f8980cd
--- /dev/null
+++ b/web/vite.config.js
@@ -0,0 +1,8 @@
+import { defineConfig } from "vite";
+import react from "@vitejs/plugin-react";
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ base: "./",
+ plugins: [react()],
+});