124 Commits

Author SHA1 Message Date
pluv f7e668863a Merge branch 'dev'
完成 0.5.1 版本更新
2026-05-17 00:22:13 +08:00
pluv 3d113f2eaa feat: 改进命令行入口 2026-05-17 00:22:01 +08:00
pluv b0625ef636 fix: 修复 playsound3 依赖问题 2026-05-17 00:07:12 +08:00
pluv dc8fa36a28 fix: 修复 zmq 依赖问题 2026-05-17 00:05:04 +08:00
pluv 2918662222 docs: 修改文档 2026-05-17 00:01:09 +08:00
pluv 60caee0f67 docs: 修改文档 2026-05-16 23:59:25 +08:00
pluv cfa85a3cac Merge branch 'dev'
合并 0.5.1 版本
2026-05-16 23:50:55 +08:00
pluv 4ba164e2ab fix: 修改一处显示重复 2026-05-16 23:49:38 +08:00
pluv 2735465629 feat: 简化并统一命令行入口
删除了原有 __main__.py 中冗长且烦人的说教, heurams 现作为所有功能的
统一入口, 并移除了单独的 heurams-tui 入口(现为 heurams tui)
2026-05-16 23:46:39 +08:00
pluv be9e79b576 docs: 更换包下载方式 2026-05-16 23:30:54 +08:00
pluv 470a7383bf docs: 修改文档 2026-05-16 23:24:33 +08:00
pluv ceaebf2c54 docs: 修改文档 2026-05-16 23:21:07 +08:00
pluv 54daa4128d build: 将构建系统换为 hatchling
由于 uv_build 在 android termux 端需编译大量 rust 代码, 极大减慢安装速度, 故使用 hatchling 作为纯 python 构建系统, 这并不影响使用 uv 管理项目
2026-05-16 23:13:14 +08:00
pluv d22966b34d fix: 修复 Termux 声音功能 2026-05-16 22:56:57 +08:00
pluv 0889bfa1c3 fix: 几处修复 2026-05-15 13:53:48 +08:00
pluv 92796451d1 docs: 改动文档 2026-05-10 15:59:09 +08:00
pluv 66870c4987 docs: 修复一处换行 2026-05-10 00:24:08 +08:00
pluv 477fa972eb docs: 改变仓库说明 2026-05-10 00:22:04 +08:00
pluv 5b52e4b3ee chore: 改变仓库说明 2026-05-08 19:20:45 +08:00
pluv 5058fb010f chore: 改变仓库分支配置和说明 2026-05-08 19:20:45 +08:00
pluv f1e87c6ff2 docs: 改进文档 2026-05-08 19:20:45 +08:00
pluv 6502efd84f Merge branch 'dev'
发布 0.5.0 版本
2026-05-07 19:48:25 +08:00
pluv 048e74ad7f style: 格式化代码 2026-05-07 19:48:07 +08:00
pluv fcda88488b Merge branch 'refactor/v0.5.0' into dev
完成 0.5.0 版本重构工作
2026-05-07 18:45:12 +08:00
pluv 69f8bfb853 docs: 修改文档 2026-05-07 18:43:49 +08:00
pluv e019ffc957 docs: 修改文档 2026-05-07 18:38:03 +08:00
pluv dd2469b49a fix: 修复若干可用性问题 2026-05-07 18:17:39 +08:00
pluv 7bf78ecdff fix: 修复一个依赖问题 2026-05-07 18:02:59 +08:00
pluv cf2283446d docs: 合并前准备 2026-05-07 17:55:22 +08:00
pluv d33aa7055b fix: 总体体验改进与版本号变更 2026-05-07 17:50:30 +08:00
pluv 1975474c94 docs: 修改文档 2026-05-07 13:26:22 +08:00
pluv c2496c1bb5 docs: 更新文档 2026-05-06 21:01:51 +08:00
pluv 1caccc9114 docs: 更新文档 2026-05-06 09:46:50 +08:00
pluv cd23c2d773 docs: 更新文档 2026-05-06 09:35:58 +08:00
pluv 1cbd27279d docs: 更新文档 2026-05-05 11:53:37 +08:00
pluv 0cc19ca92f chore: 更新文档 2026-05-05 10:34:51 +08:00
pluv 03300f0b18 feat: 升级到 playsound3 以替代问题频出的 playsound 2026-05-04 14:22:45 +08:00
pluv ca86b2d8e9 feat: 使算法能被自动注册 2026-05-04 13:55:57 +08:00
pluv e2b9fb94f3 fix: 稳定性修复 2026-05-04 13:13:05 +08:00
pluv 40f4d6c6e3 docs: 更新文档 2026-05-02 02:38:33 +08:00
pluv 520c78dbc5 docs: 更新文档 2026-05-02 02:36:14 +08:00
pluv 5182572cc7 chore: 修改版本文本 2026-04-30 04:52:17 +08:00
pluv a1c1c93c57 fix(interface): 修复持久化问题 2026-04-30 04:45:05 +08:00
pluv 22b0607273 fix: 修改一处语法错误 2026-04-27 02:27:29 +08:00
pluv a95ac55f00 chore: 说明依赖 2026-04-27 02:26:32 +08:00
pluv 7b558f2438 chore: 更新依赖和文档 2026-04-27 02:04:52 +08:00
pluv dead6cb1a1 feat: 高精度时间戳支持与 SM-15M 改进 2026-04-25 02:14:55 +08:00
pluv fa2f8fa701 feat: 增加早期 FSRS 支持 2026-04-25 01:54:18 +08:00
pluv 7f2bcf45de test: 增加测试 2026-04-25 01:38:33 +08:00
pluv b235651db5 docs: 修改文档 2026-04-24 15:40:42 +08:00
pluv f0b63fdeb6 docs: 修改文档 2026-04-24 15:38:10 +08:00
pluv 5b7b4ba443 style: 代码格式化 2026-04-23 00:13:57 +08:00
pluv 1c05f42b61 docs: 更新文档 2026-04-22 23:39:20 +08:00
pluv f50c19ba82 feat(interface): 组件自动聚焦与键盘操作改进 2026-04-22 22:54:25 +08:00
pluv c2a1867c49 fix(interface): 修复 CSS_PATH 导致的样式覆写问题 2026-04-22 06:55:58 +08:00
pluv b9d88383f9 perf: 用 autoflake 删除无用依赖
没想到居然能意外地大幅提升启动速度
2026-04-22 06:44:59 +08:00
pluv 093034828b feat: 开发 unifront 前端会话模块 2026-04-21 16:52:04 +08:00
pluv fc70aa07f6 refactor: 开始翻新状态机 2026-04-21 12:52:30 +08:00
pluv e53e905e1b fix: 修复部分问题 2026-04-21 02:06:28 +08:00
pluv a610904290 style: 格式化代码 2026-04-21 00:17:03 +08:00
pluv c0483b87f8 fix: 优化 CSS 结构 2026-04-21 00:15:57 +08:00
pluv e943b1b7d7 fix: 修复 Lict 问题 2026-04-20 18:55:25 +08:00
pluv 2a47cad2d5 perf: 脏标记优化 Lict 对象操作复杂度 2026-04-20 18:43:27 +08:00
pluv 417588acea feat: 用户界面实现算法共存与切换 2026-04-20 17:50:36 +08:00
pluv 65fbdec0a9 feat: 代码格式化, 改进仪表盘, 新增多CSS支持 2026-04-20 16:30:04 +08:00
pluv 845a505ca1 feat: 试增加单元集独立设置 2026-04-20 07:39:57 +08:00
pluv d16ec03da6 feat: 增加 ZMQ 调试服务器并完善设置功能 2026-04-20 06:37:46 +08:00
pluv 41af2ada45 feat: 补全设置提示与完善设置页 2026-04-20 05:05:44 +08:00
pluv b3f95861f0 feat(interface): 图形化设置页原型 2026-04-20 03:33:05 +08:00
pluv 4a4237acbd style: 删除旧配置文件 2026-04-20 01:46:40 +08:00
pluv a38fd3d398 refactor: 对配置处理器和配置结构进行重构 2026-04-20 01:44:43 +08:00
pluv 5c43059518 fix: 变更哈希注册表以修复重复键造成的崩溃 2026-04-19 12:08:58 +08:00
pluv 053c4660d0 feat: FAST-0 特殊算法 2026-04-19 00:05:49 +08:00
pluv 215a8648c2 style: 移除设计不当的部分模块 2026-04-16 13:20:12 +08:00
pluv f7c072dd0b build: 修改依赖并引入外部库 2026-03-27 19:31:40 +08:00
pluv 230a76fe27 feat(interface): 改进界面 2026-01-28 03:35:58 +08:00
pluv 26e053f79f feat(interface): 改进仪表盘 2026-01-22 06:13:01 +08:00
pluv 76c9537ff0 fix: 修复若干问题 2026-01-17 05:45:45 +08:00
pluv 56f5dc076e fix(interface): 修复按钮标识和一个哈希问题 2026-01-15 12:49:57 +08:00
pluv 3f7bbcdc19 feat(interface): 改进状态显示 2026-01-13 23:39:10 +08:00
pluv 4cb6edf073 build: 使用 uv 包管理器 2026-01-09 00:47:34 +08:00
pluv 264af76fad fix: 改进 2026-01-08 01:00:08 +08:00
pluv c9cc8a7917 fix: 小范围修补 2026-01-08 00:56:04 +08:00
pluv 6d60f95d6a feat: 一系列新功能 2026-01-08 00:05:00 +08:00
pluv d3dadced85 feat(interface): 完成队列式记忆模块更新 2026-01-06 20:32:27 +08:00
pluv 9d9858788c fix: 修复完成屏幕问题 2026-01-06 19:58:46 +08:00
pluv 3266eda44d fix: 修正逻辑问题 2026-01-06 18:28:57 +08:00
pluv 4dd8e373b2 feat: 更新状态机 2026-01-05 05:25:14 +08:00
pluv 1d0c87b5f7 fix: 改进代码 2026-01-04 04:46:19 +08:00
pluv b8b1c5e0d7 fix(interface): 界面兼容性改进 2026-01-04 04:14:57 +08:00
pluv 4d494546b8 fix(interface): 完成主要屏幕重构 2026-01-04 03:46:45 +08:00
pluv 5a825f6eb3 fix: 部分修复重构数据格式差异 2026-01-04 02:11:07 +08:00
pluv 10f541325b feat(reactor): 状态机进一步改进 2026-01-04 00:28:44 +08:00
pluv 7f36450079 feat: 改进状态机 2026-01-03 13:08:08 +08:00
pluv 32cd44b8e7 feat(kernel): 状态机改进 2026-01-03 05:05:41 +08:00
pluv f2d91b0164 feat: 完成部分界面重构 2026-01-02 06:12:49 +08:00
pluv bd313db5f2 feat: 改进对象系统 2026-01-01 20:18:18 +08:00
pluv d25e398701 feat: 基本完成对象系统更新 2026-01-01 16:19:46 +08:00
pluv af63cceba9 feat: 改进粒子对象 2026-01-01 06:36:27 +08:00
pluv 8358e2532a feat: 进一步改进 2025-12-31 00:57:07 +08:00
pluv 8828db24b5 feat: 一些改进 2025-12-29 21:53:20 +08:00
pluv ecefc53a20 refactor: 部分更改数据结构 2025-12-28 06:16:21 +08:00
pluv b3bc5b1a09 0.4.3 版本合并 2025-12-21 23:44:28 +08:00
pluv e562e02227 style: 格式化代码 2025-12-21 23:44:13 +08:00
pluv c10a18bafd feat(interface): 增加智能单元集排序 2025-12-21 23:42:02 +08:00
pluv 6a5120920a fix: 暂时禁用实验性功能 2025-12-21 23:06:17 +08:00
pluv 56038afefe refactor(synctool): 改进同步方案 2025-12-21 21:18:31 +08:00
pluv d4dce68449 feat(synctool): 虚拟文件系统初步方案 2025-12-21 18:48:25 +08:00
pluv 8dd323a789 style: 格式化代码 2025-12-21 07:56:10 +08:00
pluv 531b0756bf feat(synctool): 增加同步功能 2025-12-21 07:49:19 +08:00
pluv 6adf1c62f6 0.4.2 版本合并 2025-12-21 06:49:38 +08:00
pluv 058cc1e4d8 feat(kernel): 添加算法切换设置 2025-12-21 06:48:30 +08:00
pluv 7e28e0cd6b style: 更新版本号和合并规则 2025-12-21 06:34:17 +08:00
pluv a3612bd3b3 fix(interface): 修复仪表盘详情 2025-12-21 06:27:00 +08:00
pluv 77441e2d40 feat(interface): 更改启动方式 2025-12-21 06:06:16 +08:00
pluv 72697f652f fix(interface): 修复显示问题 2025-12-21 05:47:22 +08:00
pluv c5fd625c87 feat: 自动音频播放与改进设计 2025-12-21 05:32:58 +08:00
pluv abd94d9a21 0.4.1 版本合并 2025-12-21 03:03:06 +08:00
pluv 91d3c86871 style(version): 更新版本号 2025-12-21 03:02:29 +08:00
pluv 66ad50c44d feat: 实验性 SM-15M 算法实现
实验性 SM-15M 逆向工程算法实现
2025-12-21 02:15:23 +08:00
pluv 2527daa923 style: isort 格式化 2025-12-19 15:13:42 +08:00
pluv 1883ca2387 style: 格式化代码 2025-12-19 15:08:26 +08:00
pluv dde6f872f0 fix(interface): 修复默认配置文件 2025-12-18 15:53:18 +08:00
pluv 16c22cf207 refactor: 完成 0.4.0 版本更新
完成 0.4.0 版本更新, 为了消除此前提交消息风格不一致与错误提交超大文件的问题, 维持代码统计数据的准确性和提交消息风格的一致性, 重新初始化仓库; 旧的提交历史在 HeurAMS-legacy 仓库(https://gitea.imwangzhiyu.xyz/ajax/HeurAMS-legacy)
2025-12-17 22:31:38 +08:00
31 changed files with 421 additions and 607 deletions
+7 -7
View File
@@ -1,12 +1,12 @@
# AI 编程工具说明 # AI 编程工具说明
本文档为 AI 工具以及在使用 AI 辅助向 HeurAMS 项目贡献代码的开发者提供指导, 一般而言此文件会被自动读入多种 AI 工具的上下文. 本文档为 AI 工具以及在使用 AI 辅助向 HeurAMS 项目贡献代码的开发者提供指导, 一般而言此文件会被自动读入多种 AI 工具的上下文.
AI 工具应当完整阅读此 `/AGENTS.md` 文件. AI 工具应当完整阅读此 `/AGENTS.md` 文件.
## 查阅开发文档 ## 查阅开发文档
在帮助进行 HeurAMS 开发时,AI 工具应遵循标准的开发规范与流程, 应当自动查看或是在用户发出"初始化/init"指令后查看: 在帮助进行 HeurAMS 开发时,AI 工具应遵循标准的开发规范与流程, 应当自动查看或是在用户发出"初始化/init"指令后查看:
- [贡献指南](/CONTRIBUTING.md) - [贡献指南](/CONTRIBUTING.md)
- [自述文件](/README.md) - [自述文件](/README.md)
@@ -26,22 +26,22 @@ AI 工具应当完整阅读此 `/AGENTS.md` 文件.
## 许可证与法律要求 ## 许可证与法律要求
所有贡献必须符合许可要求, 所有代码必须与 AGPL-3.0-or-later 许可以及项目附加豁免条款(位于 LICENSE 文件尾部 237 至 245 行)兼容. 所有贡献必须符合许可要求, 所有代码必须与 AGPL-3.0-or-later 许可以及项目附加豁免条款(位于 LICENSE 文件尾部 237 至 245 行)兼容.
## Signed-off-by 与 DCO ## Signed-off-by 与 DCO
AI 代理**严禁添加** Signed-off-by 标签. AI 代理**严禁添加** Signed-off-by 标签.
只有人类能够合法地认证 DCO. 只有人类能够合法地认证 DCO.
人类提交者负责: 人类提交者负责:
- 审阅所有 AI 生成的代码 - 审阅所有 AI 生成的代码
- 确保符合许可要求 - 确保符合许可要求
- 添加自己的 Signed-off-by 标签以认证 DCO - 添加自己的 Signed-off-by 标签以认证 DCO
- 对贡献负责任 - 对贡献负责任
AI 助手负责: AI 助手负责:
- 了解运行环境, 例如操作系统或具体发行版 - 了解运行环境, 例如操作系统或具体发行版
- 遵循此文档所述规则 - 遵循此文档所述规则
+20 -13
View File
@@ -1,9 +1,13 @@
# 贡献指南与二次开发 # 贡献指南与二次开发
欢迎此项目做出贡献! 欢迎支持此项目!
目前, 项目仓库主服务器为<a href="https://git.pluv27.top/pluv/HeurAMS" target="_blank" rel="noopener noreferrer">作者的 Gitea 实例</a>, 它负责管理同步, 保证可用性并同时接受来自多个社区的协作, 并在 <a href="https://github.com/pluvium27/HeurAMS" target="_blank" rel="noopener noreferrer">GitHub</a>, <a href="https://invent.kde.org/pluv/HeurAMS" target="_blank" rel="noopener noreferrer">KDE Invent</a> 和 <a href="https://gitee.com/pluv/HeurAMS" target="_blank" rel="noopener noreferrer">Gitee</a> 设置了镜像同步.
这丝毫不影响项目接受来自 <a href="https://github.com/pluvium27/HeurAMS" target="_blank" rel="noopener noreferrer">GitHub</a>, <a href="https://invent.kde.org/pluv/HeurAMS" target="_blank" rel="noopener noreferrer">KDE Invent</a> 和 <a href="https://gitee.com/pluv/HeurAMS" target="_blank" rel="noopener noreferrer">Gitee</a> 的 PR, 在 GitHub, KDE Invent 和 Gitee 所接受的 PR 会保留贡献者标识并按原样同步回所有平台, 欢迎在任意平台为项目做出贡献.
> [!NOTE] > [!NOTE]
> 我们已经开始着手于基于 KDE 用户界面框架 `Kirigami` 的现代跨平台前端开发, 称作 "KiriMemo", 包名是 "org.kde.kirimemo", 但其并非 KDE 项目 > 我们已经开始着手于基于 KDE 用户界面框架 `Kirigami` 的现代跨平台前端开发, 称作 "KiriMemo", 包名是 "org.kde.kirimemo", 但其并非 KDE 项目\
> 它通过 `PyOtherSide` 直接复用 python 内核, 为 Windows, Linux, macOS, Android, iOS 和 Plasma Mobile 提供现代用户界面 > 它通过 `PyOtherSide` 直接复用 python 内核, 为 Windows, Linux, macOS, Android, iOS 和 Plasma Mobile 提供现代用户界面
> 如果您善于开发 C++, QML, Qt 与 KDE 框架, 欢迎加入到 KiriMemo 项目的开发 > 如果您善于开发 C++, QML, Qt 与 KDE 框架, 欢迎加入到 KiriMemo 项目的开发
@@ -11,10 +15,10 @@
分支划分: 分支划分:
- `main` 分支: 稳定版本, 仅当稳定版本释出或修补版本时将 `dev` 合并到 `main` - `dev` 分支(仓库默认分支): 主线开发分支, 自身仅用于非重构的问题修复和整合功能分支, 拉取请求在该分支合并
- `dev` 分支: 主线开发版本, 自身仅用于非重构的问题修复和整合功能分支 - `master` 分支: 主线稳定版本, 仅当稳定版本释出或修补版本时将 `dev` 合并到 `master`
- 功能与重构分支: 从 `dev` 分支创建, 命名格式为 `feature/描述``fix/描述``refactor/v版本号` - 功能与重构分支: 从 `dev` 分支创建, 命名格式为 `feature/描述``fix/描述``refactor/描述``next/版本号`
- 功能与重构分支应先合并至 `dev`, 再合并至 `main` - 功能与重构分支应先合并至 `dev`, 再合并至 `master`
代码格式化: 代码格式化:
@@ -38,7 +42,7 @@
mdformat --number . mdformat --number .
``` ```
- 对于 Textual CSS, 可以使用 `prettier` 格式化 - 对于 Textual CSS, 可以使用 `prettier` 格式化
- 格式化不是必需的, 可以整合入一次 `style` 提交, 但 `main` 和 `dev` 分支上的代码应尽量整洁, 以便合并时审查 - 格式化不是必需的, 可以整合入一次 `style` 提交, 但 `master` 和 `dev` 分支上的代码应尽量整洁, 以便合并时审查
提交消息: 提交消息:
@@ -50,12 +54,16 @@
- 为了一致性和可追溯性, 项目自 v0.4.0 重构后重新初始化仓库起就禁止使用 Fast-forward 合并 - 为了一致性和可追溯性, 项目自 v0.4.0 重构后重新初始化仓库起就禁止使用 Fast-forward 合并
- 可以设置 `git config merge.ff false` - 可以设置 `git config merge.ff false`
提交署名方式:
由于 KDE Invent 设施的奇怪 git hook, commit 的 Author 字段需要看起来像个真名(例如 Wang Zhiyu 不能写为 wangzhiyu, 否则 KDE Invent 的 hook 会拒绝 push),
所以请确保您的 git 配置使用了类似正式姓名的格式 (例如 git config user.name "Li Hua", 也即中间需要空格), 不一定要真实姓名, 邮箱无要求, 也可以将单名重复使用两次 (例如 Thura Thura) 以通过检测.
## 设置开发环境 ## 设置开发环境
```bash ```bash
git clone https://git.pluv27.top/pluv/HeurAMS git clone https://git.pluv27.top/pluv/HeurAMS # 默认分支为 dev, 所以不必切换分支
cd HeurAMS cd HeurAMS
git checkout dev
# 如果决定使用 uv (推荐) # 如果决定使用 uv (推荐)
@@ -63,9 +71,7 @@ python3 -m pip install uv
uv sync --all-extras # 同步开发运行环境 uv sync --all-extras # 同步开发运行环境
uv run heurams # 验证包安装 uv run heurams
uv run heurams-tui # 启动 TUI
# 如果决定使用原生 python 环境 (不推荐, 但我们保留了这种方式以便在不便支持 uv 与硬链接的环境和文件系统(例如 termux)上运行) # 如果决定使用原生 python 环境 (不推荐, 但我们保留了这种方式以便在不便支持 uv 与硬链接的环境和文件系统(例如 termux)上运行)
@@ -81,6 +87,7 @@ python3 -m heurams.interface # 启动 TUI
贡献者拥有其贡献部分的版权同意其贡献将在 AGPL-3.0 许可证(包括附加的本机 API 调用豁免条款)下发布. 贡献者拥有其贡献部分的版权同意其贡献将在 AGPL-3.0 许可证(包括附加的本机 API 调用豁免条款)下发布.
如有以下情况, 请在 PR 描述中注明: 如有以下情况, 请在 PR 描述中注明:
- 如果需要引入其他开源 vendor - 如果需要引入其他开源 vendor
- 如果需要引入其他专有的网络服务(例如当前项目中的 edgetts) - 如果需要引入其他专有的网络服务(例如当前项目中的 edgetts)
- 如果需要升级某个依赖或运行环境的版本 - 如果需要升级某个依赖或运行环境的版本
@@ -96,7 +103,7 @@ HeurAMS 被设计为一个可独立于前端的程序库, 这意味着:
- 您还可以在自己的项目中以独立进程/服务调用 HeurAMS, 根据 AGPL-3.0 及本项目的附加许可条款, 如果调用发生在同一主机上且不涉及外部网络转发, 则可豁免许可证规定的特定义务而免于受 AGPL-3.0 "污染". 为了这点, 我们正在完善可选择启用的跨进程 RPC 模块, 这将成为潜进内核的跨平台标准件. - 您还可以在自己的项目中以独立进程/服务调用 HeurAMS, 根据 AGPL-3.0 及本项目的附加许可条款, 如果调用发生在同一主机上且不涉及外部网络转发, 则可豁免许可证规定的特定义务而免于受 AGPL-3.0 "污染". 为了这点, 我们正在完善可选择启用的跨进程 RPC 模块, 这将成为潜进内核的跨平台标准件.
- 如果您通过独立进程/服务调用方式开发了另外的软件, 开源但不愿使用 AGPL-3.0/GPL-3.0 许可证, 也可以联系我们, 我们乐于将您的项目链接添加到友链中 - 如果您通过独立进程/服务调用方式开发了另外的软件, 开源但不愿使用 AGPL-3.0/GPL-3.0 许可证, 也可以联系我们, 我们乐于将您的项目链接添加到友链中
## 软件开发之外的贡献 ## 软件开发之外的贡献
即使您不是软件开发人员, 我们也欢迎您加入贡献! 即使您不是软件开发人员, 我们也欢迎您加入贡献!
+51 -42
View File
@@ -2,15 +2,15 @@
## 什么是终端模拟器? ## 什么是终端模拟器?
终端模拟器是在图形桌面环境中模拟并使用终端的应用程序, 例如 KDE Konsole, GNOME Terminal, Windows Terminal, iTerm2 等. 终端模拟器是在图形桌面环境中模拟并使用终端的应用程序, 例如 KDE Konsole, GNOME Terminal, Windows Terminal, iTerm2 等.
较旧 Windows 的那个很寒酸的小黑窗口也是终端模拟器(conhost.exe), 但它对此软件基本用户界面(以及一切现代终端应用)支持不佳, 建议在 Windows 平台使用 WezTerm (支持 sixel) 或 Windows Terminal (不支持 sixel). 较旧 Windows 的那个很寒酸的小黑窗口也是终端模拟器(conhost.exe), 但它对此软件基本用户界面(以及一切现代终端应用)支持不佳, 建议在 Windows 平台使用 WezTerm (支持 sixel) 或 Windows Terminal (不支持 sixel).
## 软件支持移动设备吗? ## 软件支持移动设备吗?
基本用户界面 (Textual TUI) 可在 Android Termux 中良好运行. 基本用户界面 (Textual TUI) 可在 Android Termux 中良好运行.
此外, 正在开发的 KiriMemo 前端基于 KDE Kirigami 框架, 将原生支持 Android 和 iOS. 此外, 正在开发的 KiriMemo 前端基于 KDE Kirigami 框架, 将原生支持 Android 和 iOS.
## HeurAMS 和 Anki 有什么区别? ## HeurAMS 和 Anki 有什么区别?
@@ -29,13 +29,15 @@
## 软件是免费的吗? ## 软件是免费的吗?
是的, 完全免费, 且开源. 您无需支付任何费用即可使用全部功能. 是的, 完全免费, 且开源. 您无需支付任何费用即可使用全部功能.
## 黑乎乎的这个界面我怎么用? ## 黑乎乎的这个界面我怎么用?
得益于微软几十年对用户进行的"命令行即落后"教育, 以及 `conhost.exe``cmd.exe` 的糟糕体验, 您对终端用户界面感到不适应是完全正常的. 首先, 如果您只是想要一个亮色模式, 可以直接按下 `d` 键或点击 "d 主题" 按钮, 这会让您的界面变得白乎乎的(
但实际上, 虽然看起来像老式电脑屏幕, Textual 和终端标准其实比您想象得要现代一些. 得益于微软几十年对用户进行的"命令行即落后"教育, 以及 `conhost.exe``cmd.exe` 的糟糕体验, 您对终端用户界面感到不适应是完全正常的.
但实际上, 虽然看起来像老式电脑屏幕, Textual 和终端标准其实比您想象得要现代一些.
### 可以用鼠标 ### 可以用鼠标
@@ -44,6 +46,7 @@
所以可能和您的想象不同, 您事实上可以直接用鼠标点击按钮, 就像使用普通软件一样. 所以可能和您的想象不同, 您事实上可以直接用鼠标点击按钮, 就像使用普通软件一样.
### 也可以用键盘 ### 也可以用键盘
- `Tab` 键在不同区域之间切换焦点 - `Tab` 键在不同区域之间切换焦点
- `方向键` 在列表中上下移动 - `方向键` 在列表中上下移动
- `Enter` 确认选择 - `Enter` 确认选择
@@ -51,6 +54,7 @@
- 屏幕上会有按键提示, 例如 `[n] 导航器` 表示按 `n` 键打开导航器 - 屏幕上会有按键提示, 例如 `[n] 导航器` 表示按 `n` 键打开导航器
### 触屏也可以 ### 触屏也可以
在平板或手机 Termux 中, 您可以触摸或者滑动屏幕操作. 在平板或手机 Termux 中, 您可以触摸或者滑动屏幕操作.
## 我怎么启动这个软件? ## 我怎么启动这个软件?
@@ -58,6 +62,7 @@
首先需要确保系统中安装了 Python (推荐 3.12.13 版本) 并安装了 HeurAMS 的所需组件. 首先需要确保系统中安装了 Python (推荐 3.12.13 版本) 并安装了 HeurAMS 的所需组件.
### Windows ### Windows
打开"命令提示符"或"PowerShell", 输入以下命令后按回车, 或者把这玩意另存为快捷方式: 打开"命令提示符"或"PowerShell", 输入以下命令后按回车, 或者把这玩意另存为快捷方式:
``` ```
@@ -65,22 +70,26 @@ python -m heurams.interface
``` ```
### macOS ### macOS
打开"终端"应用程序, 输入以上命令. 打开"终端"应用程序, 输入以上命令.
### Linux ### Linux
打开您的终端模拟器 (一般是按 Ctrl + Alt + T), 输入以上命令. 打开您的终端模拟器 (一般是按 Ctrl + Alt + T), 输入以上命令.
如果您觉得每次输入命令太麻烦, 可以创建一个桌面快捷方式或脚本文件, 详见网上的相关教程. 如果您觉得每次输入命令太麻烦, 可以创建一个桌面快捷方式或脚本文件, 详见网上的相关教程.
## 我怎么退出软件? ## 我怎么退出软件?
按键盘上的 `q` 键返回主界面后退出. 按键盘上的 `q` 键返回主界面后退出.
您的学习进度会自动保存, 不会丢失. 您的学习进度会自动保存, 不会丢失.
## 我看不到图片怎么办? ## 图片像素很大, 模糊得像马赛克一样怎么办?
终端模拟器需要支持 sixel 图像协议才能显示图片. 这说明图像以 Halfcell 兼容模式显示
终端模拟器需要支持 sixel 图像协议才能高清地显示图片, 对于不支持的图片, 软件只能以低清的兼容模式显示.
- WezTerm (适用于几乎所有操作系统): 支持 - WezTerm (适用于几乎所有操作系统): 支持
- KDE Konsole: 支持 - KDE Konsole: 支持
@@ -124,15 +133,15 @@ python -m heurams.interface
## 字体太小/太大怎么办? ## 字体太小/太大怎么办?
在您的终端模拟器设置中找到"字体大小"选项进行调整. 在您的终端模拟器设置中找到"字体大小"选项进行调整.
软件会跟随终端的字体设置. 软件会跟随终端的字体设置.
## 为什么我的界面和截图不一样? ## 为什么我的界面和截图不一样?
截图使用的是 KDE Plasma 桌面上的 Konsole, 80x25 字符尺寸, Cascadia Code 和 Noto Sans SC 字体. 截图使用的是 KDE Plasma 桌面上的 Konsole, 80x25 字符尺寸, Cascadia Code 和 Noto Sans SC 字体.
如果您的终端尺寸更大, 界面会更宽裕; 如果使用不同字体或者不同操作系统, 视觉效果会略有差异. 如果您的终端尺寸更大, 界面会更宽裕; 如果使用不同字体或者不同操作系统, 视觉效果会略有差异.
功能上完全一致. 功能上完全一致.
@@ -144,9 +153,9 @@ python -m heurams.interface
并且这种方式于学术研究与实验不利, 用户自评分产生的数据是不可靠的. 并且这种方式于学术研究与实验不利, 用户自评分产生的数据是不可靠的.
因此 HeurAMS 的前端内建了基于用户行为分析的自动评分系统, 也就是"谜题". 因此 HeurAMS 的前端内建了基于用户行为分析的自动评分系统, 也就是"谜题".
它会根据题目本身难度和您的答题行为(包括但不限于正确性, 操作回退次数, 有效答题时间)并自动为您评分. 它会根据题目本身难度和您的答题行为(包括但不限于正确性, 操作回退次数, 有效答题时间)并自动为您评分.
但如果您或者某个单元集选择使用 `basic_puzzle`, 或者打算自己实现自动评分系统, 分数含义如下: 但如果您或者某个单元集选择使用 `basic_puzzle`, 或者打算自己实现自动评分系统, 分数含义如下:
@@ -170,7 +179,7 @@ python -m heurams.interface
## 我每天都要打开软件吗? 不学会怎样? ## 我每天都要打开软件吗? 不学会怎样?
理论上不需要每天打开. 软件会自动记录每个知识点下次该复习的时间. 理论上不需要每天打开. 软件会自动记录每个知识点下次该复习的时间.
但建议您每天打开软件看下状态. 但建议您每天打开软件看下状态.
@@ -183,9 +192,9 @@ python -m heurams.interface
## 能同时学多个科目吗? ## 能同时学多个科目吗?
可以. 可以.
每个科目或课程可以做成独立的"单元集". 每个科目或课程可以做成独立的"单元集".
## 我换电脑了, 怎么迁移数据? ## 我换电脑了, 怎么迁移数据?
@@ -215,13 +224,13 @@ python -m heurams.interface
## 同时用 Anki 和 HeurAMS 会冲突吗? ## 同时用 Anki 和 HeurAMS 会冲突吗?
不会. 不会.
两者是独立的软件, 数据互不影响. 您可以逐步将内容迁移到 HeurAMS, 也可以两个一起用. 两者是独立的软件, 数据互不影响. 您可以逐步将内容迁移到 HeurAMS, 也可以两个一起用.
## 我需要安装 Python 吗? ## 我需要安装 Python 吗?
需要的, HeurAMS 是基于 Python 的软件. 需要的, HeurAMS 是基于 Python 的软件.
- Windows/macOS: 从 python.org 下载安装即可 - Windows/macOS: 从 python.org 下载安装即可
- Linux: 系统通常已自带 Python - Linux: 系统通常已自带 Python
@@ -233,9 +242,9 @@ HeurAMS 建议的 Python 版本是 3.12.13.
## 软件安全吗? 会不会有病毒? ## 软件安全吗? 会不会有病毒?
HeurAMS 是开源软件, 所有代码公开可查阅, 不会有病毒或后门. HeurAMS 是开源软件, 所有代码公开可查阅, 不会有病毒或后门.
它只读写自己的 `data/` 文件夹, 不会动您电脑上的其他文件. 它只读写自己的 `data/` 文件夹, 不会动您电脑上的其他文件.
## 软件报错, 出现一堆我看不懂的英文怎么办? ## 软件报错, 出现一堆我看不懂的英文怎么办?
@@ -249,13 +258,13 @@ HeurAMS 是开源软件, 所有代码公开可查阅, 不会有病毒或后门.
## 怎么看我学了多少? 有统计吗? ## 怎么看我学了多少? 有统计吗?
仪表盘界面会显示统计信息. 仪表盘界面会显示统计信息.
您可以通过导航器随时回到仪表盘查看. 您可以通过导航器随时回到仪表盘查看.
## 我觉得复习太快/太慢了, 能调吗? ## 我觉得复习太快/太慢了, 能调吗?
可以. 您可以通过切换算法或调整算法参数或改变记忆单元数来改变复习节奏. 可以. 您可以通过切换算法或调整算法参数或改变记忆单元数来改变复习节奏.
在设置界面可以找到相关设置. 在设置界面可以找到相关设置.
@@ -277,13 +286,13 @@ HeurAMS 是开源软件, 所有代码公开可查阅, 不会有病毒或后门.
## 哪里可以下载别人做好的单元集? ## 哪里可以下载别人做好的单元集?
目前项目还没有官方的单元集市场. 目前项目还没有官方的单元集市场.
但随着社区发展, 未来可能会有用户分享的单元集, 您也可以和朋友互相分享. 但随着社区发展, 未来可能会有用户分享的单元集, 您也可以和朋友互相分享.
## 我能把学习内容导出打印吗? ## 我能把学习内容导出打印吗?
可以. 可以.
软件本身支持将单元集导出为单一文本文件, 您可以用任何文本编辑器打开并打印. 也可以直接复制内容到 Word 等软件. 软件本身支持将单元集导出为单一文本文件, 您可以用任何文本编辑器打开并打印. 也可以直接复制内容到 Word 等软件.
@@ -318,13 +327,13 @@ data/repo/my_pack/
## 为什么不用 Flutter? ## 为什么不用 Flutter?
Flutter 是构建跨平台图形界面的优秀框架, HeurAMS 的设计目标之一是保持核心程序库独立于特定前端. Flutter 是构建跨平台图形界面的优秀框架, HeurAMS 的设计目标之一是保持核心程序库独立于特定前端.
但 Flutter 在 "集成 python" 方面不如 PyOtherSide, 只能通过 RPC 标准件和程序库通讯, 并且 Flutter 的桌面多窗口一直以来没有被官方稳定支持, 所以我们暂时放弃了 Flutter 而选择了 Kirigami. 但 Flutter 在 "集成 python" 方面不如 PyOtherSide, 只能通过 RPC 标准件和程序库通讯, 并且 Flutter 的桌面多窗口一直以来没有被官方稳定支持, 所以我们暂时放弃了 Flutter 而选择了 Kirigami.
当前我们优先开发了基于 Textual 的 TUI 前端和基于 Kirigami 的原生前端, 但这不排除未来出现 Flutter 或其他框架前端的可能性. 当前我们优先开发了基于 Textual 的 TUI 前端和基于 Kirigami 的原生前端, 但这不排除未来出现 Flutter 或其他框架前端的可能性.
如果您有兴趣开发 Flutter 前端, 欢迎参考[贡献指南](CONTRIBUTING.md#新的用户界面前端). 如果您有兴趣开发 Flutter 前端, 欢迎参考[贡献指南](CONTRIBUTING.md#%E6%96%B0%E7%9A%84%E7%94%A8%E6%88%B7%E7%95%8C%E9%9D%A2%E5%89%8D%E7%AB%AF).
## 软件需要联网吗? ## 软件需要联网吗?
@@ -336,11 +345,11 @@ Flutter 是构建跨平台图形界面的优秀框架, HeurAMS 的设计目标
## 许可证中的"本机 API 调用豁免"是什么? ## 许可证中的"本机 API 调用豁免"是什么?
简言之, 如果您在自己的程序中通过本地进程间 API 方式的通信 (如同一主机上的 RPC 调用) 使用 HeurAMS, 而无需通过网络转发, 则您的程序不受 AGPL-3.0 许可证的约束. 简言之, 如果您在自己的程序中通过本地进程间 API 方式的通信 (如同一主机上的 RPC 调用) 使用 HeurAMS, 而无需通过网络转发, 则您的程序不受 AGPL-3.0 许可证的约束.
这项附加条款旨在鼓励第三方前端和工具的开发. 这项附加条款旨在鼓励第三方前端和工具的开发.
所以 HeurAMS 的许可证实质上是比原始的 AGPL-3.0 松一点的. 所以 HeurAMS 的许可证实质上是比原始的 AGPL-3.0 松一点的.
## HeurAMS 和百词斩有什么区别? ## HeurAMS 和百词斩有什么区别?
@@ -360,29 +369,29 @@ Flutter 是构建跨平台图形界面的优秀框架, HeurAMS 的设计目标
## 百词斩有图片联想记忆, HeurAMS 也有吗? ## 百词斩有图片联想记忆, HeurAMS 也有吗?
支持. 支持.
如果您的终端支持图片显示 (如 Konsole 或者 WezTerm), 单元集中可以包含图片, 复习时会直接展示. 如果您的终端支持图片显示 (如 Konsole 或者 WezTerm), 单元集中可以包含图片, 复习时会直接展示.
但图片需要您自己放入单元集. 但图片需要您自己放入单元集.
## 百词斩有打卡和排行榜, HeurAMS 有吗? ## 百词斩有打卡和排行榜, HeurAMS 有吗?
目前没有. 目前没有.
HeurAMS 不设打卡、排行榜或社交功能, 也不向任何人收集您的学习数据. HeurAMS 不设打卡、排行榜或社交功能, 也不向任何人收集您的学习数据.
## 百词斩有现成的词书, HeurAMS 去哪找内容? ## 百词斩有现成的词书, HeurAMS 去哪找内容?
百词斩的课程是官方制作好的, HeurAMS 的内容需要您自己创建或从社区获取. 百词斩的课程是官方制作好的, HeurAMS 的内容需要您自己创建或从社区获取.
详见"如何创建自己的单元集?". 详见"如何创建自己的单元集?".
## 百词斩在手机上用很方便, HeurAMS 能在手机用吗? ## 百词斩在手机上用很方便, HeurAMS 能在手机用吗?
可以, 但现阶段需要您"折腾"一下. 可以, 但现阶段需要您"折腾"一下.
Android 手机安装 Termux 后可运行 HeurAMS 的基本用户界面. Android 手机安装 Termux 后可运行 HeurAMS 的基本用户界面.
此外, 正在开发的 KiriMemo 前端将原生支持 Android 和 iOS, 这就不需要用户去折腾了. 此外, 正在开发的 KiriMemo 前端将原生支持 Android 和 iOS, 这就不需要用户去折腾了.
@@ -396,12 +405,12 @@ Android 手机安装 Termux 后可运行 HeurAMS 的基本用户界面.
考虑到百词斩的算法和词库是事实上闭源的, 我们无从得知算法来源. 考虑到百词斩的算法和词库是事实上闭源的, 我们无从得知算法来源.
但 HeurAMS 的架构设计可保证单元集制成后效果不比百词斩差, 甚至优于百词斩. 但 HeurAMS 的架构设计可保证单元集制成后效果不比百词斩差, 甚至优于百词斩.
HeurAMS 的间隔重复算法基于相同的认知科学原理, 且算法透明可调, 您可以自由选择最适合自己的调度策略. HeurAMS 的间隔重复算法基于相同的认知科学原理, 且算法透明可调, 您可以自由选择最适合自己的调度策略.
## 如何参与项目? ## 如何参与项目?
详见[贡献指南](CONTRIBUTING.md). 详见[贡献指南](CONTRIBUTING.md).
即使不是开发者, 您也可以通过编写文档、制作记忆单元集、翻译界面、答疑等方式参与. 即使不是开发者, 您也可以通过编写文档、制作记忆单元集、翻译界面、答疑等方式参与.
+84
View File
@@ -0,0 +1,84 @@
## 特性
### 间隔重复调度器
> 许多出版物都广泛讨论了不同重复间隔对学习效果的影响. 特别是, 间隔效应被认为是一种普遍现象. 间隔效应是指, 如果重复的间隔是分散/稀疏的, 而不是集中重复, 那么学习任务的表现会更好. 因此, 有观点提出, 学习中使用的最佳重复间隔是**最长的, 但不会导致遗忘的间隔**.
- 软件开箱即用, 无需多加配置即可使用默认的 `SM-2` 算法进行学习
- 算法模块是 "潜进" 内核 (heurams.kernel) 中的一等公民, 内核天然支持插拔各型算法
- 无需安装繁杂的插件即可分单元集完成算法快速切换与调优, 研究者可以方便地修改算法模块以便捷地进行研究与测试
- 默认使用 `SM-2` 简单间隔重复算法, 此算法亦用作 `Anki` 闪卡记忆软件的默认闪卡调度器
- 还内置了 `NSP-0` 筛选用非间隔重复算法以便快速筛选记忆内容, `FSRS` 先进间隔重复算法作为效率更高的调度器, 与 `SM-15M (移植自 sm.js 项目)` 复杂间隔重复算法(逆向工程)
- 算法模块可以标记记忆项目, 也可以动态规划每个记忆单元的记忆间隔时间表, 动态跟踪记忆反馈数据, 以优化长期记忆保留率与稳定性
- 得益于项目的模块化架构与单元集结构设计, 同一个单元集可以与任意种算法共存并互通, 这对研究者及想探索/实验高效率方法的用户极其友好
### 多模态学习进程
与 Anki 的 SQLite `.apkg` 包不同, 我们坚持使用人类可读的文件夹组织单元集, 这带来了若干好处, 包括:
- 人类可读: 您可以用任意工具, 乃至一个记事本自由修改记忆载荷数据而无需打开软件
- 元数据配置: 配置自由度极高, 可以任意组合, 重造, 乃至创造新内容
- 测验, 算法与知识互相隔离: 一条知识不再是单一的闪卡, 不仅可以用若干不同的算法规划, 还可以用多种并行的谜题类型测验, 极大地提升学习效果和丰富度. 作为学习者, 您无需担忧概念复杂--仅需从云端下载单元集即可开箱即用上述特性!
- 多模态学习
- 软件自身集成了文本转语音 (TTS) , 音频与语言模型 (LLM) 模块, 这些功能乃至功能本身都是可插拔, 可扩展, 可切换驱动的, 这为内容创建了极大的丰富度
- 软件内置多种谜题类型, 包括选择题 (MCQ), 填空题 (Cloze) 与识别题 (Recognition), 您可在同一单元应用多种, 或是选择性启用
- 软件天然支持动态内容生成, 支持宏驱动的模板系统, 根据上下文乃至语言模型动态生成知识点的解析
- 在间隔重复研究尚被 SuperMemo 系列独占的时代, Wozniak 就早已表示 "如果不能理解知识, 就无需记忆它". 今天, 我们依然相信理解是记忆的基石
- 云同步与分享优化:
- 由于记忆数据和单元集文件都是文本文件, 故可进行快速的增量同步而无需完整地上传所有文件, 并且设计天然支持版本控制
- 如果您想分享单文件, 软件也支持导出为压缩包或合并成单文本文件以通过纯文本文件形式在 pastebin 等平台分享
- 性能提升: 得益于现代且支持分块的文件组织结构, 潜进能在保持高自由度的同时仅使用 python 就能达到敏捷且低占用的用户体验
- AI 辅助友好: 想象您有一些 `.apkg` 牌组或一大段教材内容, 您可以方便且高效率地使用 AI 工具以创建可在 HeurAMS 使用的单元集
### 内置实用用户界面
尽管不是唯一前端, 但响应式 Textual 框架构建的内置终端用户界面在多种场景下仍具有独特优势:
- 跨平台, 并支持触屏/鼠标/键盘多操作模式
- 与几乎所有现代终端模拟器相容
- 对于<a href="https://www.arewesixelyet.com/" target="_blank" rel="noopener noreferrer">支持 sixel 协议的终端模拟器</a>, 可高清显示图像内容
- 对于不支持 sixel 协议的终端模拟器, 也支持图片低清的兼容显示模式
- 可通过 textual-web 作为服务部署, 并在任意浏览器使用
- 简洁直观, 键盘友好, 全功能且高效率的用户界面设计
- 易于嵌入: 可在 getty/kmscon 中运行而无需任何桌面图形服务
- 资源占用小, 运行流畅, 不拖泥带水
- 便于测试与调试程序库
查看[屏幕截图](SCREENSHOTS.md).
## 包依赖组说明
由于部分依赖只被少数功能需要, 所以我们把可选依赖分得比较细, 前面提供的命令会安装部分可选依赖, 以下是依赖组列表:
| 依赖组 | 包含模块 | 说明 |
|--------|----------|------|
| 构建系统 | hatchling | 构建时安装 |
| 最小化安装 | tabulate, toml, transitions, click | 核心驱动程序库, 始终必需 |
| interface | textual | 基本用户界面依赖 |
| algo-fsrs | fsrs | FSRS 算法模块 |
| tts-edgetts | edge-tts | 微软文本转语音 |
| llm | llms-py | API 调用 |
| audio-playsound | playsound3 | 通用音频模块 |
| dev | zmq, pytest, pytest-cov | 开发调试与测试工具 |
| basic | [tts-edgetts], [llm], [algo-fsrs] | 适用于用户体验的较轻依赖组(推荐) |
| all | 以上所有依赖 | 完整安装组 |
## 关于此仓库
此仓库为 "潜进" 的核心程序库在 python 语言下的实现\
包含数据模型与框架, 并内置了基于 textual 框架的前端实现 (interface 子模块)\
除了通过内置前端进行学习外, 开发者也能在 python 环境中导入 `heurams` 库或使用 `RPC``heurams` 程序库实例通讯, 使用框架构建其他辅助记忆功能前端或其他应用程序
潜进项目的所有仓库如下:
| 项目名称 | 状态 | 说明 | 包名 | 技术栈 | 目标平台 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| HeurAMS | 开发中<br/>原型可用 | 提供通用核心程序库与基本用户界面 | `heurams` | Python | 标准 Python 环境 |
| KiriMemo | 开发中<br/>原型可用 | 基于 KDE 技术的现代跨平台前端 | `org.kde.kirimemo` | C++, Qt6, Kirigami, PyOtherSide | 桌面与移动设备 |
| ArkMemo | 开发中 | 基于 ArkUI 的现代跨平台前端 | `top.pluv27.arkmemo` | ArkTS, ArkUI | 移动设备 |
| HeurStudio | 计划中 | AI 辅助的单体单元集高级创建与编辑工具 | `top.pluv27.heurstudio` | C++, Qt6, Kirigami, PyOtherSide | 桌面 |
| HeurSync | 开发中 | 用户数据同步服务器<br/>集成 Web 前端与排行榜 | `heursync` | Go, SQL | 网页与服务器 |
| HeurRepo | 开发中 | 单元集文档源服务器<br/>与单元集分享平台 | `heurrepo` | Go, SQL | 网页与服务器 |
尽管现在后三样有点画大饼的意思, 但是我们的路线是明了的
+46 -95
View File
@@ -3,116 +3,65 @@
## 概述 ## 概述
"潜进" (HeurAMS: Heuristic Auxiliary Memorizing Scheduler, 启发式记忆辅助调度器) 是一种基于启发式算法与认知科学理论的辅助记忆调度器, 旨在帮助用户更高效地进行记忆工作与学习规划, "潜进" (HeurAMS: Heuristic Auxiliary Memorizing Scheduler, 启发式记忆辅助调度器) 是一种基于启发式算法与认知科学理论的辅助记忆调度器, 旨在帮助用户更高效地进行记忆工作与学习规划,
也是一种开放, 优雅, 易于扩展的间隔重复调度器实验平台, 旨在帮助研究者更高效地进行前沿记忆算法的研究. 也是一种开放, 优雅, 易于扩展的间隔重复调度器实验平台, 旨在帮助研究者更高效地进行前沿记忆算法的调查实验与研究.
## 关于此仓库 [详细介绍](INTRODUCTION.md) [屏幕截图](SCREENSHOTS.md)
此仓库为 "潜进" 的核心程序库在 python 语言下的实现 <p align="left">
包含数据模型与框架, 并内置了基于 textual 框架的前端实现 (interface 子模块) <a href="https://github.com/pluvium27/HeurAMS" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/GitHub-fafafa?style=for-the-badge&logo=github&logoColor=181717" alt="GitHub" /></a>
除了通过内置前端进行学习外, 开发者也能在 python 环境中导入 `heurams` 库或使用 `RPC``heurams` 程序库实例通讯, 使用框架构建其他辅助记忆功能前端或其他应用程序 <a href="https://invent.kde.org/pluv/HeurAMS" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/KDE_Invent-1D99F3?style=for-the-badge&logo=kde&logoColor=white" alt="KDE Invent" /></a>
<a href="https://gitee.com/pluv/HeurAMS" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/Gitee-C71D23?style=for-the-badge&logo=gitee&logoColor=white" alt="Gitee" /></a>
> [!NOTE] <a href="https://git.pluv27.top/pluv/HeurAMS" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/git.pluv27.top-609926?style=for-the-badge&logo=gitea&logoColor=white" alt="git.pluv27.top" /></a>
> 我们已经着手于基于 KDE 用户界面框架 `Kirigami` 的现代跨平台前端开发, 称作 "KiriMemo", 包名是 "org.kde.kirimemo", 但其并非 KDE 项目 </p>
> 它通过 `PyOtherSide` 直接复用 python 内核, 为 Windows, Linux, macOS, Android, iOS 和 Plasma Mobile 提供现代用户界面
> 如果您善于开发 C++, QML, Qt 与 KDE 框架, 欢迎加入到 KiriMemo 项目的开发
## 特性
### 间隔重复调度器
> 许多出版物都广泛讨论了不同重复间隔对学习效果的影响. 特别是, 间隔效应被认为是一种普遍现象. 间隔效应是指, 如果重复的间隔是分散/稀疏的, 而不是集中重复, 那么学习任务的表现会更好. 因此, 有观点提出, 学习中使用的最佳重复间隔是**最长的, 但不会导致遗忘的间隔**.
- 软件开箱即用, 无需多加配置即可使用默认的 `SM-2` 算法进行学习
- 此外, 算法模块是 "潜进" 内核 (heurams.kernel) 中的一等公民, 内核天然支持插拔各型算法
- 无需安装繁杂的插件即可分单元集完成算法快速切换与调优, 研究者可以方便地修改算法模块以便捷地进行研究与测试
- 默认使用 `SM-2` 简单间隔重复算法, 此算法亦用作 `Anki` 闪卡记忆软件的默认闪卡调度器
- 内置 `NSP-0` 筛选用非间隔重复算法以便快速筛选记忆内容, `FSRS` 先进间隔重复算法作为效率更高的调度器, 与 `SM-15M (移植自 sm.js 项目)` 复杂间隔重复算法(逆向工程)
- 算法模块可以标记记忆项目, 也可以动态规划每个记忆单元的记忆间隔时间表, 动态跟踪记忆反馈数据, 以优化长期记忆保留率与稳定性
- 得益于项目的模块化架构与单元集结构设计, 一个项目甚至可以与任意种算法共存并互通, 这对研究者及想探索/实验高效率方法的用户极其友好
### 多模态学习进程
与 Anki 的 SQLite `.apkg` 包不同, 我们坚持使用人类可读的文件夹组织单元集, 这带来了若干好处, 包括:
- 人类可读: 您可以用任意工具, 乃至一个记事本自由修改记忆载荷数据而无需打开软件
- 元数据配置: 配置自由度极高, 可以任意组合, 重造, 乃至创造新内容
- 测验, 算法与知识互相隔离: 一条知识不再是单一的闪卡, 不仅可以用若干不同的算法规划, 还可以用多种并行的谜题类型测验, 极大地提升学习效果和丰富度. 作为学习者, 您无需担忧概念复杂--仅需从云端下载单元集即可开箱即用上述特性!
- 多模态学习
- 软件自身集成了文本转语音 (TTS) , 音频与语言模型 (LLM) 模块, 这些功能乃至功能本身都是可插拔, 可扩展, 可切换驱动的, 这为内容创建了极大的丰富度
- 软件内置多种谜题类型, 包括选择题 (MCQ), 填空题 (Cloze) 与识别题 (Recognition), 您可在同一单元应用多种, 或是选择性启用
- 软件天然支持动态内容生成, 支持宏驱动的模板系统, 根据上下文乃至语言模型动态生成知识点的解析
- 在间隔重复研究尚被 SuperMemo 系列独占的时代, Wozniak 就早已表示 "如果不能理解知识, 就无需记忆它". 今天, 我们依然相信理解是记忆的基石
- 云同步与分享优化:
- 由于记忆数据和单元集文件都是文本文件, 故可进行快速的增量同步而无需完整地上传所有文件, 并且设计天然支持版本控制
- 如果您想分享单文件, 软件也支持导出为压缩包或合并成单文本文件以通过纯文本文件形式在 pastebin 等平台分享
- 性能提升: 得益于现代且支持分块的文件组织结构, 潜进能在保持高自由度的同时仅使用 python 就能达到敏捷且低占用的用户体验
- AI 辅助友好: 想象您有一些 .apkg 牌组或一大段教材内容, 您可以方便且高效率地使用 AI 工具创建可在 HeurAMS 使用的单元集
### 内置实用用户界面
尽管不是唯一前端, 但响应式 Textual 框架构建的内置终端用户界面在多种场景下仍具有独特优势:
- 跨平台, 并支持触屏/鼠标/键盘多操作模式
- 与几乎所有现代终端模拟器相容
- 对于<a href="https://www.arewesixelyet.com/" target="_blank" rel="noopener noreferrer">支持 sixel 协议的终端模拟器</a>, 可显示图像内容
- 可通过 textual-web 作为服务部署, 并在任意浏览器使用
- 简洁直观, 键盘友好, 全功能且高效率的用户界面设计
- 易于嵌入: 可在 getty/kmscon 中运行而无需任何桌面图形服务
- 资源占用小, 运行流畅, 不拖泥带水
- 便于测试与调试程序库
[查看屏幕截图](SCREENSHOTS.md)
## 快速开始 ## 快速开始
### 从包管理器安装 ### 从包管理器安装
潜进 (包名是 `heurams`) 处于早期开发考虑, 尚未上架 PyPI, 但您可以用我们的基础设施安装稳定版和开发版本. 潜进 (包名是 `heurams`) 处于早期开发考虑, 尚未上架 PyPI, 但您可以用 pip 支持的 git 协议安装稳定版和开发版本, 这要求您的电脑上安装了 python 环境 (建议 3.12.13 及之后版本).
#### 稳定版本 #### 面向用户的安装
从稳定的 `master` 分支安装, 并安装适用于用户体验的可选依赖(推荐):
安装适用于用户体验的可选依赖(推荐):
``` ```
python -m pip install heurams[basic] -i https://pypi.pluv27.top/root/stable/+simple/ pip install --upgrade 'heurams[basic] @ https://git.pluv27.top/pluv/HeurAMS/archive/master.zip'
``` ```
安装适用于一般计算机的通用音频模块(基于 playsound3):
从较前沿, 大致稳定的 `dev` 分支安装, 并安装适用于用户体验的可选依赖(如果您追求较前沿的改进):
```
pip install --force-reinstall --no-deps 'heurams[basic] @ https://git.pluv27.top/pluv/HeurAMS/archive/dev.zip'
```
安装适用于一般计算机的通用音频模块(基于 playsound3):\
(此项不适用于 termux 环境, termux 的音频支持是内建的) (此项不适用于 termux 环境, termux 的音频支持是内建的)
``` ```
python -m pip install heurams[audio-playsound] -i https://pypi.pluv27.top/root/stable/+simple/ pip install --upgrade 'heurams[audio-playsound] @ https://git.pluv27.top/pluv/HeurAMS/archive/master.zip'
``` ```
#### 开发版本 #### 面向开发者的安装
> [!CAUTION] > [!CAUTION]
> 对于部分 Linux 发行版和 Android Termux 用户: > 对于部分 Linux 发行版和 Android Termux 用户:\
> 您需要先行安装 `cmake` 和 `libzmq` 才能正确安装项目的 `zmq` 依赖. > 您需要先行安装 `cmake` 和 `libzmq` 才能正确安装项目的 `zmq` 依赖.\
> 例如在 termux 上先运行 `pkg install cmake clang libzmq`. > 例如在 termux 上先运行 `pkg install cmake clang libzmq`.\
> 项目功能本身不依赖它, 但需要该依赖用于启动可选的调试服务器. > 项目功能本身不依赖它, 但需要该依赖用于启动可选的调试服务器.
`dev` 分支进行基于 git 的可编辑安装, 并安装全部可选依赖(推荐):
安装全部可选依赖(推荐):
``` ```
python -m pip install heurams[all] -i https://pypi.pluv27.top/root/dev/+simple/ pip install --force-reinstall --no-deps 'heurams[all] @ https://git.pluv27.top/pluv/HeurAMS/archive/dev.zip'
``` ```
#### 依赖组说明 > 您也可以从 `refactor/...` 等特定分支安装
由于部分依赖只被少数功能需要, 所以我们把可选依赖分得比较细, 前面提供的命令会安装部分可选依赖, 以下是依赖组列表: [依赖组说明](INTRODUCTION.md#包依赖组说明)
| 依赖组 | 包含模块 | 说明 |
|--------|----------|------|
| 最小化安装 | tabulate, toml, transitions | 核心驱动程序库, 始终必需 |
| interface | textual, psutil | 基本用户界面依赖 |
| algo-fsrs | fsrs | FSRS 算法模块 |
| tts-edgetts | edge-tts | 微软文本转语音 |
| llm | openai | OpenAI 式 API 调用 |
| audio-playsound | playsound3 | 通用音频模块 |
| dev | zmq, pytest, pytest-cov | 开发调试与测试工具 |
| basic | [tts-edgetts], [llm-openai], [algo-fsrs] | 适用于用户体验的较轻依赖组(推荐) |
| all | 以上所有依赖 | 完整安装组 |
### 从源码安装 ### 从源码安装
我们提供原生 python 和 uv 两种安装方式. 我们提供原生 python 和 uv 两种安装方式.\
详见[贡献指南](CONTRIBUTING.md). 详见[贡献指南](CONTRIBUTING.md).
## 常见问题 (FAQ) ## 常见问题 (FAQ)
@@ -125,29 +74,31 @@ python -m pip install heurams[all] -i https://pypi.pluv27.top/root/dev/+simple/
## 参与项目 ## 参与项目
欢迎参与到项目协作中! 欢迎参与到项目协作中!\
详见[贡献指南](CONTRIBUTING.md). 详见[贡献指南](CONTRIBUTING.md).\
关于 AI 辅助开发的说明, 请参阅 [AGENTS.md](AGENTS.md). 关于 AI 辅助开发的说明, 请参阅 [AGENTS.md](AGENTS.md).
## 项目标识 ## 项目标识
HeurAMS 项目标识如下, 矢量图文件位于 `./src/heurams/assets/art/` 目录. HeurAMS 项目标识如下, 文件(位图和矢量图)位于 `./src/heurams/assets/art/` 目录.
<img src="src/heurams/assets/art/banner128-light.png" height="96px" title="位图横幅(不透明)">
<div style="display: flex; flex-wrap: wrap; gap: 5px;"> <div style="display: flex; flex-wrap: wrap; gap: 5px;">
<img src="src/heurams/assets/art/logo.svg" height="96px"> <img src="src/heurams/assets/art/logo.svg" height="96px" title="矢量图标">
<img src="src/heurams/assets/art/logo-mono-light.svg" height="96px"> <img src="src/heurams/assets/art/logo-mono-light.svg" height="96px" title="单色明亮矢量图标">
<img src="src/heurams/assets/art/logo-mono-dark.svg" height="96px"> <img src="src/heurams/assets/art/logo-mono-dark.svg" height="96px" title="单色暗色矢量图标">
</div> </div>
颜色分别是: `#1660A5 (海蓝色)` `#545F70 (蓝灰色)` `#1A1A1A (暗色单色图标深黑色)` `#FFFFFF (明亮单色图标白色)`. 颜色分别是: `#1660A5 (海蓝色)` `#545F70 (蓝灰色)` `#FFFFFF (单色明亮图标白色)` `#1A1A1A (单色暗色图标深黑色)` `#2f2f35 (文字颜色)`.
## 许可证 ## 许可证
### 项目本身 ### 项目本身
本项目基于 AGPL-3.0 许可证开放源代码, 并有一个豁免本机 API 调用的附加条款, 较标准 AGPL-3.0 更松. 本项目基于 AGPL-3.0 许可证开放源代码, 并有一个豁免本机 API 调用的附加条款, 较标准 AGPL-3.0 更松.
详见根目录下 [LICENSE](LICENSE) 文件. 详见根目录下 [LICENSE](LICENSE) 文件.
### 第三方代码 ### 第三方代码
@@ -155,7 +106,7 @@ HeurAMS 项目标识如下, 矢量图文件位于 `./src/heurams/assets/art/`
#### SM.js (slaypni) #### SM.js (slaypni)
- 上游版本: commit `6e3bb4afaf484426deb4a9fa3bcffe42ac066b45` (2015年2月4日上游已停止维护) - 上游版本: commit `6e3bb4a` (2015年2月4日上游已停止维护)
- 引用方式: 将 coffeescript 重写为 python 并间接引用, 数学原理一致; 并对重写后代码进行逻辑, 性能与标准化 API 改进 - 引用方式: 将 coffeescript 重写为 python 并间接引用, 数学原理一致; 并对重写后代码进行逻辑, 性能与标准化 API 改进
- 位置: `src/heurams/kernel/algorithms/sm15m*.py` - 位置: `src/heurams/kernel/algorithms/sm15m*.py`
- 原项目: [SM.js](https://github.com/slaypni/SM-15) - 原项目: [SM.js](https://github.com/slaypni/SM-15)
+17 -17
View File
@@ -1,23 +1,23 @@
# 用户界面屏幕截图 # 用户界面屏幕截图
潜进 (HeurAMS) 项目目前有两个前端实现, 此文档用于呈现它们的截图 (尽量与最新版本同步): 潜进 (HeurAMS) 项目目前有两个前端实现, 此文档用于呈现它们的截图 (尽量与最新版本同步):
- Textual 基本用户界面 (heurams.interface): 基于 Python Textual 框架构建的程序库内置跨平台 TUI 界面, 支持触屏、鼠标、键盘多操作模式, 是当前开箱即用的默认前端. - Textual 基本用户界面 (heurams.interface): 基于 Python Textual 框架构建的程序库内置跨平台 TUI 界面, 支持触屏、鼠标、键盘多操作模式, 是当前开箱即用的默认前端.
- KiriMemo (org.kde.kirimemo): 基于 KDE Kirigami 框架的现代跨平台前端, 使用 C++ 和 QML 构建, 通过 `PyOtherSide` 直接复用 Python 内核, 为多种平台提供原生体验 (尚未稳定). - KiriMemo (org.kde.kirimemo): 基于 KDE Kirigami 框架的现代跨平台前端, 使用 C++ 和 QML 构建, 通过 `PyOtherSide` 直接复用 Python 内核, 为多种平台提供原生体验 (尚未稳定).
欢迎为现有前端贡献代码, 或开发您自己的前端. 欢迎为现有前端贡献代码, 或开发您自己的前端.\
详见[贡献指南](CONTRIBUTING.md#新的用户界面前端). 详见[贡献指南](CONTRIBUTING.md#%E6%96%B0%E7%9A%84%E7%94%A8%E6%88%B7%E7%95%8C%E9%9D%A2%E5%89%8D%E7%AB%AF).
## 基本用户界面前端的截图 ## 基本用户界面前端的截图
> 截图所使用的终端模拟器为 KDE Konsole > 截图所使用的终端模拟器为 KDE Konsole\
> 字体为 Cascadia Code 和 Noto Sans SC > 字体为 Cascadia Code 和 Noto Sans SC\
> 终端尺寸设置为 80x25 (软件也支持更大的终端尺寸) > 终端尺寸设置为 80x25 (软件也支持更大的终端尺寸)
### 仪表盘与导航器 ### 仪表盘与导航器
仪表盘包含学习面板的总体视图, 包括不同功能区域的操作入口, 统计信息, 以及单元集概览. 仪表盘包含学习面板的总体视图, 包括不同功能区域的操作入口, 统计信息, 以及单元集概览.\
导航器是一个实用的模态窗口, 能带您在多种功能间自如切换, 按 `n` 键或单击下方按钮可在任意界面迅速打开/关闭导航器. 导航器是一个实用的模态窗口, 能带您在多种功能间自如切换, 按 `n` 键或单击下方按钮可在任意界面迅速打开/关闭导航器.
<div style="display: flex; flex-wrap: wrap; gap: 10px;"> <div style="display: flex; flex-wrap: wrap; gap: 10px;">
<img src="screenshots/dashboard_1.png" width="48%"> <img src="screenshots/dashboard_1.png" width="48%">
@@ -27,8 +27,8 @@
### 准备界面与预缓存工具 ### 准备界面与预缓存工具
学习准备界面展示了单元集基本信息和每个单元的学习状态, 并提供了学习和预缓存的入口. 学习准备界面展示了单元集基本信息和每个单元的学习状态, 并提供了学习和预缓存的入口.\
预缓存工具使您能提前预缓存文本转语音资源以确保复习流程的顺畅体验和离线复习能力, 但即使您不预先缓存, 资源也会在复习播放时被自动加载. 预缓存工具使您能提前预缓存文本转语音资源以确保复习流程的顺畅体验和离线复习能力, 但即使您不预先缓存, 资源也会在复习播放时被自动加载.
<div style="display: flex; flex-wrap: wrap; gap: 10px;"> <div style="display: flex; flex-wrap: wrap; gap: 10px;">
<img src="screenshots/preparation.png" width="48%"> <img src="screenshots/preparation.png" width="48%">
@@ -37,8 +37,8 @@
### 记忆队列界面 ### 记忆队列界面
队列式学习记忆的主要界面. 队列式学习记忆的主要界面.\
同一知识点可产生多种谜题类型的评估方式, 软件内置完形填空与识别题等多种测试类型, 您可在复习流程中按顺序完成不同测试. 同一知识点可产生多种谜题类型的评估方式, 软件内置完形填空与识别题等多种测试类型, 您可在复习流程中按顺序完成不同测试.
<div style="display: flex; flex-wrap: wrap; gap: 10px;"> <div style="display: flex; flex-wrap: wrap; gap: 10px;">
<img src="screenshots/memoqueue_cloze_1.png" width="48%"> <img src="screenshots/memoqueue_cloze_1.png" width="48%">
@@ -46,10 +46,9 @@
<img src="screenshots/memoqueue_recognition_2.png" width="48%"> <img src="screenshots/memoqueue_recognition_2.png" width="48%">
</div> </div>
### 设置界面 ### 设置界面
配置界面包含算法选择、音频与多种服务的提供者切换、以及界面与算法设置等选项. 配置界面包含算法选择、音频与多种服务的提供者切换、以及界面与算法设置等选项.
<div style="display: flex; flex-wrap: wrap; gap: 10px;"> <div style="display: flex; flex-wrap: wrap; gap: 10px;">
<img src="screenshots/setting_1.png" width="48%"> <img src="screenshots/setting_1.png" width="48%">
@@ -58,8 +57,8 @@
### 其他界面 ### 其他界面
收藏管理器可管理您手动标记的个人收藏集. 收藏管理器可管理您手动标记的个人收藏集.\
关于页面提供了程序版本号、许可协议等信息. 关于页面提供了程序版本号、许可协议等信息.
<div style="display: flex; flex-wrap: wrap; gap: 10px;"> <div style="display: flex; flex-wrap: wrap; gap: 10px;">
<img src="screenshots/about_1.png" width="48%"> <img src="screenshots/about_1.png" width="48%">
@@ -68,5 +67,6 @@
## KiriMemo 前端的截图 ## KiriMemo 前端的截图
截图将在 KiriMemo 前端开发趋于稳定后补充. 截图将在 KiriMemo 前端开发趋于稳定后补充.
<!-- TODO: 补充截图 --> <!-- TODO: 补充截图 -->
+14 -9
View File
@@ -1,7 +1,7 @@
[project] [project]
name = "heurams" name = "heurams"
version = "0.5.0" version = "0.5.1"
authors = [{ name = "pluvium27", email = "pluvium27@outlook.com" }] authors = [{ name = "Wang Zhiyu", email = "pluvium27@outlook.com" }]
description = "Heuristic Auxiliary Memory Scheduler" description = "Heuristic Auxiliary Memory Scheduler"
readme = "README.md" readme = "README.md"
requires-python = ">=3.12" requires-python = ">=3.12"
@@ -13,6 +13,7 @@ license = "AGPL-3.0-or-later"
license-files = ["LICENSE"] license-files = ["LICENSE"]
dependencies = [ # 这些依赖只能驱动 kernel 程序库 dependencies = [ # 这些依赖只能驱动 kernel 程序库
"click>=8.3.3",
"tabulate>=0.10.0", "tabulate>=0.10.0",
"toml>=0.10.2", "toml>=0.10.2",
"transitions>=0.9.3", "transitions>=0.9.3",
@@ -21,15 +22,15 @@ dependencies = [ # 这些依赖只能驱动 kernel 程序库
[project.optional-dependencies] [project.optional-dependencies]
interface = [ # 基本用户界面依赖 interface = [ # 基本用户界面依赖
"textual>=8.2.5", "textual>=8.2.5",
"psutil>=7.2.2",
] ]
algo-fsrs = [ algo-fsrs = [
"fsrs>=6.3.1", # FSRS 算法底层依赖 "fsrs>=6.3.1", # FSRS 算法底层依赖
] ]
tts-edgetts = [ tts-edgetts = [
"edge-tts>=7.2.8", # 微软 TTS "edge-tts>=7.2.8", # 微软 TTS
] ]
llm = ["openai>=2.32.0"] llm = ["llms-py>=3.0.0"]
audio-playsound = ["playsound3>=3.3.1"] audio-playsound = ["playsound3>=3.3.1"]
dev = [ # 调试所需依赖 dev = [ # 调试所需依赖
"zmq>=0.0.0", # 用于 ZMQ 远程调试服务器, 在 linux 上建议先安装 libzmq "zmq>=0.0.0", # 用于 ZMQ 远程调试服务器, 在 linux 上建议先安装 libzmq
@@ -43,10 +44,15 @@ all = [
"heurams[audio-playsound]", "heurams[audio-playsound]",
"heurams[dev]", "heurams[dev]",
] ]
basic = ["heurams[algo-fsrs]", "heurams[tts-edgetts]", "heurams[llm]"] basic = [
"heurams[algo-fsrs]",
"heurams[interface]",
"heurams[tts-edgetts]",
"heurams[llm]",
]
[project.urls] [project.urls]
Homepage = "https://ams.pluv.top" Homepage = "https://ams.pluv27.top"
Issues = "https://github.com/heurams/heurams/issues" Issues = "https://github.com/heurams/heurams/issues"
[[tool.uv.index]] [[tool.uv.index]]
@@ -55,7 +61,6 @@ default = true
[project.scripts] [project.scripts]
heurams = "heurams.__main__:main" heurams = "heurams.__main__:main"
heurams-tui = "heurams.interface.__main__:main"
[tool.pytest.ini_options] [tool.pytest.ini_options]
testpaths = ["tests"] testpaths = ["tests"]
@@ -67,5 +72,5 @@ markers = [
] ]
[build-system] [build-system]
requires = ["uv_build>=0.7.19"] requires = ["hatchling"]
build-backend = "uv_build" build-backend = "hatchling.build"
+1 -1
View File
@@ -1,4 +1,4 @@
print("欢迎使用 HeurAMS 及其组件!") #print("欢迎使用 HeurAMS 及其组件!")
# 补充日志记录 # 补充日志记录
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
+58 -17
View File
@@ -1,23 +1,64 @@
import heurams.services.version as ver import platform
import click
from heurams.services.version import ver, stage, codename, codename_cn
@click.group(
invoke_without_command=True,
help=(
f"HeurAMS {ver} - 启发式辅助记忆调度器"
),
context_settings={"help_option_names": ["-h", "--help"]},
)
@click.version_option(
ver, "-v", "--version",
prog_name="HeurAMS",
message=f"%(prog)s %(version)s {stage} ({codename}/{codename_cn}), {platform.system()}",
)
@click.pass_context
def cli(ctx):
if ctx.invoked_subcommand is None:
click.echo(cli.get_help(ctx))
ctx.exit(0)
@cli.command()
def tui():
"""启动内置基本用户界面 (TUI)"""
import heurams.interface.__main__ as tui_module
tui_module.main()
def _print_version():
click.echo(
f"HeurAMS {ver} ({codename}/{codename_cn}), 阶段: {stage}"
)
@cli.command()
def version():
"""输出版本信息"""
_print_version()
@cli.command(name="ver", hidden=True)
def ver_cmd():
"""输出版本信息"""
_print_version()
@cli.command(name="help")
@click.pass_context
def help_cmd(ctx):
"""显示此帮助信息"""
click.echo(cli.get_help(ctx.parent))
# __main__.py
def main(): def main():
prompt = f"""HeurAMS {ver.ver} 已经被成功地安装在系统中. cli()
HeurAMS 被设计为一个带有辅助记忆调度器功能的软件包, 无法直接被执行, 但可被其他 Python 程序调用.
若您想启动内置的基本用户界面:
请运行 python -m heurams.interface,
或者 python -m heurams.interface.__main__
python 代指您使用的解释器, 在某些发行版中可能是 python3, 而 python 命令被指向了 python2.
尽管项目保留了 requirements.txt, 我们仍不推荐使用系统 python 和原始 venv 进行开发.
项目的推荐开发环境工具是 uv.
如果你的环境已经安装了 uv:
先运行 uv sync --all-extras 同步环境, 此命令只需要执行一遍, uv 会自动处理依赖.
然后通过运行 uv run heurams-tui 启动内置基本用户界面.
此时您的解释器在项目目录里的 .venv/bin 中, 使用 IDE 开发前, 务必切换解释器!
注意: 一个常见的误区是, 执行 interface 下的 __main__.py 运行基本用户界面, 这会导致 Python 上下文环境异常, 请不要这样做."""
print(prompt)
if __name__ == "__main__": if __name__ == "__main__":
main() main()
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

+1
View File
@@ -27,6 +27,7 @@ user_data = workdir / "data"
if not user_data.exists(): if not user_data.exists():
logger.info("初始化数据目录: %s", user_data) logger.info("初始化数据目录: %s", user_data)
import shutil import shutil
shutil.copytree(default_data, user_data) shutil.copytree(default_data, user_data)
else: else:
(workdir / "data" / "config").mkdir(parents=True, exist_ok=True) (workdir / "data" / "config").mkdir(parents=True, exist_ok=True)
+3 -3
View File
@@ -72,9 +72,8 @@ class HeurAMSApp(App):
) -> None: # 用来给没使用/禁用的快捷键占位, 因为 Binding 删除不了 ) -> None: # 用来给没使用/禁用的快捷键占位, 因为 Binding 删除不了
pass pass
# 移除烦人的 "rich traceback" '''
# Textual 官方不会管这破事, 写 Rich 写入脑了导致的 # 移除烦人的 "rich traceback", 但可能导致未定义行为出现, 所以注释掉
# 不知道哪来的自信改标准库的 traceback
# https://github.com/Textualize/textual/discussions/6255 # https://github.com/Textualize/textual/discussions/6255
# NOTE: 进行 textual 版本升级时, 确保查看过上游代码, 尤其是 App 的 _exception # NOTE: 进行 textual 版本升级时, 确保查看过上游代码, 尤其是 App 的 _exception
# 如果行为变了就把下面的删了 (虽然有 fallback) # 如果行为变了就把下面的删了 (虽然有 fallback)
@@ -89,3 +88,4 @@ class HeurAMSApp(App):
self._close_messages_no_wait() self._close_messages_no_wait()
raise self._exception raise self._exception
super().panic(*args) # ditto super().panic(*args) # ditto
'''
+2 -1
View File
@@ -2,12 +2,13 @@ from heurams.interface import *
from heurams.context import config_var from heurams.context import config_var
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
import threading import threading
import zmq
import pickle import pickle
logger = get_logger(__name__) logger = get_logger(__name__)
def start_debug_server(app): def start_debug_server(app):
import zmq
logger = get_logger("zmq_debug") logger = get_logger("zmq_debug")
context = zmq.Context() context = zmq.Context()
socket = context.socket(zmq.REP) socket = context.socket(zmq.REP)
+6 -24
View File
@@ -4,14 +4,12 @@ from textual.app import ComposeResult
from textual.containers import ScrollableContainer from textual.containers import ScrollableContainer
from textual.screen import Screen from textual.screen import Screen
from textual.widgets import Button, Footer, Header, Label, Markdown from textual.widgets import Button, Footer, Header, Label, Markdown
from textual import events, on from textual import events, on
import heurams.services.version as version import heurams.services.version as version
from heurams.context import * from heurams.context import *
import platform import platform
import shutil import shutil
import psutil
import os import os
import sys import sys
@@ -40,14 +38,12 @@ class AboutScreen(Screen):
) )
with ScrollableContainer(id="about_container"): with ScrollableContainer(id="about_container"):
yield Label("[b]关于与版本信息[/b]") yield Label("[b]关于与版本信息[/b]")
# 获取系统信息 # 获取系统信息
textual_version = self._get_textual_version() textual_version = self._get_textual_version()
terminal_info = self._get_terminal_info() terminal_info = self._get_terminal_info()
python_version = self._get_python_version() python_version = self._get_python_version()
os_version = self._get_os_version() os_version = self._get_os_version()
disk_usage = self._get_disk_usage() disk_usage = self._get_disk_usage()
memory_info = self._get_memory_info()
about_text = f""" about_text = f"""
# 关于 HeurAMS "潜进" # 关于 HeurAMS "潜进"
@@ -67,7 +63,6 @@ API 版本代号: `{version.codename.capitalize()}`
您正使用程序库内置的终端用户界面, 它是第一个全功能前端实现与程序库测试套件, 位于程序库的 interface 子目录. 您正使用程序库内置的终端用户界面, 它是第一个全功能前端实现与程序库测试套件, 位于程序库的 interface 子目录.
开发人员列表: 开发人员列表:
- Wang Zhiyu ([@pluvium27](https://github.com/pluvium27)): 项目发起与主要开发者 - Wang Zhiyu ([@pluvium27](https://github.com/pluvium27)): 项目发起与主要开发者
感谢以下人士与团体, 他们的算法与理论构成了此软件现有算法的基石: 感谢以下人士与团体, 他们的算法与理论构成了此软件现有算法的基石:
@@ -85,12 +80,10 @@ Textual 框架版本: {textual_version}
终端模拟器: {terminal_info} 终端模拟器: {terminal_info}
操作系统版本: {os_version} 操作系统版本: {os_version}
存储余量: {disk_usage} 存储余量: {disk_usage}
内存总量: {memory_info}
报告问题时, 请复制这些信息到问题描述, 并上传软件日志 `heurams.log` 作为附件, 以协助开发者定位错误 报告问题时, 请复制这些信息到问题描述, 并上传软件日志 `heurams.log` 作为附件, 以协助开发者定位错误
""" """
yield Markdown(about_text, classes="about-markdown") yield Markdown(about_text, classes="about-markdown")
yield Button( yield Button(
"返回主界面", "返回主界面",
id="back_button", id="back_button",
@@ -159,20 +152,9 @@ Textual 框架版本: {textual_version}
def _get_disk_usage(self) -> str: def _get_disk_usage(self) -> str:
"""获取磁盘使用情况""" """获取磁盘使用情况"""
try: usage = shutil.disk_usage("/")
usage = psutil.disk_usage("/") free_gb = usage.free / (1024**3)
free_gb = usage.free / (1024**3) total_gb = usage.total / (1024**3)
total_gb = usage.total / (1024**3) percent_free = (free_gb / total_gb) * 100
percent_free = (free_gb / total_gb) * 100 #print(f"{free_gb:.1f} GB ({percent_free:.1f}%)")
return f"{free_gb:.1f} GB ({percent_free:.1f}%)" return f"{free_gb:.1f} GB ({percent_free:.1f}%)"
except Exception:
return "未知"
def _get_memory_info(self) -> str:
"""获取内存信息"""
try:
memory = psutil.virtual_memory()
total_gb = memory.total / (1024**3)
return f"{total_gb:.1f} GB"
except Exception:
return "未知"
+7 -2
View File
@@ -16,7 +16,6 @@ from textual.widgets import (
Label, Label,
ListItem, ListItem,
ListView, ListView,
Markdown,
Static, Static,
) )
@@ -117,7 +116,13 @@ class FavoriteManagerScreen(Screen):
# 创建列表项, 包含移除按钮 # 创建列表项, 包含移除按钮
container = Horizontal( container = Horizontal(
Label(display_text, classes="favorite-content"), Label(display_text, classes="favorite-content"),
Button("移除", id=f"remove-{button_key}", variant="error", flat=True, classes="favorite-item-btn"), Button(
"移除",
id=f"remove-{button_key}",
variant="error",
flat=True,
classes="favorite-item-btn",
),
classes="favorite-item", classes="favorite-item",
) )
return ListItem(container) return ListItem(container)
+7 -1
View File
@@ -140,7 +140,11 @@ class MemScreen(Screen):
if config_var.get()["interface"]["global"]["persist_to_file"]: if config_var.get()["interface"]["global"]["persist_to_file"]:
self.repo.persist_to_repodir() self.repo.persist_to_repodir()
container.mount(Finished(is_saved=config_var.get()["interface"]["global"]["persist_to_file"])) container.mount(
Finished(
is_saved=config_var.get()["interface"]["global"]["persist_to_file"]
)
)
def on_button_pressed(self, event): def on_button_pressed(self, event):
event.stop() event.stop()
@@ -162,6 +166,7 @@ class MemScreen(Screen):
play_by_path(path) play_by_path(path)
else: else:
from heurams.services.tts_service import convertor from heurams.services.tts_service import convertor
convertor(self.atom.registry["nucleon"]["tts_text"], path) convertor(self.atom.registry["nucleon"]["tts_text"], path)
play_by_path(path) play_by_path(path)
@@ -224,6 +229,7 @@ class MemScreen(Screen):
def action_go_back_notif(self): def action_go_back_notif(self):
self.notify("确定吗? 按下大写 Q 以返回") self.notify("确定吗? 按下大写 Q 以返回")
def action_go_back(self): def action_go_back(self):
self.app.pop_screen() self.app.pop_screen()
+1 -1
View File
@@ -34,7 +34,7 @@ class NavigatorScreen(ModalScreen):
OTHERS = [ OTHERS = [
("退出程序", "self.app.exit()"), ("退出程序", "self.app.exit()"),
("项目主页", "webbrowser.open('https://ams.imwangzhiyu.xyz')"), ("项目主页", "webbrowser.open('https://ams.pluv27.top')"),
] ]
def compose(self) -> ComposeResult: def compose(self) -> ComposeResult:
@@ -81,10 +81,10 @@ class ClozePuzzle(BasePuzzleWidget):
btnid = f"sel000-{h}" btnid = f"sel000-{h}"
logger.debug(f"建立按钮 {btnid}") logger.debug(f"建立按钮 {btnid}")
self.btn_shortcuts[f"{c}"] = btnid self.btn_shortcuts[f"{c}"] = btnid
btns.append(Button(f"{i}", id=f"{btnid}", classes='cloze-option-btn')) btns.append(Button(f"{i}", id=f"{btnid}", classes="cloze-option-btn"))
for i in range((len(btns)+1)//2): for i in range((len(btns) + 1) // 2):
if 2 * i + 1 + 1 <= len(btns): if 2 * i + 1 + 1 <= len(btns):
yield Horizontal(btns[i], btns[len(btns) - 1 - i], classes='hori') yield Horizontal(btns[i], btns[len(btns) - 1 - i], classes="hori")
else: else:
yield btns[i] yield btns[i]
s.focus() s.focus()
@@ -136,7 +136,7 @@ class ClozePuzzle(BasePuzzleWidget):
self.atom.minimize(rating) self.atom.minimize(rating)
def on_key(self, event: Key) -> None: def on_key(self, event: Key) -> None:
#self.notify(event.key) # self.notify(event.key)
if event.key in self.btn_shortcuts: if event.key in self.btn_shortcuts:
btn_id = self.btn_shortcuts.get(event.key) btn_id = self.btn_shortcuts.get(event.key)
btn_id = "#" + btn_id btn_id = "#" + btn_id
+1 -1
View File
@@ -11,4 +11,4 @@ for _finder, _name, _ispkg in pkgutil.iter_modules(__path__):
continue continue
importlib.import_module(f".{_name}", __package__) importlib.import_module(f".{_name}", __package__)
algorithms = BaseAlgorithm.get_registry() algorithms = BaseAlgorithm.get_registry()
+1
View File
@@ -7,6 +7,7 @@ logger = get_logger(__name__)
_registry: dict[str, type["BaseAlgorithm"]] = {} _registry: dict[str, type["BaseAlgorithm"]] = {}
class BaseAlgorithm: class BaseAlgorithm:
algo_name = "BaseAlgorithm" algo_name = "BaseAlgorithm"
desc = "算法基类" desc = "算法基类"
+12 -16
View File
@@ -3,7 +3,7 @@ FSRS 算法模块 — 基于 py-fsrs 的现代间隔重复调度器
基于: https://github.com/open-spaced-repetition/py-fsrs 基于: https://github.com/open-spaced-repetition/py-fsrs
""" """
import json
import os import os
import pathlib import pathlib
from datetime import datetime, timezone, timedelta from datetime import datetime, timezone, timedelta
@@ -20,9 +20,10 @@ from .base import BaseAlgorithm
logger = get_logger(__name__) logger = get_logger(__name__)
# 全局 Scheduler 状态文件路径 # 全局 Scheduler 状态文件路径
_SCHEDULER_STATE_FILE = pathlib.Path( _SCHEDULER_STATE_FILE = (
config_var.get()["global"]["paths"]["misc"] pathlib.Path(config_var.get()["global"]["paths"]["misc"])
) / "fsrs_scheduler_state.json" / "fsrs_scheduler_state.json"
)
def _get_global_scheduler(): def _get_global_scheduler():
@@ -78,10 +79,10 @@ class FSRSAlgorithm(BaseAlgorithm):
class AlgodataDict(TypedDict): class AlgodataDict(TypedDict):
# FSRS 特有字段 # FSRS 特有字段
fsrs_state: int # State 枚举值: 1=Learning, 2=Review, 3=Relearning fsrs_state: int # State 枚举值: 1=Learning, 2=Review, 3=Relearning
fsrs_step: int # 当前学习步进索引, -1 表示 None (Review 状态) fsrs_step: int # 当前学习步进索引, -1 表示 None (Review 状态)
fsrs_stability: float # 稳定性(秒), 0.0 表示尚未计算 fsrs_stability: float # 稳定性(秒), 0.0 表示尚未计算
fsrs_difficulty: float # 难度 [1.0, 10.0], 0.0 表示尚未计算 fsrs_difficulty: float # 难度 [1.0, 10.0], 0.0 表示尚未计算
# 标准 BaseAlgorithm 兼容字段 # 标准 BaseAlgorithm 兼容字段
real_rept: int real_rept: int
rept: int rept: int
@@ -92,7 +93,7 @@ class FSRSAlgorithm(BaseAlgorithm):
last_modify: float last_modify: float
defaults = { defaults = {
"fsrs_state": 1, # State.Learning "fsrs_state": 1, # State.Learning
"fsrs_step": 0, "fsrs_step": 0,
"fsrs_stability": 0.0, "fsrs_stability": 0.0,
"fsrs_difficulty": 0.0, "fsrs_difficulty": 0.0,
@@ -136,9 +137,7 @@ class FSRSAlgorithm(BaseAlgorithm):
# last_review # last_review
last_date = data.get("last_date", 0) last_date = data.get("last_date", 0)
card.last_review = ( card.last_review = _daystamp_to_datetime(last_date) if last_date > 0 else None
_daystamp_to_datetime(last_date) if last_date > 0 else None
)
return card return card
@@ -160,9 +159,7 @@ class FSRSAlgorithm(BaseAlgorithm):
if card.last_review if card.last_review
else data.get("last_date", 0) else data.get("last_date", 0)
) )
data["next_date"] = ( data["next_date"] = _datetime_to_daystamp(card.due) if card.due else 0
_datetime_to_daystamp(card.due) if card.due else 0
)
data["interval"] = max(0, data["next_date"] - data["last_date"]) data["interval"] = max(0, data["next_date"] - data["last_date"])
data["last_modify"] = get_timestamp() data["last_modify"] = get_timestamp()
return algodata return algodata
@@ -209,8 +206,7 @@ class FSRSAlgorithm(BaseAlgorithm):
algodata[cls.algo_name]["rept"] += 1 algodata[cls.algo_name]["rept"] += 1
logger.debug( logger.debug(
"FSRS.revisor 完成: stability=%s, difficulty=%s, state=%s, " "FSRS.revisor 完成: stability=%s, difficulty=%s, state=%s, " "next_date=%d",
"next_date=%d",
card.stability, card.stability,
card.difficulty, card.difficulty,
card.state, card.state,
+19 -15
View File
@@ -4,6 +4,7 @@ SM-15M — 基于 sm.js 的间隔重复算法
基于: https://github.com/slaypni/sm.js 基于: https://github.com/slaypni/sm.js
原始 CoffeeScript (c) 2014 Kazuaki Tanida, MIT 许可证 原始 CoffeeScript (c) 2014 Kazuaki Tanida, MIT 许可证
""" """
import datetime import datetime
import json import json
import math import math
@@ -19,7 +20,6 @@ from heurams.services.timer import (
get_timestamp_ms, get_timestamp_ms,
daystamp_to_datetime, daystamp_to_datetime,
datetime_to_daystamp, datetime_to_daystamp,
get_now_datetime,
) )
from .base import BaseAlgorithm from .base import BaseAlgorithm
@@ -111,7 +111,7 @@ def power_law_model(a, b):
"""y = a * x^b""" """y = a * x^b"""
def y_func(x): def y_func(x):
return a * (x ** b) return a * (x**b)
def x_func(y): def x_func(y):
if a == 0 or b == 0: if a == 0 or b == 0:
@@ -134,7 +134,7 @@ def fixed_point_power_law_regression(points, fixed_point):
sum_sqX = sum(x * x for x in X) sum_sqX = sum(x * x for x in X)
b = sumXY / sum_sqX if sum_sqX else 0 b = sumXY / sum_sqX if sum_sqX else 0
return power_law_model(q / (p ** b), b) return power_law_model(q / (p**b), b)
# ============================================================================ # ============================================================================
@@ -161,7 +161,7 @@ class FI_G:
def _register_point(self, fi, grade): def _register_point(self, fi, grade):
self.points.append([fi, grade + self.GRADE_OFFSET]) self.points.append([fi, grade + self.GRADE_OFFSET])
if len(self.points) > self.MAX_POINTS_COUNT: if len(self.points) > self.MAX_POINTS_COUNT:
self.points = self.points[-self.MAX_POINTS_COUNT:] self.points = self.points[-self.MAX_POINTS_COUNT :]
self._graph = None self._graph = None
def update(self, grade, item, now): def update(self, grade, item, now):
@@ -203,7 +203,7 @@ class ForgettingCurve:
is_remembered = grade >= THRESHOLD_RECALL is_remembered = grade >= THRESHOLD_RECALL
self.points.append([uf, self.REMEMBERED if is_remembered else self.FORGOTTEN]) self.points.append([uf, self.REMEMBERED if is_remembered else self.FORGOTTEN])
if len(self.points) > self.MAX_POINTS_COUNT: if len(self.points) > self.MAX_POINTS_COUNT:
self.points = self.points[-self.MAX_POINTS_COUNT:] self.points = self.points[-self.MAX_POINTS_COUNT :]
self._curve = None self._curve = None
def retention(self, uf): def retention(self, uf):
@@ -253,9 +253,9 @@ class ForgettingCurves:
pts = [] pts = []
for i in range(21): for i in range(21):
v = MIN_AF + NOTCH_AF * i v = MIN_AF + NOTCH_AF * i
y = math.exp( y = math.exp(-1.0 / (10 + 1 * (a + 1)) * (i - a**0.6)) * (
-1.0 / (10 + 1 * (a + 1)) * (i - a ** 0.6) self.REMEMBERED - self.sm.requested_fi
) * (self.REMEMBERED - self.sm.requested_fi) )
pts.append([v, min(self.REMEMBERED, y)]) pts.append([v, min(self.REMEMBERED, y)])
partial = [[0, self.REMEMBERED]] + pts partial = [[0, self.REMEMBERED]] + pts
row.append(ForgettingCurve(partial)) row.append(ForgettingCurve(partial))
@@ -427,7 +427,9 @@ class Item:
now = datetime.datetime.now() now = datetime.datetime.now()
af_idx = self.lapse if self.repetition == 0 else self.af_index() af_idx = self.lapse if self.repetition == 0 else self.af_index()
of_val = self.sm.ofm.of(self.repetition, af_idx) of_val = self.sm.ofm.of(self.repetition, af_idx)
self.of = max(1.0, (of_val - 1) * (self.interval(now) / self.optimum_interval) + 1) self.of = max(
1.0, (of_val - 1) * (self.interval(now) / self.optimum_interval) + 1
)
self.optimum_interval = round(self.optimum_interval * self.of) self.optimum_interval = round(self.optimum_interval * self.of)
self.previous_date = now self.previous_date = now
self.due_date = now + datetime.timedelta(milliseconds=self.optimum_interval) self.due_date = now + datetime.timedelta(milliseconds=self.optimum_interval)
@@ -443,7 +445,7 @@ class Item:
estimated_af = max(MIN_AF, min(MAX_AF, corrected_uf)) estimated_af = max(MIN_AF, min(MAX_AF, corrected_uf))
self._afs.append(estimated_af) self._afs.append(estimated_af)
if len(self._afs) > self.MAX_AFS_COUNT: if len(self._afs) > self.MAX_AFS_COUNT:
self._afs = self._afs[-self.MAX_AFS_COUNT:] self._afs = self._afs[-self.MAX_AFS_COUNT :]
wsum = sum(af * (i + 1) for i, af in enumerate(self._afs)) wsum = sum(af * (i + 1) for i, af in enumerate(self._afs))
wtotal = sum(range(1, len(self._afs) + 1)) wtotal = sum(range(1, len(self._afs) + 1))
self.af(wsum / wtotal if wtotal else estimated_af) self.af(wsum / wtotal if wtotal else estimated_af)
@@ -600,7 +602,10 @@ class SM:
# Global state management # Global state management
# ============================================================================ # ============================================================================
_GLOBAL_STATE_FILE = pathlib.Path(config_var.get()["global"]["paths"]["misc"]) / "sm15m_global_state.json" _GLOBAL_STATE_FILE = (
pathlib.Path(config_var.get()["global"]["paths"]["misc"])
/ "sm15m_global_state.json"
)
def _get_global_sm(): def _get_global_sm():
@@ -702,7 +707,8 @@ class SM15MAlgorithm(BaseAlgorithm):
last_date = data.get("last_date", 0) last_date = data.get("last_date", 0)
item.previous_date = ( item.previous_date = (
daystamp_to_datetime(last_date).replace(tzinfo=None) daystamp_to_datetime(last_date).replace(tzinfo=None)
if last_date > 0 else None if last_date > 0
else None
) )
next_date_ms = data.get("next_date_ms", 0) next_date_ms = data.get("next_date_ms", 0)
@@ -743,9 +749,7 @@ class SM15MAlgorithm(BaseAlgorithm):
data["last_date"] = datetime_to_daystamp(item.previous_date) data["last_date"] = datetime_to_daystamp(item.previous_date)
data["next_date_ms"] = int(item.due_date.timestamp() * 1000) data["next_date_ms"] = int(item.due_date.timestamp() * 1000)
data["next_date"] = datetime_to_daystamp(item.due_date) data["next_date"] = datetime_to_daystamp(item.due_date)
data["interval"] = max( data["interval"] = max(0, data["next_date"] - (data.get("last_date", 0) or 0))
0, data["next_date"] - (data.get("last_date", 0) or 0)
)
data["last_modify"] = get_timestamp() data["last_modify"] = get_timestamp()
return algodata return algodata
@@ -5,15 +5,15 @@
import pathlib import pathlib
import playsound3
from heurams.services.logger import get_logger from heurams.services.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
def play_by_path(path: pathlib.Path): def play_by_path(path: pathlib.Path):
logger.debug("playsound_audio.play_by_path: 开始播放 %s", path) logger.debug("playsound_audio.play_by_path: 开始播放 %s", path)
try: try:
import playsound3
playsound3.playsound(str(path)) playsound3.playsound(str(path))
logger.debug("播放完成: %s", path) logger.debug("播放完成: %s", path)
except Exception as e: except Exception as e:
+1 -3
View File
@@ -12,12 +12,10 @@ logger = get_logger(__name__)
# from .protocol import PlayFunctionProtocol # from .protocol import PlayFunctionProtocol
def play_by_path(path: pathlib.Path): def play_by_path(path: pathlib.Path):
logger.debug("termux_audio.play_by_path: 开始播放 %s", path) logger.debug("termux_audio.play_by_path: 开始播放 %s", path)
try: try:
os.system(f"play-audio {path}") os.system(f"play-audio {path.resolve()}")
logger.debug("播放命令已执行: %s", path) logger.debug("播放命令已执行: %s", path)
except Exception as e: except Exception as e:
logger.error("播放失败: %s, 错误: %s", path, e) logger.error("播放失败: %s, 错误: %s", path, e)
raise
+3 -3
View File
@@ -43,9 +43,9 @@ def get_timestamp_ms() -> int:
def daystamp_to_datetime(daystamp: int) -> datetime.datetime: def daystamp_to_datetime(daystamp: int) -> datetime.datetime:
"""将日戳转换为 UTC datetime (当日午夜)""" """将日戳转换为 UTC datetime (当日午夜)"""
return datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc) + datetime.timedelta( return datetime.datetime(
days=daystamp 1970, 1, 1, tzinfo=datetime.timezone.utc
) ) + datetime.timedelta(days=daystamp)
def datetime_to_daystamp(dt: datetime.datetime) -> int: def datetime_to_daystamp(dt: datetime.datetime) -> int:
+1 -1
View File
@@ -3,7 +3,7 @@ from heurams.services.logger import get_logger
logger = get_logger(__name__) logger = get_logger(__name__)
ver = "0.5.0" ver = "0.5.1"
stage = "stable" stage = "stable"
codename = "fulcrum" codename = "fulcrum"
codename_cn = "支点" codename_cn = "支点"
+12 -3
View File
@@ -25,9 +25,18 @@ class TestElectronInit:
assert e.algodata["SM-2"]["efactor"] == 2.5 assert e.algodata["SM-2"]["efactor"] == 2.5
def test_existing_data_preserved(self, timer_context): def test_existing_data_preserved(self, timer_context):
data = {"SM-2": {"efactor": 1.5, "rept": 3, "real_rept": 5, "interval": 10, data = {
"last_date": 100, "next_date": 200, "is_activated": 1, "SM-2": {
"last_modify": 1e9}} "efactor": 1.5,
"rept": 3,
"real_rept": 5,
"interval": 10,
"last_date": 100,
"next_date": 200,
"is_activated": 1,
"last_modify": 1e9,
}
}
e = Electron("test-id", data) e = Electron("test-id", data)
assert e.algodata["SM-2"]["efactor"] == 1.5 assert e.algodata["SM-2"]["efactor"] == 1.5
assert e.algodata["SM-2"]["rept"] == 3 assert e.algodata["SM-2"]["rept"] == 3
+1 -3
View File
@@ -65,8 +65,6 @@ class TestEpathModify:
def test_modify_list_index_with_parents(self): def test_modify_list_index_with_parents(self):
d = {"items": []} d = {"items": []}
result = epath( result = epath(d, "items.[3]", enable_modify=True, new_value=42, parents=True)
d, "items.[3]", enable_modify=True, new_value=42, parents=True
)
assert result == 42 assert result == 42
assert d["items"] == [None, None, None, 42] assert d["items"] == [None, None, None, 42]
Generated
+39 -323
View File
@@ -109,28 +109,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" },
] ]
[[package]]
name = "annotated-types"
version = "0.7.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" },
]
[[package]]
name = "anyio"
version = "4.13.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "idna" },
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" },
]
[[package]] [[package]]
name = "attrs" name = "attrs"
version = "26.1.0" version = "26.1.0"
@@ -206,6 +184,18 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/ae/3a/dbeec9d1ee0844c679f6bb5d6ad4e9f198b1224f4e7a32825f47f6192b0c/cffi-2.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:0a1527a803f0a659de1af2e1fd700213caba79377e27e4693648c2923da066f9", size = 184195, upload-time = "2025-09-08T23:23:43.004Z" },
] ]
[[package]]
name = "click"
version = "8.3.3"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" },
]
[[package]] [[package]]
name = "colorama" name = "colorama"
version = "0.4.6" version = "0.4.6"
@@ -299,15 +289,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346, upload-time = "2026-03-17T10:33:15.691Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346, upload-time = "2026-03-17T10:33:15.691Z" },
] ]
[[package]]
name = "distro"
version = "1.9.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" },
]
[[package]] [[package]]
name = "edge-tts" name = "edge-tts"
version = "7.2.8" version = "7.2.8"
@@ -424,20 +405,12 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/67/3c/e7e140f8cdb95b042cb125ee142e7630187e8e78d21847ca81e9d1e99bb8/fsrs-6.3.1-py3-none-any.whl", hash = "sha256:ac1bf9939573592d8c9bc1e11a00bd17e04146dc9f2c913127e2bcc431b9040b", size = 22840, upload-time = "2026-03-10T14:01:01.084Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/67/3c/e7e140f8cdb95b042cb125ee142e7630187e8e78d21847ca81e9d1e99bb8/fsrs-6.3.1-py3-none-any.whl", hash = "sha256:ac1bf9939573592d8c9bc1e11a00bd17e04146dc9f2c913127e2bcc431b9040b", size = 22840, upload-time = "2026-03-10T14:01:01.084Z" },
] ]
[[package]]
name = "h11"
version = "0.16.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
]
[[package]] [[package]]
name = "heurams" name = "heurams"
version = "0.5.0" version = "0.5.1"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "click" },
{ name = "tabulate" }, { name = "tabulate" },
{ name = "toml" }, { name = "toml" },
{ name = "transitions" }, { name = "transitions" },
@@ -450,7 +423,7 @@ algo-fsrs = [
all = [ all = [
{ name = "edge-tts" }, { name = "edge-tts" },
{ name = "fsrs" }, { name = "fsrs" },
{ name = "openai" }, { name = "llms-py" },
{ name = "playsound3" }, { name = "playsound3" },
{ name = "pytest" }, { name = "pytest" },
{ name = "pytest-cov" }, { name = "pytest-cov" },
@@ -462,7 +435,8 @@ audio-playsound = [
basic = [ basic = [
{ name = "edge-tts" }, { name = "edge-tts" },
{ name = "fsrs" }, { name = "fsrs" },
{ name = "openai" }, { name = "llms-py" },
{ name = "textual" },
] ]
dev = [ dev = [
{ name = "pytest" }, { name = "pytest" },
@@ -470,11 +444,10 @@ dev = [
{ name = "zmq" }, { name = "zmq" },
] ]
interface = [ interface = [
{ name = "psutil" },
{ name = "textual" }, { name = "textual" },
] ]
llm = [ llm = [
{ name = "openai" }, { name = "llms-py" },
] ]
tts-edgetts = [ tts-edgetts = [
{ name = "edge-tts" }, { name = "edge-tts" },
@@ -482,19 +455,20 @@ tts-edgetts = [
[package.metadata] [package.metadata]
requires-dist = [ requires-dist = [
{ name = "click", specifier = ">=8.3.3" },
{ name = "edge-tts", marker = "extra == 'tts-edgetts'", specifier = ">=7.2.8" }, { name = "edge-tts", marker = "extra == 'tts-edgetts'", specifier = ">=7.2.8" },
{ name = "fsrs", marker = "extra == 'algo-fsrs'", specifier = ">=6.3.1" }, { name = "fsrs", marker = "extra == 'algo-fsrs'", specifier = ">=6.3.1" },
{ name = "heurams", extras = ["algo-fsrs"], marker = "extra == 'all'" }, { name = "heurams", extras = ["algo-fsrs"], marker = "extra == 'all'" },
{ name = "heurams", extras = ["algo-fsrs"], marker = "extra == 'basic'" }, { name = "heurams", extras = ["algo-fsrs"], marker = "extra == 'basic'" },
{ name = "heurams", extras = ["audio-playsound"], marker = "extra == 'all'" }, { name = "heurams", extras = ["audio-playsound"], marker = "extra == 'all'" },
{ name = "heurams", extras = ["dev"], marker = "extra == 'all'" }, { name = "heurams", extras = ["dev"], marker = "extra == 'all'" },
{ name = "heurams", extras = ["interface"], marker = "extra == 'basic'" },
{ name = "heurams", extras = ["llm"], marker = "extra == 'all'" }, { name = "heurams", extras = ["llm"], marker = "extra == 'all'" },
{ name = "heurams", extras = ["llm"], marker = "extra == 'basic'" }, { name = "heurams", extras = ["llm"], marker = "extra == 'basic'" },
{ name = "heurams", extras = ["tts-edgetts"], marker = "extra == 'all'" }, { name = "heurams", extras = ["tts-edgetts"], marker = "extra == 'all'" },
{ name = "heurams", extras = ["tts-edgetts"], marker = "extra == 'basic'" }, { name = "heurams", extras = ["tts-edgetts"], marker = "extra == 'basic'" },
{ name = "openai", marker = "extra == 'llm'", specifier = ">=2.32.0" }, { name = "llms-py", marker = "extra == 'llm'", specifier = ">=3.0.0" },
{ name = "playsound3", marker = "extra == 'audio-playsound'", specifier = ">=3.3.1" }, { name = "playsound3", marker = "extra == 'audio-playsound'", specifier = ">=3.3.1" },
{ name = "psutil", marker = "extra == 'interface'", specifier = ">=7.2.2" },
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.0.0" },
{ name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" }, { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=6.0.0" },
{ name = "tabulate", specifier = ">=0.10.0" }, { name = "tabulate", specifier = ">=0.10.0" },
@@ -505,34 +479,6 @@ requires-dist = [
] ]
provides-extras = ["interface", "algo-fsrs", "tts-edgetts", "llm", "audio-playsound", "dev", "all", "basic"] provides-extras = ["interface", "algo-fsrs", "tts-edgetts", "llm", "audio-playsound", "dev", "all", "basic"]
[[package]]
name = "httpcore"
version = "1.0.9"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "certifi" },
{ name = "h11" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
]
[[package]]
name = "httpx"
version = "0.28.1"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "anyio" },
{ name = "certifi" },
{ name = "httpcore" },
{ name = "idna" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
]
[[package]] [[package]]
name = "idna" name = "idna"
version = "3.13" version = "3.13"
@@ -551,78 +497,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
] ]
[[package]]
name = "jiter"
version = "0.14.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/6e/c1/0cddc6eb17d4c53a99840953f95dd3accdc5cfc7a337b0e9b26476276be9/jiter-0.14.0.tar.gz", hash = "sha256:e8a39e66dac7153cf3f964a12aad515afa8d74938ec5cc0018adcdae5367c79e", size = 165725, upload-time = "2026-04-10T14:28:42.01Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/5a/68/7390a418f10897da93b158f2d5a8bd0bcd73a0f9ec3bb36917085bb759ef/jiter-0.14.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:2fb2ce3a7bc331256dfb14cefc34832366bb28a9aca81deaf43bbf2a5659e607", size = 316295, upload-time = "2026-04-10T14:26:24.887Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/60/a0/5854ac00ff63551c52c6c89534ec6aba4b93474e7924d64e860b1c94165b/jiter-0.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5252a7ca23785cef5d02d4ece6077a1b556a410c591b379f82091c3001e14844", size = 315898, upload-time = "2026-04-10T14:26:26.601Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/41/a1/4f44832650a16b18e8391f1bf1d6ca4909bc738351826bcc198bba4357f4/jiter-0.14.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c409578cbd77c338975670ada777add4efd53379667edf0aceea730cabede6fb", size = 343730, upload-time = "2026-04-10T14:26:28.326Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/48/64/a329e9d469f86307203594b1707e11ae51c3348d03bfd514a5f997870012/jiter-0.14.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7ede4331a1899d604463369c730dbb961ffdc5312bc7f16c41c2896415b1304a", size = 370102, upload-time = "2026-04-10T14:26:30.089Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/94/c1/5e3dfc59635aa4d4c7bd20a820ac1d09b8ed851568356802cf1c08edb3cf/jiter-0.14.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92cd8b6025981a041f5310430310b55b25ca593972c16407af8837d3d7d2ca01", size = 461335, upload-time = "2026-04-10T14:26:31.911Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e3/1b/dd157009dbc058f7b00108f545ccb72a2d56461395c4fc7b9cfdccb00af4/jiter-0.14.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:351bf6eda4e3a7ceb876377840c702e9a3e4ecc4624dbfb2d6463c67ae52637d", size = 378536, upload-time = "2026-04-10T14:26:33.595Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/91/78/256013667b7c10b8834f8e6e54cd3e562d4c6e34227a1596addccc05e38c/jiter-0.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1dcfbeb93d9ecd9ca128bbf8910120367777973fa193fb9a39c31237d8df165", size = 353859, upload-time = "2026-04-10T14:26:35.098Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/de/d9/137d65ade9093a409fe80955ce60b12bb753722c986467aeda47faf450ad/jiter-0.14.0-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:ae039aaef8de3f8157ecc1fdd4d85043ac4f57538c245a0afaecb8321ec951c3", size = 357626, upload-time = "2026-04-10T14:26:36.685Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/2e/48/76750835b87029342727c1a268bea8878ab988caf81ee4e7b880900eeb5a/jiter-0.14.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7d9d51eb96c82a9652933bd769fe6de66877d6eb2b2440e281f2938c51b5643e", size = 393172, upload-time = "2026-04-10T14:26:38.097Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a6/60/456c4e81d5c8045279aefe60e9e483be08793828800a4e64add8fdde7f2a/jiter-0.14.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d824ca4148b705970bf4e120924a212fdfca9859a73e42bd7889a63a4ea6bb98", size = 520300, upload-time = "2026-04-10T14:26:39.532Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a8/9f/2020e0984c235f678dced38fe4eec3058cf528e6af36ebf969b410305941/jiter-0.14.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ff3a6465b3a0f54b1a430f45c3c0ba7d61ceb45cbc3e33f9e1a7f638d690baf3", size = 553059, upload-time = "2026-04-10T14:26:40.991Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ef/32/e2d298e1a22a4bbe6062136d1c7192db7dba003a6975e51d9a9eecabc4c2/jiter-0.14.0-cp312-cp312-win32.whl", hash = "sha256:5dec7c0a3e98d2a3f8a2e67382d0d7c3ac60c69103a4b271da889b4e8bb1e129", size = 206030, upload-time = "2026-04-10T14:26:42.517Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/36/ac/96369141b3d8a4a8e4590e983085efe1c436f35c0cda940dd76d942e3e40/jiter-0.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:fc7e37b4b8bc7e80a63ad6cfa5fc11fab27dbfea4cc4ae644b1ab3f273dc348f", size = 201603, upload-time = "2026-04-10T14:26:44.328Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/01/c3/75d847f264647017d7e3052bbcc8b1e24b95fa139c320c5f5066fa7a0bdd/jiter-0.14.0-cp312-cp312-win_arm64.whl", hash = "sha256:ee4a72f12847ef29b072aee9ad5474041ab2924106bdca9fcf5d7d965853e057", size = 191525, upload-time = "2026-04-10T14:26:46Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/97/2a/09f70020898507a89279659a1afe3364d57fc1b2c89949081975d135f6f5/jiter-0.14.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:af72f204cf4d44258e5b4c1745130ac45ddab0e71a06333b01de660ab4187a94", size = 315502, upload-time = "2026-04-10T14:26:47.697Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d6/be/080c96a45cd74f9fce5db4fd68510b88087fb37ffe2541ff73c12db92535/jiter-0.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4b77da71f6e819be5fbcec11a453fde5b1d0267ef6ed487e2a392fd8e14e4e3a", size = 314870, upload-time = "2026-04-10T14:26:49.149Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/7d/5e/2d0fee155826a968a832cc32438de5e2a193292c8721ca70d0b53e58245b/jiter-0.14.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f4ea612fe8b84b8b04e51d0e78029ecf3466348e25973f953de6e6a59aa4c1", size = 343406, upload-time = "2026-04-10T14:26:50.762Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/70/af/bf9ee0d3a4f8dc0d679fc1337f874fe60cdbf841ebbb304b374e1c9aaceb/jiter-0.14.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:62fe2451f8fcc0240261e6a4df18ecbcd58327857e61e625b2393ea3b468aac9", size = 369415, upload-time = "2026-04-10T14:26:52.188Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0f/83/8e8561eadba31f4d3948a5b712fb0447ec71c3560b57a855449e7b8ddc98/jiter-0.14.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6112f26f5afc75bcb475787d29da3aa92f9d09c7858f632f4be6ffe607be82e9", size = 461456, upload-time = "2026-04-10T14:26:53.611Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/f6/c9/c5299e826a5fe6108d172b344033f61c69b1bb979dd8d9ddd4278a160971/jiter-0.14.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:215a6cb8fb7dc702aa35d475cc00ddc7f970e5c0b1417fb4b4ac5d82fa2a29db", size = 378488, upload-time = "2026-04-10T14:26:55.211Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/5d/37/c16d9d15c0a471b8644b1abe3c82668092a707d9bedcf076f24ff2e380cd/jiter-0.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4ab96a30fb3cb2c7e0cd33f7616c8860da5f5674438988a54ac717caccdbaa", size = 353242, upload-time = "2026-04-10T14:26:56.705Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/58/ea/8050cb0dc654e728e1bfacbc0c640772f2181af5dedd13ae70145743a439/jiter-0.14.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:3a99c1387b1f2928f799a9de899193484d66206a50e98233b6b088a7f0c1edb2", size = 356823, upload-time = "2026-04-10T14:26:58.281Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b0/3b/cf71506d270e5f84d97326bf220e47aed9b95e9a4a060758fb07772170ab/jiter-0.14.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ab18d11074485438695f8d34a1b6da61db9754248f96d51341956607a8f39985", size = 392564, upload-time = "2026-04-10T14:27:00.018Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b0/cc/8c6c74a3efb5bd671bfd14f51e8a73375464ca914b1551bc3b40e26ac2c9/jiter-0.14.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:801028dcfc26ac0895e4964cbc0fd62c73be9fd4a7d7b1aaf6e5790033a719b7", size = 520322, upload-time = "2026-04-10T14:27:01.664Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/41/24/68d7b883ec959884ddf00d019b2e0e82ba81b167e1253684fa90519ce33c/jiter-0.14.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ad425b087aafb4a1c7e1e98a279200743b9aaf30c3e0ba723aec93f061bd9bc8", size = 552619, upload-time = "2026-04-10T14:27:03.316Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b6/89/b1a0985223bbf3150ff9e8f46f98fc9360c1de94f48abe271bbe1b465682/jiter-0.14.0-cp313-cp313-win32.whl", hash = "sha256:882bcb9b334318e233950b8be366fe5f92c86b66a7e449e76975dfd6d776a01f", size = 205699, upload-time = "2026-04-10T14:27:04.662Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/4c/19/3f339a5a7f14a11730e67f6be34f9d5105751d547b615ef593fa122a5ded/jiter-0.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:9b8c571a5dba09b98bd3462b5a53f27209a5cbbe85670391692ede71974e979f", size = 201323, upload-time = "2026-04-10T14:27:06.139Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/50/56/752dd89c84be0e022a8ea3720bcfa0a8431db79a962578544812ce061739/jiter-0.14.0-cp313-cp313-win_arm64.whl", hash = "sha256:34f19dcc35cb1abe7c369b3756babf8c7f04595c0807a848df8f26ef8298ef92", size = 191099, upload-time = "2026-04-10T14:27:07.564Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/91/28/292916f354f25a1fe8cf2c918d1415c699a4a659ae00be0430e1c5d9ffea/jiter-0.14.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e89bcd7d426a75bb4952c696b267075790d854a07aad4c9894551a82c5b574ab", size = 320880, upload-time = "2026-04-10T14:27:09.326Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ad/c7/b002a7d8b8957ac3d469bd59c18ef4b1595a5216ae0de639a287b9816023/jiter-0.14.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b25beaa0d4447ea8c7ae0c18c688905d34840d7d0b937f2f7bdd52162c98a40", size = 346563, upload-time = "2026-04-10T14:27:11.287Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/f9/3b/f8d07580d8706021d255a6356b8fab13ee4c869412995550ce6ed4ddf97d/jiter-0.14.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:651a8758dd413c51e3b7f6557cdc6921faf70b14106f45f969f091f5cda990ea", size = 357928, upload-time = "2026-04-10T14:27:12.729Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/47/5b/ac1a974da29e35507230383110ffec59998b290a8732585d04e19a9eb5ba/jiter-0.14.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e1a7eead856a5038a8d291f1447176ab0b525c77a279a058121b5fccee257f6f", size = 203519, upload-time = "2026-04-10T14:27:14.125Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/96/6d/9fc8433d667d2454271378a79747d8c76c10b51b482b454e6190e511f244/jiter-0.14.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e692633a12cda97e352fdcd1c4acc971b1c28707e1e33aeef782b0cbf051975", size = 190113, upload-time = "2026-04-10T14:27:16.638Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/4f/1e/354ed92461b165bd581f9ef5150971a572c873ec3b68a916d5aa91da3cc2/jiter-0.14.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:6f396837fc7577871ca8c12edaf239ed9ccef3bbe39904ae9b8b63ce0a48b140", size = 315277, upload-time = "2026-04-10T14:27:18.109Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a6/95/8c7c7028aa8636ac21b7a55faef3e34215e6ed0cbf5ae58258427f621aa3/jiter-0.14.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a4d50ea3d8ba4176f79754333bd35f1bbcd28e91adc13eb9b7ca91bc52a6cef9", size = 315923, upload-time = "2026-04-10T14:27:19.603Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/47/40/e2a852a44c4a089f2681a16611b7ce113224a80fd8504c46d78491b47220/jiter-0.14.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce17f8a050447d1b4153bda4fb7d26e6a9e74eb4f4a41913f30934c5075bf615", size = 344943, upload-time = "2026-04-10T14:27:21.262Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/fc/1f/670f92adee1e9895eac41e8a4d623b6da68c4d46249d8b556b60b63f949e/jiter-0.14.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f4f1c4b125e1652aefbc2e2c1617b60a160ab789d180e3d423c41439e5f32850", size = 369725, upload-time = "2026-04-10T14:27:22.766Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/01/2f/541c9ba567d05de1c4874a0f8f8c5e3fd78e2b874266623da9a775cf46e0/jiter-0.14.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be808176a6a3a14321d18c603f2d40741858a7c4fc982f83232842689fe86dd9", size = 461210, upload-time = "2026-04-10T14:27:24.315Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ce/a9/c31cbec09627e0d5de7aeaec7690dba03e090caa808fefd8133137cf45bc/jiter-0.14.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26679d58ba816f88c3849306dd58cb863a90a1cf352cdd4ef67e30ccf8a77994", size = 380002, upload-time = "2026-04-10T14:27:26.155Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/50/02/3c05c1666c41904a2f607475a73e7a4763d1cbde2d18229c4f85b22dc253/jiter-0.14.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80381f5a19af8fa9aef743f080e34f6b25ebd89656475f8cf0470ec6157052aa", size = 354678, upload-time = "2026-04-10T14:27:27.701Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/7d/97/e15b33545c2b13518f560d695f974b9891b311641bdcf178d63177e8801e/jiter-0.14.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:004df5fdb8ecbd6d99f3227df18ba1a259254c4359736a2e6f036c944e02d7c5", size = 358920, upload-time = "2026-04-10T14:27:29.256Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ad/d2/8b1461def6b96ba44530df20d07ef7a1c7da22f3f9bf1727e2d611077bf1/jiter-0.14.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cff5708f7ed0fa098f2b53446c6fa74c48469118e5cd7497b4f1cd569ab06928", size = 394512, upload-time = "2026-04-10T14:27:31.344Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e3/88/837566dd6ed6e452e8d3205355afd484ce44b2533edfa4ed73a298ea893e/jiter-0.14.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:2492e5f06c36a976d25c7cc347a60e26d5470178d44cde1b9b75e60b4e519f28", size = 521120, upload-time = "2026-04-10T14:27:33.299Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/89/6b/b00b45c4d1b4c031777fe161d620b755b5b02cdade1e316dcb46e4471d63/jiter-0.14.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:7609cfbe3a03d37bfdbf5052012d5a879e72b83168a363deae7b3a26564d57de", size = 553668, upload-time = "2026-04-10T14:27:34.868Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ad/d8/6fe5b42011d19397433d345716eac16728ac241862a2aac9c91923c7509a/jiter-0.14.0-cp314-cp314-win32.whl", hash = "sha256:7282342d32e357543565286b6450378c3cd402eea333fc1ebe146f1fabb306fc", size = 207001, upload-time = "2026-04-10T14:27:36.455Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e5/43/5c2e08da1efad5e410f0eaaabeadd954812612c33fbbd8fd5328b489139d/jiter-0.14.0-cp314-cp314-win_amd64.whl", hash = "sha256:bd77945f38866a448e73b0b7637366afa814d4617790ecd88a18ca74377e6c02", size = 202187, upload-time = "2026-04-10T14:27:38Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/aa/1f/6e39ac0b4cdfa23e606af5b245df5f9adaa76f35e0c5096790da430ca506/jiter-0.14.0-cp314-cp314-win_arm64.whl", hash = "sha256:f2d4c61da0821ee42e0cdf5489da60a6d074306313a377c2b35af464955a3611", size = 192257, upload-time = "2026-04-10T14:27:39.504Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/05/57/7dbc0ffbbb5176a27e3518716608aa464aee2e2887dc938f0b900a120449/jiter-0.14.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1bf7ff85517dd2f20a5750081d2b75083c1b269cf75afc7511bdf1f9548beb3b", size = 323441, upload-time = "2026-04-10T14:27:41.039Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/83/6e/7b3314398d8983f06b557aa21b670511ec72d3b79a68ee5e4d9bff972286/jiter-0.14.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8ef8791c3e78d6c6b157c6d360fbb5c715bebb8113bc6a9303c5caff012754a", size = 348109, upload-time = "2026-04-10T14:27:42.552Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ae/4f/8dc674bcd7db6dba566de73c08c763c337058baff1dbeb34567045b27cdc/jiter-0.14.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e74663b8b10da1fe0f4e4703fd7980d24ad17174b6bb35d8498d6e3ebce2ae6a", size = 368328, upload-time = "2026-04-10T14:27:44.574Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/3b/5f/188e09a1f20906f98bbdec44ed820e19f4e8eb8aff88b9d1a5a497587ff3/jiter-0.14.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1aca29ba52913f78362ec9c2da62f22cdc4c3083313403f90c15460979b84d9b", size = 463301, upload-time = "2026-04-10T14:27:46.717Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ac/f0/19046ef965ed8f349e8554775bb12ff4352f443fbe12b95d31f575891256/jiter-0.14.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8b39b7d87a952b79949af5fef44d2544e58c21a28da7f1bae3ef166455c61746", size = 378891, upload-time = "2026-04-10T14:27:48.32Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/c4/c3/da43bd8431ee175695777ee78cf0e93eacbb47393ff493f18c45231b427d/jiter-0.14.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d918a68b26e9fab068c2b5453577ef04943ab2807b9a6275df2a812599a310", size = 360749, upload-time = "2026-04-10T14:27:49.88Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/72/26/e054771be889707c6161dbdec9c23d33a9ec70945395d70f07cfea1e9a6f/jiter-0.14.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:b08997c35aee1201c1a5361466a8fb9162d03ae7bf6568df70b6c859f1e654a4", size = 358526, upload-time = "2026-04-10T14:27:51.504Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/c3/0f/7bea65ea2a6d91f2bf989ff11a18136644392bf2b0497a1fa50934c30a9c/jiter-0.14.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:260bf7ca20704d58d41f669e5e9fe7fe2fa72901a6b324e79056f5d52e9c9be2", size = 393926, upload-time = "2026-04-10T14:27:53.368Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/3c/a1/b1ff7d70deef61ac0b7c6c2f12d2ace950cdeecb4fdc94500a0926802857/jiter-0.14.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:37826e3df29e60f30a382f9294348d0238ef127f4b5d7f5f8da78b5b9e050560", size = 521052, upload-time = "2026-04-10T14:27:55.058Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0b/7b/3b0649983cbaf15eda26a414b5b1982e910c67bd6f7b1b490f3cfc76896a/jiter-0.14.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:645be49c46f2900937ba0eaf871ad5183c96858c0af74b6becc7f4e367e36e06", size = 553716, upload-time = "2026-04-10T14:27:57.269Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/97/f8/33d78c83bd93ae0c0af05293a6660f88a1977caef39a6d72a84afab94ce0/jiter-0.14.0-cp314-cp314t-win32.whl", hash = "sha256:2f7877ed45118de283786178eceaf877110abacd04fde31efff3940ae9672674", size = 207957, upload-time = "2026-04-10T14:27:59.285Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d6/ac/2b760516c03e2227826d1f7025d89bf6bf6357a28fe75c2a2800873c50bf/jiter-0.14.0-cp314-cp314t-win_amd64.whl", hash = "sha256:14c0cb10337c49f5eafe8e7364daca5e29a020ea03580b8f8e6c597fed4e1588", size = 204690, upload-time = "2026-04-10T14:28:00.962Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/dc/2e/a44c20c58aeed0355f2d326969a181696aeb551a25195f47563908a815be/jiter-0.14.0-cp314-cp314t-win_arm64.whl", hash = "sha256:5419d4aa2024961da9fe12a9cfe7484996735dca99e8e090b5c88595ef1951ff", size = 191338, upload-time = "2026-04-10T14:28:02.853Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/21/42/9042c3f3019de4adcb8c16591c325ec7255beea9fcd33a42a43f3b0b1000/jiter-0.14.0-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:fbd9e482663ca9d005d051330e4d2d8150bb208a209409c10f7e7dfdf7c49da9", size = 308810, upload-time = "2026-04-10T14:28:34.673Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/60/cf/a7e19b308bd86bb04776803b1f01a5f9a287a4c55205f4708827ee487fbf/jiter-0.14.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:33a20d838b91ef376b3a56896d5b04e725c7df5bc4864cc6569cf046a8d73b6d", size = 308443, upload-time = "2026-04-10T14:28:36.658Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ca/44/e26ede3f0caeff93f222559cb0cc4ca68579f07d009d7b6010c5b586f9b1/jiter-0.14.0-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:432c4db5255d86a259efde91e55cb4c8d18c0521d844c9e2e7efcce3899fb016", size = 343039, upload-time = "2026-04-10T14:28:38.356Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/da/e9/1f9ada30cef7b05e74bb06f52127e7a724976c225f46adb65c37b1dadfb6/jiter-0.14.0-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67f00d94b281174144d6532a04b66a12cb866cbdc47c3af3bfe2973677f9861a", size = 349613, upload-time = "2026-04-10T14:28:40.066Z" },
]
[[package]] [[package]]
name = "linkify-it-py" name = "linkify-it-py"
version = "2.1.0" version = "2.1.0"
@@ -635,16 +509,28 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b4/de/88b3be5c31b22333b3ca2f6ff1de4e863d8fe45aaea7485f591970ec1d3e/linkify_it_py-2.1.0-py3-none-any.whl", hash = "sha256:0d252c1594ecba2ecedc444053db5d3a9b7ec1b0dd929c8f1d74dce89f86c05e", size = 19878, upload-time = "2026-03-01T07:48:46.098Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/b4/de/88b3be5c31b22333b3ca2f6ff1de4e863d8fe45aaea7485f591970ec1d3e/linkify_it_py-2.1.0-py3-none-any.whl", hash = "sha256:0d252c1594ecba2ecedc444053db5d3a9b7ec1b0dd929c8f1d74dce89f86c05e", size = 19878, upload-time = "2026-03-01T07:48:46.098Z" },
] ]
[[package]]
name = "llms-py"
version = "3.0.44"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "aiohttp" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/5d/3e/2a8c381f0713aa46d78477504e0a21249a3dfe23dda4d0a0acf0bc4ef4f8/llms_py-3.0.44.tar.gz", hash = "sha256:4d1de78e388e3a6d81cfed632b2f4bc47f872eec3702185d3e4b38a59363c00f", size = 3397414, upload-time = "2026-04-24T17:23:37.549Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/39/c9/9703f9ad198bb63f4e713e71fd022d4b979b3bdc298471ae2e2cdb7ae286/llms_py-3.0.44-py3-none-any.whl", hash = "sha256:8983f37a8cfcfc47aa45f61f16f574f8111db8480ffcf569e74e26abdfcf53c4", size = 3469508, upload-time = "2026-04-24T17:23:35.494Z" },
]
[[package]] [[package]]
name = "markdown-it-py" name = "markdown-it-py"
version = "4.0.0" version = "4.2.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" } source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [ dependencies = [
{ name = "mdurl" }, { name = "mdurl" },
] ]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" }
wheels = [ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" },
] ]
[package.optional-dependencies] [package.optional-dependencies]
@@ -654,14 +540,14 @@ linkify = [
[[package]] [[package]]
name = "mdit-py-plugins" name = "mdit-py-plugins"
version = "0.5.0" version = "0.6.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" } source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [ dependencies = [
{ name = "markdown-it-py" }, { name = "markdown-it-py" },
] ]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/b2/fd/a756d36c0bfba5f6e39a1cdbdbfdd448dc02692467d83816dff4592a1ebc/mdit_py_plugins-0.5.0.tar.gz", hash = "sha256:f4918cb50119f50446560513a8e311d574ff6aaed72606ddae6d35716fe809c6", size = 44655, upload-time = "2025-08-11T07:25:49.083Z" } sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/d8/3d/e0e8d9d1cee04f758120915e2b2a3a07eb41f8cf4654b4734788a522bcd1/mdit_py_plugins-0.6.0.tar.gz", hash = "sha256:2436f14a7295837ac9228a36feeabda867c4abc488c8d019ad5c0bda88eee040", size = 56025, upload-time = "2026-05-07T12:20:42.295Z" }
wheels = [ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/fb/86/dd6e5db36df29e76c7a7699123569a4a18c1623ce68d826ed96c62643cae/mdit_py_plugins-0.5.0-py3-none-any.whl", hash = "sha256:07a08422fc1936a5d26d146759e9155ea466e842f5ab2f7d2266dd084c8dab1f", size = 57205, upload-time = "2025-08-11T07:25:47.597Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/71/d6/48f5b9e44e2e760855d7b489b1317cd7620e82dcb73197961e5cc1391348/mdit_py_plugins-0.6.0-py3-none-any.whl", hash = "sha256:f7e7a25d8b616fee99cb1e330da73451d11a8061baf39bb9663ab9ce0e005b90", size = 66655, upload-time = "2026-05-07T12:20:41.226Z" },
] ]
[[package]] [[package]]
@@ -772,25 +658,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/81/08/7036c080d7117f28a4af526d794aab6a84463126db031b007717c1a6676e/multidict-6.7.1-py3-none-any.whl", hash = "sha256:55d97cc6dae627efa6a6e548885712d4864b81110ac76fa4e534c03819fa4a56", size = 12319, upload-time = "2026-01-26T02:46:44.004Z" },
] ]
[[package]]
name = "openai"
version = "2.34.0"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "anyio" },
{ name = "distro" },
{ name = "httpx" },
{ name = "jiter" },
{ name = "pydantic" },
{ name = "sniffio" },
{ name = "tqdm" },
{ name = "typing-extensions" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/7b/89/f1e78f5f828f4e97a6ebca8f45c6b35667da12b074ac490dc8362b882279/openai-2.34.0.tar.gz", hash = "sha256:828b4efcbb126352c2b5eb97d33ae890c92a71ab72511aefc1b7fe64aeccb07b", size = 759556, upload-time = "2026-05-04T17:34:08.721Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/f2/40/f090499f10514515081d09cb9da09f25b821eb20497e9423afe4f07b4ecf/openai-2.34.0-py3-none-any.whl", hash = "sha256:c996a71b1a210f3569844572ad4c609307e978515fb76877cf449b72596e549e", size = 1316535, upload-time = "2026-05-04T17:34:06.773Z" },
]
[[package]] [[package]]
name = "packaging" name = "packaging"
version = "26.2" version = "26.2"
@@ -914,34 +781,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" },
] ]
[[package]]
name = "psutil"
version = "7.2.2"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/51/08/510cbdb69c25a96f4ae523f733cdc963ae654904e8db864c07585ef99875/psutil-7.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2edccc433cbfa046b980b0df0171cd25bcaeb3a68fe9022db0979e7aa74a826b", size = 130595, upload-time = "2026-01-28T18:14:57.293Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d6/f5/97baea3fe7a5a9af7436301f85490905379b1c6f2dd51fe3ecf24b4c5fbf/psutil-7.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e78c8603dcd9a04c7364f1a3e670cea95d51ee865e4efb3556a3a63adef958ea", size = 131082, upload-time = "2026-01-28T18:14:59.732Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/16/ba/0756dca669f5a9300d0cbcbfae9a4c30e446dfc7440ffe43ded5724bfd93/psutil-7.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:ab486563df44c17f5173621c7b198955bd6b613fb87c71c161f827d3fb149a9b", size = 139893, upload-time = "2026-01-28T18:15:06.378Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/1c/61/8fa0e26f33623b49949346de05ec1ddaad02ed8ba64af45f40a147dbfa97/psutil-7.2.2-cp313-cp313t-win_arm64.whl", hash = "sha256:ae0aefdd8796a7737eccea863f80f81e468a1e4cf14d926bd9b6f5f2d5f90ca9", size = 135589, upload-time = "2026-01-28T18:15:08.03Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/81/69/ef179ab5ca24f32acc1dac0c247fd6a13b501fd5534dbae0e05a1c48b66d/psutil-7.2.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:eed63d3b4d62449571547b60578c5b2c4bcccc5387148db46e0c2313dad0ee00", size = 130664, upload-time = "2026-01-28T18:15:09.469Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/7b/64/665248b557a236d3fa9efc378d60d95ef56dd0a490c2cd37dafc7660d4a9/psutil-7.2.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7b6d09433a10592ce39b13d7be5a54fbac1d1228ed29abc880fb23df7cb694c9", size = 131087, upload-time = "2026-01-28T18:15:11.724Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/dd/2c/ff9bfb544f283ba5f83ba725a3c5fec6d6b10b8f27ac1dc641c473dc390d/psutil-7.2.2-cp314-cp314t-win_amd64.whl", hash = "sha256:c7663d4e37f13e884d13994247449e9f8f574bc4655d509c3b95e9ec9e2b9dc1", size = 141228, upload-time = "2026-01-28T18:15:18.385Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/f2/fc/f8d9c31db14fcec13748d373e668bc3bed94d9077dbc17fb0eebc073233c/psutil-7.2.2-cp314-cp314t-win_arm64.whl", hash = "sha256:11fe5a4f613759764e79c65cf11ebdf26e33d6dd34336f8a337aa2996d71c841", size = 136284, upload-time = "2026-01-28T18:15:19.912Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e7/36/5ee6e05c9bd427237b11b3937ad82bb8ad2752d72c6969314590dd0c2f6e/psutil-7.2.2-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ed0cace939114f62738d808fdcecd4c869222507e266e574799e9c0faa17d486", size = 129090, upload-time = "2026-01-28T18:15:22.168Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/80/c4/f5af4c1ca8c1eeb2e92ccca14ce8effdeec651d5ab6053c589b074eda6e1/psutil-7.2.2-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:1a7b04c10f32cc88ab39cbf606e117fd74721c831c98a27dc04578deb0c16979", size = 129859, upload-time = "2026-01-28T18:15:23.795Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b4/90/e2159492b5426be0c1fef7acba807a03511f97c5f86b3caeda6ad92351a7/psutil-7.2.2-cp37-abi3-win_amd64.whl", hash = "sha256:eb7e81434c8d223ec4a219b5fc1c47d0417b12be7ea866e24fb5ad6e84b3d988", size = 137737, upload-time = "2026-01-28T18:15:33.849Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8c/c7/7bb2e321574b10df20cbde462a94e2b71d05f9bbda251ef27d104668306a/psutil-7.2.2-cp37-abi3-win_arm64.whl", hash = "sha256:8c233660f575a5a89e6d4cb65d9f938126312bca76d8fe087b947b3a1aaac9ee", size = 134617, upload-time = "2026-01-28T18:15:36.514Z" },
]
[[package]] [[package]]
name = "pycparser" name = "pycparser"
version = "3.0" version = "3.0"
@@ -951,96 +790,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" },
] ]
[[package]]
name = "pydantic"
version = "2.13.3"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "annotated-types" },
{ name = "pydantic-core" },
{ name = "typing-extensions" },
{ name = "typing-inspection" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" },
]
[[package]]
name = "pydantic-core"
version = "2.46.3"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "typing-extensions" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/4b/cb/5b47425556ecc1f3fe18ed2a0083188aa46e1dd812b06e406475b3a5d536/pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67", size = 2101946, upload-time = "2026-04-20T14:40:52.581Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a1/4f/2fb62c2267cae99b815bbf4a7b9283812c88ca3153ef29f7707200f1d4e5/pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089", size = 1951612, upload-time = "2026-04-20T14:42:42.996Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/50/6e/b7348fd30d6556d132cddd5bd79f37f96f2601fe0608afac4f5fb01ec0b3/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0", size = 1977027, upload-time = "2026-04-20T14:42:02.001Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/82/11/31d60ee2b45540d3fb0b29302a393dbc01cd771c473f5b5147bcd353e593/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789", size = 2063008, upload-time = "2026-04-20T14:44:17.952Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8a/db/3a9d1957181b59258f44a2300ab0f0be9d1e12d662a4f57bb31250455c52/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d", size = 2233082, upload-time = "2026-04-20T14:40:57.934Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/9c/e1/3277c38792aeb5cfb18c2f0c5785a221d9ff4e149abbe1184d53d5f72273/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c", size = 2304615, upload-time = "2026-04-20T14:42:12.584Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/5e/d5/e3d9717c9eba10855325650afd2a9cba8e607321697f18953af9d562da2f/pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395", size = 2094380, upload-time = "2026-04-20T14:43:05.522Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a1/20/abac35dedcbfd66c6f0b03e4e3564511771d6c9b7ede10a362d03e110d9b/pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396", size = 2135429, upload-time = "2026-04-20T14:41:55.549Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/6c/a5/41bfd1df69afad71b5cf0535055bccc73022715ad362edbc124bc1e021d7/pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d", size = 2174582, upload-time = "2026-04-20T14:41:45.96Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/79/65/38d86ea056b29b2b10734eb23329b7a7672ca604df4f2b6e9c02d4ee22fe/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca", size = 2187533, upload-time = "2026-04-20T14:40:55.367Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b6/55/a1129141678a2026badc539ad1dee0a71d06f54c2f06a4bd68c030ac781b/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976", size = 2332985, upload-time = "2026-04-20T14:44:13.05Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d7/60/cb26f4077719f709e54819f4e8e1d43f4091f94e285eb6bd21e1190a7b7c/pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b", size = 2373670, upload-time = "2026-04-20T14:41:53.421Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/6b/7e/c3f21882bdf1d8d086876f81b5e296206c69c6082551d776895de7801fa0/pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4", size = 1966722, upload-time = "2026-04-20T14:44:30.588Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/57/be/6b5e757b859013ebfbd7adba02f23b428f37c86dcbf78b5bb0b4ffd36e99/pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1", size = 2072970, upload-time = "2026-04-20T14:42:54.248Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/bf/f8/a989b21cc75e9a32d24192ef700eea606521221a89faa40c919ce884f2b1/pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72", size = 2035963, upload-time = "2026-04-20T14:44:20.4Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37", size = 2102109, upload-time = "2026-04-20T14:41:24.219Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f", size = 1951820, upload-time = "2026-04-20T14:42:14.236Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8", size = 1977785, upload-time = "2026-04-20T14:42:31.648Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad", size = 2062761, upload-time = "2026-04-20T14:40:37.093Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c", size = 2232989, upload-time = "2026-04-20T14:42:59.254Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f", size = 2303975, upload-time = "2026-04-20T14:41:32.287Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35", size = 2095325, upload-time = "2026-04-20T14:42:47.685Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687", size = 2133368, upload-time = "2026-04-20T14:41:22.766Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3", size = 2173908, upload-time = "2026-04-20T14:42:52.044Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022", size = 2186422, upload-time = "2026-04-20T14:43:29.55Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23", size = 2332709, upload-time = "2026-04-20T14:42:16.134Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7", size = 2372428, upload-time = "2026-04-20T14:41:10.974Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13", size = 1965601, upload-time = "2026-04-20T14:41:42.128Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0", size = 2071517, upload-time = "2026-04-20T14:43:36.096Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec", size = 2035802, upload-time = "2026-04-20T14:43:38.507Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/34/42/f426db557e8ab2791bc7562052299944a118655496fbff99914e564c0a94/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803", size = 2091877, upload-time = "2026-04-20T14:43:27.091Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/5c/4f/86a832a9d14df58e663bfdf4627dc00d3317c2bd583c4fb23390b0f04b8e/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3", size = 1932428, upload-time = "2026-04-20T14:40:45.781Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/11/1a/fe857968954d93fb78e0d4b6df5c988c74c4aaa67181c60be7cfe327c0ca/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5", size = 1997550, upload-time = "2026-04-20T14:44:02.425Z" },
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/17/eb/9d89ad2d9b0ba8cd65393d434471621b98912abb10fbe1df08e480ba57b5/pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4", size = 2137657, upload-time = "2026-04-20T14:42:45.149Z" },
]
[[package]] [[package]]
name = "pygments" name = "pygments"
version = "2.20.0" version = "2.20.0"
@@ -1161,15 +910,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" },
] ]
[[package]]
name = "sniffio"
version = "1.3.1"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" },
]
[[package]] [[package]]
name = "tabulate" name = "tabulate"
version = "0.10.0" version = "0.10.0"
@@ -1205,18 +945,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" },
] ]
[[package]]
name = "tqdm"
version = "4.67.3"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" },
]
[[package]] [[package]]
name = "transitions" name = "transitions"
version = "0.9.3" version = "0.9.3"
@@ -1238,18 +966,6 @@ wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, { url = "https://mirrors.ustc.edu.cn/pypi/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
] ]
[[package]]
name = "typing-inspection"
version = "0.4.2"
source = { registry = "https://mirrors.ustc.edu.cn/pypi/simple" }
dependencies = [
{ name = "typing-extensions" },
]
sdist = { url = "https://mirrors.ustc.edu.cn/pypi/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" }
wheels = [
{ url = "https://mirrors.ustc.edu.cn/pypi/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" },
]
[[package]] [[package]]
name = "uc-micro-py" name = "uc-micro-py"
version = "2.0.0" version = "2.0.0"