├── arm ├── __init__.py ├── libs │ ├── __init__.py │ ├── openai_rpc.py │ └── feishu_auth.py ├── views │ ├── __init__.py │ ├── plus_menu.py │ └── group_bot.py ├── constants.py ├── app.py └── templates │ └── plus_menu_shortcut.html.jinja ├── entrypoint.sh ├── docs ├── SCR-20240401-maea.png └── SCR-20240401-mbag-2.png ├── Pipfile ├── .vscode └── launch.json ├── README.md ├── .gitignore ├── LICENSE └── Pipfile.lock /arm/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /arm/libs/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /arm/views/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /entrypoint.sh: -------------------------------------------------------------------------------- 1 | uvicorn arm.app:app --reload --log-level debug --proxy-headers 2 | 3 | -------------------------------------------------------------------------------- /docs/SCR-20240401-maea.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HatePM/friendly-arm/HEAD/docs/SCR-20240401-maea.png -------------------------------------------------------------------------------- /docs/SCR-20240401-mbag-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HatePM/friendly-arm/HEAD/docs/SCR-20240401-mbag-2.png -------------------------------------------------------------------------------- /Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | openai = "*" 8 | retry = "*" 9 | fastapi = {extras = ["all"], version = "*"} 10 | 11 | [dev-packages] 12 | ipykernel = "*" 13 | 14 | [requires] 15 | python_version = "3.12" 16 | python_full_version = "3.12.2" 17 | -------------------------------------------------------------------------------- /arm/constants.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pathlib 3 | 4 | # 需要设置的环境变量 5 | FEISHU_APP_ID = os.environ["FEISHU_APP_ID"] 6 | FEISHU_APP_SECRET = os.environ["FEISHU_APP_SECRET"] 7 | OPENAI_API_KEY = os.environ["OPENAI_API_KEY"] 8 | 9 | NONCE_STR = "13oEviLbrTo458A3NjrOwS70oTOXVOAm" 10 | 11 | TEMPLATE_DIR = pathlib.Path(__file__).absolute().parent / "templates" 12 | -------------------------------------------------------------------------------- /arm/app.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI 2 | 3 | from arm.views.group_bot import router as group_bot_router 4 | from arm.views.plus_menu import router as plus_menu_router 5 | 6 | app = FastAPI(title="FriendlyArm") 7 | 8 | app.include_router(group_bot_router, prefix="/group_bot", tags=["Group Bot"]) 9 | app.include_router(plus_menu_router, prefix="/plus_menu", tags=["Plus Menu"]) 10 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "webapp", 5 | "type": "debugpy", 6 | "request": "launch", 7 | "module": "uvicorn", 8 | "args": [ 9 | "arm.app:app", 10 | "--reload", 11 | "--log-level", 12 | "debug", 13 | "--proxy-headers", 14 | "--forwarded-allow-ips", 15 | "*", 16 | ], 17 | "jinja": true, 18 | "justMyCode": false 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /arm/libs/openai_rpc.py: -------------------------------------------------------------------------------- 1 | from typing import Literal, Tuple 2 | 3 | from openai import OpenAI 4 | from retry import retry 5 | 6 | from arm.constants import OPENAI_API_KEY 7 | 8 | OPENAI_CLIENT = OpenAI(api_key=OPENAI_API_KEY) 9 | 10 | PROMPT_OF_EVALUATION = """\ 11 | 请对用户输入文本的情感友善度按以下三个等级进行评估,并输出情感友善度等级。请只输出 A、B 或 C,不要包含其他文字。 12 | -【A】表达文本情感极为友善,犹如春风拂面,温暖和善。 13 | -【B】表达文本情感一般,如平静的水面,稳定而平和。 14 | -【C】表达文本情感最为不友善,情绪极度激烈,仿佛置身于危险之中。 15 | """ 16 | 17 | PROMPT_OF_REWRITING = """\ 18 | 请对用户输入文本进行分析并转换为更为友善更加委婉的表达方式,使其更易于被人接受。以下是一些例子: 19 | 20 | 输入:你真是个蠢货,一点用都没有。 21 | 输出:你已经表现的很不错了,但还有提高的空间,希望你能更加努力。 22 | 23 | 输入:你这个文档写的是什么垃圾? 24 | 输出:你写的这篇文档有点不太理想,可以再改进一下吗? 25 | 26 | 输入:bug,bug,一定是后端的 bug! 27 | 输出:嗯,看起来出了点问题,也许是后端出了些小差错吧? 28 | 29 | 请在转换时满足以下几点要求: 30 | - 输出内容长度与原文长度尽量相似; 31 | - 请在改变友善度的同时,尽量准确传达出原文的意思。 32 | - 请仅输出转换后内容,不要包含其他文字,也不要对用户的输入做出回答。 33 | """ 34 | 35 | 36 | @retry(exceptions=Exception, tries=2, delay=1, backoff=2, logger=None) 37 | def evaluate_text_friendly_level(text: str) -> Literal["A", "B", "C"]: 38 | chat_completion = OPENAI_CLIENT.chat.completions.create( 39 | messages=[ 40 | { 41 | "role": "system", 42 | "content": PROMPT_OF_EVALUATION, 43 | }, 44 | { 45 | "role": "user", 46 | "content": text, 47 | }, 48 | ], 49 | model="gpt-3.5-turbo", 50 | temperature=0, 51 | ) 52 | level = (chat_completion.choices[0].message.content).upper() 53 | assert level in ("A", "B", "C") 54 | 55 | return level 56 | 57 | 58 | @retry(exceptions=Exception, tries=2, delay=1, backoff=2, logger=None) 59 | def rewrite_to_friendly_text(text: str) -> str: 60 | chat_completion = OPENAI_CLIENT.chat.completions.create( 61 | messages=[ 62 | { 63 | "role": "system", 64 | "content": PROMPT_OF_REWRITING, 65 | }, 66 | { 67 | "role": "user", 68 | "content": text, 69 | }, 70 | ], 71 | model="gpt-3.5-turbo", 72 | temperature=0, 73 | ) 74 | return chat_completion.choices[0].message.content 75 | 76 | 77 | def evaluate_and_rewrite_text(text: str) -> Tuple[Literal["A", "B", "C"], str]: 78 | level = evaluate_text_friendly_level(text) 79 | if level in ("A", "B"): 80 | return level, text 81 | return level, rewrite_to_friendly_text(text) 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # friendly-arm / 友善之臂 2 | 3 | 这是一个帮助团队进行友善沟通的工具,它可以有效提升团队成员之间的积极互动和合作,保持团队士气与和谐度,从而提高团队的工作效率和生产力。 4 | 5 | ## 主要功能 6 | 7 | ### 友善度评估 8 | 9 | 基于 LLM,我们对消息的友善程度进行了智能评估,并将其划分为三个等级: 10 | 1. 如沐春风:表达文本情感极为友善,犹如春风拂面,温暖和善。 11 | 2. 如水相安:表达文本情感一般,如平静的水面,稳定而平和。 12 | 3. 剑拔弩张:表达文本情感最为不友善,情绪极度激烈,仿佛置身于危险之中。 13 | 14 | ### 友善度重写 15 | 16 | 基于 LLM,我们对不友善的消息进行重写,避免将自己的情绪暴露给对方。 17 | 18 | > 输入:你这个文档写的是什么垃圾? 19 | > 输出:你写的这篇文档有点不太理想,可以再改进一下吗? 20 | 21 | > 输入:bug,bug,一定是后端的 bug! 22 | > 输出:嗯,看起来出了点问题,也许是后端出了些小差错吧? 23 | 24 | ### 与飞书深度集成 25 | 26 | 本项目与飞书/Lark 深度集成,触发入口位于「聊天框“+”菜单」。**基于飞书的多端能力,本项目可以多平台多终端可用,且用户无需安装任何 App。** 27 | 28 | 流程如下: 29 | - 消息输入框 -> More 按钮(“+”菜单) -> 选择「友善之臂」功能; 30 | - 尽情地输入你想表达的情绪和你想说的话; 31 | - 点击 「Magic🪄」按钮,查看友善度评估结果和重新结果; 32 | - 点击「发送」,消息上屏。 33 | 34 |
35 | 功能入口 36 | 功能展示 37 |
38 | 39 | ## One More Thing - 上帝之手 40 | 41 | 为个人,我们带来了友善之臂,让想发言愿意发言有能力发言的人,尽情表达自己。为团队,我们也做了考虑,我们隆重推出友善之臂团队版——上帝之手。 42 | 43 | “上帝之手”是一款飞书/Lark 团队群中的发言的友善度监控及提升工具。他能够在群聊中自动评估团队成员的言论,并将不友好的言论重写为友好言论,以维护群聊的和谐氛围。 44 | 45 | 它的主体是一个飞书/Lark bot。使用 Bot 创建一个群聊,Bot 就会自动监控群聊中的发言,对不友好的发言进行友善度评估和重写,以维护群聊的和谐氛围。 46 | 47 | Demo: 48 | 49 | [](https://github.com/HatePM/friendly-arm/assets/16170578/62605312-f5e3-4a3f-8409-584cc7664b34) 50 | 51 | ## 部署 52 | 53 | ### Run 起来你的服务 54 | 55 | 配置三个环境变量: 56 | - `FEISHU_APP_ID` 飞书开放平台 APP 的 App ID; 57 | - `FEISHU_APP_SECRET` 飞书开放平台 App 的 App Secret; 58 | - `OPENAI_API_KEY` OpenAI 的 API Key。 59 | 60 | 目前调用的是 gpt-3.5-turbo 模型。 61 | 62 | 安装依赖(目前使用 Python 3.12,理论上 Python 3.9+ 都可以) 63 | 64 | ``` 65 | pipenv install 66 | ``` 67 | 68 | 运行服务 69 | 70 | ``` 71 | ./entrypoint.sh 72 | ``` 73 | 74 | ### 飞书开放平台配置 75 | 76 | 1. 在飞书开放平台中新建一个 App; 77 | 78 | 2. 申请以下权限(可能不需要这么细); 79 | - contact:contact.base:readonly 80 | - contact:user.base:readonly 81 | - contact:user.employee_id:readonly 82 | - im:chat 83 | - im:message.group_at_msg 84 | - im:message.group_at_msg:readonly 85 | - im:message.group_msg 86 | - im:message.p2p_msg 87 | - im:message.p2p_msg:readonly 88 | - im:message:readonly 89 | - im:message:send_as_bot 90 | 91 | 3. 配置服务地址(假设域名为 `https://example.com`): 92 | - 网页应用配置:`https://example.com/plus_menu/homepage` 93 | - 聊天框“+”菜单:`https://applink.feishu.cn/client/web_app/open?appId=&mode=sidebar` 94 | - 事件回调:`https://example.com/group_bot/webhook` 95 | 96 | ## 说明 97 | 98 | 本项目为 2024 年彩云 10 周年 Hackathon 作品,由「I like working with PM」团队完成。 99 | -------------------------------------------------------------------------------- /arm/libs/feishu_auth.py: -------------------------------------------------------------------------------- 1 | import time 2 | 3 | import httpx 4 | from pydantic import BaseModel 5 | 6 | from arm.constants import FEISHU_APP_ID, FEISHU_APP_SECRET 7 | 8 | 9 | class TenantAccessTokenCache(BaseModel): 10 | expired_at: int 11 | token: str 12 | 13 | 14 | class JSSDKTicketCache(BaseModel): 15 | expired_at: int 16 | ticket: str 17 | 18 | 19 | class FeishuAuth(object): 20 | def __init__(self, app_id, app_secret): 21 | self.app_id = app_id 22 | self.app_secret = app_secret 23 | self._tenant_access_token_cache = None 24 | self._jssdk_ticket_cache = None 25 | self.get_tenant_access_token() 26 | self.get_jssdk_ticket() 27 | 28 | def _get_tenant_access_token(self): 29 | url = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal" 30 | response = httpx.post( 31 | url, 32 | json={"app_id": self.app_id, "app_secret": self.app_secret}, 33 | ) 34 | response.raise_for_status() 35 | # { 36 | # "code": 0, 37 | # "msg": "ok", 38 | # "tenant_access_token": "t-caecc734c2e3328a62489fe0648c4b98779515d3", 39 | # "expire": 7200, 40 | # } 41 | return response.json() 42 | 43 | def get_tenant_access_token(self) -> str: 44 | now = int(time.time()) 45 | if ( 46 | self._tenant_access_token_cache 47 | and self._tenant_access_token_cache.expired_at > now 48 | ): 49 | return self._tenant_access_token_cache.token 50 | token_data = self._get_tenant_access_token() 51 | self._tenant_access_token_cache = TenantAccessTokenCache( 52 | expired_at=now + token_data["expire"] - 100, 53 | token=token_data["tenant_access_token"], 54 | ) 55 | return self._tenant_access_token_cache.token 56 | 57 | def _get_jssdk_ticket(self): 58 | url = "https://open.feishu.cn/open-apis/jssdk/ticket/get" 59 | headers = { 60 | "Authorization": "Bearer " + self.get_tenant_access_token(), 61 | "Content-Type": "application/json", 62 | } 63 | resp = httpx.post(url=url, headers=headers) 64 | resp.raise_for_status() 65 | # { 66 | # "code": 0, 67 | # "msg": "ok", 68 | # "data": { 69 | # "expire_in": 7200, 70 | # "ticket": "0560604568baf296731aa37f0c8ebe3e049c19d7", 71 | # }, 72 | # } 73 | return resp.json()["data"] 74 | 75 | def get_jssdk_ticket(self) -> str: 76 | now = int(time.time()) 77 | if self._jssdk_ticket_cache and self._jssdk_ticket_cache.expired_at > now: 78 | return self._jssdk_ticket_cache.ticket 79 | ticket_data = self._get_jssdk_ticket() 80 | self._jssdk_ticket_cache = JSSDKTicketCache( 81 | expired_at=now + ticket_data["expire_in"] - 100, 82 | ticket=ticket_data["ticket"], 83 | ) 84 | return self._jssdk_ticket_cache.ticket 85 | 86 | 87 | FEISHU_AUTH = FeishuAuth(app_id=FEISHU_APP_ID, app_secret=FEISHU_APP_SECRET) 88 | -------------------------------------------------------------------------------- /arm/templates/plus_menu_shortcut.html.jinja: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 友善之臂 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 27 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /arm/views/plus_menu.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import time 3 | 4 | from fastapi import APIRouter, Body, Request 5 | from fastapi.responses import HTMLResponse 6 | from fastapi.templating import Jinja2Templates 7 | from pydantic import constr 8 | 9 | from arm.constants import FEISHU_APP_ID, NONCE_STR, TEMPLATE_DIR 10 | from arm.libs.feishu_auth import FEISHU_AUTH 11 | from arm.libs.openai_rpc import evaluate_and_rewrite_text 12 | 13 | router = APIRouter() 14 | 15 | 16 | @router.get("/homepage", response_class=HTMLResponse) 17 | def render_homepage(request: Request): 18 | amis_schema = [ 19 | { 20 | "type": "form", 21 | "title": "会员信息", 22 | "wrapWithPanel": False, 23 | "mode": "inline", 24 | "body": [ 25 | { 26 | "type": "static-mapping", 27 | "label": "会员信息", 28 | "value": "内测", 29 | "map": { 30 | "内测": "彩云内测用户 / ∞", 31 | }, 32 | }, 33 | ], 34 | }, 35 | { 36 | "type": "form", 37 | "title": "输入", 38 | "api": "/plus_menu/api/magic_writing", 39 | "reload": "resultForm?level=${level}&output=${output}", 40 | "autoFocus": True, 41 | "body": [ 42 | { 43 | "name": "text", 44 | "type": "textarea", 45 | "required": True, 46 | "trimContents": True, 47 | "showCounter": True, 48 | "minRows": 5, 49 | "maxLength": 2000, 50 | "placeholder": "请在此输入你想说的话", 51 | }, 52 | ], 53 | "actions": [ 54 | { 55 | "type": "submit", 56 | "label": "Magic🪄", 57 | "level": "light", 58 | "onEvent": { 59 | "click": { 60 | "actions": [ 61 | {"actionType": "show", "componentId": "resultForm"} 62 | ] 63 | } 64 | }, 65 | } 66 | ], 67 | }, 68 | { 69 | "name": "resultForm", 70 | "id": "resultForm", 71 | "visible": False, 72 | "type": "form", 73 | "title": "输出", 74 | "body": [ 75 | { 76 | "label": "友善度评级", 77 | "name": "level", 78 | "type": "static-mapping", 79 | "map": { 80 | "A": "如沐春风", 81 | "B": "如水相安", 82 | "C": "剑拔弩张", 83 | }, 84 | }, 85 | { 86 | "label": "重写结果", 87 | "name": "output", 88 | "type": "textarea", 89 | "trimContents": True, 90 | "minRows": 5, 91 | "description": "如果对友善之臂的输出结果不满意,可以自由修改", 92 | }, 93 | ], 94 | "actions": [ 95 | { 96 | "label": "发送到聊天", 97 | "type": "button", 98 | "level": "primary", 99 | "onEvent": { 100 | "click": { 101 | "actions": [ 102 | { 103 | "actionType": "custom", 104 | "script": "sendFeishuMessage(event.data.output);", 105 | } 106 | ] 107 | } 108 | }, 109 | }, 110 | ], 111 | }, 112 | ] 113 | return Jinja2Templates(directory=TEMPLATE_DIR).TemplateResponse( 114 | name="plus_menu_shortcut.html.jinja", 115 | context={ 116 | "request": request, 117 | "amis_schema": amis_schema, 118 | }, 119 | ) 120 | 121 | 122 | @router.post("/api/magic_writing") 123 | def magic_writing(text: constr(strip_whitespace=True) = Body(..., embed=True)): 124 | level, output = evaluate_and_rewrite_text(text) 125 | return {"level": level, "output": output} 126 | 127 | 128 | @router.get("/api/lark_sign") 129 | def generate_lark_sign(url: str): 130 | ticket = FEISHU_AUTH.get_jssdk_ticket() 131 | timestamp = int(time.time() * 1000) 132 | verify_str = ( 133 | f"jsapi_ticket={ticket}&noncestr={NONCE_STR}×tamp={timestamp}&url={url}" 134 | ) 135 | signature = hashlib.sha1(verify_str.encode("utf-8")).hexdigest() 136 | return { 137 | "appid": FEISHU_APP_ID, 138 | "signature": signature, 139 | "noncestr": NONCE_STR, 140 | "timestamp": timestamp, 141 | } 142 | -------------------------------------------------------------------------------- /arm/views/group_bot.py: -------------------------------------------------------------------------------- 1 | import json 2 | import time 3 | import uuid 4 | 5 | import httpx 6 | from fastapi import APIRouter, BackgroundTasks, Request 7 | 8 | from arm.libs.feishu_auth import FEISHU_AUTH 9 | from arm.libs.openai_rpc import evaluate_text_friendly_level, rewrite_to_friendly_text 10 | 11 | router = APIRouter() 12 | 13 | 14 | def delete_msg(msg_id: str): 15 | url = f"https://open.feishu.cn/open-apis/im/v1/messages/{msg_id}" 16 | response = httpx.delete( 17 | url, 18 | headers={"Authorization": f"Bearer {FEISHU_AUTH.get_tenant_access_token()}"}, 19 | ) 20 | content = response.text 21 | print(content) 22 | return 23 | 24 | 25 | def check_if_make_new_group(data: dict): 26 | chat_type = data["event"]["message"]["chat_type"] 27 | event_type = data["header"]["event_type"] 28 | chat_type = data["event"]["message"]["chat_type"] 29 | message_type = data["event"]["message"]["message_type"] 30 | if event_type != "im.message.receive_v1" or chat_type != "group" or message_type != "text": 31 | print("Not a message event") 32 | return 33 | content = json.loads(data["event"]["message"]["content"])["text"] 34 | print(chat_type, content) 35 | if chat_type == "p2p" and content == "/new_group": 36 | return True 37 | return False 38 | 39 | 40 | def make_new_group(data: dict): 41 | url = "https://open.feishu.cn/open-apis/im/v1/chats" 42 | params = { 43 | "user_id_type": "open_id", 44 | "set_bot_manager": "true", 45 | } 46 | body = { 47 | "user_id_list": [data["event"]["sender"]["sender_id"]["open_id"]], 48 | } 49 | response = httpx.post( 50 | url, 51 | headers={"Authorization": f"Bearer {FEISHU_AUTH.get_tenant_access_token()}"}, 52 | params=params, 53 | json=body, 54 | ) 55 | body = response.json() 56 | print(body) 57 | 58 | 59 | def get_user_info(open_id: str): 60 | url = f"https://open.feishu.cn/open-apis/contact/v3/users/{open_id}" 61 | params = { 62 | "user_id_type": "open_id", 63 | } 64 | response = httpx.get( 65 | url, 66 | headers={"Authorization": f"Bearer {FEISHU_AUTH.get_tenant_access_token()}"}, 67 | params=params, 68 | ) 69 | body = response.json() 70 | print(body) 71 | return body # ["data"]["user"]["name"] 72 | 73 | 74 | def send_msg(data: dict, text: str): 75 | chat_id = data["event"]["message"]["chat_id"] 76 | url = "https://open.feishu.cn/open-apis/im/v1/messages" 77 | params = {"receive_id_type": "chat_id"} 78 | user_id = data["event"]["sender"]["sender_id"]["open_id"] 79 | user_name = get_user_info(user_id)["data"]["user"]["name"] 80 | body = { 81 | "receive_id": chat_id, 82 | "msg_type": "text", 83 | "content": json.dumps( 84 | {"text": f"{user_name}: {text}"}, 85 | ), 86 | "uuid": str(uuid.uuid4()), 87 | } 88 | payload = json.dumps(body) 89 | print(payload) 90 | response = httpx.post( 91 | url, 92 | headers={ 93 | "Authorization": f"Bearer {FEISHU_AUTH.get_tenant_access_token()}", 94 | "Content-Type": "application/json", 95 | }, 96 | params=params, 97 | data=payload, 98 | ) 99 | content = response.text 100 | print(content) 101 | 102 | 103 | def evaluate_and_rewrite_msg(data: dict): 104 | 105 | start = time.time() 106 | 107 | # sender_id = data["event"]["sender"]["sender_id"]["open_id"] 108 | 109 | event_type = data["header"]["event_type"] 110 | chat_type = data["event"]["message"]["chat_type"] 111 | message_type = data["event"]["message"]["message_type"] 112 | if event_type != "im.message.receive_v1" or chat_type != "group" or message_type != "text": 113 | print("Not a message event") 114 | return 115 | text = json.loads(data["event"]["message"]["content"])["text"] 116 | level = evaluate_text_friendly_level(text) 117 | evaluate_end = time.time() 118 | print(f"evaluate cost: {evaluate_end - start}") 119 | if level in ["A", "B"]: 120 | print(f"Level {level})") 121 | return 122 | msg_id = data["event"]["message"]["message_id"] 123 | delete_msg(msg_id) 124 | output = rewrite_to_friendly_text(text) 125 | rewrite_end = time.time() 126 | print(f"rewrite cost: {rewrite_end - evaluate_end}") 127 | res = {"level": level, "output": output} 128 | print(res) 129 | send_msg(data, output) 130 | end = time.time() 131 | print(f"total cost: {end - start}") 132 | return 133 | 134 | 135 | def process_event(data: dict): 136 | if check_if_make_new_group(data): 137 | make_new_group(data) 138 | return 139 | evaluate_and_rewrite_msg(data) 140 | 141 | 142 | @router.post("/webhook") 143 | async def webhook(request: Request, background_tasks: BackgroundTasks): 144 | body = await request.body() 145 | print(body) 146 | data = json.loads(body) 147 | print(json.dumps(data, ensure_ascii=False)) 148 | if "challenge" in data: 149 | return {"challenge": data["challenge"]} 150 | background_tasks.add_task(process_event, data) 151 | return {"message": "Webhook received"} 152 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/python,macos,visualstudiocode 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=python,macos,visualstudiocode 3 | 4 | ### macOS ### 5 | # General 6 | .DS_Store 7 | .AppleDouble 8 | .LSOverride 9 | 10 | # Icon must end with two \r 11 | Icon 12 | 13 | 14 | # Thumbnails 15 | ._* 16 | 17 | # Files that might appear in the root of a volume 18 | .DocumentRevisions-V100 19 | .fseventsd 20 | .Spotlight-V100 21 | .TemporaryItems 22 | .Trashes 23 | .VolumeIcon.icns 24 | .com.apple.timemachine.donotpresent 25 | 26 | # Directories potentially created on remote AFP share 27 | .AppleDB 28 | .AppleDesktop 29 | Network Trash Folder 30 | Temporary Items 31 | .apdisk 32 | 33 | ### macOS Patch ### 34 | # iCloud generated files 35 | *.icloud 36 | 37 | ### Python ### 38 | # Byte-compiled / optimized / DLL files 39 | __pycache__/ 40 | *.py[cod] 41 | *$py.class 42 | 43 | # C extensions 44 | *.so 45 | 46 | # Distribution / packaging 47 | .Python 48 | build/ 49 | develop-eggs/ 50 | dist/ 51 | downloads/ 52 | eggs/ 53 | .eggs/ 54 | lib/ 55 | lib64/ 56 | parts/ 57 | sdist/ 58 | var/ 59 | wheels/ 60 | share/python-wheels/ 61 | *.egg-info/ 62 | .installed.cfg 63 | *.egg 64 | MANIFEST 65 | 66 | # PyInstaller 67 | # Usually these files are written by a python script from a template 68 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 69 | *.manifest 70 | *.spec 71 | 72 | # Installer logs 73 | pip-log.txt 74 | pip-delete-this-directory.txt 75 | 76 | # Unit test / coverage reports 77 | htmlcov/ 78 | .tox/ 79 | .nox/ 80 | .coverage 81 | .coverage.* 82 | .cache 83 | nosetests.xml 84 | coverage.xml 85 | *.cover 86 | *.py,cover 87 | .hypothesis/ 88 | .pytest_cache/ 89 | cover/ 90 | 91 | # Translations 92 | *.mo 93 | *.pot 94 | 95 | # Django stuff: 96 | *.log 97 | local_settings.py 98 | db.sqlite3 99 | db.sqlite3-journal 100 | 101 | # Flask stuff: 102 | instance/ 103 | .webassets-cache 104 | 105 | # Scrapy stuff: 106 | .scrapy 107 | 108 | # Sphinx documentation 109 | docs/_build/ 110 | 111 | # PyBuilder 112 | .pybuilder/ 113 | target/ 114 | 115 | # Jupyter Notebook 116 | .ipynb_checkpoints 117 | 118 | # IPython 119 | profile_default/ 120 | ipython_config.py 121 | 122 | # pyenv 123 | # For a library or package, you might want to ignore these files since the code is 124 | # intended to run in multiple environments; otherwise, check them in: 125 | # .python-version 126 | 127 | # pipenv 128 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 129 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 130 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 131 | # install all needed dependencies. 132 | #Pipfile.lock 133 | 134 | # poetry 135 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 136 | # This is especially recommended for binary packages to ensure reproducibility, and is more 137 | # commonly ignored for libraries. 138 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 139 | #poetry.lock 140 | 141 | # pdm 142 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 143 | #pdm.lock 144 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 145 | # in version control. 146 | # https://pdm.fming.dev/#use-with-ide 147 | .pdm.toml 148 | 149 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 150 | __pypackages__/ 151 | 152 | # Celery stuff 153 | celerybeat-schedule 154 | celerybeat.pid 155 | 156 | # SageMath parsed files 157 | *.sage.py 158 | 159 | # Environments 160 | .env 161 | .venv 162 | env/ 163 | venv/ 164 | ENV/ 165 | env.bak/ 166 | venv.bak/ 167 | 168 | # Spyder project settings 169 | .spyderproject 170 | .spyproject 171 | 172 | # Rope project settings 173 | .ropeproject 174 | 175 | # mkdocs documentation 176 | /site 177 | 178 | # mypy 179 | .mypy_cache/ 180 | .dmypy.json 181 | dmypy.json 182 | 183 | # Pyre type checker 184 | .pyre/ 185 | 186 | # pytype static type analyzer 187 | .pytype/ 188 | 189 | # Cython debug symbols 190 | cython_debug/ 191 | 192 | # PyCharm 193 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 194 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 195 | # and can be added to the global gitignore or merged into this file. For a more nuclear 196 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 197 | #.idea/ 198 | 199 | ### Python Patch ### 200 | # Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration 201 | poetry.toml 202 | 203 | # ruff 204 | .ruff_cache/ 205 | 206 | # LSP config files 207 | pyrightconfig.json 208 | 209 | ### VisualStudioCode ### 210 | .vscode/* 211 | !.vscode/settings.json 212 | !.vscode/tasks.json 213 | !.vscode/launch.json 214 | !.vscode/extensions.json 215 | !.vscode/*.code-snippets 216 | 217 | # Local History for Visual Studio Code 218 | .history/ 219 | 220 | # Built Visual Studio Code Extensions 221 | *.vsix 222 | 223 | ### VisualStudioCode Patch ### 224 | # Ignore all local history of files 225 | .history 226 | .ionide 227 | 228 | # End of https://www.toptal.com/developers/gitignore/api/python,macos,visualstudiocode 229 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | 635 | Copyright (C) 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | Copyright (C) 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /Pipfile.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_meta": { 3 | "hash": { 4 | "sha256": "bb55d7694843d978b7c1a78204d8b5b2056685f11ebd45c0467283f34cc2fd1e" 5 | }, 6 | "pipfile-spec": 6, 7 | "requires": { 8 | "python_full_version": "3.12.2", 9 | "python_version": "3.12" 10 | }, 11 | "sources": [ 12 | { 13 | "name": "pypi", 14 | "url": "https://pypi.org/simple", 15 | "verify_ssl": true 16 | } 17 | ] 18 | }, 19 | "default": { 20 | "annotated-types": { 21 | "hashes": [ 22 | "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43", 23 | "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d" 24 | ], 25 | "markers": "python_version >= '3.8'", 26 | "version": "==0.6.0" 27 | }, 28 | "anyio": { 29 | "hashes": [ 30 | "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8", 31 | "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6" 32 | ], 33 | "markers": "python_version >= '3.8'", 34 | "version": "==4.3.0" 35 | }, 36 | "certifi": { 37 | "hashes": [ 38 | "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", 39 | "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" 40 | ], 41 | "markers": "python_version >= '3.6'", 42 | "version": "==2024.2.2" 43 | }, 44 | "click": { 45 | "hashes": [ 46 | "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", 47 | "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" 48 | ], 49 | "markers": "python_version >= '3.7'", 50 | "version": "==8.1.7" 51 | }, 52 | "decorator": { 53 | "hashes": [ 54 | "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", 55 | "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" 56 | ], 57 | "markers": "python_version >= '3.5'", 58 | "version": "==5.1.1" 59 | }, 60 | "distro": { 61 | "hashes": [ 62 | "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", 63 | "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2" 64 | ], 65 | "markers": "python_version >= '3.6'", 66 | "version": "==1.9.0" 67 | }, 68 | "dnspython": { 69 | "hashes": [ 70 | "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", 71 | "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc" 72 | ], 73 | "markers": "python_version >= '3.8'", 74 | "version": "==2.6.1" 75 | }, 76 | "email-validator": { 77 | "hashes": [ 78 | "sha256:200a70680ba08904be6d1eef729205cc0d687634399a5924d842533efb824b84", 79 | "sha256:97d882d174e2a65732fb43bfce81a3a834cbc1bde8bf419e30ef5ea976370a05" 80 | ], 81 | "version": "==2.1.1" 82 | }, 83 | "fastapi": { 84 | "extras": [ 85 | "all" 86 | ], 87 | "hashes": [ 88 | "sha256:266775f0dcc95af9d3ef39bad55cff525329a931d5fd51930aadd4f428bf7ff3", 89 | "sha256:87a1f6fb632a218222c5984be540055346a8f5d8a68e8f6fb647b1dc9934de4b" 90 | ], 91 | "markers": "python_version >= '3.8'", 92 | "version": "==0.110.0" 93 | }, 94 | "h11": { 95 | "hashes": [ 96 | "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", 97 | "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" 98 | ], 99 | "markers": "python_version >= '3.7'", 100 | "version": "==0.14.0" 101 | }, 102 | "httpcore": { 103 | "hashes": [ 104 | "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", 105 | "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5" 106 | ], 107 | "markers": "python_version >= '3.8'", 108 | "version": "==1.0.5" 109 | }, 110 | "httptools": { 111 | "hashes": [ 112 | "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563", 113 | "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142", 114 | "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d", 115 | "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b", 116 | "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4", 117 | "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb", 118 | "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658", 119 | "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084", 120 | "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2", 121 | "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97", 122 | "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837", 123 | "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3", 124 | "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58", 125 | "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da", 126 | "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d", 127 | "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90", 128 | "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0", 129 | "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1", 130 | "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2", 131 | "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e", 132 | "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0", 133 | "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf", 134 | "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc", 135 | "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3", 136 | "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503", 137 | "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a", 138 | "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3", 139 | "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949", 140 | "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84", 141 | "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb", 142 | "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a", 143 | "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f", 144 | "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e", 145 | "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81", 146 | "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185", 147 | "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3" 148 | ], 149 | "version": "==0.6.1" 150 | }, 151 | "httpx": { 152 | "hashes": [ 153 | "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", 154 | "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5" 155 | ], 156 | "markers": "python_version >= '3.8'", 157 | "version": "==0.27.0" 158 | }, 159 | "idna": { 160 | "hashes": [ 161 | "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", 162 | "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" 163 | ], 164 | "markers": "python_version >= '3.5'", 165 | "version": "==3.6" 166 | }, 167 | "itsdangerous": { 168 | "hashes": [ 169 | "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44", 170 | "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a" 171 | ], 172 | "version": "==2.1.2" 173 | }, 174 | "jinja2": { 175 | "hashes": [ 176 | "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa", 177 | "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90" 178 | ], 179 | "version": "==3.1.3" 180 | }, 181 | "markupsafe": { 182 | "hashes": [ 183 | "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", 184 | "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", 185 | "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", 186 | "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", 187 | "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", 188 | "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", 189 | "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", 190 | "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", 191 | "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", 192 | "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", 193 | "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", 194 | "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", 195 | "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", 196 | "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", 197 | "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", 198 | "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", 199 | "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", 200 | "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", 201 | "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", 202 | "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", 203 | "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", 204 | "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", 205 | "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", 206 | "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", 207 | "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", 208 | "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", 209 | "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", 210 | "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", 211 | "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", 212 | "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", 213 | "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", 214 | "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", 215 | "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", 216 | "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", 217 | "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", 218 | "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", 219 | "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", 220 | "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", 221 | "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", 222 | "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", 223 | "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", 224 | "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", 225 | "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", 226 | "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", 227 | "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", 228 | "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", 229 | "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", 230 | "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", 231 | "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", 232 | "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", 233 | "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", 234 | "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", 235 | "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", 236 | "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", 237 | "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", 238 | "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", 239 | "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", 240 | "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", 241 | "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", 242 | "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" 243 | ], 244 | "markers": "python_version >= '3.7'", 245 | "version": "==2.1.5" 246 | }, 247 | "openai": { 248 | "hashes": [ 249 | "sha256:37b514e9c0ff45383ec9b242abd0f7859b1080d4b54b61393ed341ecad1b8eb9", 250 | "sha256:7a465994a7ccf677a110c6cc2ef9d86229bad42c060b585b67049aa749f3b774" 251 | ], 252 | "index": "pypi", 253 | "markers": "python_full_version >= '3.7.1'", 254 | "version": "==1.14.3" 255 | }, 256 | "orjson": { 257 | "hashes": [ 258 | "sha256:115498c4ad34188dcb73464e8dc80e490a3e5e88a925907b6fedcf20e545001a", 259 | "sha256:13b5d3c795b09a466ec9fcf0bd3ad7b85467d91a60113885df7b8d639a9d374b", 260 | "sha256:175a41500ebb2fdf320bf78e8b9a75a1279525b62ba400b2b2444e274c2c8bee", 261 | "sha256:1897aa25a944cec774ce4a0e1c8e98fb50523e97366c637b7d0cddabc42e6643", 262 | "sha256:1bef1050b1bdc9ea6c0d08468e3e61c9386723633b397e50b82fda37b3563d72", 263 | "sha256:1de3fd5c7b208d836f8ecb4526995f0d5877153a4f6f12f3e9bf11e49357de98", 264 | "sha256:22c2f7e377ac757bd3476ecb7480c8ed79d98ef89648f0176deb1da5cd014eb7", 265 | "sha256:237ba922aef472761acd697eef77fef4831ab769a42e83c04ac91e9f9e08fa0e", 266 | "sha256:23c12bb4ced1c3308eff7ba5c63ef8f0edb3e4c43c026440247dd6c1c61cea4b", 267 | "sha256:30707e646080dd3c791f22ce7e4a2fc2438765408547c10510f1f690bd336217", 268 | "sha256:30d795a24be16c03dca0c35ca8f9c8eaaa51e3342f2c162d327bd0225118794a", 269 | "sha256:33e6655a2542195d6fd9f850b428926559dee382f7a862dae92ca97fea03a5ad", 270 | "sha256:400c5b7c4222cb27b5059adf1fb12302eebcabf1978f33d0824aa5277ca899bd", 271 | "sha256:414e5293b82373606acf0d66313aecb52d9c8c2404b1900683eb32c3d042dbd7", 272 | "sha256:4251964db47ef090c462a2d909f16c7c7d5fe68e341dabce6702879ec26d1134", 273 | "sha256:4329c1d24fd130ee377e32a72dc54a3c251e6706fccd9a2ecb91b3606fddd998", 274 | "sha256:5127478260db640323cea131ee88541cb1a9fbce051f0b22fa2f0892f44da302", 275 | "sha256:57d017863ec8aa4589be30a328dacd13c2dc49de1c170bc8d8c8a98ece0f2925", 276 | "sha256:5d42768db6f2ce0162544845facb7c081e9364a5eb6d2ef06cd17f6050b048d8", 277 | "sha256:5dcb32e949eae80fb335e63b90e5808b4b0f64e31476b3777707416b41682db5", 278 | "sha256:60c0b1bdbccd959ebd1575bd0147bd5e10fc76f26216188be4a36b691c937077", 279 | "sha256:658ca5cee3379dd3d37dbacd43d42c1b4feee99a29d847ef27a1cb18abdfb23f", 280 | "sha256:6735dd4a5a7b6df00a87d1d7a02b84b54d215fb7adac50dd24da5997ffb4798d", 281 | "sha256:73bbbdc43d520204d9ef0817ac03fa49c103c7f9ea94f410d2950755be2c349c", 282 | "sha256:8acd4b82a5f3a3ec8b1dc83452941d22b4711964c34727eb1e65449eead353ca", 283 | "sha256:90bfc137c75c31d32308fd61951d424424426ddc39a40e367704661a9ee97095", 284 | "sha256:9587053e0cefc284e4d1cd113c34468b7d3f17666d22b185ea654f0775316a26", 285 | "sha256:98c1bfc6a9bec52bc8f0ab9b86cc0874b0299fccef3562b793c1576cf3abb570", 286 | "sha256:9bf565a69e0082ea348c5657401acec3cbbb31564d89afebaee884614fba36b4", 287 | "sha256:aa7d507c7493252c0a0264b5cc7e20fa2f8622b8a83b04d819b5ce32c97cf57b", 288 | "sha256:ade1e21dfde1d37feee8cf6464c20a2f41fa46c8bcd5251e761903e46102dc6b", 289 | "sha256:b2d014cf8d4dc9f03fc9f870de191a49a03b1bcda51f2a957943fb9fafe55aac", 290 | "sha256:b6ebc17cfbbf741f5c1a888d1854354536f63d84bee537c9a7c0335791bb9009", 291 | "sha256:b98345529bafe3c06c09996b303fc0a21961820d634409b8639bc16bd4f21b63", 292 | "sha256:ba4d8cac5f2e2cff36bea6b6481cdb92b38c202bcec603d6f5ff91960595a1ed", 293 | "sha256:c4f60db24161534764277f798ef53b9d3063092f6d23f8f962b4a97edfa997a0", 294 | "sha256:c90681333619d78360d13840c7235fdaf01b2b129cb3a4f1647783b1971542b6", 295 | "sha256:cd583341218826f48bd7c6ebf3310b4126216920853cbc471e8dbeaf07b0b80e", 296 | "sha256:d16c6963ddf3b28c0d461641517cd312ad6b3cf303d8b87d5ef3fa59d6844337", 297 | "sha256:d2817877d0b69f78f146ab305c5975d0618df41acf8811249ee64231f5953fee", 298 | "sha256:e286a51def6626f1e0cc134ba2067dcf14f7f4b9550f6dd4535fd9d79000040b", 299 | "sha256:e62ba42bfe64c60c1bc84799944f80704e996592c6b9e14789c8e2a303279912", 300 | "sha256:eadecaa16d9783affca33597781328e4981b048615c2ddc31c47a51b833d6319", 301 | "sha256:ef0f19fdfb6553342b1882f438afd53c7cb7aea57894c4490c43e4431739c700", 302 | "sha256:f93e33f67729d460a177ba285002035d3f11425ed3cebac5f6ded4ef36b28344", 303 | "sha256:feaed5bb09877dc27ed0d37f037ddef6cb76d19aa34b108db270d27d3d2ef747" 304 | ], 305 | "version": "==3.10.0" 306 | }, 307 | "py": { 308 | "hashes": [ 309 | "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", 310 | "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378" 311 | ], 312 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", 313 | "version": "==1.11.0" 314 | }, 315 | "pydantic": { 316 | "hashes": [ 317 | "sha256:b1704e0847db01817624a6b86766967f552dd9dbf3afba4004409f908dcc84e6", 318 | "sha256:cc46fce86607580867bdc3361ad462bab9c222ef042d3da86f2fb333e1d916c5" 319 | ], 320 | "markers": "python_version >= '3.8'", 321 | "version": "==2.6.4" 322 | }, 323 | "pydantic-core": { 324 | "hashes": [ 325 | "sha256:00ee1c97b5364b84cb0bd82e9bbf645d5e2871fb8c58059d158412fee2d33d8a", 326 | "sha256:0d32576b1de5a30d9a97f300cc6a3f4694c428d956adbc7e6e2f9cad279e45ed", 327 | "sha256:0df446663464884297c793874573549229f9eca73b59360878f382a0fc085979", 328 | "sha256:0f56ae86b60ea987ae8bcd6654a887238fd53d1384f9b222ac457070b7ac4cff", 329 | "sha256:13dcc4802961b5f843a9385fc821a0b0135e8c07fc3d9949fd49627c1a5e6ae5", 330 | "sha256:162e498303d2b1c036b957a1278fa0899d02b2842f1ff901b6395104c5554a45", 331 | "sha256:1b662180108c55dfbf1280d865b2d116633d436cfc0bba82323554873967b340", 332 | "sha256:1cac689f80a3abab2d3c0048b29eea5751114054f032a941a32de4c852c59cad", 333 | "sha256:21b888c973e4f26b7a96491c0965a8a312e13be108022ee510248fe379a5fa23", 334 | "sha256:287073c66748f624be4cef893ef9174e3eb88fe0b8a78dc22e88eca4bc357ca6", 335 | "sha256:2a1ef6a36fdbf71538142ed604ad19b82f67b05749512e47f247a6ddd06afdc7", 336 | "sha256:2a72fb9963cba4cd5793854fd12f4cfee731e86df140f59ff52a49b3552db241", 337 | "sha256:2acca2be4bb2f2147ada8cac612f8a98fc09f41c89f87add7256ad27332c2fda", 338 | "sha256:2f583bd01bbfbff4eaee0868e6fc607efdfcc2b03c1c766b06a707abbc856187", 339 | "sha256:33809aebac276089b78db106ee692bdc9044710e26f24a9a2eaa35a0f9fa70ba", 340 | "sha256:36fa178aacbc277bc6b62a2c3da95226520da4f4e9e206fdf076484363895d2c", 341 | "sha256:4204e773b4b408062960e65468d5346bdfe139247ee5f1ca2a378983e11388a2", 342 | "sha256:4384a8f68ddb31a0b0c3deae88765f5868a1b9148939c3f4121233314ad5532c", 343 | "sha256:456855f57b413f077dff513a5a28ed838dbbb15082ba00f80750377eed23d132", 344 | "sha256:49d5d58abd4b83fb8ce763be7794d09b2f50f10aa65c0f0c1696c677edeb7cbf", 345 | "sha256:4ac6b4ce1e7283d715c4b729d8f9dab9627586dafce81d9eaa009dd7f25dd972", 346 | "sha256:4df8a199d9f6afc5ae9a65f8f95ee52cae389a8c6b20163762bde0426275b7db", 347 | "sha256:500960cb3a0543a724a81ba859da816e8cf01b0e6aaeedf2c3775d12ee49cade", 348 | "sha256:519ae0312616026bf4cedc0fe459e982734f3ca82ee8c7246c19b650b60a5ee4", 349 | "sha256:578114bc803a4c1ff9946d977c221e4376620a46cf78da267d946397dc9514a8", 350 | "sha256:5c5cbc703168d1b7a838668998308018a2718c2130595e8e190220238addc96f", 351 | "sha256:6162f8d2dc27ba21027f261e4fa26f8bcb3cf9784b7f9499466a311ac284b5b9", 352 | "sha256:704d35ecc7e9c31d48926150afada60401c55efa3b46cd1ded5a01bdffaf1d48", 353 | "sha256:716b542728d4c742353448765aa7cdaa519a7b82f9564130e2b3f6766018c9ec", 354 | "sha256:72282ad4892a9fb2da25defeac8c2e84352c108705c972db82ab121d15f14e6d", 355 | "sha256:7233d65d9d651242a68801159763d09e9ec96e8a158dbf118dc090cd77a104c9", 356 | "sha256:732da3243e1b8d3eab8c6ae23ae6a58548849d2e4a4e03a1924c8ddf71a387cb", 357 | "sha256:75b81e678d1c1ede0785c7f46690621e4c6e63ccd9192af1f0bd9d504bbb6bf4", 358 | "sha256:75f76ee558751746d6a38f89d60b6228fa174e5172d143886af0f85aa306fd89", 359 | "sha256:7ee8d5f878dccb6d499ba4d30d757111847b6849ae07acdd1205fffa1fc1253c", 360 | "sha256:7f752826b5b8361193df55afcdf8ca6a57d0232653494ba473630a83ba50d8c9", 361 | "sha256:86b3d0033580bd6bbe07590152007275bd7af95f98eaa5bd36f3da219dcd93da", 362 | "sha256:8d62da299c6ecb04df729e4b5c52dc0d53f4f8430b4492b93aa8de1f541c4aac", 363 | "sha256:8e47755d8152c1ab5b55928ab422a76e2e7b22b5ed8e90a7d584268dd49e9c6b", 364 | "sha256:9091632a25b8b87b9a605ec0e61f241c456e9248bfdcf7abdf344fdb169c81cf", 365 | "sha256:936e5db01dd49476fa8f4383c259b8b1303d5dd5fb34c97de194560698cc2c5e", 366 | "sha256:99b6add4c0b39a513d323d3b93bc173dac663c27b99860dd5bf491b240d26137", 367 | "sha256:9c865a7ee6f93783bd5d781af5a4c43dadc37053a5b42f7d18dc019f8c9d2bd1", 368 | "sha256:a425479ee40ff021f8216c9d07a6a3b54b31c8267c6e17aa88b70d7ebd0e5e5b", 369 | "sha256:a4b2bf78342c40b3dc830880106f54328928ff03e357935ad26c7128bbd66ce8", 370 | "sha256:a6b1bb0827f56654b4437955555dc3aeeebeddc47c2d7ed575477f082622c49e", 371 | "sha256:aaf09e615a0bf98d406657e0008e4a8701b11481840be7d31755dc9f97c44053", 372 | "sha256:b1f6f5938d63c6139860f044e2538baeee6f0b251a1816e7adb6cbce106a1f01", 373 | "sha256:b29eeb887aa931c2fcef5aa515d9d176d25006794610c264ddc114c053bf96fe", 374 | "sha256:b3992a322a5617ded0a9f23fd06dbc1e4bd7cf39bc4ccf344b10f80af58beacd", 375 | "sha256:b5b6079cc452a7c53dd378c6f881ac528246b3ac9aae0f8eef98498a75657805", 376 | "sha256:b60cc1a081f80a2105a59385b92d82278b15d80ebb3adb200542ae165cd7d183", 377 | "sha256:b926dd38db1519ed3043a4de50214e0d600d404099c3392f098a7f9d75029ff8", 378 | "sha256:bd87f48924f360e5d1c5f770d6155ce0e7d83f7b4e10c2f9ec001c73cf475c99", 379 | "sha256:bda1ee3e08252b8d41fa5537413ffdddd58fa73107171a126d3b9ff001b9b820", 380 | "sha256:be0ec334369316fa73448cc8c982c01e5d2a81c95969d58b8f6e272884df0074", 381 | "sha256:c6119dc90483a5cb50a1306adb8d52c66e447da88ea44f323e0ae1a5fcb14256", 382 | "sha256:c9803edf8e29bd825f43481f19c37f50d2b01899448273b3a7758441b512acf8", 383 | "sha256:c9bd22a2a639e26171068f8ebb5400ce2c1bc7d17959f60a3b753ae13c632975", 384 | "sha256:cbcc558401de90a746d02ef330c528f2e668c83350f045833543cd57ecead1ad", 385 | "sha256:cf6204fe865da605285c34cf1172879d0314ff267b1c35ff59de7154f35fdc2e", 386 | "sha256:d33dd21f572545649f90c38c227cc8631268ba25c460b5569abebdd0ec5974ca", 387 | "sha256:d89ca19cdd0dd5f31606a9329e309d4fcbb3df860960acec32630297d61820df", 388 | "sha256:d8f99b147ff3fcf6b3cc60cb0c39ea443884d5559a30b1481e92495f2310ff2b", 389 | "sha256:d937653a696465677ed583124b94a4b2d79f5e30b2c46115a68e482c6a591c8a", 390 | "sha256:dcca5d2bf65c6fb591fff92da03f94cd4f315972f97c21975398bd4bd046854a", 391 | "sha256:ded1c35f15c9dea16ead9bffcde9bb5c7c031bff076355dc58dcb1cb436c4721", 392 | "sha256:e3e70c94a0c3841e6aa831edab1619ad5c511199be94d0c11ba75fe06efe107a", 393 | "sha256:e56f8186d6210ac7ece503193ec84104da7ceb98f68ce18c07282fcc2452e76f", 394 | "sha256:e7774b570e61cb998490c5235740d475413a1f6de823169b4cf94e2fe9e9f6b2", 395 | "sha256:e7c6ed0dc9d8e65f24f5824291550139fe6f37fac03788d4580da0d33bc00c97", 396 | "sha256:ec08be75bb268473677edb83ba71e7e74b43c008e4a7b1907c6d57e940bf34b6", 397 | "sha256:ecdf6bf5f578615f2e985a5e1f6572e23aa632c4bd1dc67f8f406d445ac115ed", 398 | "sha256:ed25e1835c00a332cb10c683cd39da96a719ab1dfc08427d476bce41b92531fc", 399 | "sha256:f4cb85f693044e0f71f394ff76c98ddc1bc0953e48c061725e540396d5c8a2e1", 400 | "sha256:f53aace168a2a10582e570b7736cc5bef12cae9cf21775e3eafac597e8551fbe", 401 | "sha256:f651dd19363c632f4abe3480a7c87a9773be27cfe1341aef06e8759599454120", 402 | "sha256:fc4ad7f7ee1a13d9cb49d8198cd7d7e3aa93e425f371a68235f784e99741561f", 403 | "sha256:fee427241c2d9fb7192b658190f9f5fd6dfe41e02f3c1489d2ec1e6a5ab1e04a" 404 | ], 405 | "markers": "python_version >= '3.8'", 406 | "version": "==2.16.3" 407 | }, 408 | "pydantic-extra-types": { 409 | "hashes": [ 410 | "sha256:d291d521c2e2bf2e6f11971caf8d639518124ae26a76d2e712599e98c4ef2b2b", 411 | "sha256:e9a93cfb245158462acb76621785219f80ad112303a0a7784d2ada65e6ed6cba" 412 | ], 413 | "version": "==2.6.0" 414 | }, 415 | "pydantic-settings": { 416 | "hashes": [ 417 | "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed", 418 | "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091" 419 | ], 420 | "version": "==2.2.1" 421 | }, 422 | "python-dotenv": { 423 | "hashes": [ 424 | "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", 425 | "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a" 426 | ], 427 | "markers": "python_version >= '3.8'", 428 | "version": "==1.0.1" 429 | }, 430 | "python-multipart": { 431 | "hashes": [ 432 | "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026", 433 | "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215" 434 | ], 435 | "version": "==0.0.9" 436 | }, 437 | "pyyaml": { 438 | "hashes": [ 439 | "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", 440 | "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", 441 | "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", 442 | "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", 443 | "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", 444 | "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", 445 | "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", 446 | "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", 447 | "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", 448 | "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", 449 | "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", 450 | "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", 451 | "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", 452 | "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", 453 | "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", 454 | "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", 455 | "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", 456 | "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", 457 | "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", 458 | "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", 459 | "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", 460 | "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", 461 | "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", 462 | "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", 463 | "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", 464 | "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", 465 | "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", 466 | "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", 467 | "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", 468 | "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", 469 | "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", 470 | "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", 471 | "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", 472 | "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", 473 | "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", 474 | "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", 475 | "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", 476 | "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", 477 | "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", 478 | "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", 479 | "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", 480 | "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", 481 | "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", 482 | "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", 483 | "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", 484 | "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", 485 | "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", 486 | "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", 487 | "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", 488 | "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", 489 | "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" 490 | ], 491 | "version": "==6.0.1" 492 | }, 493 | "retry": { 494 | "hashes": [ 495 | "sha256:ccddf89761fa2c726ab29391837d4327f819ea14d244c232a1d24c67a2f98606", 496 | "sha256:f8bfa8b99b69c4506d6f5bd3b0aabf77f98cdb17f3c9fc3f5ca820033336fba4" 497 | ], 498 | "index": "pypi", 499 | "version": "==0.9.2" 500 | }, 501 | "sniffio": { 502 | "hashes": [ 503 | "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", 504 | "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc" 505 | ], 506 | "markers": "python_version >= '3.7'", 507 | "version": "==1.3.1" 508 | }, 509 | "starlette": { 510 | "hashes": [ 511 | "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044", 512 | "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080" 513 | ], 514 | "markers": "python_version >= '3.8'", 515 | "version": "==0.36.3" 516 | }, 517 | "tqdm": { 518 | "hashes": [ 519 | "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9", 520 | "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531" 521 | ], 522 | "markers": "python_version >= '3.7'", 523 | "version": "==4.66.2" 524 | }, 525 | "typing-extensions": { 526 | "hashes": [ 527 | "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475", 528 | "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb" 529 | ], 530 | "markers": "python_version >= '3.8'", 531 | "version": "==4.10.0" 532 | }, 533 | "ujson": { 534 | "hashes": [ 535 | "sha256:07e0cfdde5fd91f54cd2d7ffb3482c8ff1bf558abf32a8b953a5d169575ae1cd", 536 | "sha256:0b159efece9ab5c01f70b9d10bbb77241ce111a45bc8d21a44c219a2aec8ddfd", 537 | "sha256:0c4d6adb2c7bb9eb7c71ad6f6f612e13b264942e841f8cc3314a21a289a76c4e", 538 | "sha256:10ca3c41e80509fd9805f7c149068fa8dbee18872bbdc03d7cca928926a358d5", 539 | "sha256:20509a8c9f775b3a511e308bbe0b72897ba6b800767a7c90c5cca59d20d7c42c", 540 | "sha256:25fa46e4ff0a2deecbcf7100af3a5d70090b461906f2299506485ff31d9ec437", 541 | "sha256:2a8ea0f55a1396708e564595aaa6696c0d8af532340f477162ff6927ecc46e21", 542 | "sha256:2fbb90aa5c23cb3d4b803c12aa220d26778c31b6e4b7a13a1f49971f6c7d088e", 543 | "sha256:323279e68c195110ef85cbe5edce885219e3d4a48705448720ad925d88c9f851", 544 | "sha256:32bba5870c8fa2a97f4a68f6401038d3f1922e66c34280d710af00b14a3ca562", 545 | "sha256:3382a3ce0ccc0558b1c1668950008cece9bf463ebb17463ebf6a8bfc060dae34", 546 | "sha256:37ef92e42535a81bf72179d0e252c9af42a4ed966dc6be6967ebfb929a87bc60", 547 | "sha256:3b23bbb46334ce51ddb5dded60c662fbf7bb74a37b8f87221c5b0fec1ec6454b", 548 | "sha256:473fb8dff1d58f49912323d7cb0859df5585cfc932e4b9c053bf8cf7f2d7c5c4", 549 | "sha256:4a566e465cb2fcfdf040c2447b7dd9718799d0d90134b37a20dff1e27c0e9096", 550 | "sha256:4e35d7885ed612feb6b3dd1b7de28e89baaba4011ecdf995e88be9ac614765e9", 551 | "sha256:506a45e5fcbb2d46f1a51fead991c39529fc3737c0f5d47c9b4a1d762578fc30", 552 | "sha256:5635b78b636a54a86fdbf6f027e461aa6c6b948363bdf8d4fbb56a42b7388320", 553 | "sha256:5ca35f484622fd208f55041b042d9d94f3b2c9c5add4e9af5ee9946d2d30db01", 554 | "sha256:60718f1720a61560618eff3b56fd517d107518d3c0160ca7a5a66ac949c6cf1c", 555 | "sha256:63fb2e6599d96fdffdb553af0ed3f76b85fda63281063f1cb5b1141a6fcd0617", 556 | "sha256:6974b3a7c17bbf829e6c3bfdc5823c67922e44ff169851a755eab79a3dd31ec0", 557 | "sha256:6adef377ed583477cf005b58c3025051b5faa6b8cc25876e594afbb772578f21", 558 | "sha256:6bbd91a151a8f3358c29355a491e915eb203f607267a25e6ab10531b3b157c5e", 559 | "sha256:6eecbd09b316cea1fd929b1e25f70382917542ab11b692cb46ec9b0a26c7427f", 560 | "sha256:70e06849dfeb2548be48fdd3ceb53300640bc8100c379d6e19d78045e9c26120", 561 | "sha256:7309d063cd392811acc49b5016728a5e1b46ab9907d321ebbe1c2156bc3c0b99", 562 | "sha256:779a2a88c53039bebfbccca934430dabb5c62cc179e09a9c27a322023f363e0d", 563 | "sha256:7a365eac66f5aa7a7fdf57e5066ada6226700884fc7dce2ba5483538bc16c8c5", 564 | "sha256:7b1c0991c4fe256f5fdb19758f7eac7f47caac29a6c57d0de16a19048eb86bad", 565 | "sha256:7cc7e605d2aa6ae6b7321c3ae250d2e050f06082e71ab1a4200b4ae64d25863c", 566 | "sha256:829a69d451a49c0de14a9fecb2a2d544a9b2c884c2b542adb243b683a6f15908", 567 | "sha256:829b824953ebad76d46e4ae709e940bb229e8999e40881338b3cc94c771b876c", 568 | "sha256:82b5a56609f1235d72835ee109163c7041b30920d70fe7dac9176c64df87c164", 569 | "sha256:89cc92e73d5501b8a7f48575eeb14ad27156ad092c2e9fc7e3cf949f07e75532", 570 | "sha256:8ba7cac47dd65ff88571eceeff48bf30ed5eb9c67b34b88cb22869b7aa19600d", 571 | "sha256:8fc2aa18b13d97b3c8ccecdf1a3c405f411a6e96adeee94233058c44ff92617d", 572 | "sha256:9ac92d86ff34296f881e12aa955f7014d276895e0e4e868ba7fddebbde38e378", 573 | "sha256:9d302bd17989b6bd90d49bade66943c78f9e3670407dbc53ebcf61271cadc399", 574 | "sha256:9f21315f51e0db8ee245e33a649dd2d9dce0594522de6f278d62f15f998e050e", 575 | "sha256:a6d3f10eb8ccba4316a6b5465b705ed70a06011c6f82418b59278fbc919bef6f", 576 | "sha256:a807ae73c46ad5db161a7e883eec0fbe1bebc6a54890152ccc63072c4884823b", 577 | "sha256:ab71bf27b002eaf7d047c54a68e60230fbd5cd9da60de7ca0aa87d0bccead8fa", 578 | "sha256:b048aa93eace8571eedbd67b3766623e7f0acbf08ee291bef7d8106210432427", 579 | "sha256:b28407cfe315bd1b34f1ebe65d3bd735d6b36d409b334100be8cdffae2177b2f", 580 | "sha256:b5964ea916edfe24af1f4cc68488448fbb1ec27a3ddcddc2b236da575c12c8ae", 581 | "sha256:b68a0caab33f359b4cbbc10065c88e3758c9f73a11a65a91f024b2e7a1257106", 582 | "sha256:ba0823cb70866f0d6a4ad48d998dd338dce7314598721bc1b7986d054d782dfd", 583 | "sha256:bd4ea86c2afd41429751d22a3ccd03311c067bd6aeee2d054f83f97e41e11d8f", 584 | "sha256:bdf7fc21a03bafe4ba208dafa84ae38e04e5d36c0e1c746726edf5392e9f9f36", 585 | "sha256:c4eec2ddc046360d087cf35659c7ba0cbd101f32035e19047013162274e71fcf", 586 | "sha256:cdcb02cabcb1e44381221840a7af04433c1dc3297af76fde924a50c3054c708c", 587 | "sha256:d0fd2eba664a22447102062814bd13e63c6130540222c0aa620701dd01f4be81", 588 | "sha256:d581db9db9e41d8ea0b2705c90518ba623cbdc74f8d644d7eb0d107be0d85d9c", 589 | "sha256:dc80f0f5abf33bd7099f7ac94ab1206730a3c0a2d17549911ed2cb6b7aa36d2d", 590 | "sha256:e015122b337858dba5a3dc3533af2a8fc0410ee9e2374092f6a5b88b182e9fcc", 591 | "sha256:e208d3bf02c6963e6ef7324dadf1d73239fb7008491fdf523208f60be6437402", 592 | "sha256:e2f909bc08ce01f122fd9c24bc6f9876aa087188dfaf3c4116fe6e4daf7e194f", 593 | "sha256:f0cb4a7814940ddd6619bdce6be637a4b37a8c4760de9373bac54bb7b229698b", 594 | "sha256:f4b3917296630a075e04d3d07601ce2a176479c23af838b6cf90a2d6b39b0d95", 595 | "sha256:f69f16b8f1c69da00e38dc5f2d08a86b0e781d0ad3e4cc6a13ea033a439c4844", 596 | "sha256:f833c529e922577226a05bc25b6a8b3eb6c4fb155b72dd88d33de99d53113124", 597 | "sha256:f91719c6abafe429c1a144cfe27883eace9fb1c09a9c5ef1bcb3ae80a3076a4e", 598 | "sha256:ff741a5b4be2d08fceaab681c9d4bc89abf3c9db600ab435e20b9b6d4dfef12e", 599 | "sha256:ffdfebd819f492e48e4f31c97cb593b9c1a8251933d8f8972e81697f00326ff1" 600 | ], 601 | "version": "==5.9.0" 602 | }, 603 | "uvicorn": { 604 | "extras": [ 605 | "standard" 606 | ], 607 | "hashes": [ 608 | "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de", 609 | "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0" 610 | ], 611 | "version": "==0.29.0" 612 | }, 613 | "uvloop": { 614 | "hashes": [ 615 | "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd", 616 | "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec", 617 | "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b", 618 | "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc", 619 | "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797", 620 | "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5", 621 | "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2", 622 | "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d", 623 | "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be", 624 | "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd", 625 | "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12", 626 | "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17", 627 | "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef", 628 | "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24", 629 | "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428", 630 | "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1", 631 | "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849", 632 | "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593", 633 | "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd", 634 | "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67", 635 | "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6", 636 | "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3", 637 | "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd", 638 | "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8", 639 | "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7", 640 | "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533", 641 | "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957", 642 | "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650", 643 | "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e", 644 | "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7", 645 | "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256" 646 | ], 647 | "version": "==0.19.0" 648 | }, 649 | "watchfiles": { 650 | "hashes": [ 651 | "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc", 652 | "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365", 653 | "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0", 654 | "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e", 655 | "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124", 656 | "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c", 657 | "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317", 658 | "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094", 659 | "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7", 660 | "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235", 661 | "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c", 662 | "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c", 663 | "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c", 664 | "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235", 665 | "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293", 666 | "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa", 667 | "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef", 668 | "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19", 669 | "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8", 670 | "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d", 671 | "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915", 672 | "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429", 673 | "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097", 674 | "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe", 675 | "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0", 676 | "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d", 677 | "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99", 678 | "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1", 679 | "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a", 680 | "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895", 681 | "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94", 682 | "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562", 683 | "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab", 684 | "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360", 685 | "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1", 686 | "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7", 687 | "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f", 688 | "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03", 689 | "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01", 690 | "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58", 691 | "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052", 692 | "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e", 693 | "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765", 694 | "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6", 695 | "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137", 696 | "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85", 697 | "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca", 698 | "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f", 699 | "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214", 700 | "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7", 701 | "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7", 702 | "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3", 703 | "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b", 704 | "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7", 705 | "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6", 706 | "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994", 707 | "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9", 708 | "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec", 709 | "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128", 710 | "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c", 711 | "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2", 712 | "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078", 713 | "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3", 714 | "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e", 715 | "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a", 716 | "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6", 717 | "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49", 718 | "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b", 719 | "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28", 720 | "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9", 721 | "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586", 722 | "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400", 723 | "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165", 724 | "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303", 725 | "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d" 726 | ], 727 | "version": "==0.21.0" 728 | }, 729 | "websockets": { 730 | "hashes": [ 731 | "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b", 732 | "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6", 733 | "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df", 734 | "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b", 735 | "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205", 736 | "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892", 737 | "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53", 738 | "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2", 739 | "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed", 740 | "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c", 741 | "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", 742 | "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b", 743 | "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931", 744 | "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", 745 | "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370", 746 | "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be", 747 | "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec", 748 | "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf", 749 | "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62", 750 | "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", 751 | "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402", 752 | "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f", 753 | "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123", 754 | "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9", 755 | "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603", 756 | "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45", 757 | "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558", 758 | "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4", 759 | "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438", 760 | "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137", 761 | "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480", 762 | "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447", 763 | "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8", 764 | "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04", 765 | "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c", 766 | "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb", 767 | "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967", 768 | "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b", 769 | "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d", 770 | "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def", 771 | "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c", 772 | "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92", 773 | "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2", 774 | "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", 775 | "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b", 776 | "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28", 777 | "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7", 778 | "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d", 779 | "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", 780 | "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468", 781 | "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8", 782 | "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae", 783 | "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611", 784 | "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", 785 | "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9", 786 | "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca", 787 | "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f", 788 | "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2", 789 | "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", 790 | "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2", 791 | "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6", 792 | "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374", 793 | "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc", 794 | "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", 795 | "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53", 796 | "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399", 797 | "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547", 798 | "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3", 799 | "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", 800 | "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5", 801 | "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8", 802 | "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7" 803 | ], 804 | "markers": "python_version >= '3.8'", 805 | "version": "==12.0" 806 | } 807 | }, 808 | "develop": { 809 | "appnope": { 810 | "hashes": [ 811 | "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", 812 | "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c" 813 | ], 814 | "markers": "platform_system == 'Darwin'", 815 | "version": "==0.1.4" 816 | }, 817 | "asttokens": { 818 | "hashes": [ 819 | "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24", 820 | "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0" 821 | ], 822 | "version": "==2.4.1" 823 | }, 824 | "comm": { 825 | "hashes": [ 826 | "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", 827 | "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3" 828 | ], 829 | "markers": "python_version >= '3.8'", 830 | "version": "==0.2.2" 831 | }, 832 | "debugpy": { 833 | "hashes": [ 834 | "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb", 835 | "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146", 836 | "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8", 837 | "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242", 838 | "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0", 839 | "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741", 840 | "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539", 841 | "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23", 842 | "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3", 843 | "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39", 844 | "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd", 845 | "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9", 846 | "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace", 847 | "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42", 848 | "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0", 849 | "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7", 850 | "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e", 851 | "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234", 852 | "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98", 853 | "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703", 854 | "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42", 855 | "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099" 856 | ], 857 | "markers": "python_version >= '3.8'", 858 | "version": "==1.8.1" 859 | }, 860 | "decorator": { 861 | "hashes": [ 862 | "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", 863 | "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186" 864 | ], 865 | "markers": "python_version >= '3.5'", 866 | "version": "==5.1.1" 867 | }, 868 | "executing": { 869 | "hashes": [ 870 | "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147", 871 | "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc" 872 | ], 873 | "markers": "python_version >= '3.5'", 874 | "version": "==2.0.1" 875 | }, 876 | "ipykernel": { 877 | "hashes": [ 878 | "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da", 879 | "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c" 880 | ], 881 | "index": "pypi", 882 | "markers": "python_version >= '3.8'", 883 | "version": "==6.29.4" 884 | }, 885 | "ipython": { 886 | "hashes": [ 887 | "sha256:2dcaad9049f9056f1fef63514f176c7d41f930daa78d05b82a176202818f2c14", 888 | "sha256:3c86f284c8f3d8f2b6c662f885c4889a91df7cd52056fd02b7d8d6195d7f56e9" 889 | ], 890 | "markers": "python_version >= '3.10'", 891 | "version": "==8.22.2" 892 | }, 893 | "jedi": { 894 | "hashes": [ 895 | "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd", 896 | "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0" 897 | ], 898 | "markers": "python_version >= '3.6'", 899 | "version": "==0.19.1" 900 | }, 901 | "jupyter-client": { 902 | "hashes": [ 903 | "sha256:3b7bd22f058434e3b9a7ea4b1500ed47de2713872288c0d511d19926f99b459f", 904 | "sha256:e842515e2bab8e19186d89fdfea7abd15e39dd581f94e399f00e2af5a1652d3f" 905 | ], 906 | "markers": "python_version >= '3.8'", 907 | "version": "==8.6.1" 908 | }, 909 | "jupyter-core": { 910 | "hashes": [ 911 | "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", 912 | "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9" 913 | ], 914 | "markers": "python_version >= '3.8'", 915 | "version": "==5.7.2" 916 | }, 917 | "matplotlib-inline": { 918 | "hashes": [ 919 | "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311", 920 | "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304" 921 | ], 922 | "markers": "python_version >= '3.5'", 923 | "version": "==0.1.6" 924 | }, 925 | "nest-asyncio": { 926 | "hashes": [ 927 | "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", 928 | "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c" 929 | ], 930 | "markers": "python_version >= '3.5'", 931 | "version": "==1.6.0" 932 | }, 933 | "packaging": { 934 | "hashes": [ 935 | "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", 936 | "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" 937 | ], 938 | "markers": "python_version >= '3.7'", 939 | "version": "==24.0" 940 | }, 941 | "parso": { 942 | "hashes": [ 943 | "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", 944 | "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" 945 | ], 946 | "markers": "python_version >= '3.6'", 947 | "version": "==0.8.3" 948 | }, 949 | "pexpect": { 950 | "hashes": [ 951 | "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", 952 | "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" 953 | ], 954 | "markers": "sys_platform != 'win32' and sys_platform != 'emscripten'", 955 | "version": "==4.9.0" 956 | }, 957 | "platformdirs": { 958 | "hashes": [ 959 | "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068", 960 | "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768" 961 | ], 962 | "markers": "python_version >= '3.8'", 963 | "version": "==4.2.0" 964 | }, 965 | "prompt-toolkit": { 966 | "hashes": [ 967 | "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d", 968 | "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6" 969 | ], 970 | "markers": "python_full_version >= '3.7.0'", 971 | "version": "==3.0.43" 972 | }, 973 | "psutil": { 974 | "hashes": [ 975 | "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d", 976 | "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73", 977 | "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8", 978 | "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2", 979 | "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e", 980 | "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36", 981 | "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7", 982 | "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c", 983 | "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee", 984 | "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421", 985 | "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf", 986 | "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81", 987 | "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0", 988 | "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631", 989 | "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4", 990 | "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8" 991 | ], 992 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", 993 | "version": "==5.9.8" 994 | }, 995 | "ptyprocess": { 996 | "hashes": [ 997 | "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", 998 | "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220" 999 | ], 1000 | "version": "==0.7.0" 1001 | }, 1002 | "pure-eval": { 1003 | "hashes": [ 1004 | "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350", 1005 | "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3" 1006 | ], 1007 | "version": "==0.2.2" 1008 | }, 1009 | "pygments": { 1010 | "hashes": [ 1011 | "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", 1012 | "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" 1013 | ], 1014 | "markers": "python_version >= '3.7'", 1015 | "version": "==2.17.2" 1016 | }, 1017 | "python-dateutil": { 1018 | "hashes": [ 1019 | "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", 1020 | "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" 1021 | ], 1022 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 1023 | "version": "==2.9.0.post0" 1024 | }, 1025 | "pyzmq": { 1026 | "hashes": [ 1027 | "sha256:004ff469d21e86f0ef0369717351073e0e577428e514c47c8480770d5e24a565", 1028 | "sha256:00a06faa7165634f0cac1abb27e54d7a0b3b44eb9994530b8ec73cf52e15353b", 1029 | "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979", 1030 | "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1", 1031 | "sha256:019744b99da30330798bb37df33549d59d380c78e516e3bab9c9b84f87a9592f", 1032 | "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d", 1033 | "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee", 1034 | "sha256:07cd61a20a535524906595e09344505a9bd46f1da7a07e504b315d41cd42eb07", 1035 | "sha256:0806175f2ae5ad4b835ecd87f5f85583316b69f17e97786f7443baaf54b9bb98", 1036 | "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886", 1037 | "sha256:0dabfb10ef897f3b7e101cacba1437bd3a5032ee667b7ead32bbcdd1a8422fe7", 1038 | "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75", 1039 | "sha256:0f513130c4c361201da9bc69df25a086487250e16b5571ead521b31ff6b02220", 1040 | "sha256:0f97bc2f1f13cb16905a5f3e1fbdf100e712d841482b2237484360f8bc4cb3d7", 1041 | "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a", 1042 | "sha256:146b9b1f29ead41255387fb07be56dc29639262c0f7344f570eecdcd8d683314", 1043 | "sha256:16b726c1f6c2e7625706549f9dbe9b06004dfbec30dbed4bf50cbdfc73e5b32a", 1044 | "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27", 1045 | "sha256:1b9b1f2ad6498445a941d9a4fee096d387fee436e45cc660e72e768d3d8ee611", 1046 | "sha256:1ec23bd7b3a893ae676d0e54ad47d18064e6c5ae1fadc2f195143fb27373f7f6", 1047 | "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6", 1048 | "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9", 1049 | "sha256:2c6441e0398c2baacfe5ba30c937d274cfc2dc5b55e82e3749e333aabffde561", 1050 | "sha256:2c9a79f1d2495b167119d02be7448bfba57fad2a4207c4f68abc0bab4b92925b", 1051 | "sha256:2e2713ef44be5d52dd8b8e2023d706bf66cb22072e97fc71b168e01d25192755", 1052 | "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e", 1053 | "sha256:3516e0b6224cf6e43e341d56da15fd33bdc37fa0c06af4f029f7d7dfceceabbc", 1054 | "sha256:359f7f74b5d3c65dae137f33eb2bcfa7ad9ebefd1cab85c935f063f1dbb245cc", 1055 | "sha256:39b1067f13aba39d794a24761e385e2eddc26295826530a8c7b6c6c341584289", 1056 | "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d", 1057 | "sha256:3c53687dde4d9d473c587ae80cc328e5b102b517447456184b485587ebd18b62", 1058 | "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642", 1059 | "sha256:4345c9a27f4310afbb9c01750e9461ff33d6fb74cd2456b107525bbeebcb5be3", 1060 | "sha256:45999e7f7ed5c390f2e87ece7f6c56bf979fb213550229e711e45ecc7d42ccb8", 1061 | "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0", 1062 | "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4", 1063 | "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097", 1064 | "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b", 1065 | "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181", 1066 | "sha256:518efd91c3d8ac9f9b4f7dd0e2b7b8bf1a4fe82a308009016b07eaa48681af82", 1067 | "sha256:55875492f820d0eb3417b51d96fea549cde77893ae3790fd25491c5754ea2f68", 1068 | "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08", 1069 | "sha256:5dde6751e857910c1339890f3524de74007958557593b9e7e8c5f01cd919f8a7", 1070 | "sha256:5e319ed7d6b8f5fad9b76daa0a68497bc6f129858ad956331a5835785761e003", 1071 | "sha256:5edac3f57c7ddaacdb4d40f6ef2f9e299471fc38d112f4bc6d60ab9365445fb0", 1072 | "sha256:6cc0020b74b2e410287e5942e1e10886ff81ac77789eb20bec13f7ae681f0fdd", 1073 | "sha256:6dd0d50bbf9dca1d0bdea219ae6b40f713a3fb477c06ca3714f208fd69e16fd8", 1074 | "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840", 1075 | "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8", 1076 | "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe", 1077 | "sha256:7b6d09a8962a91151f0976008eb7b29b433a560fde056ec7a3db9ec8f1075438", 1078 | "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e", 1079 | "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d", 1080 | "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c", 1081 | "sha256:8807c87fa893527ae8a524c15fc505d9950d5e856f03dae5921b5e9aa3b8783b", 1082 | "sha256:889370d5174a741a62566c003ee8ddba4b04c3f09a97b8000092b7ca83ec9c49", 1083 | "sha256:8b14c75979ce932c53b79976a395cb2a8cd3aaf14aef75e8c2cb55a330b9b49d", 1084 | "sha256:8c5f80e578427d4695adac6fdf4370c14a2feafdc8cb35549c219b90652536ae", 1085 | "sha256:8e9f3fabc445d0ce320ea2c59a75fe3ea591fdbdeebec5db6de530dd4b09412e", 1086 | "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226", 1087 | "sha256:94504ff66f278ab4b7e03e4cba7e7e400cb73bfa9d3d71f58d8972a8dc67e7a6", 1088 | "sha256:967668420f36878a3c9ecb5ab33c9d0ff8d054f9c0233d995a6d25b0e95e1b6b", 1089 | "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3", 1090 | "sha256:99a6b36f95c98839ad98f8c553d8507644c880cf1e0a57fe5e3a3f3969040882", 1091 | "sha256:9a18fff090441a40ffda8a7f4f18f03dc56ae73f148f1832e109f9bffa85df15", 1092 | "sha256:9add2e5b33d2cd765ad96d5eb734a5e795a0755f7fc49aa04f76d7ddda73fd70", 1093 | "sha256:a793ac733e3d895d96f865f1806f160696422554e46d30105807fdc9841b9f7d", 1094 | "sha256:a86c2dd76ef71a773e70551a07318b8e52379f58dafa7ae1e0a4be78efd1ff16", 1095 | "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05", 1096 | "sha256:ac170e9e048b40c605358667aca3d94e98f604a18c44bdb4c102e67070f3ac9b", 1097 | "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737", 1098 | "sha256:b8c8a419dfb02e91b453615c69568442e897aaf77561ee0064d789705ff37a92", 1099 | "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348", 1100 | "sha256:bef02cfcbded83473bdd86dd8d3729cd82b2e569b75844fb4ea08fee3c26ae41", 1101 | "sha256:c0b5ca88a8928147b7b1e2dfa09f3b6c256bc1135a1338536cbc9ea13d3b7add", 1102 | "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b", 1103 | "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7", 1104 | "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d", 1105 | "sha256:d1b604734bec94f05f81b360a272fc824334267426ae9905ff32dc2be433ab96", 1106 | "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e", 1107 | "sha256:db36c27baed588a5a8346b971477b718fdc66cf5b80cbfbd914b4d6d355e44e2", 1108 | "sha256:df0c7a16ebb94452d2909b9a7b3337940e9a87a824c4fc1c7c36bb4404cb0cde", 1109 | "sha256:e10a4b5a4b1192d74853cc71a5e9fd022594573926c2a3a4802020360aa719d8", 1110 | "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4", 1111 | "sha256:e690145a8c0c273c28d3b89d6fb32c45e0d9605b2293c10e650265bf5c11cfec", 1112 | "sha256:ea1608dd169da230a0ad602d5b1ebd39807ac96cae1845c3ceed39af08a5c6df", 1113 | "sha256:ea253b368eb41116011add00f8d5726762320b1bda892f744c91997b65754d73", 1114 | "sha256:eb7e49a17fb8c77d3119d41a4523e432eb0c6932187c37deb6fbb00cc3028088", 1115 | "sha256:ef12e259e7bc317c7597d4f6ef59b97b913e162d83b421dd0db3d6410f17a244", 1116 | "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537", 1117 | "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6", 1118 | "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872", 1119 | "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30" 1120 | ], 1121 | "markers": "python_version >= '3.6'", 1122 | "version": "==25.1.2" 1123 | }, 1124 | "six": { 1125 | "hashes": [ 1126 | "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", 1127 | "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" 1128 | ], 1129 | "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", 1130 | "version": "==1.16.0" 1131 | }, 1132 | "stack-data": { 1133 | "hashes": [ 1134 | "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", 1135 | "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695" 1136 | ], 1137 | "version": "==0.6.3" 1138 | }, 1139 | "tornado": { 1140 | "hashes": [ 1141 | "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0", 1142 | "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63", 1143 | "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263", 1144 | "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052", 1145 | "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f", 1146 | "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee", 1147 | "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78", 1148 | "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579", 1149 | "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212", 1150 | "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e", 1151 | "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2" 1152 | ], 1153 | "markers": "python_version >= '3.8'", 1154 | "version": "==6.4" 1155 | }, 1156 | "traitlets": { 1157 | "hashes": [ 1158 | "sha256:8cdd83c040dab7d1dee822678e5f5d100b514f7b72b01615b26fc5718916fdf9", 1159 | "sha256:fcdf85684a772ddeba87db2f398ce00b40ff550d1528c03c14dbf6a02003cd80" 1160 | ], 1161 | "markers": "python_version >= '3.8'", 1162 | "version": "==5.14.2" 1163 | }, 1164 | "wcwidth": { 1165 | "hashes": [ 1166 | "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", 1167 | "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" 1168 | ], 1169 | "version": "==0.2.13" 1170 | } 1171 | } 1172 | } 1173 | --------------------------------------------------------------------------------