diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/.env.example b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/.env.example new file mode 100644 index 00000000..8b888822 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/.env.example @@ -0,0 +1,13 @@ +LLM_MODEL_ID="" +LLM_API_KEY="" +LLM_BASE_URL="" + +# 超时时间(可选,默认60秒) +LLM_TIMEOUT="" + +# 服务器配置 +HOST="" +PORT="" + +# CORS配置 +CORS_ORIGINS="" \ No newline at end of file diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/README.md b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/README.md new file mode 100644 index 00000000..85311b4b --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/README.md @@ -0,0 +1,183 @@ +# FitnessPlannerAgent - 健身训练规划助手 + +> 基于HelloAgents框架的健身规划助手 + +## 📝 项目简介 + +FitnessPlannerAgent是一个健身训练规划助手,能够根据用户基本信息自动规划每周期的健身计划。 + +### 核心功能 +- ✅ 智能建议:基于LLM和用户提供的基本信息进行分析和规划训练。 + + +## 🛠️ 技术栈 + +- HelloAgents框架(SimpleAgent) +- QWEN API(智能分析) + +## 🚀 快速开始 + +### 安装依赖 + +```bash +pip install -r requirements.txt +``` + +### 配置LLM参数 + +**方式1: 使用.env文件(推荐)** + +```bash +# 复制示例文件 +cp .env.example .env + +# 编辑.env文件,填入你的配置 +# LLM_MODEL_ID=Qwen/Qwen2.5-72B-Instruct +# LLM_API_KEY=your_api_key_here +# LLM_BASE_URL=https://api-inference.modelscope.cn/v1/ +``` + +### 运行项目 + +在终端进入当项目所在的EugeneChanQAQ-smart_fitness_planner目录激活虚拟环境。 + +```bash +venv_fit/Scripts/activate +# 激活虚拟环境 +python -m uvicorn app.api.main:app --reload --host 0.0.0.0 --port 8000 +# 启动项目 +``` + +## 📖 使用示例 + +### 完整功能 + +1. 用户输入自己的基本信息(身高、体重、年龄) +2. 系统生成周期性的健身规划 + +## 🎯 项目亮点 + +- **智能化**:利用LLM根据个人身体基本数据,提供专业的健身训练建议 +- **可扩展**:易于添加新的工具 + +## 📂 项目结构 + +``` +EugeneChanQAQ-smart_fitness_planner/ +│ +├── app/ # 🍱 FastAPI 服务主体 +│ ├── config.py # 配置文件(应用名、版本、路径等) +│ ├── api/ # FastAPI 相关 +│ │ ├── routers # 路由 +│ │ │ └──train.py # 路由 +│ │ ├── main.py # FastAPI 主入口 +│ ├── agents/ # 核心 Agent 逻辑模块 +│ │ ├── train_planner.py # +│ │ ├── state_manager.py # 暂空 +│ │ ├── \_\_init__.py +│ ├── models/ # Pydantic 请求模型 +│ │ └── schemas.py # 数据模型 +│ └── services/ +│ └── llm_service.py # +│ +├── tests/ +│ └── test_agent.py # 暂空 +│ +├── requirements.txt # Python依赖 +└── README.md # 项目说明 +``` + +## 🔧 技术实现 + + +### 智能体设计 + +使用HelloAgents的SimpleAgent。 + +## 📊 示例输出 + +```markdown +============================================================ +🚀 HelloAgents健身规划助手 v1.0.0 +============================================================ +应用名称: HelloAgents健身规划助手 +版本: 1.0.0 +服务器: 0.0.0.0:8000 +LLM API Key: 已配置 +LLM Base URL: https://dashscope.aliyuncs.com/compatible-mode/v1 +LLM Model: qwen-max +日志级别: INFO + + ✔验证通过 + +============================================================ +📚 API文档: http://localhost:8000/docs +📖 ReDoc文档: http://localhost:8000/redoc +============================================================ + +INFO: Application startup complete. +INFO: 127.0.0.1:57008 - "GET / HTTP/1.1" 307 Temporary Redirect +INFO: 127.0.0.1:57008 - "GET /train/ HTTP/1.1" 200 OK +INFO: 127.0.0.1:57008 - "GET /favicon.ico HTTP/1.1" 404 Not Found + +============================================================ +📥 收到训练计划制定请求: + 身高: 183 + 体重: 76 + 年龄: 21 +============================================================ + +获取Agent系统 +开始初始化智能体健身规划系统 +✅ LLM服务初始化成功 + 提供商: qwen + 模型: qwen-max +创建健身规划Agent + +============================================================ +🚀 开始智能体规划训练... +身高:183 +体重:76 +年龄:21 + +============================================================ +制定训练计划中... +训练规划结果: [ + {"day":1,"action":"深蹲","muscle":"腿部","group_num":3,"amount":12}, + {"day":1,"action":"卧推","muscle":"胸部","group_num":3,"amount":10}, + {"day":1,"action":"引体向上","muscle":"背部","group_num":3,"amount":8}, + {"day":2,"action":"休息"}, + {"day":3,"action":"硬拉","muscle":"背部","group_num":3,"amount":10}, + ... + +============================================================ +✅ 训练计划生成完成! +============================================================ + +✅ 训练计划生成成功,准备返回响应 + +INFO: 127.0.0.1:61389 - "POST /train/plan HTTP/1.1" 200 OK +``` + +## 🚧 未来改进 + +- [ ] 提供更多的基础信息以及特殊需求填写(性别、健身目的等) +- [ ] 添加食谱规划Agent(帮助提高健身效率) +- [ ] 调用API查找附近的健身餐食 +- [ ] 提供周期性反馈,根据用户的最新数据更改健身策略和方案 +- [ ] 生成用户身体数据报告 + +## 👤 作者 + +- GitHub: [@EugeneChanQAQ](https://github.com/EugeneChanQAQ) +- 项目链接:[FitnessPlannerAgent](https://github.com/datawhalechina/Hello-Agents/tree/main/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner) + +## 🙏 致谢 + +感谢Datawhale社区和Hello-Agents项目! + +## 📄 许可证 + +所有共创项目遵循CC BY-NC-SA 4.0 License,欢迎学习和共创。 + + diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/__init__.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/__init__.py new file mode 100644 index 00000000..2d66a7db --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/__init__.py @@ -0,0 +1,4 @@ +__all__ = [ + "train_planner.py", + "state_manager", +] \ No newline at end of file diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/state_manager.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/state_manager.py new file mode 100644 index 00000000..e69de29b diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/train_planner.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/train_planner.py new file mode 100644 index 00000000..b417836c --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/agents/train_planner.py @@ -0,0 +1,185 @@ +import json +from typing import Dict, Any, List +from hello_agents import SimpleAgent + +from ..models.schemas import FitnessRequest, TrainPlan +from ..services.llm_service import get_llm +from ..config import get_settings + +# ========== Agent 提示词 ========== +PLANNER_AGENT_PROMPT = """你是健身规划专家,你的任务是根据客户的身高、体重和年龄,生成详细的健身计划。 + +请为以下用户生成个性化的健身计划: +- 年龄:{request.age}岁 +- 身高:{request.height}cm +- 体重:{request.weight}kg + +要求: +1. 包含训练计划(每周3-5天) +2. 包含营养建议 +3. 包含注意事项 +4. 用中文回复,格式美观 + +""" + +class FitnessPlanner: + + def __init__(self): + print("开始初始化智能体健身规划系统") + + try: + settings = get_settings() + self.llm = get_llm() + + print("创建健身规划Agent") + self.planner_agent = SimpleAgent( + name="健身规划专家", + llm=self.llm, + system_prompt=PLANNER_AGENT_PROMPT + ) + + except Exception as e: + print(f"❌ 智能体系统初始化失败: {str(e)}") + import traceback + traceback.print_exc() + raise + + def plan_train(self, request: FitnessRequest) -> List[TrainPlan]: + try: + print(f"\n{'=' * 60}") + print(f"🚀 开始智能体规划训练...") + print(f"身高:{request.height}") + print(f"体重:{request.weight}") + print(f"年龄:{request.age}") + print(f"\n{'=' * 60}") + + print("制定训练计划中...") + planner_query = self._build_planner_query(request) + planner_response = self.planner_agent.run(planner_query) + print(f"训练规划结果: {planner_response[:300]}...\n") + + # 解析响应为列表 + train_plan_list = self._parse_response(planner_response, request) + + # 确保返回 7 天列表,如果不足则用休息日填充 + full_plan = [] + for day in range(1, 8): + day_plan = next((p for p in train_plan_list if p.get("day") == day), None) + if day_plan: + # 转换为 TrainPlan 对象 + full_plan.append(TrainPlan(**day_plan)) + else: + # 休息日占位 + full_plan.append(TrainPlan( + day=day, + action="休息", + muscle=None, + group_num=None, + amount=None + )) + + print(f"{'=' * 60}") + print(f"✅ 训练计划生成完成!") + print(f"{'=' * 60}\n") + + return full_plan + + except Exception as e: + print(f"❌ 生成训练计划失败: {str(e)}") + import traceback + traceback.print_exc() + return self._create_fallback_plan(request) + + def _build_planner_query(self, request: FitnessRequest) -> str: + + query = f""" + 你是一个健身训练计划生成器,只能返回 JSON 格式。 + + 请根据以下信息生成 **7 天训练计划**,并严格按下面的 JSON schema 输出: + + 每条数据格式必须如下: + {{ + "day": int, + "action": str, + "muscle": str, + "group_num": int, + "amount": int + }} + + 输出格式必须是一个 JSON 数组,例如: + [ + {{ ... }}, + {{ ... }}, + ... + ] + + 用户信息: + - 身高: {request.height} + - 体重: {request.weight} + - 年龄: {request.age} + + 生成要求: + 1. 输出完整 7 天计划,每天 3~4 个动作(可拆成多条 JSON) + 2. 返回标准 JSON 数组 + 3. 严禁输出解释、文字、标题,只能输出 JSON + + """ + return query + + def _parse_response(self, response: str, request: FitnessRequest) -> List[dict]: + """ + 解析 Agent 响应为字典列表,每个元素对应一天训练计划 + """ + try: + import json + + # 提取 JSON 部分 + if "```json" in response: + start = response.find("```json") + 7 + end = response.find("```", start) + json_str = response[start:end].strip() + elif "```" in response: + start = response.find("```") + 3 + end = response.find("```", start) + json_str = response[start:end].strip() + else: + # 尝试直接解析 JSON + json_str = response.strip() + + data = json.loads(json_str) + + # 确保返回的是列表 + if isinstance(data, dict): + return [data] + elif isinstance(data, list): + return data + else: + raise ValueError("Agent 返回数据格式不正确") + + except Exception as e: + print(f"⚠️ 解析响应失败: {str(e)}") + print(f" 将使用备用方案生成计划") + return [p.dict() for p in self._create_fallback_plan(request)] + + def _create_fallback_plan(self, request: FitnessRequest) -> List[TrainPlan]: + """ + 生成 7 天 fallback 计划 + """ + fallback = [] + for day in range(1, 8): + if day % 2 == 0: + fallback.append(TrainPlan(day=day, action="休息", muscle=None, group_num=None, amount=None)) + else: + fallback.append(TrainPlan(day=day, action="深蹲", muscle="腿部", group_num=4, amount=12)) + return fallback + + +_fitness_planner = None + +def get_fitness_planner_agent() -> FitnessPlanner: + global _fitness_planner + + if _fitness_planner is None: + _fitness_planner = FitnessPlanner() + + return _fitness_planner diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/api/main.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/api/main.py new file mode 100644 index 00000000..51d96de8 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/api/main.py @@ -0,0 +1,98 @@ +from contextlib import asynccontextmanager + +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import RedirectResponse +from ..config import get_settings, valid_config, print_config +from .routers import train +import asyncio + +settings = get_settings() + +app = FastAPI( + title=settings.app_name, + version=settings.app_version, + description="基于HelloAgents框架的健身助手Agent", + docs_url="/docs", + redoc_url="/redoc" +) + +# 配置CORS +app.add_middleware( + CORSMiddleware, + allow_origins=settings.get_cors_origins(), + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"] +) + +# 注册路由 +app.include_router(train.router) + +@app.on_event("startup") +async def startup_event(): + """应用启动事件""" + print("\n" + "=" * 60) + print(f"🚀 {settings.app_name} v{settings.app_version}") + print("=" * 60) + + # 打印config配置信息 + print_config() + + # 验证配置 + try: + valid_config() + print("\n ✔验证通过") + except ValueError as e: + print(f"\n❌ 配置验证失败:\n{e}") + print("\n请检查.env文件并确保所有必要的配置项都已设置") + raise + + print("\n" + "=" * 60) + print("📚 API文档: http://localhost:8000/docs") + print("📖 ReDoc文档: http://localhost:8000/redoc") + print("=" * 60 + "\n") + +@app.on_event("shutdown") +async def shutdown_event(): + """应用关闭事件""" + print("\n" + "="*60) + print("👋 应用正在关闭...") + print("="*60 + "\n") + +# @app.get("/") +# async def root(): +# """根路径""" +# return { +# "name": settings.app_name, +# "version": settings.app_version, +# "status": "running", +# "docs": "/docs", +# "redoc": "/redoc" +# } + +@app.get("/") +async def root(): + return RedirectResponse(url="/train/") + + +@app.get("/health") +async def health(): + """健康检查""" + return { + "status": "healthy", + "service": settings.app_name, + "version": settings.app_version + } + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run( + "app.api.main:app", + host=settings.host, + port=settings.port, + reload=True + ) + diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/api/routers/train.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/api/routers/train.py new file mode 100644 index 00000000..2ed9b35c --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/api/routers/train.py @@ -0,0 +1,361 @@ +from fastapi import APIRouter, HTTPException +from fastapi.responses import HTMLResponse +from ...models.schemas import ( + FitnessRequest, + FitnessResponse, + ErrorResponse +) +from ...agents.train_planner import get_fitness_planner_agent + +router = APIRouter(prefix="/train", tags=["训练计划"]) + +# 前端界面HTML +TRAINING_HTML = """ + + + + + + 健身计划生成器 + + + +
+
+

🏋️ 健身计划生成器

+

输入您的身体信息,获取个性化的训练计划

+
+ +
+
+ +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + + +
+
+

正在生成个性化的训练计划...

+
+ +
+ +
+ +
+
+
+ + + + +""" + + +@router.get("/", response_class=HTMLResponse) +async def training_page(): + """训练计划生成器页面""" + return TRAINING_HTML + +@router.post( + "/plan", + response_model=FitnessResponse, + summary="生成训练计划", + description="根据用户的基本情况生成训练计划" +) + +async def plan_train(request: FitnessRequest): + """ + 生成训练计划 + :param request: 训练请求参数(个人基本数据) + :return:训练计划建议 + """ + try: + print(f"\n{'='*60}") + print(f"📥 收到训练计划制定请求:") + print(f" 身高: {request.height}") + print(f" 体重: {request.weight}") + print(f" 年龄: {request.age}") + print(f"{'='*60}\n") + + # 获取agent实例 + print("获取Agent系统") + agent = get_fitness_planner_agent() + + # 开始生成健身计划 + train_plan = agent.plan_train(request) + + print("✅ 训练计划生成成功,准备返回响应\n") + + return FitnessResponse( + success=True, + message="训练计划生成成功", + fitness_plan=train_plan + ) + + except Exception as e: + print(f"❌ 生成训练计划失败: {str(e)}") + import traceback + traceback.print_exc() + raise HTTPException( + status_code=500, + detail=f"生成训练计划失败: {str(e)}" + ) \ No newline at end of file diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/config.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/config.py new file mode 100644 index 00000000..2b78c2a7 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/config.py @@ -0,0 +1,85 @@ +"""配置管理模块""" + +import os +from pathlib import Path +from typing import List +from pydantic_settings import BaseSettings +from dotenv import load_dotenv + +# 加载环境变量 +load_dotenv(Path(__file__).parent.parent / '.env') + +# 尝试加载helloagents的.env文件 +helloagents_env = Path(__file__).parent.parent.parent / 'Hello-Agents' / '.env' +if helloagents_env.exists(): + load_dotenv(helloagents_env, override=False) + +class Settings(BaseSettings): + """应用配置""" + app_name: str = "HelloAgents健身规划助手" + app_version: str = "1.0.0" + debug: bool = False + + # 服务器配置 + host: str = "0.0.0.0" + port: int = 8000 + + # CORS配置 - 使用字符串,在代码中分割 + cors_origins: str = "http://localhost:5173,http://localhost:3000,http://127.0.0.1:5173,http://127.0.0.1:3000" + + # LLM配置 (从环境变量读取,由HelloAgents管理) + openai_api_key: str = "" + openai_base_url: str = "https://api.openai.com/v1" + openai_model: str = "gpt-4" + + # 日志配置 + log_level: str = "INFO" + + class Config: + env_file = ".env" + case_sensitive = False + extra = "ignore" + + def get_cors_origins(self) -> List[str]: + return [origin.strip() for origin in self.cors_origins.split(',')] + +settings = Settings() + +def get_settings() -> Settings: + return settings + +# 验证必要配置 +def valid_config(): + errors = [] + warnings = [] + + llm_api_key = os.getenv("LLM_API_KEY") or os.getenv("OPENAI_API_KEY") + if not llm_api_key: + warnings.append("LLM_API_KEY或OPENAI_API_KEY未配置,LLM功能可能无法使用") + + if errors: + error_msg = "配置错误:\n" + "\n".join(f" - {e}" for e in errors) + raise ValueError(error_msg) + + if warnings: + print("\n⚠️ 配置警告:") + for w in warnings: + print(f" - {w}") + + return True + +def print_config(): + """打印当前配置(隐藏敏感信息)""" + print(f"应用名称: {settings.app_name}") + print(f"版本: {settings.app_version}") + print(f"服务器: {settings.host}:{settings.port}") + + # 检查LLM配置 + llm_api_key = os.getenv("LLM_API_KEY") or os.getenv("OPENAI_API_KEY") + llm_base_url = os.getenv("LLM_BASE_URL") or settings.openai_base_url + llm_model = os.getenv("LLM_MODEL_ID") or settings.openai_model + + print(f"LLM API Key: {'已配置' if llm_api_key else '未配置'}") + print(f"LLM Base URL: {llm_base_url}") + print(f"LLM Model: {llm_model}") + print(f"日志级别: {settings.log_level}") diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/models/schemas.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/models/schemas.py new file mode 100644 index 00000000..51b2adfc --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/models/schemas.py @@ -0,0 +1,38 @@ +from typing import Dict, Optional, Union, List +from pydantic import BaseModel, Field, field_validator + +# ========== 请求模型 ========== +class FitnessRequest(BaseModel): + """运动计划请求""" + height: int = Field(..., description="身高", examples=183) + weight: int = Field(..., description="体重", examples=76) + age: int = Field(..., description="年龄", examples=26) + + class Config: + json_schema_extra = { + "example": { + "height": 183, + "weight": 76, + "age": 26 + } + } + +# ========== 单日训练计划模型 ========== +class TrainPlan(BaseModel): + day: int = Field(..., description="训练日(1~7)") + action: str = Field(..., description="训练动作") + muscle: str = Field(default=None, description="肌肉群") + group_num: int = Field(default=None, description="组数") + amount: int = Field(default=None, description="每组数量") + +# ========== 响应模型(支持 7 天列表) ========== +class FitnessResponse(BaseModel): + success: bool = Field(..., description="是否成功") + message: str = Field(..., description="消息") + fitness_plan: List[TrainPlan] = Field(..., description="7 天训练计划") + +# ========== 错误响应 ========== +class ErrorResponse(BaseModel): + success: bool = Field(default=False, description="是否成功") + message: str = Field(..., description="错误消息") + error_code: Optional[str] = Field(default=None, description="错误代码") \ No newline at end of file diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/run_demo.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/run_demo.py new file mode 100644 index 00000000..850fdfa9 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/run_demo.py @@ -0,0 +1,16 @@ +"""启动脚本""" + +import uvicorn +from .config import get_settings + +if __name__ == "__main__": + settings = get_settings() + + uvicorn.run( + "app.api.main:app", + host=settings.host, + port=settings.port, + reload=True, + log_level=settings.log_level.lower() + ) + diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/services/llm_service.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/services/llm_service.py new file mode 100644 index 00000000..5bb65b40 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/app/services/llm_service.py @@ -0,0 +1,23 @@ +from hello_agents.core import HelloAgentsLLM +from ..config import get_settings + +_llm_instance = None + +def get_llm() -> HelloAgentsLLM: + global _llm_instance + + if _llm_instance is None: + settings = get_settings() + + _llm_instance = HelloAgentsLLM() + + print(f"✅ LLM服务初始化成功") + print(f" 提供商: {_llm_instance.provider}") + print(f" 模型: {_llm_instance.model}") + + return _llm_instance + +def reset_llm(): + """重置LLM实例(用于测试或重新配置)""" + global _llm_instance + _llm_instance = None \ No newline at end of file diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/requirements.txt b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/requirements.txt new file mode 100644 index 00000000..33151dc2 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/requirements.txt @@ -0,0 +1,29 @@ +# HelloAgents框架 +hello-agents[protocols]>=0.2.4 + +# FastAPI和相关依赖 +fastapi>=0.115.0 +uvicorn[standard]>=0.32.0 +pydantic>=2.0.0 +pydantic-settings>=2.0.0 + +# HTTP客户端 +httpx>=0.27.0 +aiohttp>=3.10.0 + +# 环境变量管理 +python-dotenv>=1.0.0 + +# CORS支持 +python-multipart>=0.0.9 + +# 日志 +loguru>=0.7.0 + +# MCP相关 +fastmcp>=2.0.0 +uv>=0.8.0 + +# 其他工具 +python-dateutil>=2.8.2 +huggingface-hub>=1.1.5 \ No newline at end of file diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/Activate.ps1 b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/Activate.ps1 new file mode 100644 index 00000000..918eac3e --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/Activate.ps1 @@ -0,0 +1,528 @@ +<# +.Synopsis +Activate a Python virtual environment for the current PowerShell session. + +.Description +Pushes the python executable for a virtual environment to the front of the +$Env:PATH environment variable and sets the prompt to signify that you are +in a Python virtual environment. Makes use of the command line switches as +well as the `pyvenv.cfg` file values present in the virtual environment. + +.Parameter VenvDir +Path to the directory that contains the virtual environment to activate. The +default value for this is the parent of the directory that the Activate.ps1 +script is located within. + +.Parameter Prompt +The prompt prefix to display when this virtual environment is activated. By +default, this prompt is the name of the virtual environment folder (VenvDir) +surrounded by parentheses and followed by a single space (ie. '(.venv) '). + +.Example +Activate.ps1 +Activates the Python virtual environment that contains the Activate.ps1 script. + +.Example +Activate.ps1 -Verbose +Activates the Python virtual environment that contains the Activate.ps1 script, +and shows extra information about the activation as it executes. + +.Example +Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv +Activates the Python virtual environment located in the specified location. + +.Example +Activate.ps1 -Prompt "MyPython" +Activates the Python virtual environment that contains the Activate.ps1 script, +and prefixes the current prompt with the specified string (surrounded in +parentheses) while the virtual environment is active. + +.Notes +On Windows, it may be required to enable this Activate.ps1 script by setting the +execution policy for the user. You can do this by issuing the following PowerShell +command: + +PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser + +For more information on Execution Policies: +https://go.microsoft.com/fwlink/?LinkID=135170 + +#> +Param( + [Parameter(Mandatory = $false)] + [String] + $VenvDir, + [Parameter(Mandatory = $false)] + [String] + $Prompt +) + +<# Function declarations --------------------------------------------------- #> + +<# +.Synopsis +Remove all shell session elements added by the Activate script, including the +addition of the virtual environment's Python executable from the beginning of +the PATH variable. + +.Parameter NonDestructive +If present, do not remove this function from the global namespace for the +session. + +#> +function global:deactivate ([switch]$NonDestructive) { + # Revert to original values + + # The prior prompt: + if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { + Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt + Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT + } + + # The prior PYTHONHOME: + if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { + Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME + Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME + } + + # The prior PATH: + if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { + Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH + Remove-Item -Path Env:_OLD_VIRTUAL_PATH + } + + # Just remove the VIRTUAL_ENV altogether: + if (Test-Path -Path Env:VIRTUAL_ENV) { + Remove-Item -Path env:VIRTUAL_ENV + } + + # Just remove VIRTUAL_ENV_PROMPT altogether. + if (Test-Path -Path Env:VIRTUAL_ENV_PROMPT) { + Remove-Item -Path env:VIRTUAL_ENV_PROMPT + } + + # Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: + if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { + Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force + } + + # Leave deactivate function in the global namespace if requested: + if (-not $NonDestructive) { + Remove-Item -Path function:deactivate + } +} + +<# +.Description +Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the +given folder, and returns them in a map. + +For each line in the pyvenv.cfg file, if that line can be parsed into exactly +two strings separated by `=` (with any amount of whitespace surrounding the =) +then it is considered a `key = value` line. The left hand string is the key, +the right hand is the value. + +If the value starts with a `'` or a `"` then the first and last character is +stripped from the value before being captured. + +.Parameter ConfigDir +Path to the directory that contains the `pyvenv.cfg` file. +#> +function Get-PyVenvConfig( + [String] + $ConfigDir +) { + Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" + + # Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). + $pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue + + # An empty map will be returned if no config file is found. + $pyvenvConfig = @{ } + + if ($pyvenvConfigPath) { + + Write-Verbose "File exists, parse `key = value` lines" + $pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath + + $pyvenvConfigContent | ForEach-Object { + $keyval = $PSItem -split "\s*=\s*", 2 + if ($keyval[0] -and $keyval[1]) { + $val = $keyval[1] + + # Remove extraneous quotations around a string value. + if ("'""".Contains($val.Substring(0, 1))) { + $val = $val.Substring(1, $val.Length - 2) + } + + $pyvenvConfig[$keyval[0]] = $val + Write-Verbose "Adding Key: '$($keyval[0])'='$val'" + } + } + } + return $pyvenvConfig +} + + +<# Begin Activate script --------------------------------------------------- #> + +# Determine the containing directory of this script +$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition +$VenvExecDir = Get-Item -Path $VenvExecPath + +Write-Verbose "Activation script is located in path: '$VenvExecPath'" +Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" +Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" + +# Set values required in priority: CmdLine, ConfigFile, Default +# First, get the location of the virtual environment, it might not be +# VenvExecDir if specified on the command line. +if ($VenvDir) { + Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" +} +else { + Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." + $VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") + Write-Verbose "VenvDir=$VenvDir" +} + +# Next, read the `pyvenv.cfg` file to determine any required value such +# as `prompt`. +$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir + +# Next, set the prompt from the command line, or the config file, or +# just use the name of the virtual environment folder. +if ($Prompt) { + Write-Verbose "Prompt specified as argument, using '$Prompt'" +} +else { + Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" + if ($pyvenvCfg -and $pyvenvCfg['prompt']) { + Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" + $Prompt = $pyvenvCfg['prompt']; + } + else { + Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virtual environment)" + Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" + $Prompt = Split-Path -Path $venvDir -Leaf + } +} + +Write-Verbose "Prompt = '$Prompt'" +Write-Verbose "VenvDir='$VenvDir'" + +# Deactivate any currently active virtual environment, but leave the +# deactivate function in place. +deactivate -nondestructive + +# Now set the environment variable VIRTUAL_ENV, used by many tools to determine +# that there is an activated venv. +$env:VIRTUAL_ENV = $VenvDir + +if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { + + Write-Verbose "Setting prompt to '$Prompt'" + + # Set the prompt to include the env name + # Make sure _OLD_VIRTUAL_PROMPT is global + function global:_OLD_VIRTUAL_PROMPT { "" } + Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT + New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt + + function global:prompt { + Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " + _OLD_VIRTUAL_PROMPT + } + $env:VIRTUAL_ENV_PROMPT = $Prompt +} + +# Clear PYTHONHOME +if (Test-Path -Path Env:PYTHONHOME) { + Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME + Remove-Item -Path Env:PYTHONHOME +} + +# Add the venv to the PATH +Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH +$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" + +# SIG # Begin signature block +# MII0CQYJKoZIhvcNAQcCoIIz+jCCM/YCAQExDzANBglghkgBZQMEAgEFADB5Bgor +# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG +# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBnL745ElCYk8vk +# dBtMuQhLeWJ3ZGfzKW4DHCYzAn+QB6CCG9IwggXMMIIDtKADAgECAhBUmNLR1FsZ +# lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK +# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu +# dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy +# MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT +# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv +# c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo +# b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD +# Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH +# or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD +# PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV +# qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70 +# ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1 +# vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3 +# W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK +# xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg +# trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj +# O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7 +# swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE +# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ +# T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn +# LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c +# Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF +# xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx +# AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8 +# FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY +# lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2 +# 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY +# uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al +# GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk +# ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T +# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggb+MIIE5qADAgECAhMzAAM/y2Wy +# WWnFfpZcAAAAAz/LMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD +# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ +# RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDEwHhcNMjUwNDA4MDEwNzI0WhcNMjUwNDEx +# MDEwNzI0WjB8MQswCQYDVQQGEwJVUzEPMA0GA1UECBMGT3JlZ29uMRIwEAYDVQQH +# EwlCZWF2ZXJ0b24xIzAhBgNVBAoTGlB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9u +# MSMwIQYDVQQDExpQeXRob24gU29mdHdhcmUgRm91bmRhdGlvbjCCAaIwDQYJKoZI +# hvcNAQEBBQADggGPADCCAYoCggGBAI0elXEcbTdGLOszMU2fzimHGM9Y4EjwFgC2 +# iGPdieHc0dK1DyEIdtnvjKxnG/KICC3J2MrhePGzMEkie3yQjx05B5leG0q8YoGU +# m9z9K67V6k3DSXX0vQe9FbaNVuyXed31MEf/qek7Zo4ELxu8n/LO3ibURBLRHNoW +# Dz9zr4DcU+hha0bdIL6SnKMLwHqRj59gtFFEPqXcOVO7kobkzQS3O1T5KNL/zGuW +# UGQln7fS4YI9bj24bfrSeG/QzLgChVYScxnUgjAANfT1+SnSxrT4/esMtfbcvfID +# BIvOWk+FPPj9IQWsAMEG/LLG4cF/pQ/TozUXKx362GJBbe6paTM/RCUTcffd83h2 +# bXo9vXO/roZYk6H0ecd2h2FFzLUQn/0i4RQQSOp6zt1eDf28h6F8ev+YYKcChph8 +# iRt32bJPcLQVbUzhehzT4C0pz6oAqPz8s0BGvlj1G6r4CY1Cs2YiMU09/Fl64pWf +# IsA/ReaYj6yNsgQZNUcvzobK2mTxMwIDAQABo4ICGTCCAhUwDAYDVR0TAQH/BAIw +# ADAOBgNVHQ8BAf8EBAMCB4AwPAYDVR0lBDUwMwYKKwYBBAGCN2EBAAYIKwYBBQUH +# AwMGGysGAQQBgjdhgqKNuwqmkohkgZH0oEWCk/3hbzAdBgNVHQ4EFgQU4Y4Xr/Xn +# zEXblXrNC0ZLdaPEJYUwHwYDVR0jBBgwFoAU6IPEM9fcnwycdpoKptTfh6ZeWO4w +# ZwYDVR0fBGAwXjBcoFqgWIZWaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w +# cy9jcmwvTWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENTJTIwQU9DJTIwQ0El +# MjAwMS5jcmwwgaUGCCsGAQUFBwEBBIGYMIGVMGQGCCsGAQUFBzAChlhodHRwOi8v +# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIw +# VmVyaWZpZWQlMjBDUyUyMEFPQyUyMENBJTIwMDEuY3J0MC0GCCsGAQUFBzABhiFo +# dHRwOi8vb25lb2NzcC5taWNyb3NvZnQuY29tL29jc3AwZgYDVR0gBF8wXTBRBgwr +# BgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQu +# Y29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMAgGBmeBDAEEATANBgkqhkiG +# 9w0BAQwFAAOCAgEAKTeVGPXsDKqQLe1OuKx6K6q711FPxNQyLOOqeenH8zybHwNo +# k05cMk39HQ7u+R9BQIL0bWexb7wa3XeKaX06p7aY/OQs+ycvUi/fC6RGlaLWmQ9D +# YhZn2TBz5znimvSf3P+aidCuXeDU5c8GpBFog6fjEa/k+n7TILi0spuYZ4yC9R48 +# R63/VvpLi2SqxfJbx5n92bY6driNzAntjoravF25BSejXVrdzefbnqbQnZPB39g8 +# XHygGPb0912fIuNKPLQa/uCnmYdXJnPb0ZgMxxA8fyxvL2Q30Qf5xpFDssPDElvD +# DoAbvR24CWvuHbu+CMMr2SJUpX4RRvDioO7JeB6wZb+64MXyPUSSf6QwkKNsHPIa +# e9tSfREh86sYn5bOA0Wd+Igk0RpA5jDRTu3GgPOPWbm1PU+VoeqThtHt6R3l17pr +# aQ5wIuuLXgxi1K4ZWgtvXw8BtIXfZz24qCtoo0+3kEGUpEHBgkF1SClbRb8uAzx+ +# 0ROGniLPJRU20Xfn7CgipeKLcNn33JPFwQHk1zpbGS0090mi0erOQCz0S47YdHmm +# RJcbkNIL9DeNAglTZ/TFxrYUM1NRS1Cp4e63MgBKcWh9VJNokInzzmS+bofZz+u1 +# mm8YNtiJjdT8fmizXdUEk68EXQhOs0+HBNvc9nMRK6R28MZu/J+PaUcPL84wggda +# MIIFQqADAgECAhMzAAAABzeMW6HZW4zUAAAAAAAHMA0GCSqGSIb3DQEBDAUAMGMx +# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xNDAy +# BgNVBAMTK01pY3Jvc29mdCBJRCBWZXJpZmllZCBDb2RlIFNpZ25pbmcgUENBIDIw +# MjEwHhcNMjEwNDEzMTczMTU0WhcNMjYwNDEzMTczMTU0WjBaMQswCQYDVQQGEwJV +# UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSswKQYDVQQDEyJNaWNy +# b3NvZnQgSUQgVmVyaWZpZWQgQ1MgQU9DIENBIDAxMIICIjANBgkqhkiG9w0BAQEF +# AAOCAg8AMIICCgKCAgEAt/fAAygHxbo+jxA04hNI8bz+EqbWvSu9dRgAawjCZau1 +# Y54IQal5ArpJWi8cIj0WA+mpwix8iTRguq9JELZvTMo2Z1U6AtE1Tn3mvq3mywZ9 +# SexVd+rPOTr+uda6GVgwLA80LhRf82AvrSwxmZpCH/laT08dn7+Gt0cXYVNKJORm +# 1hSrAjjDQiZ1Jiq/SqiDoHN6PGmT5hXKs22E79MeFWYB4y0UlNqW0Z2LPNua8k0r +# bERdiNS+nTP/xsESZUnrbmyXZaHvcyEKYK85WBz3Sr6Et8Vlbdid/pjBpcHI+Hyt +# oaUAGE6rSWqmh7/aEZeDDUkz9uMKOGasIgYnenUk5E0b2U//bQqDv3qdhj9UJYWA +# DNYC/3i3ixcW1VELaU+wTqXTxLAFelCi/lRHSjaWipDeE/TbBb0zTCiLnc9nmOjZ +# PKlutMNho91wxo4itcJoIk2bPot9t+AV+UwNaDRIbcEaQaBycl9pcYwWmf0bJ4IF +# n/CmYMVG1ekCBxByyRNkFkHmuMXLX6PMXcveE46jMr9syC3M8JHRddR4zVjd/FxB +# nS5HOro3pg6StuEPshrp7I/Kk1cTG8yOWl8aqf6OJeAVyG4lyJ9V+ZxClYmaU5yv +# tKYKk1FLBnEBfDWw+UAzQV0vcLp6AVx2Fc8n0vpoyudr3SwZmckJuz7R+S79BzMC +# AwEAAaOCAg4wggIKMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAd +# BgNVHQ4EFgQU6IPEM9fcnwycdpoKptTfh6ZeWO4wVAYDVR0gBE0wSzBJBgRVHSAA +# MEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv +# RG9jcy9SZXBvc2l0b3J5Lmh0bTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAS +# BgNVHRMBAf8ECDAGAQH/AgEAMB8GA1UdIwQYMBaAFNlBKbAPD2Ns72nX9c0pnqRI +# ajDmMHAGA1UdHwRpMGcwZaBjoGGGX2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w +# a2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDb2RlJTIwU2ln +# bmluZyUyMFBDQSUyMDIwMjEuY3JsMIGuBggrBgEFBQcBAQSBoTCBnjBtBggrBgEF +# BQcwAoZhaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNy +# b3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAy +# MDIxLmNydDAtBggrBgEFBQcwAYYhaHR0cDovL29uZW9jc3AubWljcm9zb2Z0LmNv +# bS9vY3NwMA0GCSqGSIb3DQEBDAUAA4ICAQB3/utLItkwLTp4Nfh99vrbpSsL8NwP +# Ij2+TBnZGL3C8etTGYs+HZUxNG+rNeZa+Rzu9oEcAZJDiGjEWytzMavD6Bih3nEW +# FsIW4aGh4gB4n/pRPeeVrK4i1LG7jJ3kPLRhNOHZiLUQtmrF4V6IxtUFjvBnijaZ +# 9oIxsSSQP8iHMjP92pjQrHBFWHGDbkmx+yO6Ian3QN3YmbdfewzSvnQmKbkiTibJ +# gcJ1L0TZ7BwmsDvm+0XRsPOfFgnzhLVqZdEyWww10bflOeBKqkb3SaCNQTz8nsha +# UZhrxVU5qNgYjaaDQQm+P2SEpBF7RolEC3lllfuL4AOGCtoNdPOWrx9vBZTXAVdT +# E2r0IDk8+5y1kLGTLKzmNFn6kVCc5BddM7xoDWQ4aUoCRXcsBeRhsclk7kVXP+zJ +# GPOXwjUJbnz2Kt9iF/8B6FDO4blGuGrogMpyXkuwCC2Z4XcfyMjPDhqZYAPGGTUI +# NMtFbau5RtGG1DOWE9edCahtuPMDgByfPixvhy3sn7zUHgIC/YsOTMxVuMQi/bga +# memo/VNKZrsZaS0nzmOxKpg9qDefj5fJ9gIHXcp2F0OHcVwe3KnEXa8kqzMDfrRl +# /wwKrNSFn3p7g0b44Ad1ONDmWt61MLQvF54LG62i6ffhTCeoFT9Z9pbUo2gxlyTF +# g7Bm0fgOlnRfGDCCB54wggWGoAMCAQICEzMAAAAHh6M0o3uljhwAAAAAAAcwDQYJ +# KoZIhvcNAQEMBQAwdzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBD +# b3Jwb3JhdGlvbjFIMEYGA1UEAxM/TWljcm9zb2Z0IElkZW50aXR5IFZlcmlmaWNh +# dGlvbiBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDIwMB4XDTIxMDQwMTIw +# MDUyMFoXDTM2MDQwMTIwMTUyMFowYzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1p +# Y3Jvc29mdCBDb3Jwb3JhdGlvbjE0MDIGA1UEAxMrTWljcm9zb2Z0IElEIFZlcmlm +# aWVkIENvZGUgU2lnbmluZyBQQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP +# ADCCAgoCggIBALLwwK8ZiCji3VR6TElsaQhVCbRS/3pK+MHrJSj3Zxd3KU3rlfL3 +# qrZilYKJNqztA9OQacr1AwoNcHbKBLbsQAhBnIB34zxf52bDpIO3NJlfIaTE/xrw +# eLoQ71lzCHkD7A4As1Bs076Iu+mA6cQzsYYH/Cbl1icwQ6C65rU4V9NQhNUwgrx9 +# rGQ//h890Q8JdjLLw0nV+ayQ2Fbkd242o9kH82RZsH3HEyqjAB5a8+Ae2nPIPc8s +# ZU6ZE7iRrRZywRmrKDp5+TcmJX9MRff241UaOBs4NmHOyke8oU1TYrkxh+YeHgfW +# o5tTgkoSMoayqoDpHOLJs+qG8Tvh8SnifW2Jj3+ii11TS8/FGngEaNAWrbyfNrC6 +# 9oKpRQXY9bGH6jn9NEJv9weFxhTwyvx9OJLXmRGbAUXN1U9nf4lXezky6Uh/cgjk +# Vd6CGUAf0K+Jw+GE/5VpIVbcNr9rNE50Sbmy/4RTCEGvOq3GhjITbCa4crCzTTHg +# YYjHs1NbOc6brH+eKpWLtr+bGecy9CrwQyx7S/BfYJ+ozst7+yZtG2wR461uckFu +# 0t+gCwLdN0A6cFtSRtR8bvxVFyWwTtgMMFRuBa3vmUOTnfKLsLefRaQcVTgRnzeL +# zdpt32cdYKp+dhr2ogc+qM6K4CBI5/j4VFyC4QFeUP2YAidLtvpXRRo3AgMBAAGj +# ggI1MIICMTAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0O +# BBYEFNlBKbAPD2Ns72nX9c0pnqRIajDmMFQGA1UdIARNMEswSQYEVR0gADBBMD8G +# CCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3Mv +# UmVwb3NpdG9yeS5odG0wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwDwYDVR0T +# AQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTIftJqhSobyhmYBAcnz1AQT2ioojCBhAYD +# VR0fBH0wezB5oHegdYZzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j +# cmwvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIw +# Q2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNybDCBwwYIKwYBBQUHAQEE +# gbYwgbMwgYEGCCsGAQUFBzAChnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp +# b3BzL2NlcnRzL01pY3Jvc29mdCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIw +# Um9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQwLQYIKwYB +# BQUHMAGGIWh0dHA6Ly9vbmVvY3NwLm1pY3Jvc29mdC5jb20vb2NzcDANBgkqhkiG +# 9w0BAQwFAAOCAgEAfyUqnv7Uq+rdZgrbVyNMul5skONbhls5fccPlmIbzi+OwVdP +# Q4H55v7VOInnmezQEeW4LqK0wja+fBznANbXLB0KrdMCbHQpbLvG6UA/Xv2pfpVI +# E1CRFfNF4XKO8XYEa3oW8oVH+KZHgIQRIwAbyFKQ9iyj4aOWeAzwk+f9E5StNp5T +# 8FG7/VEURIVWArbAzPt9ThVN3w1fAZkF7+YU9kbq1bCR2YD+MtunSQ1Rft6XG7b4 +# e0ejRA7mB2IoX5hNh3UEauY0byxNRG+fT2MCEhQl9g2i2fs6VOG19CNep7SquKaB +# jhWmirYyANb0RJSLWjinMLXNOAga10n8i9jqeprzSMU5ODmrMCJE12xS/NWShg/t +# uLjAsKP6SzYZ+1Ry358ZTFcx0FS/mx2vSoU8s8HRvy+rnXqyUJ9HBqS0DErVLjQw +# K8VtsBdekBmdTbQVoCgPCqr+PDPB3xajYnzevs7eidBsM71PINK2BoE2UfMwxCCX +# 3mccFgx6UsQeRSdVVVNSyALQe6PT12418xon2iDGE81OGCreLzDcMAZnrUAx4XQL +# Uz6ZTl65yPUiOh3k7Yww94lDf+8oG2oZmDh5O1Qe38E+M3vhKwmzIeoB1dVLlz4i +# 3IpaDcR+iuGjH2TdaC1ZOmBXiCRKJLj4DT2uhJ04ji+tHD6n58vhavFIrmcxgheN +# MIIXiQIBATBxMFoxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y +# cG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBBT0Mg +# Q0EgMDECEzMAAz/LZbJZacV+llwAAAADP8swDQYJYIZIAWUDBAIBBQCggcowGQYJ +# KoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQB +# gjcCARUwLwYJKoZIhvcNAQkEMSIEIGcBno/ti9PCrR9sXrajsTvlHQvGxbk63JiI +# URJByQuGMF4GCisGAQQBgjcCAQwxUDBOoEiARgBCAHUAaQBsAHQAOgAgAFIAZQBs +# AGUAYQBzAGUAXwB2ADMALgAxADIALgAxADAAXwAyADAAMgA1ADAANAAwADgALgAw +# ADKhAoAAMA0GCSqGSIb3DQEBAQUABIIBgE9xMVem4h5iAbvBzmB1pTdA4LYNkvd/ +# hSbYmJRt5oJqBR0RGbUmcfYAgTlhdb/S84aGvI3N62I8qeMApnH89q+UF0i8p6+U +# Qza6Mu1cAHCq0NkHH6+N8g7nIfe5Cn+BBCBJ6kuYfQm9bx1JwEm5/yVCwG9I6+XV +# 3WonOeA8djuZFfB9OIW6N9ubX7X+nYqWaeT6w6/lDs8mL+s0Fumy4mJ8B15pd9mr +# N6dIRFokzhuALq6G0USKFzYf3qJQ4GyCos/Luez3cr8sE/78ds6vah5IlLP6qXMM +# ETwAdoymIYSm3Dly3lflodd4d7/nkMhfHITOxSUDoBbCP6MO1rhChX591rJy/omK +# 0RdM9ZpMl6VXHhzZ+lB8U/6j7xJGlxJSJHet7HFEuTnJEjY9dDy2bUgzk0vK1Rs2 +# l7VLOP3X87p9iVz5vDAOQB0fcsMDJvhIzJlmIb5z2uZ6hqD4UZdTDMLIBWe9H7Kv +# rhmGDPHPRboFKtTrKoKcWaf4fJJ2NUtYlKGCFKAwghScBgorBgEEAYI3AwMBMYIU +# jDCCFIgGCSqGSIb3DQEHAqCCFHkwghR1AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFh +# BgsqhkiG9w0BCRABBKCCAVAEggFMMIIBSAIBAQYKKwYBBAGEWQoDATAxMA0GCWCG +# SAFlAwQCAQUABCAY3nVyqXzzboHwsVGd+j5FjG9eaMv+O3mJKpX+3EJ43AIGZ9gU +# uyvYGBMyMDI1MDQwODEyNDEyMi40MTNaMASAAgH0oIHgpIHdMIHaMQswCQYDVQQG +# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG +# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQg +# QW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjozREE1 +# LTk2M0ItRTFGNDE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBT +# dGFtcGluZyBBdXRob3JpdHmggg8gMIIHgjCCBWqgAwIBAgITMwAAAAXlzw//Zi7J +# hwAAAAAABTANBgkqhkiG9w0BAQwFADB3MQswCQYDVQQGEwJVUzEeMBwGA1UEChMV +# TWljcm9zb2Z0IENvcnBvcmF0aW9uMUgwRgYDVQQDEz9NaWNyb3NvZnQgSWRlbnRp +# dHkgVmVyaWZpY2F0aW9uIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAw +# HhcNMjAxMTE5MjAzMjMxWhcNMzUxMTE5MjA0MjMxWjBhMQswCQYDVQQGEwJVUzEe +# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv +# ZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDCCAiIwDQYJKoZIhvcN +# AQEBBQADggIPADCCAgoCggIBAJ5851Jj/eDFnwV9Y7UGIqMcHtfnlzPREwW9ZUZH +# d5HBXXBvf7KrQ5cMSqFSHGqg2/qJhYqOQxwuEQXG8kB41wsDJP5d0zmLYKAY8Zxv +# 3lYkuLDsfMuIEqvGYOPURAH+Ybl4SJEESnt0MbPEoKdNihwM5xGv0rGofJ1qOYST +# Ncc55EbBT7uq3wx3mXhtVmtcCEr5ZKTkKKE1CxZvNPWdGWJUPC6e4uRfWHIhZcgC +# sJ+sozf5EeH5KrlFnxpjKKTavwfFP6XaGZGWUG8TZaiTogRoAlqcevbiqioUz1Yt +# 4FRK53P6ovnUfANjIgM9JDdJ4e0qiDRm5sOTiEQtBLGd9Vhd1MadxoGcHrRCsS5r +# O9yhv2fjJHrmlQ0EIXmp4DhDBieKUGR+eZ4CNE3ctW4uvSDQVeSp9h1SaPV8UWEf +# yTxgGjOsRpeexIveR1MPTVf7gt8hY64XNPO6iyUGsEgt8c2PxF87E+CO7A28TpjN +# q5eLiiunhKbq0XbjkNoU5JhtYUrlmAbpxRjb9tSreDdtACpm3rkpxp7AQndnI0Sh +# u/fk1/rE3oWsDqMX3jjv40e8KN5YsJBnczyWB4JyeeFMW3JBfdeAKhzohFe8U5w9 +# WuvcP1E8cIxLoKSDzCCBOu0hWdjzKNu8Y5SwB1lt5dQhABYyzR3dxEO/T1K/BVF3 +# rV69AgMBAAGjggIbMIICFzAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMC +# AQAwHQYDVR0OBBYEFGtpKDo1L0hjQM972K9J6T7ZPdshMFQGA1UdIARNMEswSQYE +# VR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp +# b3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJ +# KwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME +# GDAWgBTIftJqhSobyhmYBAcnz1AQT2ioojCBhAYDVR0fBH0wezB5oHegdYZzaHR0 +# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSWRl +# bnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRo +# b3JpdHklMjAyMDIwLmNybDCBlAYIKwYBBQUHAQEEgYcwgYQwgYEGCCsGAQUFBzAC +# hnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29m +# dCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRl +# JTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQwDQYJKoZIhvcNAQEMBQADggIBAF+Idsd+ +# bbVaFXXnTHho+k7h2ESZJRWluLE0Oa/pO+4ge/XEizXvhs0Y7+KVYyb4nHlugBes +# nFqBGEdC2IWmtKMyS1OWIviwpnK3aL5JedwzbeBF7POyg6IGG/XhhJ3UqWeWTO+C +# zb1c2NP5zyEh89F72u9UIw+IfvM9lzDmc2O2END7MPnrcjWdQnrLn1Ntday7JSyr +# DvBdmgbNnCKNZPmhzoa8PccOiQljjTW6GePe5sGFuRHzdFt8y+bN2neF7Zu8hTO1 +# I64XNGqst8S+w+RUdie8fXC1jKu3m9KGIqF4aldrYBamyh3g4nJPj/LR2CBaLyD+ +# 2BuGZCVmoNR/dSpRCxlot0i79dKOChmoONqbMI8m04uLaEHAv4qwKHQ1vBzbV/nG +# 89LDKbRSSvijmwJwxRxLLpMQ/u4xXxFfR4f/gksSkbJp7oqLwliDm/h+w0aJ/U5c +# cnYhYb7vPKNMN+SZDWycU5ODIRfyoGl59BsXR/HpRGtiJquOYGmvA/pk5vC1lcnb +# eMrcWD/26ozePQ/TWfNXKBOmkFpvPE8CH+EeGGWzqTCjdAsno2jzTeNSxlx3glDG +# Jgcdz5D/AAxw9Sdgq/+rY7jjgs7X6fqPTXPmaCAJKVHAP19oEjJIBwD1LyHbaEgB +# xFCogYSOiUIr0Xqcr1nJfiWG2GwYe6ZoAF1bMIIHljCCBX6gAwIBAgITMwAAAEYX +# 5HV6yv3a5QAAAAAARjANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEeMBwG +# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQg +# UHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDAeFw0yNDExMjYxODQ4NDla +# Fw0yNTExMTkxODQ4NDlaMIHaMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu +# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv +# cmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYw +# JAYDVQQLEx1UaGFsZXMgVFNTIEVTTjozREE1LTk2M0ItRTFGNDE1MDMGA1UEAxMs +# TWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHkwggIi +# MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwlXzoj/MNL1BfnV+gg4d0fZum +# 1HdUJidSNTcDzpHJvmIBqH566zBYcV0TyN7+3qOnJjpoTx6JBMgNYnL5BmTX9Hrm +# X0WdNMLf74u7NtBSuAD2sf6n2qUUrz7i8f7r0JiZixKJnkvA/1akLHppQMDCug1o +# C0AYjd753b5vy1vWdrHXE9hL71BZe5DCq5/4LBny8aOQZlzvjewgONkiZm+Sfctk +# Jjh9LxdkDlq5EvGE6YU0uC37XF7qkHvIksD2+XgBP0lEMfmPJo2fI9FwIA9YMX7K +# IINEM5OY6nkvKryM9s5bK6LV4z48NYpiI1xvH15YDps+19nHCtKMVTZdB4cYhA0d +# VqJ7dAu4VcxUwD1AEcMxWbIOR1z6OFkVY9GX5oH8k17d9t35PWfn0XuxW4SG/rim +# gtFgpE/shRsy5nMCbHyeCdW0He1plrYQqTsSHP2n/lz2DCgIlnx+uvPLVf5+JG/1 +# d1i/LdwbC2WH6UEEJyZIl3a0YwM4rdzoR+P4dO9I/2oWOxXCYqFytYdCy9ljELUw +# byLjrjRddteR8QTxrCfadKpKfFY6Ak/HNZPUHaAPak3baOIvV7Q8axo3DWQy2ib3 +# zXV6hMPNt1v90pv+q9daQdwUzUrgcbwThdrRhWHwlRIVg2sR668HPn4/8l9ikGok +# rL6gAmVxNswEZ9awCwIDAQABo4IByzCCAccwHQYDVR0OBBYEFBE20NSvdrC6Z6cm +# 6RPGP8YbqIrxMB8GA1UdIwQYMBaAFGtpKDo1L0hjQM972K9J6T7ZPdshMGwGA1Ud +# HwRlMGMwYaBfoF2GW2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3Js +# L01pY3Jvc29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIw +# MjAyMC5jcmwweQYIKwYBBQUHAQEEbTBrMGkGCCsGAQUFBzAChl1odHRwOi8vd3d3 +# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFB1YmxpYyUy +# MFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIwMjAyMC5jcnQwDAYDVR0TAQH/BAIw +# ADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwZgYDVR0g +# BF8wXTBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5t +# aWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMAgGBmeBDAEE +# AjANBgkqhkiG9w0BAQwFAAOCAgEAFIW5L+gGzX4gyHorS33YKXuK9iC91iZTpm30 +# x/EdHG6U8NAu2qityxjZVq6MDq300gspG0ntzLYqVhjfku7iNzE78k6tNgFCr9wv +# GkIHeK+Q2RAO9/s5R8rhNC+lywOB+6K5Zi0kfO0agVXf7Nk2O6F6D9AEzNLijG+c +# Oe5Ef2F5l4ZsVSkLFCI5jELC+r4KnNZjunc+qvjSz2DkNsXfrjFhyk+K7v7U7+JF +# Z8kZ58yFuxEX0cxDKpJLxiNh/ODCOL2UxYkhyfI3AR0EhfxX9QZHVgxyZwnavR35 +# FxqLSiGTeAJsK7YN3bIxyuP6eCcnkX8TMdpu9kPD97sHnM7po0UQDrjaN7etviLD +# xnax2nemdvJW3BewOLFrD1nSnd7ZHdPGPB3oWTCaK9/3XwQERLi3Xj+HZc89RP50 +# Nt7h7+3G6oq2kXYNidI9iWd+gL+lvkQZH9YTIfBCLWjvuXvUUUU+AvFI00Utqrvd +# rIdqCFaqE9HHQgSfXeQ53xLWdMCztUP/YnMXiJxNBkc6UE2px/o6+/LXJDIpwIXR +# 4HSodLfkfsNQl6FFrJ1xsOYGSHvcFkH8389RmUvrjr1NBbdesc4Bu4kox+3cabOZ +# c1zm89G+1RRL2tReFzSMlYSGO3iKn3GGXmQiRmFlBb3CpbUVQz+fgxVMfeL0j4Lm +# KQfT1jIxggPUMIID0AIBATB4MGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNy +# b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNB +# IFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAARhfkdXrK/drlAAAAAABGMA0GCWCG +# SAFlAwQCAQUAoIIBLTAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZI +# hvcNAQkEMSIEIHgwQkiMhul6IrfEKmPaCFR+R91oZOlPqVgP/9PPcfn+MIHdBgsq +# hkiG9w0BCRACLzGBzTCByjCBxzCBoAQgEid2SJpUPj5xQm73M4vqDmVh1QR6TiuT +# UVkL3P8Wis4wfDBlpGMwYTELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m +# dCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGlt +# ZXN0YW1waW5nIENBIDIwMjACEzMAAABGF+R1esr92uUAAAAAAEYwIgQgVp6I1YBM +# Mni0rCuD57vEK/tzWZypHqWFikWLFVY11RwwDQYJKoZIhvcNAQELBQAEggIAnRBH +# voM5+wbJp+aOwrrL8fi8Rv/eFV820Nhr+jMny73UscN60OWdcdcZDbjDlnDX1KEP +# sNcEOFvaruHHrF4kDK8N0yemElNz63IgqhUoGoXXQKT2RgVg7T/kiQJH7zuaEjgB +# YNniAZdXXJJ1C+uv2ZQzkGIEVIEA6pB5/xo4kFhrfkOrdGzqL8HXT/RZQDMn5Uzk +# W+Sl2JmsyYBS4sgI9Ay3qT5nv+frzngbWlqx1dre21uj37Fgk5mWHJEdmY1nqTTd +# 25j6oDLGPC8AS9wtgZBXggemKAXwyeOFFahXUFN7X7cbwTALy5aWjE/rqp+N5J7M +# +YApl3aknUZ13KTXz9pfAF0uhmZimngvBHjijyctleF8HUP2RNAhS/l68OqW7oKi +# Dqvb7tSHJbcnYkxo7dUq6ppfN51ah61ZsyMVG6SaH015+5QO1k50ohXcFff2GOuZ +# d3Z9JOoAjIkeiVTNeRlPDlHtS0CSYu4ZKsWsst+0VY2R9rJBeoii9Xa0oiIggkYL +# 1pHAPH0B1uLlvFcI6B+fAXe0OiCJodbO5lk8ZpvCG5WWYbjzp2c3B8PZGSBgEpSf +# KYlVavvBAvaJCORUO7j8PyzzDINuzQorP9+i399ORjOnqeC92Cb0V12LcoqqtJaf +# 7oSB86VOI0lfHnPUlLWvoiLHrFR5PsYkltOuPqU= +# SIG # End signature block diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/activate b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/activate new file mode 100644 index 00000000..9dce461c --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/activate @@ -0,0 +1,76 @@ +# This file must be used with "source bin/activate" *from bash* +# You cannot run it directly + +deactivate () { + # reset old environment variables + if [ -n "${_OLD_VIRTUAL_PATH:-}" ] ; then + PATH="${_OLD_VIRTUAL_PATH:-}" + export PATH + unset _OLD_VIRTUAL_PATH + fi + if [ -n "${_OLD_VIRTUAL_PYTHONHOME:-}" ] ; then + PYTHONHOME="${_OLD_VIRTUAL_PYTHONHOME:-}" + export PYTHONHOME + unset _OLD_VIRTUAL_PYTHONHOME + fi + + # Call hash to forget past locations. Without forgetting + # past locations the $PATH changes we made may not be respected. + # See "man bash" for more details. hash is usually a builtin of your shell + hash -r 2> /dev/null + + if [ -n "${_OLD_VIRTUAL_PS1:-}" ] ; then + PS1="${_OLD_VIRTUAL_PS1:-}" + export PS1 + unset _OLD_VIRTUAL_PS1 + fi + + unset VIRTUAL_ENV + unset VIRTUAL_ENV_PROMPT + if [ ! "${1:-}" = "nondestructive" ] ; then + # Self destruct! + unset -f deactivate + fi +} + +# unset irrelevant variables +deactivate nondestructive + +# on Windows, a path can contain colons and backslashes and has to be converted: +case "$(uname)" in + CYGWIN*|MSYS*|MINGW*) + # transform D:\path\to\venv to /d/path/to/venv on MSYS and MINGW + # and to /cygdrive/d/path/to/venv on Cygwin + VIRTUAL_ENV=$(cygpath 'D:\pythonProject\smart_fitness_planner\venv_fit') + export VIRTUAL_ENV + ;; + *) + # use the path as-is + export VIRTUAL_ENV='D:\pythonProject\smart_fitness_planner\venv_fit' + ;; +esac + +_OLD_VIRTUAL_PATH="$PATH" +PATH="$VIRTUAL_ENV/"Scripts":$PATH" +export PATH + +VIRTUAL_ENV_PROMPT='(venv_fit) ' +export VIRTUAL_ENV_PROMPT + +# unset PYTHONHOME if set +# this will fail if PYTHONHOME is set to the empty string (which is bad anyway) +# could use `if (set -u; : $PYTHONHOME) ;` in bash +if [ -n "${PYTHONHOME:-}" ] ; then + _OLD_VIRTUAL_PYTHONHOME="${PYTHONHOME:-}" + unset PYTHONHOME +fi + +if [ -z "${VIRTUAL_ENV_DISABLE_PROMPT:-}" ] ; then + _OLD_VIRTUAL_PS1="${PS1:-}" + PS1="("'(venv_fit) '") ${PS1:-}" + export PS1 +fi + +# Call hash to forget past commands. Without forgetting +# past commands the $PATH changes we made may not be respected +hash -r 2> /dev/null diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/activate.bat b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/activate.bat new file mode 100644 index 00000000..7974de0e --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/activate.bat @@ -0,0 +1,34 @@ +@echo off + +rem This file is UTF-8 encoded, so we need to update the current code page while executing it +for /f "tokens=2 delims=:." %%a in ('"%SystemRoot%\System32\chcp.com"') do ( + set _OLD_CODEPAGE=%%a +) +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" 65001 > nul +) + +set "VIRTUAL_ENV=D:\pythonProject\smart_fitness_planner\venv_fit" + +if not defined PROMPT set PROMPT=$P$G + +if defined _OLD_VIRTUAL_PROMPT set PROMPT=%_OLD_VIRTUAL_PROMPT% +if defined _OLD_VIRTUAL_PYTHONHOME set PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME% + +set _OLD_VIRTUAL_PROMPT=%PROMPT% +set PROMPT=(venv_fit) %PROMPT% + +if defined PYTHONHOME set _OLD_VIRTUAL_PYTHONHOME=%PYTHONHOME% +set PYTHONHOME= + +if defined _OLD_VIRTUAL_PATH set PATH=%_OLD_VIRTUAL_PATH% +if not defined _OLD_VIRTUAL_PATH set _OLD_VIRTUAL_PATH=%PATH% + +set "PATH=%VIRTUAL_ENV%\Scripts;%PATH%" +set "VIRTUAL_ENV_PROMPT=(venv_fit) " + +:END +if defined _OLD_CODEPAGE ( + "%SystemRoot%\System32\chcp.com" %_OLD_CODEPAGE% > nul + set _OLD_CODEPAGE= +) diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/cyclopts.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/cyclopts.exe new file mode 100644 index 00000000..b9ae2889 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/cyclopts.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/deactivate.bat b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/deactivate.bat new file mode 100644 index 00000000..62a39a75 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/deactivate.bat @@ -0,0 +1,22 @@ +@echo off + +if defined _OLD_VIRTUAL_PROMPT ( + set "PROMPT=%_OLD_VIRTUAL_PROMPT%" +) +set _OLD_VIRTUAL_PROMPT= + +if defined _OLD_VIRTUAL_PYTHONHOME ( + set "PYTHONHOME=%_OLD_VIRTUAL_PYTHONHOME%" + set _OLD_VIRTUAL_PYTHONHOME= +) + +if defined _OLD_VIRTUAL_PATH ( + set "PATH=%_OLD_VIRTUAL_PATH%" +) + +set _OLD_VIRTUAL_PATH= + +set VIRTUAL_ENV= +set VIRTUAL_ENV_PROMPT= + +:END diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/distro.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/distro.exe new file mode 100644 index 00000000..49a84a2b Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/distro.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/docutils.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/docutils.exe new file mode 100644 index 00000000..dddd83d9 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/docutils.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/dotenv.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/dotenv.exe new file mode 100644 index 00000000..79a6df3e Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/dotenv.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/email_validator.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/email_validator.exe new file mode 100644 index 00000000..a0668704 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/email_validator.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/f2py.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/f2py.exe new file mode 100644 index 00000000..6078b7ee Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/f2py.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/fastapi.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/fastapi.exe new file mode 100644 index 00000000..f5ec0746 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/fastapi.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/fastmcp.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/fastmcp.exe new file mode 100644 index 00000000..8847fe1e Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/fastmcp.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/hf.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/hf.exe new file mode 100644 index 00000000..4656a845 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/hf.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/httpx.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/httpx.exe new file mode 100644 index 00000000..f41e32b5 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/httpx.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/jsonschema.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/jsonschema.exe new file mode 100644 index 00000000..ef1bb2c4 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/jsonschema.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/keyring.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/keyring.exe new file mode 100644 index 00000000..f6399329 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/keyring.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/markdown-it.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/markdown-it.exe new file mode 100644 index 00000000..c492b770 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/markdown-it.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/mcp.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/mcp.exe new file mode 100644 index 00000000..d16c0245 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/mcp.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/normalizer.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/normalizer.exe new file mode 100644 index 00000000..f075a90a Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/normalizer.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/numpy-config.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/numpy-config.exe new file mode 100644 index 00000000..09d39831 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/numpy-config.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/openai.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/openai.exe new file mode 100644 index 00000000..a1bfbe85 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/openai.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip.exe new file mode 100644 index 00000000..f5226160 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip3.12.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip3.12.exe new file mode 100644 index 00000000..f5226160 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip3.12.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip3.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip3.exe new file mode 100644 index 00000000..f5226160 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pip3.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pygmentize.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pygmentize.exe new file mode 100644 index 00000000..9b859a90 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pygmentize.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-decrypt.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-decrypt.exe new file mode 100644 index 00000000..60992ce7 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-decrypt.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-encrypt.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-encrypt.exe new file mode 100644 index 00000000..1ed7e769 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-encrypt.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-keygen.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-keygen.exe new file mode 100644 index 00000000..91e2cde9 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-keygen.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-priv2pub.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-priv2pub.exe new file mode 100644 index 00000000..59fde908 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-priv2pub.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-sign.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-sign.exe new file mode 100644 index 00000000..9e0c527e Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-sign.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-verify.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-verify.exe new file mode 100644 index 00000000..bc4c4d34 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pyrsa-verify.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/python.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/python.exe new file mode 100644 index 00000000..ba0cd040 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/python.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pythonw.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pythonw.exe new file mode 100644 index 00000000..68b3cfe9 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pythonw.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_postinstall.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_postinstall.exe new file mode 100644 index 00000000..f8927b8f Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_postinstall.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_postinstall.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_postinstall.py new file mode 100644 index 00000000..3348b8cd --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_postinstall.py @@ -0,0 +1,733 @@ +# postinstall script for pywin32 +# +# copies pywintypesXX.dll and pythoncomXX.dll into the system directory, +# and creates a pth file +import argparse +import glob +import os +import shutil +import sys +import sysconfig +import tempfile +import winreg + +tee_f = open( + os.path.join( + tempfile.gettempdir(), # Send output somewhere so it can be found if necessary... + "pywin32_postinstall.log", + ), + "w", +) + + +class Tee: + def __init__(self, file): + self.f = file + + def write(self, what): + if self.f is not None: + try: + self.f.write(what.replace("\n", "\r\n")) + except OSError: + pass + tee_f.write(what) + + def flush(self): + if self.f is not None: + try: + self.f.flush() + except OSError: + pass + tee_f.flush() + + +sys.stderr = Tee(sys.stderr) +sys.stdout = Tee(sys.stdout) + +com_modules = [ + # module_name, class_names + ("win32com.servers.interp", "Interpreter"), + ("win32com.servers.dictionary", "DictionaryPolicy"), + ("win32com.axscript.client.pyscript", "PyScript"), +] + +# Is this a 'silent' install - ie, avoid all dialogs. +# Different than 'verbose' +silent = 0 + +# Verbosity of output messages. +verbose = 1 + +root_key_name = "Software\\Python\\PythonCore\\" + sys.winver + + +def get_root_hkey(): + try: + winreg.OpenKey( + winreg.HKEY_LOCAL_MACHINE, root_key_name, 0, winreg.KEY_CREATE_SUB_KEY + ) + return winreg.HKEY_LOCAL_MACHINE + except OSError: + # Either not exist, or no permissions to create subkey means + # must be HKCU + return winreg.HKEY_CURRENT_USER + + +# Create a function with the same signature as create_shortcut +# previously provided by bdist_wininst +def create_shortcut( + path, description, filename, arguments="", workdir="", iconpath="", iconindex=0 +): + import pythoncom + from win32com.shell import shell + + ilink = pythoncom.CoCreateInstance( + shell.CLSID_ShellLink, + None, + pythoncom.CLSCTX_INPROC_SERVER, + shell.IID_IShellLink, + ) + ilink.SetPath(path) + ilink.SetDescription(description) + if arguments: + ilink.SetArguments(arguments) + if workdir: + ilink.SetWorkingDirectory(workdir) + if iconpath or iconindex: + ilink.SetIconLocation(iconpath, iconindex) + # now save it. + ipf = ilink.QueryInterface(pythoncom.IID_IPersistFile) + ipf.Save(filename, 0) + + +# Support the same list of "path names" as bdist_wininst used to +def get_special_folder_path(path_name): + from win32com.shell import shell, shellcon + + for maybe in """ + CSIDL_COMMON_STARTMENU CSIDL_STARTMENU CSIDL_COMMON_APPDATA + CSIDL_LOCAL_APPDATA CSIDL_APPDATA CSIDL_COMMON_DESKTOPDIRECTORY + CSIDL_DESKTOPDIRECTORY CSIDL_COMMON_STARTUP CSIDL_STARTUP + CSIDL_COMMON_PROGRAMS CSIDL_PROGRAMS CSIDL_PROGRAM_FILES_COMMON + CSIDL_PROGRAM_FILES CSIDL_FONTS""".split(): + if maybe == path_name: + csidl = getattr(shellcon, maybe) + return shell.SHGetSpecialFolderPath(0, csidl, False) + raise ValueError(f"{path_name} is an unknown path ID") + + +def CopyTo(desc, src, dest): + import win32api + import win32con + + while 1: + try: + win32api.CopyFile(src, dest, 0) + return + except win32api.error as details: + if details.winerror == 5: # access denied - user not admin. + raise + if silent: + # Running silent mode - just re-raise the error. + raise + full_desc = ( + f"Error {desc}\n\n" + "If you have any Python applications running, " + f"please close them now\nand select 'Retry'\n\n{details.strerror}" + ) + rc = win32api.MessageBox( + 0, full_desc, "Installation Error", win32con.MB_ABORTRETRYIGNORE + ) + if rc == win32con.IDABORT: + raise + elif rc == win32con.IDIGNORE: + return + # else retry - around we go again. + + +# We need to import win32api to determine the Windows system directory, +# so we can copy our system files there - but importing win32api will +# load the pywintypes.dll already in the system directory preventing us +# from updating them! +# So, we pull the same trick pywintypes.py does, but it loads from +# our pywintypes_system32 directory. +def LoadSystemModule(lib_dir, modname): + # See if this is a debug build. + import importlib.machinery + import importlib.util + + suffix = "_d" if "_d.pyd" in importlib.machinery.EXTENSION_SUFFIXES else "" + filename = "%s%d%d%s.dll" % ( + modname, + sys.version_info.major, + sys.version_info.minor, + suffix, + ) + filename = os.path.join(lib_dir, "pywin32_system32", filename) + loader = importlib.machinery.ExtensionFileLoader(modname, filename) + spec = importlib.machinery.ModuleSpec(name=modname, loader=loader, origin=filename) + mod = importlib.util.module_from_spec(spec) + loader.exec_module(mod) + + +def SetPyKeyVal(key_name, value_name, value): + root_hkey = get_root_hkey() + root_key = winreg.OpenKey(root_hkey, root_key_name) + try: + my_key = winreg.CreateKey(root_key, key_name) + try: + winreg.SetValueEx(my_key, value_name, 0, winreg.REG_SZ, value) + if verbose: + print(f"-> {root_key_name}\\{key_name}[{value_name}]={value!r}") + finally: + my_key.Close() + finally: + root_key.Close() + + +def UnsetPyKeyVal(key_name, value_name, delete_key=False): + root_hkey = get_root_hkey() + root_key = winreg.OpenKey(root_hkey, root_key_name) + try: + my_key = winreg.OpenKey(root_key, key_name, 0, winreg.KEY_SET_VALUE) + try: + winreg.DeleteValue(my_key, value_name) + if verbose: + print(f"-> DELETE {root_key_name}\\{key_name}[{value_name}]") + finally: + my_key.Close() + if delete_key: + winreg.DeleteKey(root_key, key_name) + if verbose: + print(f"-> DELETE {root_key_name}\\{key_name}") + except OSError as why: + winerror = getattr(why, "winerror", why.errno) + if winerror != 2: # file not found + raise + finally: + root_key.Close() + + +def RegisterCOMObjects(register=True): + import win32com.server.register + + if register: + func = win32com.server.register.RegisterClasses + else: + func = win32com.server.register.UnregisterClasses + flags = {} + if not verbose: + flags["quiet"] = 1 + for module, klass_name in com_modules: + __import__(module) + mod = sys.modules[module] + flags["finalize_register"] = getattr(mod, "DllRegisterServer", None) + flags["finalize_unregister"] = getattr(mod, "DllUnregisterServer", None) + klass = getattr(mod, klass_name) + func(klass, **flags) + + +def RegisterHelpFile(register=True, lib_dir=None): + if lib_dir is None: + lib_dir = sysconfig.get_paths()["platlib"] + if register: + # Register the .chm help file. + chm_file = os.path.join(lib_dir, "PyWin32.chm") + if os.path.isfile(chm_file): + # This isn't recursive, so if 'Help' doesn't exist, we croak + SetPyKeyVal("Help", None, None) + SetPyKeyVal("Help\\Pythonwin Reference", None, chm_file) + return chm_file + else: + print("NOTE: PyWin32.chm can not be located, so has not been registered") + else: + UnsetPyKeyVal("Help\\Pythonwin Reference", None, delete_key=True) + return None + + +def RegisterPythonwin(register=True, lib_dir=None): + """Add (or remove) Pythonwin to context menu for python scripts. + ??? Should probably also add Edit command for pys files also. + Also need to remove these keys on uninstall, but there's no function + to add registry entries to uninstall log ??? + """ + import os + + if lib_dir is None: + lib_dir = sysconfig.get_paths()["platlib"] + classes_root = get_root_hkey() + ## Installer executable doesn't seem to pass anything to postinstall script indicating if it's a debug build + pythonwin_exe = os.path.join(lib_dir, "Pythonwin", "Pythonwin.exe") + pythonwin_edit_command = pythonwin_exe + ' -edit "%1"' + + keys_vals = [ + ( + "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\Pythonwin.exe", + "", + pythonwin_exe, + ), + ( + "Software\\Classes\\Python.File\\shell\\Edit with Pythonwin", + "command", + pythonwin_edit_command, + ), + ( + "Software\\Classes\\Python.NoConFile\\shell\\Edit with Pythonwin", + "command", + pythonwin_edit_command, + ), + ] + + try: + if register: + for key, sub_key, val in keys_vals: + ## Since winreg only uses the character Api functions, this can fail if Python + ## is installed to a path containing non-ascii characters + hkey = winreg.CreateKey(classes_root, key) + if sub_key: + hkey = winreg.CreateKey(hkey, sub_key) + winreg.SetValueEx(hkey, None, 0, winreg.REG_SZ, val) + hkey.Close() + else: + for key, sub_key, val in keys_vals: + try: + if sub_key: + hkey = winreg.OpenKey(classes_root, key) + winreg.DeleteKey(hkey, sub_key) + hkey.Close() + winreg.DeleteKey(classes_root, key) + except OSError as why: + winerror = getattr(why, "winerror", why.errno) + if winerror != 2: # file not found + raise + finally: + # tell windows about the change + from win32com.shell import shell, shellcon + + shell.SHChangeNotify( + shellcon.SHCNE_ASSOCCHANGED, shellcon.SHCNF_IDLIST, None, None + ) + + +def get_shortcuts_folder(): + if get_root_hkey() == winreg.HKEY_LOCAL_MACHINE: + try: + fldr = get_special_folder_path("CSIDL_COMMON_PROGRAMS") + except OSError: + # No CSIDL_COMMON_PROGRAMS on this platform + fldr = get_special_folder_path("CSIDL_PROGRAMS") + else: + # non-admin install - always goes in this user's start menu. + fldr = get_special_folder_path("CSIDL_PROGRAMS") + + try: + install_group = winreg.QueryValue( + get_root_hkey(), root_key_name + "\\InstallPath\\InstallGroup" + ) + except OSError: + install_group = "Python %d.%d" % ( + sys.version_info.major, + sys.version_info.minor, + ) + return os.path.join(fldr, install_group) + + +# Get the system directory, which may be the Wow64 directory if we are a 32bit +# python on a 64bit OS. +def get_system_dir(): + import win32api # we assume this exists. + + try: + import pythoncom + import win32process + from win32com.shell import shell, shellcon + + try: + if win32process.IsWow64Process(): + return shell.SHGetSpecialFolderPath(0, shellcon.CSIDL_SYSTEMX86) + return shell.SHGetSpecialFolderPath(0, shellcon.CSIDL_SYSTEM) + except (pythoncom.com_error, win32process.error): + return win32api.GetSystemDirectory() + except ImportError: + return win32api.GetSystemDirectory() + + +def fixup_dbi(): + # We used to have a dbi.pyd with our .pyd files, but now have a .py file. + # If the user didn't uninstall, they will find the .pyd which will cause + # problems - so handle that. + import win32api + import win32con + + pyd_name = os.path.join(os.path.dirname(win32api.__file__), "dbi.pyd") + pyd_d_name = os.path.join(os.path.dirname(win32api.__file__), "dbi_d.pyd") + py_name = os.path.join(os.path.dirname(win32con.__file__), "dbi.py") + for this_pyd in (pyd_name, pyd_d_name): + this_dest = this_pyd + ".old" + if os.path.isfile(this_pyd) and os.path.isfile(py_name): + try: + if os.path.isfile(this_dest): + print( + f"Old dbi '{this_dest}' already exists - deleting '{this_pyd}'" + ) + os.remove(this_pyd) + else: + os.rename(this_pyd, this_dest) + print(f"renamed '{this_pyd}'->'{this_pyd}.old'") + except OSError as exc: + print(f"FAILED to rename '{this_pyd}': {exc}") + + +def install(lib_dir): + import traceback + + # The .pth file is now installed as a regular file. + # Create the .pth file in the site-packages dir, and use only relative paths + # We used to write a .pth directly to sys.prefix - clobber it. + if os.path.isfile(os.path.join(sys.prefix, "pywin32.pth")): + os.unlink(os.path.join(sys.prefix, "pywin32.pth")) + # The .pth may be new and therefore not loaded in this session. + # Setup the paths just in case. + for name in "win32 win32\\lib Pythonwin".split(): + sys.path.append(os.path.join(lib_dir, name)) + # It is possible people with old versions installed with still have + # pywintypes and pythoncom registered. We no longer need this, and stale + # entries hurt us. + for name in "pythoncom pywintypes".split(): + keyname = "Software\\Python\\PythonCore\\" + sys.winver + "\\Modules\\" + name + for root in winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER: + try: + winreg.DeleteKey(root, keyname + "\\Debug") + except OSError: + pass + try: + winreg.DeleteKey(root, keyname) + except OSError: + pass + LoadSystemModule(lib_dir, "pywintypes") + LoadSystemModule(lib_dir, "pythoncom") + import win32api + + # and now we can get the system directory: + files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*")) + if not files: + raise RuntimeError("No system files to copy!!") + # Try the system32 directory first - if that fails due to "access denied", + # it implies a non-admin user, and we use sys.prefix + for dest_dir in [get_system_dir(), sys.prefix]: + # and copy some files over there + worked = 0 + try: + for fname in files: + base = os.path.basename(fname) + dst = os.path.join(dest_dir, base) + CopyTo("installing %s" % base, fname, dst) + if verbose: + print(f"Copied {base} to {dst}") + worked = 1 + # Nuke any other versions that may exist - having + # duplicates causes major headaches. + bad_dest_dirs = [ + os.path.join(sys.prefix, "Library\\bin"), + os.path.join(sys.prefix, "Lib\\site-packages\\win32"), + ] + if dest_dir != sys.prefix: + bad_dest_dirs.append(sys.prefix) + for bad_dest_dir in bad_dest_dirs: + bad_fname = os.path.join(bad_dest_dir, base) + if os.path.exists(bad_fname): + # let exceptions go here - delete must succeed + os.unlink(bad_fname) + if worked: + break + except win32api.error as details: + if details.winerror == 5: + # access denied - user not admin - try sys.prefix dir, + # but first check that a version doesn't already exist + # in that place - otherwise that one will still get used! + if os.path.exists(dst): + msg = ( + "The file '%s' exists, but can not be replaced " + "due to insufficient permissions. You must " + "reinstall this software as an Administrator" % dst + ) + print(msg) + raise RuntimeError(msg) + continue + raise + else: + raise RuntimeError( + "You don't have enough permissions to install the system files" + ) + + # Register our demo COM objects. + try: + try: + RegisterCOMObjects() + except win32api.error as details: + if details.winerror != 5: # ERROR_ACCESS_DENIED + raise + print("You do not have the permissions to install COM objects.") + print("The sample COM objects were not registered.") + except Exception: + print("FAILED to register the Python COM objects") + traceback.print_exc() + + # There may be no main Python key in HKCU if, eg, an admin installed + # python itself. + winreg.CreateKey(get_root_hkey(), root_key_name) + + chm_file = None + try: + chm_file = RegisterHelpFile(True, lib_dir) + except Exception: + print("Failed to register help file") + traceback.print_exc() + else: + if verbose: + print("Registered help file") + + # misc other fixups. + fixup_dbi() + + # Register Pythonwin in context menu + try: + RegisterPythonwin(True, lib_dir) + except Exception: + print("Failed to register pythonwin as editor") + traceback.print_exc() + else: + if verbose: + print("Pythonwin has been registered in context menu") + + # Create the win32com\gen_py directory. + make_dir = os.path.join(lib_dir, "win32com", "gen_py") + if not os.path.isdir(make_dir): + if verbose: + print(f"Creating directory {make_dir}") + os.mkdir(make_dir) + + try: + # create shortcuts + # CSIDL_COMMON_PROGRAMS only available works on NT/2000/XP, and + # will fail there if the user has no admin rights. + fldr = get_shortcuts_folder() + # If the group doesn't exist, then we don't make shortcuts - its + # possible that this isn't a "normal" install. + if os.path.isdir(fldr): + dst = os.path.join(fldr, "PythonWin.lnk") + create_shortcut( + os.path.join(lib_dir, "Pythonwin\\Pythonwin.exe"), + "The Pythonwin IDE", + dst, + "", + sys.prefix, + ) + if verbose: + print("Shortcut for Pythonwin created") + # And the docs. + if chm_file: + dst = os.path.join(fldr, "Python for Windows Documentation.lnk") + doc = "Documentation for the PyWin32 extensions" + create_shortcut(chm_file, doc, dst) + if verbose: + print("Shortcut to documentation created") + else: + if verbose: + print(f"Can't install shortcuts - {fldr!r} is not a folder") + except Exception as details: + print(details) + + # importing win32com.client ensures the gen_py dir created - not strictly + # necessary to do now, but this makes the installation "complete" + try: + import win32com.client # noqa + except ImportError: + # Don't let this error sound fatal + pass + print("The pywin32 extensions were successfully installed.") + + +def uninstall(lib_dir): + # First ensure our system modules are loaded from pywin32_system, so + # we can remove the ones we copied... + LoadSystemModule(lib_dir, "pywintypes") + LoadSystemModule(lib_dir, "pythoncom") + + try: + RegisterCOMObjects(False) + except Exception as why: + print(f"Failed to unregister COM objects: {why}") + + try: + RegisterHelpFile(False, lib_dir) + except Exception as why: + print(f"Failed to unregister help file: {why}") + else: + if verbose: + print("Unregistered help file") + + try: + RegisterPythonwin(False, lib_dir) + except Exception as why: + print(f"Failed to unregister Pythonwin: {why}") + else: + if verbose: + print("Unregistered Pythonwin") + + try: + # remove gen_py directory. + gen_dir = os.path.join(lib_dir, "win32com", "gen_py") + if os.path.isdir(gen_dir): + shutil.rmtree(gen_dir) + if verbose: + print(f"Removed directory {gen_dir}") + + # Remove pythonwin compiled "config" files. + pywin_dir = os.path.join(lib_dir, "Pythonwin", "pywin") + for fname in glob.glob(os.path.join(pywin_dir, "*.cfc")): + os.remove(fname) + + # The dbi.pyd.old files we may have created. + try: + os.remove(os.path.join(lib_dir, "win32", "dbi.pyd.old")) + except OSError: + pass + try: + os.remove(os.path.join(lib_dir, "win32", "dbi_d.pyd.old")) + except OSError: + pass + + except Exception as why: + print(f"Failed to remove misc files: {why}") + + try: + fldr = get_shortcuts_folder() + for link in ("PythonWin.lnk", "Python for Windows Documentation.lnk"): + fqlink = os.path.join(fldr, link) + if os.path.isfile(fqlink): + os.remove(fqlink) + if verbose: + print(f"Removed {link}") + except Exception as why: + print(f"Failed to remove shortcuts: {why}") + # Now remove the system32 files. + files = glob.glob(os.path.join(lib_dir, "pywin32_system32\\*.*")) + # Try the system32 directory first - if that fails due to "access denied", + # it implies a non-admin user, and we use sys.prefix + try: + for dest_dir in [get_system_dir(), sys.prefix]: + # and copy some files over there + worked = 0 + for fname in files: + base = os.path.basename(fname) + dst = os.path.join(dest_dir, base) + if os.path.isfile(dst): + try: + os.remove(dst) + worked = 1 + if verbose: + print("Removed file %s" % (dst)) + except Exception: + print(f"FAILED to remove {dst}") + if worked: + break + except Exception as why: + print(f"FAILED to remove system files: {why}") + + +# NOTE: This used to be run from inside the bdist_wininst created binary un/installer. +# From inside the binary installer this script HAD to NOT +# call sys.exit() or raise SystemExit, otherwise the installer would also terminate! +# Out of principle, we're still not using system exits. + + +def verify_destination(location: str) -> str: + location = os.path.abspath(location) + if not os.path.isdir(location): + raise argparse.ArgumentTypeError( + f'Path "{location}" is not an existing directory!' + ) + return location + + +def main(): + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description="""A post-install script for the pywin32 extensions. + + * Typical usage: + + > python -m pywin32_postinstall -install + + * or (shorter but you don't have control over which python environment is used) + + > pywin32_postinstall -install + + You need to execute this script, with a '-install' parameter, + to ensure the environment is setup correctly to install COM objects, services, etc. + """, + ) + parser.add_argument( + "-install", + default=False, + action="store_true", + help="Configure the Python environment correctly for pywin32.", + ) + parser.add_argument( + "-remove", + default=False, + action="store_true", + help="Try and remove everything that was installed or copied.", + ) + parser.add_argument( + "-wait", + type=int, + help="Wait for the specified process to terminate before starting.", + ) + parser.add_argument( + "-silent", + default=False, + action="store_true", + help='Don\'t display the "Abort/Retry/Ignore" dialog for files in use.', + ) + parser.add_argument( + "-quiet", + default=False, + action="store_true", + help="Don't display progress messages.", + ) + parser.add_argument( + "-destination", + default=sysconfig.get_paths()["platlib"], + type=verify_destination, + help="Location of the PyWin32 installation", + ) + + args = parser.parse_args() + + if not args.quiet: + print(f"Parsed arguments are: {args}") + + if not args.install ^ args.remove: + parser.error("You need to either choose to -install or -remove!") + + if args.wait is not None: + try: + os.waitpid(args.wait, 0) + except OSError: + # child already dead + pass + + silent = args.silent + verbose = not args.quiet + + if args.install: + install(args.destination) + + if args.remove: + uninstall(args.destination) + + +if __name__ == "__main__": + main() diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_testall.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_testall.exe new file mode 100644 index 00000000..79d5b8cc Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_testall.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_testall.py b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_testall.py new file mode 100644 index 00000000..345d6413 --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/pywin32_testall.py @@ -0,0 +1,120 @@ +"""A test runner for pywin32""" + +import os +import site +import subprocess +import sys + +# locate the dirs based on where this script is - it may be either in the +# source tree, or in an installed Python 'Scripts' tree. +project_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +site_packages = [site.getusersitepackages()] + site.getsitepackages() + +failures = [] + + +# Run a test using subprocess and wait for the result. +# If we get an returncode != 0, we know that there was an error, but we don't +# abort immediately - we run as many tests as we can. +def run_test(script, cmdline_extras): + dirname, scriptname = os.path.split(script) + # some tests prefer to be run from their directory. + cmd = [sys.executable, "-u", scriptname] + cmdline_extras + print("--- Running '%s' ---" % script) + sys.stdout.flush() + result = subprocess.run(cmd, check=False, cwd=dirname) + print(f"*** Test script '{script}' exited with {result.returncode}") + sys.stdout.flush() + if result.returncode: + failures.append(script) + + +def find_and_run(possible_locations, extras): + for maybe in possible_locations: + if os.path.isfile(maybe): + run_test(maybe, extras) + break + else: + raise RuntimeError( + "Failed to locate a test script in one of %s" % possible_locations + ) + + +def main(): + import argparse + + code_directories = [project_root] + site_packages + + parser = argparse.ArgumentParser( + description="A script to trigger tests in all subprojects of PyWin32." + ) + parser.add_argument( + "-no-user-interaction", + default=False, + action="store_true", + help="(This is now the default - use `-user-interaction` to include them)", + ) + + parser.add_argument( + "-user-interaction", + action="store_true", + help="Include tests which require user interaction", + ) + + parser.add_argument( + "-skip-adodbapi", + default=False, + action="store_true", + help="Skip the adodbapi tests; useful for CI where there's no provider", + ) + + args, remains = parser.parse_known_args() + + # win32, win32ui / Pythonwin + + extras = [] + if args.user_interaction: + extras.append("-user-interaction") + extras.extend(remains) + scripts = [ + "win32/test/testall.py", + "Pythonwin/pywin/test/all.py", + ] + for script in scripts: + maybes = [os.path.join(directory, script) for directory in code_directories] + find_and_run(maybes, extras) + + # win32com + maybes = [ + os.path.join(directory, "win32com", "test", "testall.py") + for directory in [os.path.join(project_root, "com")] + site_packages + ] + extras = remains + ["1"] # only run "level 1" tests in CI + find_and_run(maybes, extras) + + # adodbapi + if not args.skip_adodbapi: + maybes = [ + os.path.join(directory, "adodbapi", "test", "adodbapitest.py") + for directory in code_directories + ] + find_and_run(maybes, remains) + # This script has a hard-coded sql server name in it, (and markh typically + # doesn't have a different server to test on) but there is now supposed to be a server out there on the Internet + # just to run these tests, so try it... + maybes = [ + os.path.join(directory, "adodbapi", "test", "test_adodbapi_dbapi20.py") + for directory in code_directories + ] + find_and_run(maybes, remains) + + if failures: + print("The following scripts failed") + for failure in failures: + print(">", failure) + sys.exit(1) + print("All tests passed \\o/") + + +if __name__ == "__main__": + main() diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html.exe new file mode 100644 index 00000000..06a80782 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html4.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html4.exe new file mode 100644 index 00000000..d25301e7 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html4.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html5.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html5.exe new file mode 100644 index 00000000..c23c6d6c Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2html5.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2latex.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2latex.exe new file mode 100644 index 00000000..aaf0b6fc Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2latex.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2man.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2man.exe new file mode 100644 index 00000000..743ac8cc Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2man.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2odt.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2odt.exe new file mode 100644 index 00000000..c3cb682d Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2odt.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2pseudoxml.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2pseudoxml.exe new file mode 100644 index 00000000..f0697b3e Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2pseudoxml.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2s5.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2s5.exe new file mode 100644 index 00000000..8ece440e Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2s5.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2xetex.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2xetex.exe new file mode 100644 index 00000000..d540570d Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2xetex.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2xml.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2xml.exe new file mode 100644 index 00000000..1162dacd Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/rst2xml.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/tiny-agents.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/tiny-agents.exe new file mode 100644 index 00000000..3f93c232 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/tiny-agents.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/tqdm.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/tqdm.exe new file mode 100644 index 00000000..c934d6f3 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/tqdm.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uv.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uv.exe new file mode 100644 index 00000000..ab07d148 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uv.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvicorn.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvicorn.exe new file mode 100644 index 00000000..a1406029 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvicorn.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvw.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvw.exe new file mode 100644 index 00000000..b270dd44 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvw.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvx.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvx.exe new file mode 100644 index 00000000..72ec2139 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/uvx.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/watchfiles.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/watchfiles.exe new file mode 100644 index 00000000..0e98bc87 Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/watchfiles.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/websockets.exe b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/websockets.exe new file mode 100644 index 00000000..cfbc18dc Binary files /dev/null and b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/Scripts/websockets.exe differ diff --git a/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/pyvenv.cfg b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/pyvenv.cfg new file mode 100644 index 00000000..30daa8da --- /dev/null +++ b/Co-creation-projects/EugeneChanQAQ-smart_fitness_planner/venv_fit/pyvenv.cfg @@ -0,0 +1,5 @@ +home = C:\Users\admin\AppData\Local\Programs\Python\Python312 +include-system-site-packages = false +version = 3.12.10 +executable = C:\Users\admin\AppData\Local\Programs\Python\Python312\python.exe +command = C:\Users\admin\AppData\Local\Programs\Python\Python312\python.exe -m venv D:\pythonProject\smart_fitness_planner\venv_fit